Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mpc-hc/FFmpeg.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHendrik Leppkes <h.leppkes@gmail.com>2016-01-09 18:34:40 +0300
committerHendrik Leppkes <h.leppkes@gmail.com>2017-08-04 20:18:33 +0300
commit2cc24d02730e48bc1b900de1695b9e43f21ad2e3 (patch)
treefbc658cd98f8040cfe3593b5034623d276932645
parenta3240934b49732042f6f077ec1c5ece28c28df4f (diff)
h264_parser: add support for parsing h264 mvc NALUs
-rw-r--r--libavcodec/allcodecs.c1
-rw-r--r--libavcodec/h264.h2
-rw-r--r--libavcodec/h264_parser.c34
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,
+};