From a12d3188cbec15e22070e139fa5cc541da07e2c3 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 29 Jan 2015 08:42:14 +0100 Subject: h264: use a smaller struct for the ref lists There is no need to store a whole H264Picture, with a full AVFrame embedded in it. This should allow getting rid of the embedded AVFrame later. --- libavcodec/h264_refs.c | 90 ++++++++++++++++++++++++++------------------------ 1 file changed, 47 insertions(+), 43 deletions(-) (limited to 'libavcodec/h264_refs.c') diff --git a/libavcodec/h264_refs.c b/libavcodec/h264_refs.c index 04cfa9eec3..5782c8e271 100644 --- a/libavcodec/h264_refs.c +++ b/libavcodec/h264_refs.c @@ -35,31 +35,34 @@ #include -#define COPY_PICTURE(dst, src) \ -do {\ - *(dst) = *(src);\ - (dst)->f.extended_data = (dst)->f.data;\ - (dst)->tf.f = &(dst)->f;\ -} while (0) - - -static void pic_as_field(H264Picture *pic, const int parity){ +static void pic_as_field(H264Ref *pic, const int parity) +{ int i; - for (i = 0; i < 4; ++i) { + for (i = 0; i < FF_ARRAY_ELEMS(pic->data); ++i) { if (parity == PICT_BOTTOM_FIELD) - pic->f.data[i] += pic->f.linesize[i]; + pic->data[i] += pic->linesize[i]; pic->reference = parity; - pic->f.linesize[i] *= 2; + pic->linesize[i] *= 2; } - pic->poc= pic->field_poc[parity == PICT_BOTTOM_FIELD]; + pic->poc = pic->parent->field_poc[parity == PICT_BOTTOM_FIELD]; +} + +static void ref_from_h264pic(H264Ref *dst, H264Picture *src) +{ + memcpy(dst->data, src->f.data, sizeof(dst->data)); + memcpy(dst->linesize, src->f.linesize, sizeof(dst->linesize)); + dst->reference = src->reference; + dst->poc = src->poc; + dst->pic_id = src->pic_id; + dst->parent = src; } -static int split_field_copy(H264Picture *dest, H264Picture *src, int parity, int id_add) +static int split_field_copy(H264Ref *dest, H264Picture *src, int parity, int id_add) { int match = !!(src->reference & parity); if (match) { - COPY_PICTURE(dest, src); + ref_from_h264pic(dest, src); if (parity != PICT_FRAME) { pic_as_field(dest, parity); dest->pic_id *= 2; @@ -70,7 +73,7 @@ static int split_field_copy(H264Picture *dest, H264Picture *src, int parity, int return match; } -static int build_def_list(H264Picture *def, int def_len, +static int build_def_list(H264Ref *def, int def_len, H264Picture **in, int len, int is_long, int sel) { int i[2] = { 0 }; @@ -142,19 +145,16 @@ int ff_h264_fill_default_ref_list(H264Context *h, H264SliceContext *sl) h->long_ref, 16, 1, h->picture_structure); 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; } if (lens[0] == lens[1] && lens[1] > 1) { for (i = 0; i < lens[0] && - h->default_ref_list[0][i].f.buf[0]->buffer == - h->default_ref_list[1][i].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]) { - H264Picture tmp; - COPY_PICTURE(&tmp, &h->default_ref_list[1][0]); - COPY_PICTURE(&h->default_ref_list[1][0], &h->default_ref_list[1][1]); - COPY_PICTURE(&h->default_ref_list[1][1], &tmp); + FFSWAP(H264Ref, h->default_ref_list[1][0], h->default_ref_list[1][1]); } } } else { @@ -165,7 +165,7 @@ int ff_h264_fill_default_ref_list(H264Context *h, H264SliceContext *sl) h-> long_ref, 16, 1, h->picture_structure); 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++) { @@ -214,14 +214,13 @@ static int pic_num_extract(H264Context *h, int pic_num, int *structure) int ff_h264_decode_ref_pic_list_reordering(H264Context *h, H264SliceContext *sl) { - int list, index, pic_structure, i; + int list, index, pic_structure; print_short_term(h); print_long_term(h); for (list = 0; list < sl->list_count; list++) { - for (i = 0; i < sl->ref_count[list]; i++) - COPY_PICTURE(&sl->ref_list[list][i], &h->default_ref_list[list][i]); + 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; @@ -304,17 +303,18 @@ int ff_h264_decode_ref_pic_list_reordering(H264Context *h, H264SliceContext *sl) if (i < 0) { av_log(h->avctx, AV_LOG_ERROR, "reference picture missing during reorder\n"); - memset(&sl->ref_list[list][index], 0, sizeof(H264Picture)); // FIXME + memset(&sl->ref_list[list][index], 0, sizeof(sl->ref_list[0][0])); // FIXME } else { for (i = index; i + 1 < sl->ref_count[list]; i++) { - if (ref->long_ref == sl->ref_list[list][i].long_ref && + if (sl->ref_list[list][i].parent && + ref->long_ref == sl->ref_list[list][i].parent->long_ref && ref->pic_id == sl->ref_list[list][i].pic_id) break; } for (; i > index; i--) { - COPY_PICTURE(&sl->ref_list[list][i], &sl->ref_list[list][i - 1]); + sl->ref_list[list][i] = sl->ref_list[list][i - 1]; } - COPY_PICTURE(&sl->ref_list[list][index], ref); + ref_from_h264pic(&sl->ref_list[list][index], ref); if (FIELD_PICTURE(h)) { pic_as_field(&sl->ref_list[list][index], pic_structure); } @@ -324,10 +324,10 @@ int ff_h264_decode_ref_pic_list_reordering(H264Context *h, H264SliceContext *sl) } 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].f.buf[0]) - COPY_PICTURE(&sl->ref_list[list][index], &h->default_ref_list[list][0]); + if (h->default_ref_list[list][0].parent) + sl->ref_list[list][index] = h->default_ref_list[list][0]; else return -1; } @@ -340,20 +340,24 @@ int ff_h264_decode_ref_pic_list_reordering(H264Context *h, H264SliceContext *sl) void ff_h264_fill_mbaff_ref_list(H264Context *h, H264SliceContext *sl) { int list, i, j; - for (list = 0; list < 2; list++) { //FIXME try list_count + for (list = 0; list < sl->list_count; list++) { //FIXME try list_count 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]; -- cgit v1.2.3