aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClément Bœsch <clement@stupeflix.com>2016-06-30 10:15:51 +0200
committerClément Bœsch <clement@stupeflix.com>2016-06-30 10:15:51 +0200
commitd407e76c42d5ae79791ff88d3bd5185e10ad6047 (patch)
tree2c77d67281ef3e29bf9a0e6f69bfb83ba3a55fff
parent879330c561f4214bd81c35f46f31dd7fe906a59a (diff)
parent2d410ebbaa1e760d6837cb434a6d1d4c3c6f0d85 (diff)
downloadffmpeg-d407e76c42d5ae79791ff88d3bd5185e10ad6047.tar.gz
Merge commit '2d410ebbaa1e760d6837cb434a6d1d4c3c6f0d85'
* commit '2d410ebbaa1e760d6837cb434a6d1d4c3c6f0d85': h264: decode the MMCOs into per-slice contexts Merged-by: Clément Bœsch <clement@stupeflix.com>
-rw-r--r--libavcodec/h264.h9
-rw-r--r--libavcodec/h264_refs.c44
-rw-r--r--libavcodec/h264_slice.c21
3 files changed, 29 insertions, 45 deletions
diff --git a/libavcodec/h264.h b/libavcodec/h264.h
index f0e4573e7a..84cf59e55f 100644
--- a/libavcodec/h264.h
+++ b/libavcodec/h264.h
@@ -453,6 +453,9 @@ typedef struct H264SliceContext {
CABACContext cabac;
uint8_t cabac_state[1024];
int cabac_init_idc;
+
+ MMCO mmco[MAX_MMCO_COUNT];
+ int nb_mmco;
} H264SliceContext;
/**
@@ -728,10 +731,10 @@ void ff_h264_remove_all_refs(H264Context *h);
*/
int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count);
-int ff_h264_decode_ref_pic_marking(H264Context *h, GetBitContext *gb,
- int first_slice);
+int ff_h264_decode_ref_pic_marking(const H264Context *h, H264SliceContext *sl,
+ GetBitContext *gb);
-int ff_generate_sliding_window_mmcos(H264Context *h, int first_slice);
+int ff_generate_sliding_window_mmcos(const H264Context *h, H264SliceContext *sl);
void ff_h264_hl_decode_mb(const H264Context *h, H264SliceContext *sl);
int ff_h264_decode_init(AVCodecContext *avctx);
diff --git a/libavcodec/h264_refs.c b/libavcodec/h264_refs.c
index e7ae447358..c710012e05 100644
--- a/libavcodec/h264_refs.c
+++ b/libavcodec/h264_refs.c
@@ -601,9 +601,10 @@ static int check_opcodes(MMCO *mmco1, MMCO *mmco2, int n_mmcos)
return 0;
}
-int ff_generate_sliding_window_mmcos(H264Context *h, int first_slice)
+int ff_generate_sliding_window_mmcos(const H264Context *h,
+ H264SliceContext *sl)
{
- MMCO mmco_temp[MAX_MMCO_COUNT], *mmco = first_slice ? h->mmco : mmco_temp;
+ MMCO *mmco = sl->mmco;
int nb_mmco = 0, i = 0;
if (h->short_ref_count &&
@@ -620,16 +621,8 @@ int ff_generate_sliding_window_mmcos(H264Context *h, int first_slice)
}
}
- if (first_slice) {
- h->nb_mmco = nb_mmco;
- } else if (!first_slice && nb_mmco >= 0 &&
- (nb_mmco != h->nb_mmco ||
- (i = check_opcodes(h->mmco, mmco_temp, nb_mmco)))) {
- av_log(h->avctx, AV_LOG_ERROR,
- "Inconsistent MMCO state between slices [%d, %d]\n",
- nb_mmco, h->nb_mmco);
- return AVERROR_INVALIDDATA;
- }
+ sl->nb_mmco = nb_mmco;
+
return 0;
}
@@ -842,11 +835,11 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count)
return (h->avctx->err_recognition & AV_EF_EXPLODE) ? err : 0;
}
-int ff_h264_decode_ref_pic_marking(H264Context *h, GetBitContext *gb,
- int first_slice)
+int ff_h264_decode_ref_pic_marking(const H264Context *h, H264SliceContext *sl,
+ GetBitContext *gb)
{
int i, ret;
- MMCO mmco_temp[MAX_MMCO_COUNT], *mmco = mmco_temp;
+ MMCO *mmco = sl->mmco;
int nb_mmco = 0;
if (h->nal_unit_type == NAL_IDR_SLICE) { // FIXME fields
@@ -902,26 +895,15 @@ int ff_h264_decode_ref_pic_marking(H264Context *h, GetBitContext *gb,
}
nb_mmco = i;
} else {
- if (first_slice) {
- ret = ff_generate_sliding_window_mmcos(h, first_slice);
- if (ret < 0 && h->avctx->err_recognition & AV_EF_EXPLODE)
- return ret;
- }
+ ret = ff_generate_sliding_window_mmcos(h, sl);
+ if (ret < 0 && h->avctx->err_recognition & AV_EF_EXPLODE)
+ return ret;
nb_mmco = -1;
}
}
- if (first_slice && nb_mmco != -1) {
- memcpy(h->mmco, mmco_temp, sizeof(h->mmco));
- h->nb_mmco = nb_mmco;
- } else if (!first_slice && nb_mmco >= 0 &&
- (nb_mmco != h->nb_mmco ||
- check_opcodes(h->mmco, mmco_temp, nb_mmco))) {
- av_log(h->avctx, AV_LOG_ERROR,
- "Inconsistent MMCO state between slices [%d, %d]\n",
- nb_mmco, h->nb_mmco);
- return AVERROR_INVALIDDATA;
- }
+ if (nb_mmco != -1)
+ sl->nb_mmco = nb_mmco;
return 0;
}
diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c
index a63c9b9b4c..cb52b77f3f 100644
--- a/libavcodec/h264_slice.c
+++ b/libavcodec/h264_slice.c
@@ -1421,10 +1421,12 @@ static int h264_slice_header_parse(H264Context *h, H264SliceContext *sl)
h->cur_pic_ptr->invalid_gap = !sps->gaps_in_frame_num_allowed_flag;
ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, 0);
ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, 1);
- ret = ff_generate_sliding_window_mmcos(h, 1);
+
+ ret = ff_generate_sliding_window_mmcos(h, sl);
if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE))
return ret;
- ret = ff_h264_execute_ref_pic_marking(h, h->mmco, h->nb_mmco);
+
+ ret = ff_h264_execute_ref_pic_marking(h, sl->mmco, sl->nb_mmco);
if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE))
return ret;
/* Error concealment: If a ref is missing, copy the previous ref
@@ -1575,15 +1577,8 @@ static int h264_slice_header_parse(H264Context *h, H264SliceContext *sl)
ff_h264_pred_weight_table(&sl->gb, sps, sl->ref_count,
sl->slice_type_nos, &sl->pwt, h->avctx);
- // If frame-mt is enabled, only update mmco tables for the first slice
- // in a field. Subsequent slices can temporarily clobber h->nb_mmco
- // or h->mmco, which will cause ref list mix-ups and decoding errors
- // further down the line. This may break decoding if the first slice is
- // corrupt, thus we only do this if frame-mt is enabled.
if (h->nal_ref_idc) {
- ret = ff_h264_decode_ref_pic_marking(h, &sl->gb,
- !(h->avctx->active_thread_type & FF_THREAD_FRAME) ||
- h->current_slice == 0);
+ ret = ff_h264_decode_ref_pic_marking(h, sl, &sl->gb);
if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE))
return AVERROR_INVALIDDATA;
}
@@ -1674,10 +1669,14 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl)
sl->resync_mb_y = sl->mb_y = sl->mb_y + 1;
av_assert1(sl->mb_y < h->mb_height);
- if (!h->setup_finished)
+ if (!h->setup_finished) {
ff_h264_init_poc(h->cur_pic_ptr->field_poc, &h->cur_pic_ptr->poc,
h->ps.sps, &h->poc, h->picture_structure, h->nal_ref_idc);
+ memcpy(h->mmco, sl->mmco, sl->nb_mmco * sizeof(*h->mmco));
+ h->nb_mmco = sl->nb_mmco;
+ }
+
ret = ff_h264_build_ref_list(h, sl);
if (ret < 0)
return ret;