diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2015-06-27 18:38:17 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2015-06-27 18:46:11 +0200 |
commit | f620315fa5b1710e3a47b80ca2cd4597510804ba (patch) | |
tree | 4fae7d7757418580e20bd8bd675a229798abdd7c | |
parent | cf9051deac498eed70ab68c562b761c55251d270 (diff) | |
parent | e49e0f58e273237f83b4486f3536931ed1943d18 (diff) | |
download | ffmpeg-f620315fa5b1710e3a47b80ca2cd4597510804ba.tar.gz |
Merge commit 'e49e0f58e273237f83b4486f3536931ed1943d18'
* commit 'e49e0f58e273237f83b4486f3536931ed1943d18':
h264: make sure the slices do not overlap during slice threading
Conflicts:
libavcodec/h264.h
libavcodec/h264_slice.c
See: 43b434210e597d484aef57c4139c3126d22b7e2b
Merged-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r-- | libavcodec/h264.h | 3 | ||||
-rw-r--r-- | libavcodec/h264_slice.c | 40 |
2 files changed, 25 insertions, 18 deletions
diff --git a/libavcodec/h264.h b/libavcodec/h264.h index 7565e031d5..b1921ef6f6 100644 --- a/libavcodec/h264.h +++ b/libavcodec/h264.h @@ -409,7 +409,8 @@ typedef struct H264SliceContext { int mb_xy; int resync_mb_x; int resync_mb_y; - int mb_index_end; + // 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 aee188ac5f..675ce61267 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -2321,10 +2321,9 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg) for (;;) { // START_TIMER int ret, eos; - - if (sl->mb_x + sl->mb_y * h->mb_width >= sl->mb_index_end) { - av_log(h->avctx, AV_LOG_ERROR, "Slice overlaps next at %d\n", - sl->mb_index_end); + 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); er_add_slice(sl, sl->resync_mb_x, sl->resync_mb_y, sl->mb_x, sl->mb_y, ER_MB_ERROR); return AVERROR_INVALIDDATA; @@ -2394,9 +2393,9 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg) for (;;) { int ret; - if (sl->mb_x + sl->mb_y * h->mb_width >= sl->mb_index_end) { - av_log(h->avctx, AV_LOG_ERROR, "Slice overlaps next at %d\n", - sl->mb_index_end); + 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); er_add_slice(sl, sl->resync_mb_x, sl->resync_mb_y, sl->mb_x, sl->mb_y, ER_MB_ERROR); return AVERROR_INVALIDDATA; @@ -2486,38 +2485,45 @@ int ff_h264_execute_decode_slices(H264Context *h, unsigned context_count) { AVCodecContext *const avctx = h->avctx; H264SliceContext *sl; - int i; + int i, j; av_assert0(context_count && h->slice_ctx[context_count - 1].mb_y < h->mb_height); - h->slice_ctx[0].mb_index_end = INT_MAX; + h->slice_ctx[0].next_slice_idx = INT_MAX; if (h->avctx->hwaccel || h->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU) 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 { - int j, mb_index; av_assert0(context_count > 0); for (i = 0; i < context_count; i++) { - int mb_index_end = h->mb_width * h->mb_height; + int next_slice_idx = h->mb_width * h->mb_height; + int slice_idx; + sl = &h->slice_ctx[i]; - mb_index = sl->resync_mb_x + sl->resync_mb_y * h->mb_width; if (CONFIG_ERROR_RESILIENCE) { 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 mb_index2 = sl2->resync_mb_x + sl2->resync_mb_y * h->mb_width; + int slice_idx2 = sl2->mb_y * h->mb_width + sl2->mb_x; - if (i==j || mb_index > mb_index2) + if (i == j || slice_idx2 < slice_idx) continue; - mb_index_end = FFMIN(mb_index_end, mb_index2); + next_slice_idx = FFMIN(next_slice_idx, slice_idx2); } - sl->mb_index_end = mb_index_end; + sl->next_slice_idx = next_slice_idx; } avctx->execute(avctx, decode_slice, h->slice_ctx, |