This is an automated email from the git hooks/post-receive script. Git pushed a commit to branch master in repository ffmpeg.
commit 33b215d1554a14e87416a24f8e6034312e629af7 Author: Marton Balint <[email protected]> AuthorDate: Sat Feb 7 18:17:41 2026 +0100 Commit: Marton Balint <[email protected]> CommitDate: Sun Feb 15 20:28:31 2026 +0100 avcodec/libvpxenc: add experimental support for alpha pixel formats other than YUV 4:2:0. I could not find any documentation which disallows the use of transparency for pixel formats other than YUV 4:2:0, so this patch adds support for transparency using 4:2:2, 4:4:4, RGB, and their high bit depth variants. It is not quite clear if the alpha channel should be encoded using the same pixel format as the normal channels, or it should be always YUV 4:2:0. I sticked to 4:2:0. Unfortunately the browsers I tested (chrome, firefox) only support 4:2:0 properly, so let's require an experimental flag to generate files with the new, more exotic pixel formats. Signed-off-by: Marton Balint <[email protected]> --- libavcodec/libvpxenc.c | 51 +++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 5 deletions(-) diff --git a/libavcodec/libvpxenc.c b/libavcodec/libvpxenc.c index 082709c41f..88c058c403 100644 --- a/libavcodec/libvpxenc.c +++ b/libavcodec/libvpxenc.c @@ -480,7 +480,7 @@ static av_cold int codecctl_int(AVCodecContext *avctx, return AVERROR(EINVAL); } - if (ctx->is_alpha) { + if (ctx->is_alpha && id != VP9E_SET_COLOR_SPACE) { int res_alpha = vpx_codec_control(&ctx->encoder_alpha, id, val); if (res_alpha != VPX_CODEC_OK) { snprintf(buf, sizeof(buf), "Failed to set %s alpha codec control", @@ -825,6 +825,7 @@ static int set_pix_fmt(AVCodecContext *avctx, vpx_codec_caps_t codec_caps, *img_fmt = VPX_IMG_FMT_I420; return 0; case AV_PIX_FMT_YUV422P: + case AV_PIX_FMT_YUVA422P: enccfg->g_profile = 1; *img_fmt = VPX_IMG_FMT_I422; return 0; @@ -833,12 +834,15 @@ static int set_pix_fmt(AVCodecContext *avctx, vpx_codec_caps_t codec_caps, *img_fmt = VPX_IMG_FMT_I440; return 0; case AV_PIX_FMT_GBRP: + case AV_PIX_FMT_GBRAP: ctx->vpx_cs = VPX_CS_SRGB; case AV_PIX_FMT_YUV444P: + case AV_PIX_FMT_YUVA444P: enccfg->g_profile = 1; *img_fmt = VPX_IMG_FMT_I444; return 0; case AV_PIX_FMT_YUV420P10: + case AV_PIX_FMT_YUVA420P10: case AV_PIX_FMT_YUV420P12: if (codec_caps & VPX_CODEC_CAP_HIGHBITDEPTH) { enccfg->g_profile = 2; @@ -848,6 +852,7 @@ static int set_pix_fmt(AVCodecContext *avctx, vpx_codec_caps_t codec_caps, } break; case AV_PIX_FMT_YUV422P10: + case AV_PIX_FMT_YUVA422P10: case AV_PIX_FMT_YUV422P12: if (codec_caps & VPX_CODEC_CAP_HIGHBITDEPTH) { enccfg->g_profile = 3; @@ -866,10 +871,14 @@ static int set_pix_fmt(AVCodecContext *avctx, vpx_codec_caps_t codec_caps, } break; case AV_PIX_FMT_GBRP10: + case AV_PIX_FMT_GBRAP10: case AV_PIX_FMT_GBRP12: + case AV_PIX_FMT_GBRAP12: ctx->vpx_cs = VPX_CS_SRGB; case AV_PIX_FMT_YUV444P10: + case AV_PIX_FMT_YUVA444P10: case AV_PIX_FMT_YUV444P12: + case AV_PIX_FMT_YUVA444P12: if (codec_caps & VPX_CODEC_CAP_HIGHBITDEPTH) { enccfg->g_profile = 3; *img_fmt = VPX_IMG_FMT_I44416; @@ -1004,12 +1013,21 @@ static av_cold int vpx_init(AVCodecContext *avctx, vpx_svc_extra_cfg_t svc_params; #endif const AVDictionaryEntry* en = NULL; + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt); av_log(avctx, AV_LOG_INFO, "%s\n", vpx_codec_version_str()); av_log(avctx, AV_LOG_VERBOSE, "%s\n", vpx_codec_build_config()); - if (avctx->pix_fmt == AV_PIX_FMT_YUVA420P) + if (desc && (desc->flags & AV_PIX_FMT_FLAG_ALPHA)) { ctx->is_alpha = 1; + if (avctx->pix_fmt != AV_PIX_FMT_YUVA420P && avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) { + av_log(avctx, AV_LOG_ERROR, + "Pixel format '%s' is not widely supported. " + "Use -strict experimental to use it anyway, or use 'yuva420p' pixel format instead.\n", + av_get_pix_fmt_name(avctx->pix_fmt)); + return AVERROR(EINVAL); + } + } if ((res = vpx_codec_enc_config_default(iface, &enccfg, 0)) != VPX_CODEC_OK) { av_log(avctx, AV_LOG_ERROR, "Failed to get config: %s\n", @@ -1204,6 +1222,7 @@ static av_cold int vpx_init(AVCodecContext *avctx, #endif if (ctx->is_alpha) { enccfg_alpha = enccfg; + enccfg_alpha.g_profile = (flags & VPX_CODEC_USE_HIGHBITDEPTH) ? 2 : 0; res = vpx_codec_enc_init(&ctx->encoder_alpha, iface, &enccfg_alpha, flags); if (res != VPX_CODEC_OK) { log_encoder_error(avctx, &ctx->encoder_alpha, "Failed to initialize alpha encoder"); @@ -1692,18 +1711,28 @@ static int realloc_alpha_uv(AVCodecContext *avctx, int width, int height) !planes[VPX_PLANE_V] || width != (int)rawimg_alpha->d_w || height != (int)rawimg_alpha->d_h) { + vpx_img_fmt_t alpha_fmt = ctx->rawimg.bit_depth > 8 ? + VPX_IMG_FMT_I42016 : VPX_IMG_FMT_I420; av_freep(&planes[VPX_PLANE_U]); av_freep(&planes[VPX_PLANE_V]); - vpx_img_wrap(rawimg_alpha, VPX_IMG_FMT_I420, width, height, 1, + vpx_img_wrap(rawimg_alpha, alpha_fmt, width, height, 1, (unsigned char*)1); planes[VPX_PLANE_U] = av_malloc_array(stride[VPX_PLANE_U], height); planes[VPX_PLANE_V] = av_malloc_array(stride[VPX_PLANE_V], height); if (!planes[VPX_PLANE_U] || !planes[VPX_PLANE_V]) return AVERROR(ENOMEM); - memset(planes[VPX_PLANE_U], 0x80, stride[VPX_PLANE_U] * height); - memset(planes[VPX_PLANE_V], 0x80, stride[VPX_PLANE_V] * height); + if (ctx->rawimg.bit_depth > 8) { + int val = 0x80 << (ctx->rawimg.bit_depth - 8); + AV_WN16(planes[VPX_PLANE_U], val); + AV_WN16(planes[VPX_PLANE_V], val); + av_memcpy_backptr(planes[VPX_PLANE_U] + 2, 2, stride[VPX_PLANE_U] * height - 2); + av_memcpy_backptr(planes[VPX_PLANE_V] + 2, 2, stride[VPX_PLANE_V] * height - 2); + } else { + memset(planes[VPX_PLANE_U], 0x80, stride[VPX_PLANE_U] * height); + memset(planes[VPX_PLANE_V], 0x80, stride[VPX_PLANE_V] * height); + } } return 0; @@ -2085,9 +2114,12 @@ static const enum AVPixelFormat vp9_pix_fmts_highcol[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUV422P, + AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV444P, + AV_PIX_FMT_YUVA444P, AV_PIX_FMT_GBRP, + AV_PIX_FMT_GBRAP, AV_PIX_FMT_NONE }; @@ -2095,19 +2127,28 @@ static const enum AVPixelFormat vp9_pix_fmts_highbd[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUV422P, + AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV444P, + AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUV420P10, + AV_PIX_FMT_YUVA420P10, AV_PIX_FMT_YUV422P10, + AV_PIX_FMT_YUVA422P10, AV_PIX_FMT_YUV440P10, AV_PIX_FMT_YUV444P10, + AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_YUV420P12, AV_PIX_FMT_YUV422P12, AV_PIX_FMT_YUV440P12, AV_PIX_FMT_YUV444P12, + AV_PIX_FMT_YUVA444P12, AV_PIX_FMT_GBRP, + AV_PIX_FMT_GBRAP, AV_PIX_FMT_GBRP10, + AV_PIX_FMT_GBRAP10, AV_PIX_FMT_GBRP12, + AV_PIX_FMT_GBRAP12, AV_PIX_FMT_NONE }; _______________________________________________ ffmpeg-cvslog mailing list -- [email protected] To unsubscribe send an email to [email protected]
