summaryrefslogtreecommitdiff
path: root/libavcodec/h264_parser.c
diff options
context:
space:
mode:
authorYusuke Nakamura <muken.the.vfrmaniac@gmail.com>2013-05-15 07:37:36 +0900
committerAnton Khirnov <anton@khirnov.net>2013-05-24 08:45:05 +0200
commit3f1a7ceb2c604deff10f475f4b1941458d09d1e7 (patch)
treeaae4c88e9e0e35b5be21732f963ed5712c2000a0 /libavcodec/h264_parser.c
parentb493847df4ff8ce46f258749e4a3f304696b34c1 (diff)
h264_parser: Set field_order and picture_structure.
Signed-off-by: Anton Khirnov <anton@khirnov.net>
Diffstat (limited to 'libavcodec/h264_parser.c')
-rw-r--r--libavcodec/h264_parser.c57
1 files changed, 57 insertions, 0 deletions
diff --git a/libavcodec/h264_parser.c b/libavcodec/h264_parser.c
index e5d2c03f8a..1f79f1ba2f 100644
--- a/libavcodec/h264_parser.c
+++ b/libavcodec/h264_parser.c
@@ -116,10 +116,12 @@ static inline int parse_nal_units(AVCodecParserContext *s,
unsigned int slice_type;
int state = -1;
const uint8_t *ptr;
+ int field_poc[2];
/* set some sane default values */
s->pict_type = AV_PICTURE_TYPE_I;
s->key_frame = 0;
+ s->picture_structure = AV_PICTURE_STRUCTURE_UNKNOWN;
h->avctx= avctx;
h->sei_recovery_frame_cnt = -1;
@@ -162,6 +164,11 @@ static inline int parse_nal_units(AVCodecParserContext *s,
break;
case NAL_IDR_SLICE:
s->key_frame = 1;
+
+ h->prev_frame_num = 0;
+ h->prev_frame_num_offset = 0;
+ h->prev_poc_msb =
+ h->prev_poc_lsb = 0;
/* fall through */
case NAL_SLICE:
get_ue_golomb(&h->gb); // skip first_mb_in_slice
@@ -201,6 +208,24 @@ static inline int parse_nal_units(AVCodecParserContext *s,
}
}
+ if (h->nal_unit_type == NAL_IDR_SLICE)
+ get_ue_golomb(&h->gb); /* idr_pic_id */
+ if (h->sps.poc_type == 0) {
+ h->poc_lsb = get_bits(&h->gb, h->sps.log2_max_poc_lsb);
+
+ if (h->pps.pic_order_present == 1 && h->picture_structure == PICT_FRAME)
+ h->delta_poc_bottom = get_se_golomb(&h->gb);
+ }
+
+ if (h->sps.poc_type == 1 && !h->sps.delta_pic_order_always_zero_flag) {
+ h->delta_poc[0] = get_se_golomb(&h->gb);
+
+ if (h->pps.pic_order_present == 1 && h->picture_structure == PICT_FRAME)
+ h->delta_poc[1] = get_se_golomb(&h->gb);
+ }
+
+ ff_init_poc(h, field_poc, NULL);
+
if(h->sps.pic_struct_present_flag) {
switch (h->sei_pic_struct) {
case SEI_PIC_STRUCT_TOP_FIELD:
@@ -230,6 +255,38 @@ static inline int parse_nal_units(AVCodecParserContext *s,
s->repeat_pict = h->picture_structure == PICT_FRAME ? 1 : 0;
}
+ if (h->picture_structure == PICT_FRAME) {
+ s->picture_structure = AV_PICTURE_STRUCTURE_FRAME;
+ if (h->sps.pic_struct_present_flag) {
+ switch (h->sei_pic_struct) {
+ case SEI_PIC_STRUCT_TOP_BOTTOM:
+ case SEI_PIC_STRUCT_TOP_BOTTOM_TOP:
+ s->field_order = AV_FIELD_TT;
+ break;
+ case SEI_PIC_STRUCT_BOTTOM_TOP:
+ case SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM:
+ s->field_order = AV_FIELD_BB;
+ break;
+ default:
+ s->field_order = AV_FIELD_PROGRESSIVE;
+ break;
+ }
+ } else {
+ if (field_poc[0] < field_poc[1])
+ s->field_order = AV_FIELD_TT;
+ else if (field_poc[0] > field_poc[1])
+ s->field_order = AV_FIELD_BB;
+ else
+ s->field_order = AV_FIELD_PROGRESSIVE;
+ }
+ } else {
+ if (h->picture_structure == PICT_TOP_FIELD)
+ s->picture_structure = AV_PICTURE_STRUCTURE_TOP_FIELD;
+ else
+ s->picture_structure = AV_PICTURE_STRUCTURE_BOTTOM_FIELD;
+ s->field_order = AV_FIELD_UNKNOWN;
+ }
+
return 0; /* no need to evaluate the rest */
}
buf += consumed;