[FFmpeg-devel] [PATCH] cbs_h265: Ensure that a predicted RPS doesn't contain too many pictures

James Almer jamrial at gmail.com
Sun May 3 18:43:52 EEST 2020


On 5/3/2020 12:30 PM, Mark Thompson wrote:
> If the RPS we are predicting from has maximum size then at least one of
> the pictures in it must be discarded before adding the current one.
> 
> Also revert 588114cea4ee434c9c61353ed91ffc817d2965f5, which added
> now-redundant checks for the special case of a too-large RPS with all
> pictures being in the same direction from the current one.

You could also revert it in a separate commit after this patch using git
revert, so this patch only contains the actual fix.

> ---
> It would be helpful to test this on the fuzzing samples from 20446/clusterfuzz-testcase-minimized-ffmpeg_BSF_HEVC_METADATA_fuzzer-5707770718584832 which prompted the original incomplete fix.  Is there somewhere I can find them?

Michael can send it to you. Poke him on IRC if he misses this patch.

> 
>  libavcodec/cbs_h265_syntax_template.c | 16 +++++++++++-----
>  1 file changed, 11 insertions(+), 5 deletions(-)
> 
> diff --git a/libavcodec/cbs_h265_syntax_template.c b/libavcodec/cbs_h265_syntax_template.c
> index 5f5531944c..85ff5e5dc5 100644
> --- a/libavcodec/cbs_h265_syntax_template.c
> +++ b/libavcodec/cbs_h265_syntax_template.c
> @@ -522,7 +522,7 @@ static int FUNC(st_ref_pic_set)(CodedBitstreamContext *ctx, RWContext *rw,
>          infer(inter_ref_pic_set_prediction_flag, 0);
>  
>      if (current->inter_ref_pic_set_prediction_flag) {
> -        unsigned int ref_rps_idx, num_delta_pocs;
> +        unsigned int ref_rps_idx, num_delta_pocs, num_ref_pics;
>          const H265RawSTRefPicSet *ref;
>          int delta_rps, d_poc;
>          int ref_delta_poc_s0[HEVC_MAX_REFS], ref_delta_poc_s1[HEVC_MAX_REFS];
> @@ -538,18 +538,28 @@ static int FUNC(st_ref_pic_set)(CodedBitstreamContext *ctx, RWContext *rw,
>          ref_rps_idx = st_rps_idx - (current->delta_idx_minus1 + 1);
>          ref = &sps->st_ref_pic_set[ref_rps_idx];
>          num_delta_pocs = ref->num_negative_pics + ref->num_positive_pics;
> +        av_assert0(num_delta_pocs < HEVC_MAX_DPB_SIZE);
>  
>          flag(delta_rps_sign);
>          ue(abs_delta_rps_minus1, 0, INT16_MAX);
>          delta_rps = (1 - 2 * current->delta_rps_sign) *
>              (current->abs_delta_rps_minus1 + 1);
>  
> +        num_ref_pics = 0;
>          for (j = 0; j <= num_delta_pocs; j++) {
>              flags(used_by_curr_pic_flag[j], 1, j);
>              if (!current->used_by_curr_pic_flag[j])
>                  flags(use_delta_flag[j], 1, j);
>              else
>                  infer(use_delta_flag[j], 1);
> +            if (current->use_delta_flag[i])
> +                ++num_ref_pics;
> +        }
> +        if (num_ref_pics >= HEVC_MAX_DPB_SIZE) {
> +            av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid stream: "
> +                   "short-term ref pic set %d "
> +                   "contains too many pictures.\n", st_rps_idx);
> +            return AVERROR_INVALIDDATA;
>          }
>  
>          // Since the stored form of an RPS here is actually the delta-step
> @@ -601,8 +611,6 @@ static int FUNC(st_ref_pic_set)(CodedBitstreamContext *ctx, RWContext *rw,
>              }
>          }
>  
> -        if (i > 15)
> -            return AVERROR_INVALIDDATA;
>          infer(num_negative_pics, i);
>          for (i = 0; i < current->num_negative_pics; i++) {
>              infer(delta_poc_s0_minus1[i],
> @@ -632,8 +640,6 @@ static int FUNC(st_ref_pic_set)(CodedBitstreamContext *ctx, RWContext *rw,
>              }
>          }
>  
> -        if (i + current->num_negative_pics > 15)
> -            return AVERROR_INVALIDDATA;
>          infer(num_positive_pics, i);
>          for (i = 0; i < current->num_positive_pics; i++) {
>              infer(delta_poc_s1_minus1[i],
> 



More information about the ffmpeg-devel mailing list