diff options
author | Hendrik Leppkes <h.leppkes@gmail.com> | 2016-01-09 18:34:40 +0300 |
---|---|---|
committer | Hendrik Leppkes <h.leppkes@gmail.com> | 2017-08-04 20:18:33 +0300 |
commit | 2cc24d02730e48bc1b900de1695b9e43f21ad2e3 (patch) | |
tree | fbc658cd98f8040cfe3593b5034623d276932645 | |
parent | a3240934b49732042f6f077ec1c5ece28c28df4f (diff) |
h264_parser: add support for parsing h264 mvc NALUs
-rw-r--r-- | libavcodec/allcodecs.c | 1 | ||||
-rw-r--r-- | libavcodec/h264.h | 2 | ||||
-rw-r--r-- | libavcodec/h264_parser.c | 34 |
3 files changed, 33 insertions, 4 deletions
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index 4712592a5f..f5f2547fb6 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -711,6 +711,7 @@ static void register_all(void) REGISTER_PARSER(H261, h261); REGISTER_PARSER(H263, h263); REGISTER_PARSER(H264, h264); + REGISTER_PARSER(H264_MVC, h264_mvc); REGISTER_PARSER(HEVC, hevc); REGISTER_PARSER(MJPEG, mjpeg); REGISTER_PARSER(MLP, mlp); diff --git a/libavcodec/h264.h b/libavcodec/h264.h index 86df5eb9b3..22c4f1d82a 100644 --- a/libavcodec/h264.h +++ b/libavcodec/h264.h @@ -41,7 +41,9 @@ enum { H264_NAL_END_STREAM = 11, H264_NAL_FILLER_DATA = 12, H264_NAL_SPS_EXT = 13, + H264_NAL_SPS_SUBSET = 15, H264_NAL_AUXILIARY_SLICE = 19, + H264_NAL_SLICE_EXT = 20, }; #endif /* AVCODEC_H264_H */ diff --git a/libavcodec/h264_parser.c b/libavcodec/h264_parser.c index 9d30ba736c..4b3f7cc21c 100644 --- a/libavcodec/h264_parser.c +++ b/libavcodec/h264_parser.c @@ -62,6 +62,7 @@ typedef struct H264ParseContext { int parse_last_mb; int64_t reference_dts; int last_frame_num, last_picture_structure; + int is_mvc; } H264ParseContext; @@ -109,14 +110,18 @@ static int h264_find_frame_end(H264ParseContext *p, const uint8_t *buf, } else if (state <= 5) { int nalu_type = buf[i] & 0x1F; if (nalu_type == H264_NAL_SEI || nalu_type == H264_NAL_SPS || - nalu_type == H264_NAL_PPS || nalu_type == H264_NAL_AUD) { + nalu_type == H264_NAL_PPS || nalu_type == H264_NAL_AUD || + nalu_type == H264_NAL_SPS_SUBSET) { if (pc->frame_start_found) { i++; goto found; } } else if (nalu_type == H264_NAL_SLICE || nalu_type == H264_NAL_DPA || - nalu_type == H264_NAL_IDR_SLICE) { + nalu_type == H264_NAL_IDR_SLICE || (p->is_mvc && nalu_type == H264_NAL_SLICE_EXT)) { state += 8; + + if (nalu_type == H264_NAL_SLICE_EXT) + i += 3; // skip mvc extension continue; } state = 7; @@ -597,7 +602,8 @@ static int h264_parse(AVCodecParserContext *s, } } - parse_nal_units(s, avctx, buf, buf_size); + if (!p->is_mvc) + parse_nal_units(s, avctx, buf, buf_size); if (avctx->framerate.num) avctx->time_base = av_inv_q(av_mul_q(avctx->framerate, (AVRational){avctx->ticks_per_frame, 1})); @@ -654,7 +660,7 @@ static int h264_split(AVCodecContext *avctx, if ((state & 0xFFFFFF00) != 0x100) break; nalu_type = state & 0x1F; - if (nalu_type == H264_NAL_SPS) { + if (nalu_type == H264_NAL_SPS || nalu_type == H264_NAL_SPS_SUBSET) { has_sps = 1; } else if (nalu_type == H264_NAL_PPS) has_pps = 1; @@ -706,3 +712,23 @@ AVCodecParser ff_h264_parser = { .parser_close = h264_close, .split = h264_split, }; + +static av_cold int init_mvc(AVCodecParserContext *s) +{ + H264ParseContext *p = s->priv_data; + int ret = init(s); + if (ret < 0) + return ret; + + p->is_mvc = 1; + return 0; +} + +AVCodecParser ff_h264_mvc_parser = { + .codec_ids = { AV_CODEC_ID_H264_MVC }, + .priv_data_size = sizeof(H264ParseContext), + .parser_init = init_mvc, + .parser_parse = h264_parse, + .parser_close = h264_close, + .split = h264_split, +}; |