From: Michael Niedermayer Date: Sat, 21 Mar 2015 21:08:19 +0000 (+0100) Subject: Merge commit 'a12d3188cbec15e22070e139fa5cc541da07e2c3' X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=d8151a7e944aea52d167571badc247c8d9972847;p=ffmpeg Merge commit 'a12d3188cbec15e22070e139fa5cc541da07e2c3' * commit 'a12d3188cbec15e22070e139fa5cc541da07e2c3': h264: use a smaller struct for the ref lists Conflicts: libavcodec/h264_direct.c libavcodec/h264_mb.c libavcodec/h264_picture.c libavcodec/h264_refs.c Merged-by: Michael Niedermayer --- d8151a7e944aea52d167571badc247c8d9972847 diff --cc libavcodec/h264.c index 1974f6611c2,f9ec9163bac..18e5a4dd8b9 --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@@ -77,14 -69,6 +77,14 @@@ static void h264_er_decode_mb(void *opa * practice then correct remapping should be added. */ if (ref >= sl->ref_count[0]) ref = 0; - if (!sl->ref_list[0][ref].f.data[0]) { ++ if (!sl->ref_list[0][ref].data[0]) { + av_log(h->avctx, AV_LOG_DEBUG, "Reference not available for error concealing\n"); + ref = 0; + } + if ((sl->ref_list[0][ref].reference&3) != 3) { + av_log(h->avctx, AV_LOG_DEBUG, "Reference invalid\n"); + return; + } fill_rectangle(&h->cur_pic.ref_index[0][4 * sl->mb_xy], 2, 2, 2, ref, 1); fill_rectangle(&sl->ref_cache[0][scan8[0]], 4, 4, 8, ref, 1); diff --cc libavcodec/h264.h index 5ecff73f54e,9fc5c12feea..2c38a246b6b --- a/libavcodec/h264.h +++ b/libavcodec/h264.h @@@ -325,14 -294,19 +325,25 @@@ typedef struct H264Picture int needs_realloc; ///< picture needs to be reallocated (eg due to a frame size change) int reference; int recovered; ///< picture at IDR or recovery point + recovery count + int invalid_gap; + int sei_recovery_frame_cnt; + + int crop; + int crop_left; + int crop_top; } H264Picture; + typedef struct H264Ref { + uint8_t *data[3]; + int linesize[3]; + + int reference; + int poc; + int pic_id; + + H264Picture *parent; + } H264Ref; + typedef struct H264SliceContext { struct H264Context *h264; GetBitContext gb; diff --cc libavcodec/h264_direct.c index 08cab2b8493,a7966e15e9c..5756a7ba666 --- a/libavcodec/h264_direct.c +++ b/libavcodec/h264_direct.c @@@ -155,11 -159,11 +159,11 @@@ void ff_h264_direct_ref_list_init(cons } } --static void await_reference_mb_row(const H264Context *const h, H264Picture *ref, ++static void await_reference_mb_row(const H264Context *const h, H264Ref *ref, int mb_y) { int ref_field = ref->reference - 1; -- int ref_field_picture = ref->field_picture; ++ int ref_field_picture = ref->parent->field_picture; int ref_height = 16 * h->mb_height >> ref_field_picture; if (!HAVE_THREADS || !(h->avctx->active_thread_type & FF_THREAD_FRAME)) @@@ -168,7 -172,7 +172,7 @@@ /* FIXME: It can be safe to access mb stuff * even if pixels aren't deblocked yet. */ -- ff_thread_await_progress(&ref->tf, ++ ff_thread_await_progress(&ref->parent->tf, FFMIN(16 * mb_y >> ref_field_picture, ref_height - 1), ref_field_picture && ref_field); @@@ -317,12 -320,12 +321,12 @@@ single_col } } - await_reference_mb_row(h, sl->ref_list[1][0].parent, mb_y); + await_reference_mb_row(h, &sl->ref_list[1][0], mb_y); - l1mv0 = (void*)&sl->ref_list[1][0].motion_val[0][h->mb2b_xy[mb_xy]]; - l1mv1 = (void*)&sl->ref_list[1][0].motion_val[1][h->mb2b_xy[mb_xy]]; - l1ref0 = &sl->ref_list[1][0].ref_index[0][4 * mb_xy]; - l1ref1 = &sl->ref_list[1][0].ref_index[1][4 * mb_xy]; - l1mv0 = &sl->ref_list[1][0].parent->motion_val[0][h->mb2b_xy[mb_xy]]; - l1mv1 = &sl->ref_list[1][0].parent->motion_val[1][h->mb2b_xy[mb_xy]]; ++ l1mv0 = (void*)&sl->ref_list[1][0].parent->motion_val[0][h->mb2b_xy[mb_xy]]; ++ l1mv1 = (void*)&sl->ref_list[1][0].parent->motion_val[1][h->mb2b_xy[mb_xy]]; + l1ref0 = &sl->ref_list[1][0].parent->ref_index[0][4 * mb_xy]; + l1ref1 = &sl->ref_list[1][0].parent->ref_index[1][4 * mb_xy]; if (!b8_stride) { if (sl->mb_y & 1) { l1ref0 += 2; @@@ -476,10 -479,10 +480,10 @@@ static void pred_temp_direct_motion(con assert(sl->ref_list[1][0].reference & 3); - await_reference_mb_row(h, sl->ref_list[1][0].parent, + await_reference_mb_row(h, &sl->ref_list[1][0], sl->mb_y + !!IS_INTERLACED(*mb_type)); - if (IS_INTERLACED(sl->ref_list[1][0].mb_type[mb_xy])) { // AFL/AFR/FR/FL -> AFL/FL + if (IS_INTERLACED(sl->ref_list[1][0].parent->mb_type[mb_xy])) { // AFL/AFR/FR/FL -> AFL/FL if (!IS_INTERLACED(*mb_type)) { // AFR/FR -> AFL/FL mb_y = (sl->mb_y & ~1) + sl->col_parity; mb_xy = sl->mb_x + @@@ -541,12 -544,12 +545,12 @@@ single_col } } - await_reference_mb_row(h, sl->ref_list[1][0].parent, mb_y); + await_reference_mb_row(h, &sl->ref_list[1][0], mb_y); - l1mv0 = (void*)&sl->ref_list[1][0].motion_val[0][h->mb2b_xy[mb_xy]]; - l1mv1 = (void*)&sl->ref_list[1][0].motion_val[1][h->mb2b_xy[mb_xy]]; - l1ref0 = &sl->ref_list[1][0].ref_index[0][4 * mb_xy]; - l1ref1 = &sl->ref_list[1][0].ref_index[1][4 * mb_xy]; - l1mv0 = &sl->ref_list[1][0].parent->motion_val[0][h->mb2b_xy[mb_xy]]; - l1mv1 = &sl->ref_list[1][0].parent->motion_val[1][h->mb2b_xy[mb_xy]]; ++ l1mv0 = (void*)&sl->ref_list[1][0].parent->motion_val[0][h->mb2b_xy[mb_xy]]; ++ l1mv1 = (void*)&sl->ref_list[1][0].parent->motion_val[1][h->mb2b_xy[mb_xy]]; + l1ref0 = &sl->ref_list[1][0].parent->ref_index[0][4 * mb_xy]; + l1ref1 = &sl->ref_list[1][0].parent->ref_index[1][4 * mb_xy]; if (!b8_stride) { if (sl->mb_y & 1) { l1ref0 += 2; diff --cc libavcodec/h264_mb.c index f2892710d73,57d429ab02a..b1764a099fc --- a/libavcodec/h264_mb.c +++ b/libavcodec/h264_mb.c @@@ -215,8 -215,8 +215,8 @@@ static av_always_inline void mc_dir_par const int mx = sl->mv_cache[list][scan8[n]][0] + src_x_offset * 8; int my = sl->mv_cache[list][scan8[n]][1] + src_y_offset * 8; const int luma_xy = (mx & 3) + ((my & 3) << 2); - ptrdiff_t offset = ((mx >> 2) << pixel_shift) + (my >> 2) * sl->mb_linesize; + ptrdiff_t offset = (mx >> 2) * (1 << pixel_shift) + (my >> 2) * sl->mb_linesize; - uint8_t *src_y = pic->f.data[0] + offset; + uint8_t *src_y = pic->data[0] + offset; uint8_t *src_cb, *src_cr; int extra_width = 0; int extra_height = 0; @@@ -290,9 -290,9 +290,9 @@@ emu |= (my >> 3) < 0 || (my >> 3) + 8 >= (pic_height >> 1); } - src_cb = pic->f.data[1] + ((mx >> 3) * (1 << pixel_shift)) + - src_cb = pic->data[1] + ((mx >> 3) << pixel_shift) + ++ src_cb = pic->data[1] + ((mx >> 3) * (1 << pixel_shift)) + (my >> ysh) * sl->mb_uvlinesize; - src_cr = pic->f.data[2] + ((mx >> 3) * (1 << pixel_shift)) + - src_cr = pic->data[2] + ((mx >> 3) << pixel_shift) + ++ src_cr = pic->data[2] + ((mx >> 3) * (1 << pixel_shift)) + (my >> ysh) * sl->mb_uvlinesize; if (emu) { @@@ -489,8 -483,8 +489,8 @@@ static av_always_inline void prefetch_m if (refn >= 0) { const int mx = (sl->mv_cache[list][scan8[0]][0] >> 2) + 16 * sl->mb_x + 8; const int my = (sl->mv_cache[list][scan8[0]][1] >> 2) + 16 * sl->mb_y; - uint8_t **src = sl->ref_list[list][refn].f.data; + uint8_t **src = sl->ref_list[list][refn].data; - int off = (mx << pixel_shift) + + int off = mx * (1<< pixel_shift) + (my + (sl->mb_x & 3) * 4) * sl->mb_linesize + (64 << pixel_shift); h->vdsp.prefetch(src[0] + off, h->linesize, 4); diff --cc libavcodec/h264_picture.c index d63a12e1f2a,5792f77c7cd..127bc45c885 --- a/libavcodec/h264_picture.c +++ b/libavcodec/h264_picture.c @@@ -196,27 -184,13 +196,30 @@@ int ff_h264_field_end(H264Context *h, H * past end by one (callers fault) and resync_mb_y != 0 * causes problems for the first MB line, too. */ - if (!FIELD_PICTURE(h)) { - h264_set_erpic(&sl->er.cur_pic, h->cur_pic_ptr); - h264_set_erpic(&sl->er.last_pic, - sl->ref_count[0] ? sl->ref_list[0][0].parent : NULL); - h264_set_erpic(&sl->er.next_pic, - sl->ref_count[1] ? sl->ref_list[1][0].parent : NULL); + if (!FIELD_PICTURE(h) && h->current_slice && !h->sps.new) { + int use_last_pic = h->last_pic_for_ec.f.buf[0] && !sl->ref_count[0]; + + ff_h264_set_erpic(&sl->er.cur_pic, h->cur_pic_ptr); + + if (use_last_pic) { + ff_h264_set_erpic(&sl->er.last_pic, &h->last_pic_for_ec); - COPY_PICTURE(&sl->ref_list[0][0], &h->last_pic_for_ec); ++ sl->ref_list[0][0].parent = &h->last_pic_for_ec; ++ memcpy(sl->ref_list[0][0].data, h->last_pic_for_ec.f.data, sizeof(sl->ref_list[0][0].data)); ++ memcpy(sl->ref_list[0][0].linesize, h->last_pic_for_ec.f.linesize, sizeof(sl->ref_list[0][0].linesize)); ++ sl->ref_list[0][0].reference = h->last_pic_for_ec.reference; + } else if (sl->ref_count[0]) { - ff_h264_set_erpic(&sl->er.last_pic, &sl->ref_list[0][0]); ++ ff_h264_set_erpic(&sl->er.last_pic, sl->ref_list[0][0].parent); + } else + ff_h264_set_erpic(&sl->er.last_pic, NULL); + + if (sl->ref_count[1]) - ff_h264_set_erpic(&sl->er.next_pic, &sl->ref_list[1][0]); ++ ff_h264_set_erpic(&sl->er.next_pic, sl->ref_list[1][0].parent); + + sl->er.ref_count = sl->ref_count[0]; + ff_er_frame_end(&sl->er); + if (use_last_pic) - memset(&sl->ref_list[0][0], 0, sizeof(h->last_pic_for_ec)); ++ memset(&sl->ref_list[0][0], 0, sizeof(sl->ref_list[0][0])); } #endif /* CONFIG_ERROR_RESILIENCE */ diff --cc libavcodec/h264_refs.c index 6c7ec60e683,5782c8e271b..6d72d2ae193 --- a/libavcodec/h264_refs.c +++ b/libavcodec/h264_refs.c @@@ -136,10 -143,9 +146,10 @@@ int ff_h264_fill_default_ref_list(H264C len += build_def_list(h->default_ref_list[list] + len, FF_ARRAY_ELEMS(h->default_ref_list[0]) - len, h->long_ref, 16, 1, h->picture_structure); + av_assert0(len <= 32); if (len < sl->ref_count[list]) - memset(&h->default_ref_list[list][len], 0, sizeof(H264Picture) * (sl->ref_count[list] - len)); + memset(&h->default_ref_list[list][len], 0, sizeof(H264Ref) * (sl->ref_count[list] - len)); lens[list] = len; } @@@ -160,10 -163,9 +167,10 @@@ len += build_def_list(h->default_ref_list[0] + len, FF_ARRAY_ELEMS(h->default_ref_list[0]) - len, h-> long_ref, 16, 1, h->picture_structure); + av_assert0(len <= 32); if (len < sl->ref_count[0]) - memset(&h->default_ref_list[0][len], 0, sizeof(H264Picture) * (sl->ref_count[0] - len)); + memset(&h->default_ref_list[0][len], 0, sizeof(H264Ref) * (sl->ref_count[0] - len)); } #ifdef TRACE for (i = 0; i < sl->ref_count[0]; i++) { @@@ -322,19 -324,13 +329,19 @@@ int ff_h264_decode_ref_pic_list_reorder } for (list = 0; list < sl->list_count; list++) { for (index = 0; index < sl->ref_count[list]; index++) { - if ( !sl->ref_list[list][index].f.buf[0] - if (!sl->ref_list[list][index].parent) { - av_log(h->avctx, AV_LOG_ERROR, "Missing reference picture\n"); - if (h->default_ref_list[list][0].parent) ++ if ( !sl->ref_list[list][index].parent + || (!FIELD_PICTURE(h) && (sl->ref_list[list][index].reference&3) != 3)) { + int i; + av_log(h->avctx, AV_LOG_ERROR, "Missing reference picture, default is %d\n", h->default_ref_list[list][0].poc); + for (i = 0; i < FF_ARRAY_ELEMS(h->last_pocs); i++) + h->last_pocs[i] = INT_MIN; - if (h->default_ref_list[list][0].f.buf[0] ++ if (h->default_ref_list[list][0].parent + && !(!FIELD_PICTURE(h) && (h->default_ref_list[list][0].reference&3) != 3)) - COPY_PICTURE(&sl->ref_list[list][index], &h->default_ref_list[list][0]); + sl->ref_list[list][index] = h->default_ref_list[list][0]; else return -1; } - av_assert0(av_buffer_get_ref_count(sl->ref_list[list][index].f.buf[0]) > 0); ++ av_assert0(av_buffer_get_ref_count(sl->ref_list[list][index].parent->f.buf[0]) > 0); } } @@@ -344,20 -340,24 +351,24 @@@ void ff_h264_fill_mbaff_ref_list(H264Context *h, H264SliceContext *sl) { int list, i, j; - for (list = 0; list < sl->list_count; list++) { //FIXME try list_count + for (list = 0; list < sl->list_count; list++) { for (i = 0; i < sl->ref_count[list]; i++) { - H264Picture *frame = &sl->ref_list[list][i]; - H264Picture *field = &sl->ref_list[list][16 + 2 * i]; - COPY_PICTURE(field, frame); + H264Ref *frame = &sl->ref_list[list][i]; + H264Ref *field = &sl->ref_list[list][16 + 2 * i]; + + field[0] = *frame; + for (j = 0; j < 3; j++) - field[0].f.linesize[j] <<= 1; + field[0].linesize[j] <<= 1; field[0].reference = PICT_TOP_FIELD; - field[0].poc = field[0].field_poc[0]; - COPY_PICTURE(field + 1, field); + field[0].poc = field[0].parent->field_poc[0]; + + field[1] = field[0]; + for (j = 0; j < 3; j++) - field[1].f.data[j] += frame->f.linesize[j]; + field[1].data[j] += frame->parent->f.linesize[j]; field[1].reference = PICT_BOTTOM_FIELD; - field[1].poc = field[1].field_poc[1]; + field[1].poc = field[1].parent->field_poc[1]; sl->luma_weight[16 + 2 * i][list][0] = sl->luma_weight[16 + 2 * i + 1][list][0] = sl->luma_weight[i][list][0]; sl->luma_weight[16 + 2 * i][list][1] = sl->luma_weight[16 + 2 * i + 1][list][1] = sl->luma_weight[i][list][1];