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().tags/n3.2
| @@ -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 { | |||||
| 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); | |||||
| /** | /** | ||||
| * 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) | |||||
| 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) | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| int ff_generate_sliding_window_mmcos(const H264Context *h, | |||||
| H264SliceContext *sl) | |||||
| static void generate_sliding_window_mmcos(H264Context *h) | |||||
| { | { | ||||
| MMCO *mmco = sl->mmco; | |||||
| int nb_mmco = 0, i = 0; | |||||
| MMCO *mmco = h->mmco; | |||||
| 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, | |||||
| } | } | ||||
| } | } | ||||
| sl->nb_mmco = nb_mmco; | |||||
| return 0; | |||||
| h->nb_mmco = nb_mmco; | |||||
| } | } | ||||
| 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) | |||||
| 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, | |||||
| 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,16 +800,10 @@ 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, | |||||
| 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, | |||||
| 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) | |||||
| 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); | |||||
| if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE)) | |||||
| return ret; | |||||
| ret = ff_h264_execute_ref_pic_marking(h, sl->mmco, sl->nb_mmco); | |||||
| h->explicit_ref_marking = 0; | |||||
| ret = ff_h264_execute_ref_pic_marking(h); | |||||
| 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) | |||||
| 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) | |||||
| 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); | ||||