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
