PR #22397 opened by Zhao Zhili (quink) URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/22397 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/22397.patch
Apple VideoToolbox is the dominant producer of hevc-alpha videos, but early versions generates non-standard VPS extensions that fail to parse and return AVERROR_INVALIDDATA. Fix this by returning AVERROR_PATCHWELCOME instead of AVERROR_INVALIDDATA for unsupported VPS extension configurations. Setting poc_lsb_not_present for the alpha layer in the fallback path when it has no direct dependency on the base layer, so that IDR slices on the alpha layer won't incorrectly read pic_order_cnt_lsb. Fix #22384 Signed-off-by: Zhao Zhili <[email protected]> >From 8b777ebcf10ba7cec016721e475c10260dcdce6c Mon Sep 17 00:00:00 2001 From: Zhao Zhili <[email protected]> Date: Thu, 5 Mar 2026 12:20:31 +0800 Subject: [PATCH] avcodec/hevc: workaround hevc-alpha videos generated by VideoToolbox Apple VideoToolbox is the dominant producer of hevc-alpha videos, but early versions generates non-standard VPS extensions that fail to parse and return AVERROR_INVALIDDATA. Fix this by returning AVERROR_PATCHWELCOME instead of AVERROR_INVALIDDATA for unsupported VPS extension configurations. Setting poc_lsb_not_present for the alpha layer in the fallback path when it has no direct dependency on the base layer, so that IDR slices on the alpha layer won't incorrectly read pic_order_cnt_lsb. Fix #22384 Signed-off-by: Zhao Zhili <[email protected]> --- libavcodec/hevc/ps.c | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/libavcodec/hevc/ps.c b/libavcodec/hevc/ps.c index 46b38564d5..c6d84cfec8 100644 --- a/libavcodec/hevc/ps.c +++ b/libavcodec/hevc/ps.c @@ -610,8 +610,11 @@ static int decode_vps_ext(GetBitContext *gb, AVCodecContext *avctx, HEVCVPS *vps } } vps->num_output_layer_sets = vps->vps_num_layer_sets + vps->num_add_layer_sets; - if (vps->num_output_layer_sets != 2) - return AVERROR_INVALIDDATA; + if (vps->num_output_layer_sets != 2) { + av_log(avctx, AV_LOG_WARNING, + "Unsupported num_output_layer_sets: %d\n", vps->num_output_layer_sets); + return AVERROR_PATCHWELCOME; + } sub_layers_max_present = get_bits1(gb); // vps_sub_layers_max_minus1_present_flag if (sub_layers_max_present) { @@ -677,7 +680,7 @@ static int decode_vps_ext(GetBitContext *gb, AVCodecContext *avctx, HEVCVPS *vps if (get_ue_golomb_31(gb) != 0 /* vps_num_rep_formats_minus1 */) { av_log(avctx, AV_LOG_ERROR, "Unexpected extra rep formats\n"); - return AVERROR_INVALIDDATA; + return AVERROR_PATCHWELCOME; } vps->rep_format.pic_width_in_luma_samples = get_bits(gb, 16); @@ -895,8 +898,22 @@ int ff_hevc_decode_nal_vps(GetBitContext *gb, AVCodecContext *avctx, if (vps->vps_max_layers > 1 && get_bits1(gb)) { /* vps_extension_flag */ int ret = decode_vps_ext(gb, avctx, vps, layer1_id_included); if (ret == AVERROR_PATCHWELCOME) { - vps->nb_layers = 1; - av_log(avctx, AV_LOG_WARNING, "Ignoring unsupported VPS extension\n"); + /* If alpha layer info was already parsed, preserve it for alpha decoding */ + if (vps->nb_layers == 2 && + vps->layer_id_in_nuh[1] && + (vps->scalability_mask_flag & HEVC_SCALABILITY_AUXILIARY)) { + av_log(avctx, AV_LOG_WARNING, + "Broken VPS extension, treating as alpha video\n"); + /* If alpha layer has no direct dependency on base layer, + * assume poc_lsb_not_present for the alpha layer, so that + * IDR slices on that layer won't read pic_order_cnt_lsb. + * This matches the behavior of Apple VideoToolbox encoders. */ + if (!vps->num_direct_ref_layers[1]) + vps->poc_lsb_not_present |= 1 << 1; + } else { + vps->nb_layers = 1; + av_log(avctx, AV_LOG_WARNING, "Ignoring unsupported VPS extension\n"); + } ret = 0; } else if (ret < 0) goto err; -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
