On 2015-05-09 22:00:58 +0200, Anton Khirnov wrote:
> Based on a patch by Michael Niedermayer <[email protected]>.
> CC: [email protected]
> Found-by: Kieran Kunhya <[email protected]>
> ---
>  libavcodec/h264.h       |  2 ++
>  libavcodec/h264_slice.c | 46 ++++++++++++++++++++++++++++++++++++++++------
>  2 files changed, 42 insertions(+), 6 deletions(-)
> 
> diff --git a/libavcodec/h264.h b/libavcodec/h264.h
> index 12172ac..624a761 100644
> --- a/libavcodec/h264.h
> +++ b/libavcodec/h264.h
> @@ -374,6 +374,8 @@ typedef struct H264SliceContext {
>      int mb_xy;
>      int resync_mb_x;
>      int resync_mb_y;
> +    // index of the first MB of the next slice
> +    int next_slice_idx;
>      int mb_skip_run;
>      int is_complex;
>  
> diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c
> index a250237..491c0d2 100644
> --- a/libavcodec/h264_slice.c
> +++ b/libavcodec/h264_slice.c
> @@ -2072,8 +2072,15 @@ static int decode_slice(struct AVCodecContext *avctx, 
> void *arg)
>  
>          for (;;) {
>              // START_TIMER
> -            int ret = ff_h264_decode_mb_cabac(h, sl);
> -            int eos;
> +            int ret, eos;
> +
> +            if (sl->mb_x + sl->mb_y * h->mb_width >= sl->next_slice_idx) {
> +                av_log(h->avctx, AV_LOG_ERROR, "Slice overlaps with next at 
> %d\n",
> +                       sl->next_slice_idx);
> +                return AVERROR_INVALIDDATA;
> +            }
> +
> +            ret = ff_h264_decode_mb_cabac(h, sl);
>              // STOP_TIMER("decode_mb_cabac")
>  
>              if (ret >= 0)
> @@ -2133,7 +2140,15 @@ static int decode_slice(struct AVCodecContext *avctx, 
> void *arg)
>          }
>      } else {
>          for (;;) {
> -            int ret = ff_h264_decode_mb_cavlc(h, sl);
> +            int ret;
> +
> +            if (sl->mb_x + sl->mb_y * h->mb_width >= sl->next_slice_idx) {
> +                av_log(h->avctx, AV_LOG_ERROR, "Slice overlaps with next at 
> %d\n",
> +                       sl->next_slice_idx);
> +                return AVERROR_INVALIDDATA;
> +            }
> +
> +            ret = ff_h264_decode_mb_cavlc(h, sl);
>  
>              if (ret >= 0)
>                  ff_h264_hl_decode_mb(h, sl);
> @@ -2216,18 +2231,37 @@ int ff_h264_execute_decode_slices(H264Context *h, 
> unsigned context_count)
>  {
>      AVCodecContext *const avctx = h->avctx;
>      H264SliceContext *sl;
> -    int i;
> +    int i, j;
>  
>      if (h->avctx->hwaccel)
>          return 0;
>      if (context_count == 1) {
> -        int ret = decode_slice(avctx, &h->slice_ctx[0]);
> +        int ret;
> +
> +        h->slice_ctx[0].next_slice_idx = h->mb_width * h->mb_height;
> +
> +        ret = decode_slice(avctx, &h->slice_ctx[0]);
>          h->mb_y = h->slice_ctx[0].mb_y;
>          return ret;
>      } else {
> -        for (i = 1; i < context_count; i++) {
> +        for (i = 0; i < context_count; i++) {
> +            int next_slice_idx = h->mb_width * h->mb_height;
> +            int slice_idx;
> +
>              sl                 = &h->slice_ctx[i];
>              sl->er.error_count = 0;
> +
> +            /* make sure none of those slices overlap */
> +            slice_idx = sl->mb_y * h->mb_width + sl->mb_x;
> +            for (j = 0; j < context_count; j++) {
> +                H264SliceContext *sl2 = &h->slice_ctx[j];
> +                int        slice_idx2 = sl2->mb_y * h->mb_width + sl2->mb_x;
> +
> +                if (i == j || slice_idx2 < slice_idx)
> +                    continue;
> +                next_slice_idx = FFMIN(next_slice_idx, slice_idx2);
> +            }
> +            sl->next_slice_idx = next_slice_idx;
>          }
>  
>          avctx->execute(avctx, decode_slice, h->slice_ctx,

ok

Janne

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to