Do not use the one in the SEI directly as that is reset at certain points. Inspired by patches from Michael Niedermayer <michaelni@gmx.at> and Anton Mitrofanov <BugMaster@narod.ru>. CC: libav-stable@libav.orgtags/n4.0
| @@ -391,7 +391,7 @@ single_col: | |||||
| (l1ref0[0] < 0 && !l1ref1[0] && | (l1ref0[0] < 0 && !l1ref1[0] && | ||||
| FFABS(l1mv1[0][0]) <= 1 && | FFABS(l1mv1[0][0]) <= 1 && | ||||
| FFABS(l1mv1[0][1]) <= 1 && | FFABS(l1mv1[0][1]) <= 1 && | ||||
| h->sei.unregistered.x264_build > 33U))) { | |||||
| h->x264_build > 33U))) { | |||||
| a = b = 0; | a = b = 0; | ||||
| if (ref[0] > 0) | if (ref[0] > 0) | ||||
| a = mv[0]; | a = mv[0]; | ||||
| @@ -426,7 +426,7 @@ single_col: | |||||
| (l1ref0[i8] == 0 || | (l1ref0[i8] == 0 || | ||||
| (l1ref0[i8] < 0 && | (l1ref0[i8] < 0 && | ||||
| l1ref1[i8] == 0 && | l1ref1[i8] == 0 && | ||||
| h->sei.unregistered.x264_build > 33U))) { | |||||
| h->x264_build > 33U))) { | |||||
| const int16_t (*l1mv)[2] = l1ref0[i8] == 0 ? l1mv0 : l1mv1; | const int16_t (*l1mv)[2] = l1ref0[i8] == 0 ? l1mv0 : l1mv1; | ||||
| if (IS_SUB_8X8(sub_mb_type)) { | if (IS_SUB_8X8(sub_mb_type)) { | ||||
| const int16_t *mv_col = l1mv[x8 * 3 + y8 * 3 * b4_stride]; | const int16_t *mv_col = l1mv[x8 * 3 + y8 * 3 * b4_stride]; | ||||
| @@ -403,6 +403,7 @@ int ff_h264_update_thread_context(AVCodecContext *dst, | |||||
| h->enable_er = h1->enable_er; | h->enable_er = h1->enable_er; | ||||
| h->workaround_bugs = h1->workaround_bugs; | h->workaround_bugs = h1->workaround_bugs; | ||||
| h->x264_build = h1->x264_build; | |||||
| h->droppable = h1->droppable; | h->droppable = h1->droppable; | ||||
| // extradata/NAL handling | // extradata/NAL handling | ||||
| @@ -509,6 +510,9 @@ static int h264_frame_start(H264Context *h) | |||||
| h->mb_aff_frame = h->ps.sps->mb_aff && (h->picture_structure == PICT_FRAME); | h->mb_aff_frame = h->ps.sps->mb_aff && (h->picture_structure == PICT_FRAME); | ||||
| if (h->sei.unregistered.x264_build >= 0) | |||||
| h->x264_build = h->sei.unregistered.x264_build; | |||||
| assert(h->cur_pic_ptr->long_ref == 0); | assert(h->cur_pic_ptr->long_ref == 0); | ||||
| return 0; | return 0; | ||||
| @@ -847,7 +851,7 @@ static int h264_slice_header_init(H264Context *h) | |||||
| if (sps->timing_info_present_flag) { | if (sps->timing_info_present_flag) { | ||||
| int64_t den = sps->time_scale; | int64_t den = sps->time_scale; | ||||
| if (h->sei.unregistered.x264_build < 44U) | |||||
| if (h->x264_build < 44U) | |||||
| den *= 2; | den *= 2; | ||||
| av_reduce(&h->avctx->framerate.den, &h->avctx->framerate.num, | av_reduce(&h->avctx->framerate.den, &h->avctx->framerate.num, | ||||
| sps->num_units_in_tick, den, 1 << 30); | sps->num_units_in_tick, den, 1 << 30); | ||||
| @@ -293,6 +293,7 @@ static int h264_init_context(AVCodecContext *avctx, H264Context *h) | |||||
| h->flags = avctx->flags; | h->flags = avctx->flags; | ||||
| h->poc.prev_poc_msb = 1 << 16; | h->poc.prev_poc_msb = 1 << 16; | ||||
| h->recovery_frame = -1; | h->recovery_frame = -1; | ||||
| h->x264_build = -1; | |||||
| h->frame_recovered = 0; | h->frame_recovered = 0; | ||||
| h->next_outputed_poc = INT_MIN; | h->next_outputed_poc = INT_MIN; | ||||
| @@ -361,6 +361,7 @@ typedef struct H264Context { | |||||
| int context_initialized; | int context_initialized; | ||||
| int flags; | int flags; | ||||
| int workaround_bugs; | int workaround_bugs; | ||||
| int x264_build; | |||||
| /* Set when slice threading is used and at least one slice uses deblocking | /* Set when slice threading is used and at least one slice uses deblocking | ||||
| * mode 1 (i.e. across slice boundaries). Then we disable the loop filter | * mode 1 (i.e. across slice boundaries). Then we disable the loop filter | ||||
| * during normal MB decoding and execute it serially at the end. | * during normal MB decoding and execute it serially at the end. | ||||