X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fh264_parser.c;h=bca00717c4eb7f70316faf195622c2c3b286cf56;hb=07dcef9bc7a614084f4afe39de678884a36cabf1;hp=81ccaabc1e27816ec8f863dc029e4a80a5fdd59e;hpb=9ee1f033656374a9f7c9bddcfd85739614580d62;p=ffmpeg diff --git a/libavcodec/h264_parser.c b/libavcodec/h264_parser.c index 81ccaabc1e2..bca00717c4e 100644 --- a/libavcodec/h264_parser.c +++ b/libavcodec/h264_parser.c @@ -36,10 +36,10 @@ #include "libavutil/mem.h" #include "libavutil/pixfmt.h" +#include "avcodec.h" #include "get_bits.h" #include "golomb.h" #include "h264.h" -#include "h264dec.h" #include "h264_sei.h" #include "h264_ps.h" #include "h264data.h" @@ -60,6 +60,8 @@ typedef struct H264ParseContext { uint8_t parse_history[6]; int parse_history_count; int parse_last_mb; + int64_t reference_dts; + int last_frame_num, last_picture_structure; } H264ParseContext; @@ -106,14 +108,14 @@ static int h264_find_frame_end(H264ParseContext *p, const uint8_t *buf, state >>= 1; // 2->1, 1->0, 0->0 } else if (state <= 5) { int nalu_type = buf[i] & 0x1F; - if (nalu_type == NAL_SEI || nalu_type == NAL_SPS || - nalu_type == NAL_PPS || nalu_type == NAL_AUD) { + if (nalu_type == H264_NAL_SEI || nalu_type == H264_NAL_SPS || + nalu_type == H264_NAL_PPS || nalu_type == H264_NAL_AUD) { if (pc->frame_start_found) { i++; goto found; } - } else if (nalu_type == NAL_SLICE || nalu_type == NAL_DPA || - nalu_type == NAL_IDR_SLICE) { + } else if (nalu_type == H264_NAL_SLICE || nalu_type == H264_NAL_DPA || + nalu_type == H264_NAL_IDR_SLICE) { state += 8; continue; } @@ -228,26 +230,6 @@ static int scan_mmco_reset(AVCodecParserContext *s, GetBitContext *gb, return 0; } -static inline int get_avc_nalsize(H264ParseContext *p, const uint8_t *buf, - int buf_size, int *buf_index, void *logctx) -{ - int i, nalsize = 0; - - if (*buf_index >= buf_size - p->nal_length_size) { - // the end of the buffer is reached, refill it - return AVERROR(EAGAIN); - } - - for (i = 0; i < p->nal_length_size; i++) - nalsize = ((unsigned)nalsize << 8) | buf[(*buf_index)++]; - if (nalsize <= 0 || nalsize > buf_size - *buf_index) { - av_log(logctx, AV_LOG_ERROR, - "AVC: nal size %d\n", nalsize); - return AVERROR_INVALIDDATA; - } - return nalsize; -} - /** * Parse NAL units of found picture and decode some basic information. * @@ -288,7 +270,7 @@ static inline int parse_nal_units(AVCodecParserContext *s, int src_length, consumed, nalsize = 0; if (buf_index >= next_avc) { - nalsize = get_avc_nalsize(p, buf, buf_size, &buf_index, avctx); + nalsize = get_nalsize(p->nal_length_size, buf, buf_size, &buf_index, avctx); if (nalsize < 0) break; next_avc = buf_index + nalsize; @@ -303,10 +285,10 @@ static inline int parse_nal_units(AVCodecParserContext *s, state = buf[buf_index]; switch (state & 0x1f) { - case NAL_SLICE: - case NAL_IDR_SLICE: + case H264_NAL_SLICE: + case H264_NAL_IDR_SLICE: // Do not walk the whole buffer just to decode slice header - if ((state & 0x1f) == NAL_IDR_SLICE || ((state >> 5) & 0x3) == 0) { + if ((state & 0x1f) == H264_NAL_IDR_SLICE || ((state >> 5) & 0x3) == 0) { /* IDR or disposable slice * No need to decode many bytes because MMCOs shall not be present. */ if (src_length > 60) @@ -318,7 +300,7 @@ static inline int parse_nal_units(AVCodecParserContext *s, } break; } - consumed = ff_h2645_extract_rbsp(buf + buf_index, src_length, &nal); + consumed = ff_h2645_extract_rbsp(buf + buf_index, src_length, &nal, 1); if (consumed < 0) break; @@ -332,17 +314,17 @@ static inline int parse_nal_units(AVCodecParserContext *s, nal.type = get_bits(&nal.gb, 5); switch (nal.type) { - case NAL_SPS: + case H264_NAL_SPS: ff_h264_decode_seq_parameter_set(&nal.gb, avctx, &p->ps, 0); break; - case NAL_PPS: + case H264_NAL_PPS: ff_h264_decode_picture_parameter_set(&nal.gb, avctx, &p->ps, nal.size_bits); break; - case NAL_SEI: + case H264_NAL_SEI: ff_h264_sei_decode(&p->sei, &nal.gb, &p->ps, avctx); break; - case NAL_IDR_SLICE: + case H264_NAL_IDR_SLICE: s->key_frame = 1; p->poc.prev_frame_num = 0; @@ -350,7 +332,7 @@ static inline int parse_nal_units(AVCodecParserContext *s, p->poc.prev_poc_msb = p->poc.prev_poc_lsb = 0; /* fall through */ - case NAL_SLICE: + case H264_NAL_SLICE: get_ue_golomb_long(&nal.gb); // skip first_mb_in_slice slice_type = get_ue_golomb_31(&nal.gb); s->pict_type = ff_h264_golomb_to_pict_type[slice_type % 5]; @@ -440,7 +422,7 @@ static inline int parse_nal_units(AVCodecParserContext *s, } } - if (nal.type == NAL_IDR_SLICE) + if (nal.type == H264_NAL_IDR_SLICE) get_ue_golomb_long(&nal.gb); /* idr_pic_id */ if (sps->poc_type == 0) { p->poc.poc_lsb = get_bits(&nal.gb, sps->log2_max_poc_lsb); @@ -469,7 +451,7 @@ static inline int parse_nal_units(AVCodecParserContext *s, * FIXME: MMCO_RESET could appear in non-first slice. * Maybe, we should parse all undisposable non-IDR slice of this * picture until encountering MMCO_RESET in a slice of it. */ - if (nal.ref_idc && nal.type != NAL_IDR_SLICE) { + if (nal.ref_idc && nal.type != H264_NAL_IDR_SLICE) { got_reset = scan_mmco_reset(s, &nal.gb, avctx); if (got_reset < 0) goto fail; @@ -547,7 +529,19 @@ static inline int parse_nal_units(AVCodecParserContext *s, s->picture_structure = AV_PICTURE_STRUCTURE_TOP_FIELD; else s->picture_structure = AV_PICTURE_STRUCTURE_BOTTOM_FIELD; - s->field_order = AV_FIELD_UNKNOWN; + if (p->poc.frame_num == p->last_frame_num && + p->last_picture_structure != AV_PICTURE_STRUCTURE_UNKNOWN && + p->last_picture_structure != AV_PICTURE_STRUCTURE_FRAME && + p->last_picture_structure != s->picture_structure) { + if (p->last_picture_structure == AV_PICTURE_STRUCTURE_TOP_FIELD) + s->field_order = AV_FIELD_TT; + else + s->field_order = AV_FIELD_BB; + } else { + s->field_order = AV_FIELD_UNKNOWN; + } + p->last_picture_structure = s->picture_structure; + p->last_frame_num = p->poc.frame_num; } av_freep(&nal.rbsp_buffer); @@ -618,6 +612,26 @@ static int h264_parse(AVCodecParserContext *s, s->flags &= PARSER_FLAG_COMPLETE_FRAMES; } + if (s->dts_sync_point >= 0) { + int64_t den = avctx->time_base.den * (int64_t)avctx->pkt_timebase.num; + if (den > 0) { + int64_t num = avctx->time_base.num * (int64_t)avctx->pkt_timebase.den; + if (s->dts != AV_NOPTS_VALUE) { + // got DTS from the stream, update reference timestamp + p->reference_dts = s->dts - av_rescale(s->dts_ref_dts_delta, num, den); + } else if (p->reference_dts != AV_NOPTS_VALUE) { + // compute DTS based on reference timestamp + s->dts = p->reference_dts + av_rescale(s->dts_ref_dts_delta, num, den); + } + + if (p->reference_dts != AV_NOPTS_VALUE && s->pts == AV_NOPTS_VALUE) + s->pts = s->dts + av_rescale(s->pts_dts_delta, num, den); + + if (s->dts_sync_point > 0) + p->reference_dts = s->dts; // new reference + } + } + *poutbuf = buf; *poutbuf_size = buf_size; return next; @@ -637,17 +651,17 @@ static int h264_split(AVCodecContext *avctx, if ((state & 0xFFFFFF00) != 0x100) break; nalu_type = state & 0x1F; - if (nalu_type == NAL_SPS) { + if (nalu_type == H264_NAL_SPS) { has_sps = 1; - } else if (nalu_type == NAL_PPS) + } else if (nalu_type == H264_NAL_PPS) has_pps = 1; /* else if (nalu_type == 0x01 || * nalu_type == 0x02 || * nalu_type == 0x05) { * } */ - else if ((nalu_type != NAL_SEI || has_pps) && - nalu_type != NAL_AUD && nalu_type != NAL_SPS_EXT && + else if ((nalu_type != H264_NAL_SEI || has_pps) && + nalu_type != H264_NAL_AUD && nalu_type != H264_NAL_SPS_EXT && nalu_type != 0x0f) { if (has_sps) { while (ptr - 4 > buf && ptr[-5] == 0) @@ -675,6 +689,8 @@ static av_cold int init(AVCodecParserContext *s) { H264ParseContext *p = s->priv_data; + p->reference_dts = AV_NOPTS_VALUE; + p->last_frame_num = INT_MAX; ff_h264dsp_init(&p->h264dsp, 8, 1); return 0; }