[FFmpeg-devel] [PATCH] libavformat/flvdec: add HEVC demuxing support
Xiaolei Yu
dreifachstein at gmail.com
Sun Jul 25 16:04:10 EEST 2021
Explicitly supply an HEVC codec id to enable this feature.
---
libavformat/flv.h | 1 +
libavformat/flvdec.c | 21 ++++++++++++++++++---
2 files changed, 19 insertions(+), 3 deletions(-)
diff --git a/libavformat/flv.h b/libavformat/flv.h
index 3571b90279..7cb1b72b4c 100644
--- a/libavformat/flv.h
+++ b/libavformat/flv.h
@@ -42,6 +42,7 @@
#define FLV_AUDIO_CODECID_MASK 0xf0
#define FLV_VIDEO_CODECID_MASK 0x0f
+#define FLV_VIDEO_CODECID_MAX 0x0f
#define FLV_VIDEO_FRAMETYPE_MASK 0xf0
#define AMF_END_OF_OBJECT 0x09
diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c
index b4a419177a..e44aa693b7 100644
--- a/libavformat/flvdec.c
+++ b/libavformat/flvdec.c
@@ -74,6 +74,7 @@ typedef struct FLVContext {
int64_t *keyframe_times;
int64_t *keyframe_filepositions;
int missing_streams;
+ int hevc_codec_id;
AVRational framerate;
int64_t last_ts;
int64_t time_offset;
@@ -301,7 +302,7 @@ static void flv_set_audio_codec(AVFormatContext *s, AVStream *astream,
}
}
-static int flv_same_video_codec(AVCodecParameters *vpar, int flags)
+static int flv_same_video_codec(FLVContext *flv, AVCodecParameters *vpar, int flags)
{
int flv_codecid = flags & FLV_VIDEO_CODECID_MASK;
@@ -322,6 +323,8 @@ static int flv_same_video_codec(AVCodecParameters *vpar, int flags)
case FLV_CODECID_H264:
return vpar->codec_id == AV_CODEC_ID_H264;
default:
+ if (flv->hevc_codec_id && flv_codecid == flv->hevc_codec_id)
+ return vpar->codec_id == AV_CODEC_ID_HEVC;
return vpar->codec_tag == flv_codecid;
}
}
@@ -329,6 +332,7 @@ static int flv_same_video_codec(AVCodecParameters *vpar, int flags)
static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream,
int flv_codecid, int read)
{
+ FLVContext *flv = s->priv_data;
int ret = 0;
AVCodecParameters *par = vstream->codecpar;
enum AVCodecID old_codec_id = vstream->codecpar->codec_id;
@@ -371,6 +375,12 @@ static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream,
ret = 3;
break;
default:
+ if (flv->hevc_codec_id && flv_codecid == flv->hevc_codec_id) {
+ par->codec_id = AV_CODEC_ID_HEVC;
+ vstream->internal->need_parsing = AVSTREAM_PARSE_HEADERS;
+ ret = 3; // not 4, reading packet type will consume one byte
+ break;
+ }
avpriv_request_sample(s, "Video codec (%x)", flv_codecid);
par->codec_tag = flv_codecid;
}
@@ -1126,7 +1136,7 @@ skip:
break;
} else if (stream_type == FLV_STREAM_TYPE_VIDEO) {
if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
- (s->video_codec_id || flv_same_video_codec(st->codecpar, flags)))
+ (s->video_codec_id || flv_same_video_codec(flv, st->codecpar, flags)))
break;
} else if (stream_type == FLV_STREAM_TYPE_SUBTITLE) {
if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE)
@@ -1241,6 +1251,7 @@ retry_duration:
if (st->codecpar->codec_id == AV_CODEC_ID_AAC ||
st->codecpar->codec_id == AV_CODEC_ID_H264 ||
+ st->codecpar->codec_id == AV_CODEC_ID_HEVC ||
st->codecpar->codec_id == AV_CODEC_ID_MPEG4) {
int type = avio_r8(s->pb);
size--;
@@ -1250,7 +1261,9 @@ retry_duration:
goto leave;
}
- if (st->codecpar->codec_id == AV_CODEC_ID_H264 || st->codecpar->codec_id == AV_CODEC_ID_MPEG4) {
+ if (st->codecpar->codec_id == AV_CODEC_ID_H264 ||
+ st->codecpar->codec_id == AV_CODEC_ID_HEVC ||
+ st->codecpar->codec_id == AV_CODEC_ID_MPEG4) {
// sign extension
int32_t cts = (avio_rb24(s->pb) + 0xff800000) ^ 0xff800000;
pts = av_sat_add64(dts, cts);
@@ -1266,6 +1279,7 @@ retry_duration:
}
}
if (type == 0 && (!st->codecpar->extradata || st->codecpar->codec_id == AV_CODEC_ID_AAC ||
+ st->codecpar->codec_id == AV_CODEC_ID_HEVC ||
st->codecpar->codec_id == AV_CODEC_ID_H264)) {
AVDictionaryEntry *t;
@@ -1361,6 +1375,7 @@ static const AVOption options[] = {
{ "flv_metadata", "Allocate streams according to the onMetaData array", OFFSET(trust_metadata), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VD },
{ "flv_full_metadata", "Dump full metadata of the onMetadata", OFFSET(dump_full_metadata), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VD },
{ "flv_ignore_prevtag", "Ignore the Size of previous tag", OFFSET(trust_datasize), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VD },
+ { "flv_hevc_codec_id", "Assign HEVC stream codec ID", OFFSET(hevc_codec_id), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, FLV_VIDEO_CODECID_MAX, VD },
{ "missing_streams", "", OFFSET(missing_streams), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 0xFF, VD | AV_OPT_FLAG_EXPORT | AV_OPT_FLAG_READONLY },
{ NULL }
};
--
2.32.0
More information about the ffmpeg-devel
mailing list