[FFmpeg-devel] [PATCH] avcodec/hevcdec: add support for sps_infer_scaling_list_flag == 1
James Almer
jamrial at gmail.com
Mon Sep 23 20:14:12 EEST 2024
On 9/23/2024 2:07 PM, Anton Khirnov wrote:
> Quoting James Almer (2024-09-23 18:35:35)
>> Signed-off-by: James Almer <jamrial at gmail.com>
>> ---
>> Untested, as i can't find a sample that triggers this code.
>>
>> libavcodec/hevc/cabac.c | 3 ++-
>> libavcodec/hevc/ps.c | 18 +++++++++++++-----
>> libavcodec/hevc/ps.h | 1 +
>> 3 files changed, 16 insertions(+), 6 deletions(-)
>>
>> diff --git a/libavcodec/hevc/cabac.c b/libavcodec/hevc/cabac.c
>> index 892dd1c215..ac2b52986e 100644
>> --- a/libavcodec/hevc/cabac.c
>> +++ b/libavcodec/hevc/cabac.c
>> @@ -1084,8 +1084,9 @@ void ff_hevc_hls_residual_coding(HEVCLocalContext *lc, const HEVCPPS *pps,
>> dc_scale = 16;
>>
>> if (sps->scaling_list_enabled && !(transform_skip_flag && log2_trafo_size > 2)) {
>> + const HEVCLayerContext *const l = &s->layers[sps->sps_scaling_list_ref_layer_id];
>> const ScalingList *sl = pps->scaling_list_data_present_flag ?
>> - &pps->scaling_list : &sps->scaling_list;
>> + &pps->scaling_list : &l->sps->scaling_list;
>
> You need to check that the layer is active and actually has an SPS.
>
>> int matrix_id = lc->cu.pred_mode != MODE_INTRA;
>>
>> matrix_id = 3 * matrix_id + c_idx;
>> diff --git a/libavcodec/hevc/ps.c b/libavcodec/hevc/ps.c
>> index f18b88489b..64b3089967 100644
>> --- a/libavcodec/hevc/ps.c
>> +++ b/libavcodec/hevc/ps.c
>> @@ -1373,14 +1373,22 @@ int ff_hevc_parse_sps(HEVCSPS *sps, GetBitContext *gb, unsigned int *sps_id,
>>
>> sps->scaling_list_enabled = get_bits1(gb);
>> if (sps->scaling_list_enabled) {
>> + int sps_infer_scaling_list_flag = 0;
>> +
>> set_default_scaling_list_data(&sps->scaling_list);
>>
>> - if (multi_layer_ext && get_bits1(gb)) { // sps_infer_scaling_list_flag
>> - av_log(avctx, AV_LOG_ERROR, "sps_infer_scaling_list_flag=1 not supported\n");
>> - return AVERROR_PATCHWELCOME;
>> - }
>> + if (multi_layer_ext)
>> + sps_infer_scaling_list_flag = get_bits1(gb);
>>
>> - if (get_bits1(gb)) {
>> + sps->sps_scaling_list_ref_layer_id = 0;
>> + if (sps_infer_scaling_list_flag) {
>> + sps->sps_scaling_list_ref_layer_id = get_bits(gb, 6);
>> + if (sps->sps_scaling_list_ref_layer_id >= HEVC_VPS_MAX_LAYERS) {
>
> This value is nuh_layer_id of the reference layer, but you're using it
> as an index into the VPS layer list. Mapping nuh_layer_id to VPS layer
> indices is done via vps->layer_idx.
>
>> + av_log(avctx, AV_LOG_ERROR, "Invalid value %d for sps_scaling_list_ref_layer_id",
>> + sps->sps_scaling_list_ref_layer_id);
>> + return AVERROR_INVALIDDATA;
>> + }
>> + } else if (get_bits1(gb)) {
>> ret = scaling_list_data(gb, avctx, &sps->scaling_list, sps);
>> if (ret < 0)
>> return ret;
>> diff --git a/libavcodec/hevc/ps.h b/libavcodec/hevc/ps.h
>> index 6f5b1f8755..aa4326554c 100644
>> --- a/libavcodec/hevc/ps.h
>> +++ b/libavcodec/hevc/ps.h
>> @@ -277,6 +277,7 @@ typedef struct HEVCSPS {
>> VUI vui;
>> PTL ptl;
>>
>> + int sps_scaling_list_ref_layer_id;
>
> Leading sps_ is redundant. Also might be better to store the index
> rather than layer id.
>
> Overall I'm not sure it's worth it to support something for which no
> samples are known to exist.
Ok. We should request a sample then, and not just return PATCHWELCOME.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature.asc
Type: application/pgp-signature
Size: 495 bytes
Desc: OpenPGP digital signature
URL: <https://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20240923/e28d2691/attachment.sig>
More information about the ffmpeg-devel
mailing list