Commit bec99338 authored by Anton Khirnov's avatar Anton Khirnov

h264: postpone generating the implicit MMCOs

Do it right before the MMCOs are applied to the DPB. This will allow
moving the frame_start() call out of the slice header parsing, since
generating the implicit MMCOs needs to be done after frame_start().
parent 2d410ebb
...@@ -442,6 +442,7 @@ typedef struct H264SliceContext { ...@@ -442,6 +442,7 @@ typedef struct H264SliceContext {
MMCO mmco[MAX_MMCO_COUNT]; MMCO mmco[MAX_MMCO_COUNT];
int nb_mmco; int nb_mmco;
int explicit_ref_marking;
} H264SliceContext; } H264SliceContext;
/** /**
...@@ -579,6 +580,7 @@ typedef struct H264Context { ...@@ -579,6 +580,7 @@ typedef struct H264Context {
MMCO mmco[MAX_MMCO_COUNT]; MMCO mmco[MAX_MMCO_COUNT];
int nb_mmco; int nb_mmco;
int mmco_reset; int mmco_reset;
int explicit_ref_marking;
int long_ref_count; ///< number of actual long term references int long_ref_count; ///< number of actual long term references
int short_ref_count; ///< number of actual short term references int short_ref_count; ///< number of actual short term references
...@@ -672,13 +674,11 @@ void ff_h264_remove_all_refs(H264Context *h); ...@@ -672,13 +674,11 @@ void ff_h264_remove_all_refs(H264Context *h);
/** /**
* Execute the reference picture marking (memory management control operations). * Execute the reference picture marking (memory management control operations).
*/ */
int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count); int ff_h264_execute_ref_pic_marking(H264Context *h);
int ff_h264_decode_ref_pic_marking(const H264Context *h, H264SliceContext *sl, int ff_h264_decode_ref_pic_marking(const H264Context *h, H264SliceContext *sl,
GetBitContext *gb); GetBitContext *gb);
int ff_generate_sliding_window_mmcos(const H264Context *h, H264SliceContext *sl);
void ff_h264_hl_decode_mb(const H264Context *h, H264SliceContext *sl); void ff_h264_hl_decode_mb(const H264Context *h, H264SliceContext *sl);
int ff_h264_decode_init(AVCodecContext *avctx); int ff_h264_decode_init(AVCodecContext *avctx);
void ff_h264_decode_init_vlc(void); void ff_h264_decode_init_vlc(void);
......
...@@ -154,7 +154,7 @@ int ff_h264_field_end(H264Context *h, H264SliceContext *sl, int in_setup) ...@@ -154,7 +154,7 @@ int ff_h264_field_end(H264Context *h, H264SliceContext *sl, int in_setup)
if (in_setup || !(avctx->active_thread_type & FF_THREAD_FRAME)) { if (in_setup || !(avctx->active_thread_type & FF_THREAD_FRAME)) {
if (!h->droppable) { if (!h->droppable) {
err = ff_h264_execute_ref_pic_marking(h, h->mmco, h->nb_mmco); err = ff_h264_execute_ref_pic_marking(h);
h->poc.prev_poc_msb = h->poc.poc_msb; h->poc.prev_poc_msb = h->poc.poc_msb;
h->poc.prev_poc_lsb = h->poc.poc_lsb; h->poc.prev_poc_lsb = h->poc.poc_lsb;
} }
......
...@@ -536,11 +536,10 @@ static int check_opcodes(MMCO *mmco1, MMCO *mmco2, int n_mmcos) ...@@ -536,11 +536,10 @@ static int check_opcodes(MMCO *mmco1, MMCO *mmco2, int n_mmcos)
return 0; return 0;
} }
int ff_generate_sliding_window_mmcos(const H264Context *h, static void generate_sliding_window_mmcos(H264Context *h)
H264SliceContext *sl)
{ {
MMCO *mmco = sl->mmco; MMCO *mmco = h->mmco;
int nb_mmco = 0, i = 0; int nb_mmco = 0;
assert(h->long_ref_count + h->short_ref_count <= h->ps.sps->ref_frame_count); assert(h->long_ref_count + h->short_ref_count <= h->ps.sps->ref_frame_count);
...@@ -558,17 +557,21 @@ int ff_generate_sliding_window_mmcos(const H264Context *h, ...@@ -558,17 +557,21 @@ int ff_generate_sliding_window_mmcos(const H264Context *h,
} }
} }
sl->nb_mmco = nb_mmco; h->nb_mmco = nb_mmco;
return 0;
} }
int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count) int ff_h264_execute_ref_pic_marking(H264Context *h)
{ {
MMCO *mmco = h->mmco;
int mmco_count;
int i, av_uninit(j); int i, av_uninit(j);
int current_ref_assigned = 0, err = 0; int current_ref_assigned = 0, err = 0;
H264Picture *av_uninit(pic); H264Picture *av_uninit(pic);
if (!h->explicit_ref_marking)
generate_sliding_window_mmcos(h);
mmco_count = h->nb_mmco;
if ((h->avctx->debug & FF_DEBUG_MMCO) && mmco_count == 0) if ((h->avctx->debug & FF_DEBUG_MMCO) && mmco_count == 0)
av_log(h->avctx, AV_LOG_DEBUG, "no mmco here\n"); av_log(h->avctx, AV_LOG_DEBUG, "no mmco here\n");
...@@ -739,7 +742,7 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count) ...@@ -739,7 +742,7 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count)
int ff_h264_decode_ref_pic_marking(const H264Context *h, H264SliceContext *sl, int ff_h264_decode_ref_pic_marking(const H264Context *h, H264SliceContext *sl,
GetBitContext *gb) GetBitContext *gb)
{ {
int i, ret; int i;
MMCO *mmco = sl->mmco; MMCO *mmco = sl->mmco;
int nb_mmco = 0; int nb_mmco = 0;
...@@ -750,8 +753,10 @@ int ff_h264_decode_ref_pic_marking(const H264Context *h, H264SliceContext *sl, ...@@ -750,8 +753,10 @@ int ff_h264_decode_ref_pic_marking(const H264Context *h, H264SliceContext *sl,
mmco[0].long_arg = 0; mmco[0].long_arg = 0;
nb_mmco = 1; nb_mmco = 1;
} }
sl->explicit_ref_marking = 1;
} else { } else {
if (get_bits1(gb)) { // adaptive_ref_pic_marking_mode_flag sl->explicit_ref_marking = get_bits1(gb);
if (sl->explicit_ref_marking) {
for (i = 0; i < MAX_MMCO_COUNT; i++) { for (i = 0; i < MAX_MMCO_COUNT; i++) {
MMCOOpcode opcode = get_ue_golomb_31(gb); MMCOOpcode opcode = get_ue_golomb_31(gb);
...@@ -795,15 +800,9 @@ int ff_h264_decode_ref_pic_marking(const H264Context *h, H264SliceContext *sl, ...@@ -795,15 +800,9 @@ int ff_h264_decode_ref_pic_marking(const H264Context *h, H264SliceContext *sl,
break; break;
} }
nb_mmco = i; nb_mmco = i;
} else {
ret = ff_generate_sliding_window_mmcos(h, sl);
if (ret < 0 && h->avctx->err_recognition & AV_EF_EXPLODE)
return ret;
nb_mmco = -1;
} }
} }
if (nb_mmco != -1)
sl->nb_mmco = nb_mmco; sl->nb_mmco = nb_mmco;
return 0; return 0;
......
...@@ -418,6 +418,7 @@ int ff_h264_update_thread_context(AVCodecContext *dst, ...@@ -418,6 +418,7 @@ int ff_h264_update_thread_context(AVCodecContext *dst,
memcpy(h->mmco, h1->mmco, sizeof(h->mmco)); memcpy(h->mmco, h1->mmco, sizeof(h->mmco));
h->nb_mmco = h1->nb_mmco; h->nb_mmco = h1->nb_mmco;
h->mmco_reset = h1->mmco_reset; h->mmco_reset = h1->mmco_reset;
h->explicit_ref_marking = h1->explicit_ref_marking;
h->long_ref_count = h1->long_ref_count; h->long_ref_count = h1->long_ref_count;
h->short_ref_count = h1->short_ref_count; h->short_ref_count = h1->short_ref_count;
...@@ -430,7 +431,7 @@ int ff_h264_update_thread_context(AVCodecContext *dst, ...@@ -430,7 +431,7 @@ int ff_h264_update_thread_context(AVCodecContext *dst,
return 0; return 0;
if (!h->droppable) { if (!h->droppable) {
err = ff_h264_execute_ref_pic_marking(h, h->mmco, h->nb_mmco); err = ff_h264_execute_ref_pic_marking(h);
h->poc.prev_poc_msb = h->poc.poc_msb; h->poc.prev_poc_msb = h->poc.poc_msb;
h->poc.prev_poc_lsb = h->poc.poc_lsb; h->poc.prev_poc_lsb = h->poc.poc_lsb;
} }
...@@ -1202,11 +1203,8 @@ static int h264_slice_header_parse(H264Context *h, H264SliceContext *sl) ...@@ -1202,11 +1203,8 @@ static int h264_slice_header_parse(H264Context *h, H264SliceContext *sl)
ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, 0); ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, 0);
ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, 1); ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, 1);
ret = ff_generate_sliding_window_mmcos(h, sl); h->explicit_ref_marking = 0;
if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE)) ret = ff_h264_execute_ref_pic_marking(h);
return ret;
ret = ff_h264_execute_ref_pic_marking(h, sl->mmco, sl->nb_mmco);
if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE)) if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE))
return ret; return ret;
/* Error concealment: If a ref is missing, copy the previous ref /* Error concealment: If a ref is missing, copy the previous ref
...@@ -1344,6 +1342,7 @@ static int h264_slice_header_parse(H264Context *h, H264SliceContext *sl) ...@@ -1344,6 +1342,7 @@ static int h264_slice_header_parse(H264Context *h, H264SliceContext *sl)
ff_h264_pred_weight_table(&sl->gb, sps, sl->ref_count, ff_h264_pred_weight_table(&sl->gb, sps, sl->ref_count,
sl->slice_type_nos, &sl->pwt); sl->slice_type_nos, &sl->pwt);
sl->explicit_ref_marking = 0;
if (h->nal_ref_idc) { if (h->nal_ref_idc) {
ret = ff_h264_decode_ref_pic_marking(h, sl, &sl->gb); ret = ff_h264_decode_ref_pic_marking(h, sl, &sl->gb);
if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE)) if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE))
...@@ -1442,6 +1441,7 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl) ...@@ -1442,6 +1441,7 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl)
memcpy(h->mmco, sl->mmco, sl->nb_mmco * sizeof(*h->mmco)); memcpy(h->mmco, sl->mmco, sl->nb_mmco * sizeof(*h->mmco));
h->nb_mmco = sl->nb_mmco; h->nb_mmco = sl->nb_mmco;
h->explicit_ref_marking = sl->explicit_ref_marking;
} }
ret = ff_h264_build_ref_list(h, sl); ret = ff_h264_build_ref_list(h, sl);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment