summaryrefslogtreecommitdiffstats
path: root/libavcodec/h264_parse.c
diff options
context:
space:
mode:
authorAnton Khirnov <anton@khirnov.net>2016-03-21 16:14:31 +0100
committerAnton Khirnov <anton@khirnov.net>2016-04-24 10:06:24 +0200
commitc8dcff0cdb17d0aa03ac729eba12d1a20f1f59c8 (patch)
treeb86b624464e77fe4d82a4ccef0b5fec64ff639c7 /libavcodec/h264_parse.c
parent113aeee6aed35cb786a9f6d69b0cb210f498b9da (diff)
downloadffmpeg-streaming-c8dcff0cdb17d0aa03ac729eba12d1a20f1f59c8.zip
ffmpeg-streaming-c8dcff0cdb17d0aa03ac729eba12d1a20f1f59c8.tar.gz
h264: factor out calculating the POC count into a separate file
This will allow decoupling the parser from the decoder.
Diffstat (limited to 'libavcodec/h264_parse.c')
-rw-r--r--libavcodec/h264_parse.c80
1 files changed, 80 insertions, 0 deletions
diff --git a/libavcodec/h264_parse.c b/libavcodec/h264_parse.c
index bd1a50e..4ab0fde 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;
+}
OpenPOWER on IntegriCloud