From: Michael Niedermayer <mich...@niedermayer.cc> This fixes a regression of the sample from Ticket 2371
This reverts commit bc66451e5e903698ee0500faf04c1214f3dd157f, reversing changes made to 9d1fb9ef313e0fb709ac4c35c7bf00264963fd85. --- libavcodec/h264.h | 8 +++++++ libavcodec/h264_refs.c | 57 ++++++++++++++++++++++++++--------------------- libavcodec/h264_slice.c | 17 +++++++++++++- 3 files changed, 56 insertions(+), 26 deletions(-) diff --git a/libavcodec/h264.h b/libavcodec/h264.h index 5d9aecd..b3d08c3 100644 --- a/libavcodec/h264.h +++ b/libavcodec/h264.h @@ -669,6 +669,7 @@ typedef struct H264Context { */ int max_pic_num; + H264Ref default_ref_list[2][32]; ///< base reference list for all slices of a coded picture H264Picture *short_ref[32]; H264Picture *long_ref[32]; H264Picture *delayed_pic[MAX_DELAYED_PIC_COUNT + 2]; // FIXME size? @@ -713,6 +714,8 @@ typedef struct H264Context { enum AVPictureType pict_type; + int last_slice_type; + unsigned int last_ref_count[2]; /** @} */ /** @@ -894,6 +897,11 @@ int ff_h264_get_slice_type(const H264SliceContext *sl); */ int ff_h264_alloc_tables(H264Context *h); +/** + * Fill the default_ref_list. + */ +int ff_h264_fill_default_ref_list(H264Context *h, H264SliceContext *sl); + int ff_h264_decode_ref_pic_list_reordering(H264Context *h, H264SliceContext *sl); void ff_h264_fill_mbaff_ref_list(H264Context *h, H264SliceContext *sl); void ff_h264_remove_all_refs(H264Context *h); diff --git a/libavcodec/h264_refs.c b/libavcodec/h264_refs.c index b47c995..86e8260 100644 --- a/libavcodec/h264_refs.c +++ b/libavcodec/h264_refs.c @@ -130,7 +130,7 @@ static int mismatches_ref(H264Context *h, H264Picture *pic) h->cur_pic_ptr->f->format != f->format); } -static void h264_initialise_ref_list(H264Context *h, H264SliceContext *sl) +int ff_h264_fill_default_ref_list(H264Context *h, H264SliceContext *sl) { int i, len; int j; @@ -150,64 +150,66 @@ static void h264_initialise_ref_list(H264Context *h, H264SliceContext *sl) len += add_sorted(sorted + len, h->short_ref, h->short_ref_count, cur_poc, 0 ^ list); av_assert0(len <= 32); - len = build_def_list(sl->ref_list[list], FF_ARRAY_ELEMS(sl->ref_list[0]), + len = build_def_list(h->default_ref_list[list], FF_ARRAY_ELEMS(h->default_ref_list[0]), sorted, len, 0, h->picture_structure); - len += build_def_list(sl->ref_list[list] + len, - FF_ARRAY_ELEMS(sl->ref_list[0]) - len, + 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(&sl->ref_list[list][len], 0, sizeof(H264Ref) * (sl->ref_count[list] - len)); + memset(&h->default_ref_list[list][len], 0, sizeof(H264Ref) * (sl->ref_count[list] - len)); lens[list] = len; } if (lens[0] == lens[1] && lens[1] > 1) { for (i = 0; i < lens[0] && - sl->ref_list[0][i].parent->f->buf[0]->buffer == - sl->ref_list[1][i].parent->f->buf[0]->buffer; i++); + h->default_ref_list[0][i].parent->f->buf[0]->buffer == + h->default_ref_list[1][i].parent->f->buf[0]->buffer; i++); if (i == lens[0]) { - FFSWAP(H264Ref, sl->ref_list[1][0], sl->ref_list[1][1]); + FFSWAP(H264Ref, h->default_ref_list[1][0], h->default_ref_list[1][1]); } } } else { - len = build_def_list(sl->ref_list[0], FF_ARRAY_ELEMS(sl->ref_list[0]), + len = build_def_list(h->default_ref_list[0], FF_ARRAY_ELEMS(h->default_ref_list[0]), h->short_ref, h->short_ref_count, 0, h->picture_structure); - len += build_def_list(sl->ref_list[0] + len, - FF_ARRAY_ELEMS(sl->ref_list[0]) - len, + 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(&sl->ref_list[0][len], 0, sizeof(H264Ref) * (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++) { ff_tlog(h->avctx, "List0: %s fn:%d 0x%p\n", - (sl->ref_list[0][i].long_ref ? "LT" : "ST"), - sl->ref_list[0][i].pic_id, - sl->ref_list[0][i].f->data[0]); + h->default_ref_list[0][i].parent ? (h->default_ref_list[0][i].parent->long_ref ? "LT" : "ST") : "NULL", + h->default_ref_list[0][i].pic_id, + h->default_ref_list[0][i].parent ? h->default_ref_list[0][i].parent->f->data[0] : 0); } if (sl->slice_type_nos == AV_PICTURE_TYPE_B) { for (i = 0; i < sl->ref_count[1]; i++) { ff_tlog(h->avctx, "List1: %s fn:%d 0x%p\n", - (sl->ref_list[1][i].long_ref ? "LT" : "ST"), - sl->ref_list[1][i].pic_id, - sl->ref_list[1][i].f->data[0]); + h->default_ref_list[1][i].parent ? (h->default_ref_list[1][i].parent->long_ref ? "LT" : "ST") : "NULL", + h->default_ref_list[1][i].pic_id, + h->default_ref_list[1][i].parent ? h->default_ref_list[1][i].parent->f->data[0] : 0); } } #endif for (j = 0; j<1+(sl->slice_type_nos == AV_PICTURE_TYPE_B); j++) { for (i = 0; i < sl->ref_count[j]; i++) { - if (sl->ref_list[j][i].parent) { - if (mismatches_ref(h, sl->ref_list[j][i].parent)) { + if (h->default_ref_list[j][i].parent) { + if (mismatches_ref(h, h->default_ref_list[j][i].parent)) { av_log(h->avctx, AV_LOG_ERROR, "Discarding mismatching reference\n"); - memset(&sl->ref_list[j][i], 0, sizeof(sl->ref_list[j][i])); + memset(&h->default_ref_list[j][i], 0, sizeof(h->default_ref_list[j][i])); } } } } + + return 0; } static void print_short_term(H264Context *h); @@ -243,9 +245,9 @@ int ff_h264_decode_ref_pic_list_reordering(H264Context *h, H264SliceContext *sl) print_short_term(h); print_long_term(h); - h264_initialise_ref_list(h, sl); - for (list = 0; list < sl->list_count; list++) { + memcpy(sl->ref_list[list], h->default_ref_list[list], sl->ref_count[list] * sizeof(sl->ref_list[0][0])); + if (get_bits1(&sl->gb)) { // ref_pic_list_modification_flag_l[01] int pred = h->curr_pic_num; @@ -351,10 +353,14 @@ int ff_h264_decode_ref_pic_list_reordering(H264Context *h, H264SliceContext *sl) 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\n"); + 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; - return -1; + if (h->default_ref_list[list][0].parent + && !(!FIELD_PICTURE(h) && (h->default_ref_list[list][0].reference&3) != 3)) + 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].parent->f->buf[0]) > 0); } @@ -524,6 +530,7 @@ void ff_h264_remove_all_refs(H264Context *h) } h->short_ref_count = 0; + memset(h->default_ref_list, 0, sizeof(h->default_ref_list)); for (i = 0; i < h->nb_slice_ctx; i++) { H264SliceContext *sl = &h->slice_ctx[i]; sl->list_count = sl->ref_count[0] = sl->ref_count[1] = 0; diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c index c63e6d6..2b87abd 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -540,7 +540,10 @@ int ff_h264_update_thread_context(AVCodecContext *dst, h->dequant_coeff_pps = h1->dequant_coeff_pps; // POC timing - copy_fields(h, h1, poc_lsb, current_slice); + copy_fields(h, h1, poc_lsb, default_ref_list); + + // reference lists + copy_fields(h, h1, short_ref, current_slice); copy_picture_range(h->short_ref, h1->short_ref, 32, h, h1); copy_picture_range(h->long_ref, h1->long_ref, 32, h, h1); @@ -1226,6 +1229,7 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl) sl->slice_type_fixed = 0; slice_type = golomb_to_pict_type[slice_type]; + sl->slice_type = slice_type; sl->slice_type_nos = slice_type & 3; @@ -1664,6 +1668,7 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl) memset(h->slice_table, -1, (h->mb_height * h->mb_stride - 1) * sizeof(*h->slice_table)); } + h->last_slice_type = -1; } av_assert1(h->mb_num == h->mb_width * h->mb_height); @@ -1727,6 +1732,14 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl) if (ret < 0) return ret; + if (slice_type != AV_PICTURE_TYPE_I && + (h->current_slice == 0 || + slice_type != h->last_slice_type || + memcmp(h->last_ref_count, sl->ref_count, sizeof(sl->ref_count)))) { + + ff_h264_fill_default_ref_list(h, sl); + } + if (sl->slice_type_nos != AV_PICTURE_TYPE_I) { ret = ff_h264_decode_ref_pic_list_reordering(h, sl); if (ret < 0) { @@ -1870,6 +1883,8 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl) h->pps.chroma_qp_index_offset[1]) + 6 * (h->sps.bit_depth_luma - 8); + h->last_slice_type = slice_type; + memcpy(h->last_ref_count, sl->ref_count, sizeof(h->last_ref_count)); sl->slice_num = ++h->current_slice; if (sl->slice_num) -- 1.7.9.5 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel