From c8dcff0cdb17d0aa03ac729eba12d1a20f1f59c8 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Mon, 21 Mar 2016 16:14:31 +0100 Subject: h264: factor out calculating the POC count into a separate file This will allow decoupling the parser from the decoder. --- libavcodec/h264_parse.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) (limited to 'libavcodec/h264_parse.c') diff --git a/libavcodec/h264_parse.c b/libavcodec/h264_parse.c index bd1a50ec17..4ab0fde5f7 100644 --- a/libavcodec/h264_parse.c +++ b/libavcodec/h264_parse.c @@ -225,3 +225,83 @@ fail: ref_count[1] = 0; return AVERROR_INVALIDDATA; } + +int ff_h264_init_poc(int pic_field_poc[2], int *pic_poc, + const SPS *sps, H264POCContext *pc, + int picture_structure, int nal_ref_idc) +{ + const int max_frame_num = 1 << sps->log2_max_frame_num; + int field_poc[2]; + + pc->frame_num_offset = pc->prev_frame_num_offset; + if (pc->frame_num < pc->prev_frame_num) + pc->frame_num_offset += max_frame_num; + + if (sps->poc_type == 0) { + const int max_poc_lsb = 1 << sps->log2_max_poc_lsb; + + if (pc->poc_lsb < pc->prev_poc_lsb && + pc->prev_poc_lsb - pc->poc_lsb >= max_poc_lsb / 2) + pc->poc_msb = pc->prev_poc_msb + max_poc_lsb; + else if (pc->poc_lsb > pc->prev_poc_lsb && + pc->prev_poc_lsb - pc->poc_lsb < -max_poc_lsb / 2) + pc->poc_msb = pc->prev_poc_msb - max_poc_lsb; + else + pc->poc_msb = pc->prev_poc_msb; + field_poc[0] = + field_poc[1] = pc->poc_msb + pc->poc_lsb; + if (picture_structure == PICT_FRAME) + field_poc[1] += pc->delta_poc_bottom; + } else if (sps->poc_type == 1) { + int abs_frame_num, expected_delta_per_poc_cycle, expectedpoc; + int i; + + if (sps->poc_cycle_length != 0) + abs_frame_num = pc->frame_num_offset + pc->frame_num; + else + abs_frame_num = 0; + + if (nal_ref_idc == 0 && abs_frame_num > 0) + abs_frame_num--; + + expected_delta_per_poc_cycle = 0; + for (i = 0; i < sps->poc_cycle_length; i++) + // FIXME integrate during sps parse + expected_delta_per_poc_cycle += sps->offset_for_ref_frame[i]; + + if (abs_frame_num > 0) { + int poc_cycle_cnt = (abs_frame_num - 1) / sps->poc_cycle_length; + int frame_num_in_poc_cycle = (abs_frame_num - 1) % sps->poc_cycle_length; + + expectedpoc = poc_cycle_cnt * expected_delta_per_poc_cycle; + for (i = 0; i <= frame_num_in_poc_cycle; i++) + expectedpoc = expectedpoc + sps->offset_for_ref_frame[i]; + } else + expectedpoc = 0; + + if (nal_ref_idc == 0) + expectedpoc = expectedpoc + sps->offset_for_non_ref_pic; + + field_poc[0] = expectedpoc + pc->delta_poc[0]; + field_poc[1] = field_poc[0] + sps->offset_for_top_to_bottom_field; + + if (picture_structure == PICT_FRAME) + field_poc[1] += pc->delta_poc[1]; + } else { + int poc = 2 * (pc->frame_num_offset + pc->frame_num); + + if (!nal_ref_idc) + poc--; + + field_poc[0] = poc; + field_poc[1] = poc; + } + + if (picture_structure != PICT_BOTTOM_FIELD) + pic_field_poc[0] = field_poc[0]; + if (picture_structure != PICT_TOP_FIELD) + pic_field_poc[1] = field_poc[1]; + *pic_poc = FFMIN(pic_field_poc[0], pic_field_poc[1]); + + return 0; +} -- cgit v1.2.3