diff options
author | Clément Bœsch <u@pkh.me> | 2016-06-19 12:17:41 +0200 |
---|---|---|
committer | Clément Bœsch <u@pkh.me> | 2016-06-19 12:17:41 +0200 |
commit | 0bf5fd2e19b081ce17e523944c2735586b008159 (patch) | |
tree | 72ff0ebd574dd615d59175c500dc8bb1b7428b5f /libavcodec/h264_parser.c | |
parent | 8a135a55b3570441b6147c94f24c71e5c81ac916 (diff) | |
parent | 98c97994c5b90bdae02accb155eeceeb5224b8ef (diff) | |
download | ffmpeg-0bf5fd2e19b081ce17e523944c2735586b008159.tar.gz |
Merge commit '98c97994c5b90bdae02accb155eeceeb5224b8ef'
* commit '98c97994c5b90bdae02accb155eeceeb5224b8ef':
h264: decouple extradata parsing from the decoder
Main changes:
- move get_avc_nalsize() inside h264_parser.c and make it use
H264ParseContext instead of H264Context. This helps fixing
fate-flv-demux.
- Also use is_avc/nal_length_size from the H264ParseContext in various
places instead of the H264Context one as that's the fields now filled
by ff_h264_decode_extradata()
- h264_parse: dont fail decode_extradata_ps() due to nal split failure.
Change by Michael to fix decoding of h264/ref_10.avi.
Merged-by: Clément Bœsch <u@pkh.me>
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Diffstat (limited to 'libavcodec/h264_parser.c')
-rw-r--r-- | libavcodec/h264_parser.c | 61 |
1 files changed, 32 insertions, 29 deletions
diff --git a/libavcodec/h264_parser.c b/libavcodec/h264_parser.c index 9fccdc98bc..bb167b78f7 100644 --- a/libavcodec/h264_parser.c +++ b/libavcodec/h264_parser.c @@ -52,6 +52,8 @@ typedef struct H264ParseContext { H264DSPContext h264dsp; H264POCContext poc; H264SEIContext sei; + int is_avc; + int nal_length_size; int got_first; } H264ParseContext; @@ -64,20 +66,20 @@ static int h264_find_frame_end(H264ParseContext *p, const uint8_t *buf, uint32_t state; ParseContext *pc = &p->pc; - int next_avc= h->is_avc ? 0 : buf_size; + int next_avc = p->is_avc ? 0 : buf_size; // mb_addr= pc->mb_addr - 1; state = pc->state; if (state > 13) state = 7; - if (h->is_avc && !h->nal_length_size) + if (p->is_avc && !p->nal_length_size) av_log(h->avctx, AV_LOG_ERROR, "AVC-parser: nal length size invalid\n"); for (i = 0; i < buf_size; i++) { if (i >= next_avc) { int nalsize = 0; i = next_avc; - for (j = 0; j < h->nal_length_size; j++) + for (j = 0; j < p->nal_length_size; j++) nalsize = (nalsize << 8) | buf[i++]; if (nalsize <= 0 || nalsize > buf_size - i) { av_log(h->avctx, AV_LOG_ERROR, "AVC-parser: nal size %d remaining %d\n", nalsize, buf_size - i); @@ -132,14 +134,14 @@ static int h264_find_frame_end(H264ParseContext *p, const uint8_t *buf, } } pc->state = state; - if (h->is_avc) + if (p->is_avc) return next_avc; return END_NOT_FOUND; found: pc->state = 7; pc->frame_start_found = 0; - if (h->is_avc) + if (p->is_avc) return next_avc; return i - (state & 5) - 5 * (state > 7); } @@ -222,6 +224,26 @@ 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. * @@ -258,13 +280,13 @@ static inline int parse_nal_units(AVCodecParserContext *s, return 0; buf_index = 0; - next_avc = h->is_avc ? 0 : buf_size; + next_avc = p->is_avc ? 0 : buf_size; for (;;) { const SPS *sps; int src_length, consumed, nalsize = 0; if (buf_index >= next_avc) { - nalsize = get_avc_nalsize(h, buf, buf_size, &buf_index); + nalsize = get_avc_nalsize(p, buf, buf_size, &buf_index, avctx); if (nalsize < 0) break; next_avc = buf_index + nalsize; @@ -547,8 +569,6 @@ static int h264_parse(AVCodecParserContext *s, if (!p->got_first) { p->got_first = 1; if (avctx->extradata_size) { - int i; - h->avctx = avctx; // must be done like in decoder, otherwise opening the parser, // letting it create extradata and then closing and opening again @@ -556,26 +576,9 @@ static int h264_parse(AVCodecParserContext *s, // Note that estimate_timings_from_pts does exactly this. if (!avctx->has_b_frames) h->low_delay = 1; - ff_h264_decode_extradata(h, avctx->extradata, avctx->extradata_size); - - for (i = 0; i < FF_ARRAY_ELEMS(p->ps.sps_list); i++) { - av_buffer_unref(&p->ps.sps_list[i]); - if (h->ps.sps_list[i]) { - p->ps.sps_list[i] = av_buffer_ref(h->ps.sps_list[i]); - if (!p->ps.sps_list[i]) - return AVERROR(ENOMEM); - } - } - for (i = 0; i < FF_ARRAY_ELEMS(p->ps.pps_list); i++) { - av_buffer_unref(&p->ps.pps_list[i]); - if (h->ps.pps_list[i]) { - p->ps.pps_list[i] = av_buffer_ref(h->ps.pps_list[i]); - if (!p->ps.pps_list[i]) - return AVERROR(ENOMEM); - } - } - - p->ps.sps = h->ps.sps; + ff_h264_decode_extradata(avctx->extradata, avctx->extradata_size, + &p->ps, &p->is_avc, &p->nal_length_size, + avctx->err_recognition, avctx); } } |