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>
This commit is contained in:
Michael Niedermayer 2015-06-27 18:38:17 +02:00
commit f620315fa5
2 changed files with 25 additions and 18 deletions

View File

@ -409,7 +409,8 @@ typedef struct H264SliceContext {
int mb_xy; int mb_xy;
int resync_mb_x; int resync_mb_x;
int resync_mb_y; 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 mb_skip_run;
int is_complex; int is_complex;

View File

@ -2321,10 +2321,9 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg)
for (;;) { for (;;) {
// START_TIMER // START_TIMER
int ret, eos; int ret, eos;
if (sl->mb_x + sl->mb_y * h->mb_width >= sl->next_slice_idx) {
if (sl->mb_x + sl->mb_y * h->mb_width >= sl->mb_index_end) { av_log(h->avctx, AV_LOG_ERROR, "Slice overlaps with next at %d\n",
av_log(h->avctx, AV_LOG_ERROR, "Slice overlaps next at %d\n", sl->next_slice_idx);
sl->mb_index_end);
er_add_slice(sl, sl->resync_mb_x, sl->resync_mb_y, sl->mb_x, er_add_slice(sl, sl->resync_mb_x, sl->resync_mb_y, sl->mb_x,
sl->mb_y, ER_MB_ERROR); sl->mb_y, ER_MB_ERROR);
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
@ -2394,9 +2393,9 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg)
for (;;) { for (;;) {
int ret; int ret;
if (sl->mb_x + sl->mb_y * h->mb_width >= 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 next at %d\n", av_log(h->avctx, AV_LOG_ERROR, "Slice overlaps with next at %d\n",
sl->mb_index_end); sl->next_slice_idx);
er_add_slice(sl, sl->resync_mb_x, sl->resync_mb_y, sl->mb_x, er_add_slice(sl, sl->resync_mb_x, sl->resync_mb_y, sl->mb_x,
sl->mb_y, ER_MB_ERROR); sl->mb_y, ER_MB_ERROR);
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
@ -2486,38 +2485,45 @@ int ff_h264_execute_decode_slices(H264Context *h, unsigned context_count)
{ {
AVCodecContext *const avctx = h->avctx; AVCodecContext *const avctx = h->avctx;
H264SliceContext *sl; H264SliceContext *sl;
int i; int i, j;
av_assert0(context_count && h->slice_ctx[context_count - 1].mb_y < h->mb_height); 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 || if (h->avctx->hwaccel ||
h->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU) h->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU)
return 0; return 0;
if (context_count == 1) { 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; h->mb_y = h->slice_ctx[0].mb_y;
return ret; return ret;
} else { } else {
int j, mb_index;
av_assert0(context_count > 0); av_assert0(context_count > 0);
for (i = 0; i < context_count; i++) { 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]; sl = &h->slice_ctx[i];
mb_index = sl->resync_mb_x + sl->resync_mb_y * h->mb_width;
if (CONFIG_ERROR_RESILIENCE) { if (CONFIG_ERROR_RESILIENCE) {
sl->er.error_count = 0; 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++) { for (j = 0; j < context_count; j++) {
H264SliceContext *sl2 = &h->slice_ctx[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; 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, avctx->execute(avctx, decode_slice, h->slice_ctx,