* [FFmpeg-devel] [PATCH 1/2] avformat/flvenc: Add support for HEVC over flv in muxer
@ 2023-04-06 12:12 Steven Liu
2023-04-06 12:12 ` [FFmpeg-devel] [PATCH 2/2] avformat/flvdec: support demux HEVC in Enhancing FLV Steven Liu
2023-04-06 14:44 ` [FFmpeg-devel] [PATCH 1/2] avformat/flvenc: Add support for HEVC over flv in muxer Lance Wang
0 siblings, 2 replies; 40+ messages in thread
From: Steven Liu @ 2023-04-06 12:12 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Steven Liu
Implements HEVC according to enhanced RTMP spec found at
https://github.com/veovera/enhanced-rtmp
And it has beed supported by OBS, Simple Realtime Server.
And the Enhancing FLV documentation Contributors include
Jean-Baptiste Kempf (FFmpeg, VideoLAN).
So this should be support by ffmpeg too.
Signed-off-by: Steven Liu <lq@chinaffmpeg.org>
---
libavformat/flv.h | 16 ++++++++++++++
libavformat/flvenc.c | 50 +++++++++++++++++++++++++++++++++-----------
2 files changed, 54 insertions(+), 12 deletions(-)
diff --git a/libavformat/flv.h b/libavformat/flv.h
index 3571b90279..44d3b04ff9 100644
--- a/libavformat/flv.h
+++ b/libavformat/flv.h
@@ -35,6 +35,12 @@
#define FLV_VIDEO_FRAMETYPE_OFFSET 4
+/* Extended VideoTagHeader
+ * defined in reference link:
+ * https://github.com/veovera/enhanced-rtmp/blob/main/enhanced-rtmp-v1.pdf
+ * */
+#define FLV_IS_EX_HEADER 0x80
+
/* bitmasks to isolate specific values */
#define FLV_AUDIO_CHANNEL_MASK 0x01
#define FLV_AUDIO_SAMPLESIZE_MASK 0x02
@@ -110,6 +116,16 @@ enum {
FLV_CODECID_H264 = 7,
FLV_CODECID_REALH263= 8,
FLV_CODECID_MPEG4 = 9,
+ FLV_CODECID_HEVC = 10,
+};
+
+enum {
+ PacketTypeSequenceStart = 0,
+ PacketTypeCodedFrames = 1,
+ PacketTypeSequenceEnd = 2,
+ PacketTypeCodedFramesX = 3,
+ PacketTypeMetadata = 4,
+ PacketTypeMPEG2TSSequenceStart = 5,
};
enum {
diff --git a/libavformat/flvenc.c b/libavformat/flvenc.c
index 64ea554dad..15a0f573f3 100644
--- a/libavformat/flvenc.c
+++ b/libavformat/flvenc.c
@@ -28,6 +28,7 @@
#include "libavcodec/mpeg4audio.h"
#include "avio.h"
#include "avc.h"
+#include "hevc.h"
#include "avformat.h"
#include "flv.h"
#include "internal.h"
@@ -46,6 +47,7 @@ static const AVCodecTag flv_video_codec_ids[] = {
{ AV_CODEC_ID_VP6, FLV_CODECID_VP6 },
{ AV_CODEC_ID_VP6A, FLV_CODECID_VP6A },
{ AV_CODEC_ID_H264, FLV_CODECID_H264 },
+ { AV_CODEC_ID_HEVC, FLV_CODECID_HEVC },
{ AV_CODEC_ID_NONE, 0 }
};
@@ -492,7 +494,7 @@ static void flv_write_codec_header(AVFormatContext* s, AVCodecParameters* par, i
FLVContext *flv = s->priv_data;
if (par->codec_id == AV_CODEC_ID_AAC || par->codec_id == AV_CODEC_ID_H264
- || par->codec_id == AV_CODEC_ID_MPEG4) {
+ || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC) {
int64_t pos;
avio_w8(pb,
par->codec_type == AVMEDIA_TYPE_VIDEO ?
@@ -535,10 +537,19 @@ static void flv_write_codec_header(AVFormatContext* s, AVCodecParameters* par, i
}
avio_write(pb, par->extradata, par->extradata_size);
} else {
- avio_w8(pb, par->codec_tag | FLV_FRAME_KEY); // flags
- avio_w8(pb, 0); // AVC sequence header
- avio_wb24(pb, 0); // composition time
- ff_isom_write_avcc(pb, par->extradata, par->extradata_size);
+ if (par->codec_id == AV_CODEC_ID_HEVC) {
+ avio_w8(pb, FLV_IS_EX_HEADER | PacketTypeSequenceStart); // ExVideoTagHeader mode with PacketTypeSequenceStart
+ avio_write(pb, "hvc1", 4);
+ } else {
+ avio_w8(pb, par->codec_tag | FLV_FRAME_KEY); // flags
+ avio_w8(pb, 0); // AVC sequence header
+ avio_wb24(pb, 0); // composition time
+ }
+
+ if (par->codec_id == AV_CODEC_ID_HEVC)
+ ff_isom_write_hvcc(pb, par->extradata, par->extradata_size, 0);
+ else
+ ff_isom_write_avcc(pb, par->extradata, par->extradata_size);
}
data_size = avio_tell(pb) - pos;
avio_seek(pb, -data_size - 10, SEEK_CUR);
@@ -628,7 +639,8 @@ static int flv_init(struct AVFormatContext *s)
return unsupported_codec(s, "Video", par->codec_id);
if (par->codec_id == AV_CODEC_ID_MPEG4 ||
- par->codec_id == AV_CODEC_ID_H263) {
+ par->codec_id == AV_CODEC_ID_H263 ||
+ par->codec_id == AV_CODEC_ID_HEVC) {
int error = s->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL;
av_log(s, error ? AV_LOG_ERROR : AV_LOG_WARNING,
"Codec %s is not supported in the official FLV specification,\n", avcodec_get_name(par->codec_id));
@@ -784,8 +796,11 @@ end:
for (i = 0; i < s->nb_streams; i++) {
AVCodecParameters *par = s->streams[i]->codecpar;
FLVStreamContext *sc = s->streams[i]->priv_data;
- if (par->codec_type == AVMEDIA_TYPE_VIDEO &&
- (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4))
+ if (par->codec_id == AV_CODEC_ID_HEVC) {
+ avio_w8(pb, 0x82);
+ avio_write(pb, "hvc1", 4);
+ } else if (par->codec_type == AVMEDIA_TYPE_VIDEO &&
+ (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC))
put_eos_tag(pb, sc->last_ts, par->codec_id);
}
}
@@ -836,13 +851,13 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
if (par->codec_id == AV_CODEC_ID_VP6F || par->codec_id == AV_CODEC_ID_VP6A ||
par->codec_id == AV_CODEC_ID_VP6 || par->codec_id == AV_CODEC_ID_AAC)
flags_size = 2;
- else if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4)
+ else if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC)
flags_size = 5;
else
flags_size = 1;
if (par->codec_id == AV_CODEC_ID_AAC || par->codec_id == AV_CODEC_ID_H264
- || par->codec_id == AV_CODEC_ID_MPEG4) {
+ || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC) {
size_t side_size;
uint8_t *side = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &side_size);
if (side && side_size > 0 && (side_size != par->extradata_size || memcmp(side, par->extradata, side_size))) {
@@ -862,7 +877,7 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
"Packets are not in the proper order with respect to DTS\n");
return AVERROR(EINVAL);
}
- if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4) {
+ if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC) {
if (pkt->pts == AV_NOPTS_VALUE) {
av_log(s, AV_LOG_ERROR, "Packet is missing PTS\n");
return AVERROR(EINVAL);
@@ -907,6 +922,10 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
if (par->extradata_size > 0 && *(uint8_t*)par->extradata != 1)
if ((ret = ff_avc_parse_nal_units_buf(pkt->data, &data, &size)) < 0)
return ret;
+ } else if (par->codec_id == AV_CODEC_ID_HEVC) {
+ if (par->extradata_size > 0 && *(uint8_t*)par->extradata != 1)
+ if ((ret = ff_hevc_annexb2mp4_buf(pkt->data, &data, &size, 0, NULL)) < 0)
+ return ret;
} else if (par->codec_id == AV_CODEC_ID_AAC && pkt->size > 2 &&
(AV_RB16(pkt->data) & 0xfff0) == 0xfff0) {
if (!s->streams[pkt->stream_index]->nb_frames) {
@@ -968,7 +987,12 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
avio_wb32(pb, data_size + 11);
} else {
av_assert1(flags>=0);
- avio_w8(pb,flags);
+ if (par->codec_id == AV_CODEC_ID_HEVC) {
+ avio_w8(pb, FLV_IS_EX_HEADER | PacketTypeCodedFrames); // ExVideoTagHeader mode with PacketTypeCodedFrames
+ avio_write(pb, "hvc1", 4);
+ } else {
+ avio_w8(pb, flags);
+ }
if (par->codec_id == AV_CODEC_ID_VP6)
avio_w8(pb,0);
if (par->codec_id == AV_CODEC_ID_VP6F || par->codec_id == AV_CODEC_ID_VP6A) {
@@ -982,6 +1006,8 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
else if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4) {
avio_w8(pb, 1); // AVC NALU
avio_wb24(pb, pkt->pts - pkt->dts);
+ } else if (par->codec_id == AV_CODEC_ID_HEVC) {
+ avio_wb24(pb, pkt->pts - pkt->dts);
}
avio_write(pb, data ? data : pkt->data, size);
--
2.40.0
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 40+ messages in thread
* [FFmpeg-devel] [PATCH 2/2] avformat/flvdec: support demux HEVC in Enhancing FLV
2023-04-06 12:12 [FFmpeg-devel] [PATCH 1/2] avformat/flvenc: Add support for HEVC over flv in muxer Steven Liu
@ 2023-04-06 12:12 ` Steven Liu
2023-04-06 12:18 ` James Almer
2023-04-06 14:44 ` [FFmpeg-devel] [PATCH 1/2] avformat/flvenc: Add support for HEVC over flv in muxer Lance Wang
1 sibling, 1 reply; 40+ messages in thread
From: Steven Liu @ 2023-04-06 12:12 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Steven Liu
Signed-off-by: Steven Liu <lq@chinaffmpeg.org>
---
libavformat/flvdec.c | 61 +++++++++++++++++++++++++++++++++++++++-----
1 file changed, 54 insertions(+), 7 deletions(-)
diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c
index d83edff727..999bcdff6b 100644
--- a/libavformat/flvdec.c
+++ b/libavformat/flvdec.c
@@ -79,6 +79,8 @@ typedef struct FLVContext {
int64_t last_ts;
int64_t time_offset;
int64_t time_pos;
+
+ uint8_t exheader;
} FLVContext;
/* AMF date type */
@@ -302,13 +304,26 @@ 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(AVFormatContext *s, AVCodecParameters *vpar, int flags)
{
int flv_codecid = flags & FLV_VIDEO_CODECID_MASK;
+ FLVContext *flv = s->priv_data;
if (!vpar->codec_id && !vpar->codec_tag)
return 1;
+ if (flv->exheader) {
+ uint8_t *codec_id_str = (uint8_t *)s->pb->buf_ptr;
+ uint32_t codec_id = codec_id_str[3] | codec_id_str[2] << 8 | codec_id_str[1] << 16 | codec_id_str[0] << 24;
+ switch(codec_id) {
+ case MKBETAG('h', 'v', 'c', '1'):
+ flv_codecid = FLV_CODECID_HEVC;
+ break;
+ default:
+ break;
+ }
+ }
+
switch (flv_codecid) {
case FLV_CODECID_H263:
return vpar->codec_id == AV_CODEC_ID_FLV1;
@@ -322,6 +337,8 @@ static int flv_same_video_codec(AVCodecParameters *vpar, int flags)
return vpar->codec_id == AV_CODEC_ID_VP6A;
case FLV_CODECID_H264:
return vpar->codec_id == AV_CODEC_ID_H264;
+ case FLV_CODECID_HEVC:
+ return vpar->codec_id == AV_CODEC_ID_HEVC;
default:
return vpar->codec_tag == flv_codecid;
}
@@ -331,9 +350,23 @@ static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream,
int flv_codecid, int read)
{
FFStream *const vstreami = ffstream(vstream);
+ FLVContext *flv = s->priv_data;
int ret = 0;
AVCodecParameters *par = vstream->codecpar;
enum AVCodecID old_codec_id = vstream->codecpar->codec_id;
+ flv_codecid &= FLV_VIDEO_CODECID_MASK;
+
+ if (flv->exheader) {
+ uint32_t codec_id = avio_rb32(s->pb);
+
+ switch(codec_id) {
+ case MKBETAG('h', 'v', 'c', '1'):
+ flv_codecid = FLV_CODECID_HEVC;
+ break;
+ default:
+ break;
+ }
+ }
switch (flv_codecid) {
case FLV_CODECID_H263:
par->codec_id = AV_CODEC_ID_FLV1;
@@ -372,6 +401,11 @@ static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream,
par->codec_id = AV_CODEC_ID_MPEG4;
ret = 3;
break;
+ case FLV_CODECID_HEVC:
+ par->codec_id = AV_CODEC_ID_HEVC;
+ vstreami->need_parsing = AVSTREAM_PARSE_NONE;
+ ret = 3;
+ break;
default:
avpriv_request_sample(s, "Video codec (%x)", flv_codecid);
par->codec_tag = flv_codecid;
@@ -796,6 +830,7 @@ static int flv_read_header(AVFormatContext *s)
s->start_time = 0;
flv->sum_flv_tag_size = 0;
flv->last_keyframe_stream_index = -1;
+ flv->exheader = 0;
return 0;
}
@@ -1071,6 +1106,11 @@ retry:
} else if (type == FLV_TAG_TYPE_VIDEO) {
stream_type = FLV_STREAM_TYPE_VIDEO;
flags = avio_r8(s->pb);
+ /*
+ * Reference Enhancing FLV 2023-03-v1.0.0-B.8
+ * https://github.com/veovera/enhanced-rtmp/blob/main/enhanced-rtmp-v1.pdf
+ * */
+ flv->exheader = (flags >> 7) & 1;
size--;
if ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_VIDEO_INFO_CMD)
goto skip;
@@ -1129,7 +1169,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(s, st->codecpar, flags)))
break;
} else if (stream_type == FLV_STREAM_TYPE_SUBTITLE) {
if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE)
@@ -1230,7 +1270,7 @@ retry_duration:
avcodec_parameters_free(&par);
}
} else if (stream_type == FLV_STREAM_TYPE_VIDEO) {
- int ret = flv_set_video_codec(s, st, flags & FLV_VIDEO_CODECID_MASK, 1);
+ int ret = flv_set_video_codec(s, st, flags, 1);
if (ret < 0)
return ret;
size -= ret;
@@ -1242,8 +1282,14 @@ 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_MPEG4) {
- int type = avio_r8(s->pb);
+ st->codecpar->codec_id == AV_CODEC_ID_MPEG4 ||
+ st->codecpar->codec_id == AV_CODEC_ID_HEVC) {
+ int type = 0;
+ if (flv->exheader) {
+ type = flags & 0x0F;
+ } else {
+ type = avio_r8(s->pb);
+ }
size--;
if (size < 0) {
@@ -1251,7 +1297,8 @@ 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_MPEG4
+ || (st->codecpar->codec_id == AV_CODEC_ID_HEVC && (flags & 0x0F))) {
// sign extension
int32_t cts = (avio_rb24(s->pb) + 0xff800000) ^ 0xff800000;
pts = av_sat_add64(dts, cts);
@@ -1267,7 +1314,7 @@ retry_duration:
}
}
if (type == 0 && (!st->codecpar->extradata || st->codecpar->codec_id == AV_CODEC_ID_AAC ||
- st->codecpar->codec_id == AV_CODEC_ID_H264)) {
+ st->codecpar->codec_id == AV_CODEC_ID_H264 || st->codecpar->codec_id == AV_CODEC_ID_HEVC)) {
AVDictionaryEntry *t;
if (st->codecpar->extradata) {
--
2.40.0
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [FFmpeg-devel] [PATCH 2/2] avformat/flvdec: support demux HEVC in Enhancing FLV
2023-04-06 12:12 ` [FFmpeg-devel] [PATCH 2/2] avformat/flvdec: support demux HEVC in Enhancing FLV Steven Liu
@ 2023-04-06 12:18 ` James Almer
2023-04-06 12:24 ` [FFmpeg-devel] [PATCH v2 " Steven Liu
2023-04-06 12:30 ` [FFmpeg-devel] [PATCH 2/2] avformat/flvdec: support demux HEVC in Enhancing FLV Steven Liu
0 siblings, 2 replies; 40+ messages in thread
From: James Almer @ 2023-04-06 12:18 UTC (permalink / raw)
To: ffmpeg-devel
On 4/6/2023 9:12 AM, Steven Liu wrote:
> @@ -372,6 +401,11 @@ static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream,
> par->codec_id = AV_CODEC_ID_MPEG4;
> ret = 3;
> break;
> + case FLV_CODECID_HEVC:
> + par->codec_id = AV_CODEC_ID_HEVC;
> + vstreami->need_parsing = AVSTREAM_PARSE_NONE;
Why none? You should use AVSTREAM_PARSE_HEADERS, same as h264, as the
container will not provide enough information about the bitstream in the
absence of a decoder.
> + ret = 3;
> + break;
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 40+ messages in thread
* [FFmpeg-devel] [PATCH v2 2/2] avformat/flvdec: support demux HEVC in Enhancing FLV
2023-04-06 12:18 ` James Almer
@ 2023-04-06 12:24 ` Steven Liu
2023-04-06 12:30 ` Martin Storsjö
2023-04-06 12:30 ` [FFmpeg-devel] [PATCH 2/2] avformat/flvdec: support demux HEVC in Enhancing FLV Steven Liu
1 sibling, 1 reply; 40+ messages in thread
From: Steven Liu @ 2023-04-06 12:24 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Steven Liu
Signed-off-by: Steven Liu <lq@chinaffmpeg.org>
---
libavformat/flvdec.c | 63 +++++++++++++++++++++++++++++++++++++++-----
1 file changed, 56 insertions(+), 7 deletions(-)
diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c
index d83edff727..8060c43772 100644
--- a/libavformat/flvdec.c
+++ b/libavformat/flvdec.c
@@ -79,6 +79,8 @@ typedef struct FLVContext {
int64_t last_ts;
int64_t time_offset;
int64_t time_pos;
+
+ uint8_t exheader;
} FLVContext;
/* AMF date type */
@@ -302,13 +304,26 @@ 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(AVFormatContext *s, AVCodecParameters *vpar, int flags)
{
int flv_codecid = flags & FLV_VIDEO_CODECID_MASK;
+ FLVContext *flv = s->priv_data;
if (!vpar->codec_id && !vpar->codec_tag)
return 1;
+ if (flv->exheader) {
+ uint8_t *codec_id_str = (uint8_t *)s->pb->buf_ptr;
+ uint32_t codec_id = codec_id_str[3] | codec_id_str[2] << 8 | codec_id_str[1] << 16 | codec_id_str[0] << 24;
+ switch(codec_id) {
+ case MKBETAG('h', 'v', 'c', '1'):
+ flv_codecid = FLV_CODECID_HEVC;
+ break;
+ default:
+ break;
+ }
+ }
+
switch (flv_codecid) {
case FLV_CODECID_H263:
return vpar->codec_id == AV_CODEC_ID_FLV1;
@@ -322,6 +337,8 @@ static int flv_same_video_codec(AVCodecParameters *vpar, int flags)
return vpar->codec_id == AV_CODEC_ID_VP6A;
case FLV_CODECID_H264:
return vpar->codec_id == AV_CODEC_ID_H264;
+ case FLV_CODECID_HEVC:
+ return vpar->codec_id == AV_CODEC_ID_HEVC;
default:
return vpar->codec_tag == flv_codecid;
}
@@ -331,9 +348,23 @@ static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream,
int flv_codecid, int read)
{
FFStream *const vstreami = ffstream(vstream);
+ FLVContext *flv = s->priv_data;
int ret = 0;
AVCodecParameters *par = vstream->codecpar;
enum AVCodecID old_codec_id = vstream->codecpar->codec_id;
+ flv_codecid &= FLV_VIDEO_CODECID_MASK;
+
+ if (flv->exheader) {
+ uint32_t codec_id = avio_rb32(s->pb);
+
+ switch(codec_id) {
+ case MKBETAG('h', 'v', 'c', '1'):
+ flv_codecid = FLV_CODECID_HEVC;
+ break;
+ default:
+ break;
+ }
+ }
switch (flv_codecid) {
case FLV_CODECID_H263:
par->codec_id = AV_CODEC_ID_FLV1;
@@ -372,6 +403,11 @@ static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream,
par->codec_id = AV_CODEC_ID_MPEG4;
ret = 3;
break;
+ case FLV_CODECID_HEVC:
+ par->codec_id = AV_CODEC_ID_HEVC;
+ vstreami->need_parsing = AVSTREAM_PARSE_HEADERS;
+ ret = 3;
+ break;
default:
avpriv_request_sample(s, "Video codec (%x)", flv_codecid);
par->codec_tag = flv_codecid;
@@ -796,6 +832,7 @@ static int flv_read_header(AVFormatContext *s)
s->start_time = 0;
flv->sum_flv_tag_size = 0;
flv->last_keyframe_stream_index = -1;
+ flv->exheader = 0;
return 0;
}
@@ -1071,6 +1108,11 @@ retry:
} else if (type == FLV_TAG_TYPE_VIDEO) {
stream_type = FLV_STREAM_TYPE_VIDEO;
flags = avio_r8(s->pb);
+ /*
+ * Reference Enhancing FLV 2023-03-v1.0.0-B.8
+ * https://github.com/veovera/enhanced-rtmp/blob/main/enhanced-rtmp-v1.pdf
+ * */
+ flv->exheader = (flags >> 7) & 1;
size--;
if ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_VIDEO_INFO_CMD)
goto skip;
@@ -1129,7 +1171,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(s, st->codecpar, flags)))
break;
} else if (stream_type == FLV_STREAM_TYPE_SUBTITLE) {
if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE)
@@ -1230,7 +1272,7 @@ retry_duration:
avcodec_parameters_free(&par);
}
} else if (stream_type == FLV_STREAM_TYPE_VIDEO) {
- int ret = flv_set_video_codec(s, st, flags & FLV_VIDEO_CODECID_MASK, 1);
+ int ret = flv_set_video_codec(s, st, flags, 1);
if (ret < 0)
return ret;
size -= ret;
@@ -1242,8 +1284,14 @@ 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_MPEG4) {
- int type = avio_r8(s->pb);
+ st->codecpar->codec_id == AV_CODEC_ID_MPEG4 ||
+ st->codecpar->codec_id == AV_CODEC_ID_HEVC) {
+ int type = 0;
+ if (flv->exheader) {
+ type = flags & 0x0F;
+ } else {
+ type = avio_r8(s->pb);
+ }
size--;
if (size < 0) {
@@ -1251,7 +1299,8 @@ 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_MPEG4
+ || (st->codecpar->codec_id == AV_CODEC_ID_HEVC && (flags & 0x0F))) {
// sign extension
int32_t cts = (avio_rb24(s->pb) + 0xff800000) ^ 0xff800000;
pts = av_sat_add64(dts, cts);
@@ -1267,7 +1316,7 @@ retry_duration:
}
}
if (type == 0 && (!st->codecpar->extradata || st->codecpar->codec_id == AV_CODEC_ID_AAC ||
- st->codecpar->codec_id == AV_CODEC_ID_H264)) {
+ st->codecpar->codec_id == AV_CODEC_ID_H264 || st->codecpar->codec_id == AV_CODEC_ID_HEVC)) {
AVDictionaryEntry *t;
if (st->codecpar->extradata) {
--
2.40.0
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [FFmpeg-devel] [PATCH v2 2/2] avformat/flvdec: support demux HEVC in Enhancing FLV
2023-04-06 12:24 ` [FFmpeg-devel] [PATCH v2 " Steven Liu
@ 2023-04-06 12:30 ` Martin Storsjö
2023-04-06 12:38 ` Steven Liu
0 siblings, 1 reply; 40+ messages in thread
From: Martin Storsjö @ 2023-04-06 12:30 UTC (permalink / raw)
To: FFmpeg development discussions and patches; +Cc: Steven Liu
On Thu, 6 Apr 2023, Steven Liu wrote:
> Signed-off-by: Steven Liu <lq@chinaffmpeg.org>
> ---
> libavformat/flvdec.c | 63 +++++++++++++++++++++++++++++++++++++++-----
> 1 file changed, 56 insertions(+), 7 deletions(-)
Even if the title of the linked document is "Enhancing RTMP, FLV" I kinda
would expect the name of the concept/format to be more like "Enhanced FLV"
(as the name of the repo is "enhanced-rtmp", not "enhancing-rtmp").
So I'd kinda prefer to refer to it in that form in the commit subject and
in the comment in the text. If you want to use literally the name used in
the document, I guess that's "Enhancing RTMP, FLV" though.
// Martin
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [FFmpeg-devel] [PATCH 2/2] avformat/flvdec: support demux HEVC in Enhancing FLV
2023-04-06 12:18 ` James Almer
2023-04-06 12:24 ` [FFmpeg-devel] [PATCH v2 " Steven Liu
@ 2023-04-06 12:30 ` Steven Liu
1 sibling, 0 replies; 40+ messages in thread
From: Steven Liu @ 2023-04-06 12:30 UTC (permalink / raw)
To: FFmpeg development discussions and patches
James Almer <jamrial@gmail.com> 于2023年4月6日周四 20:18写道:
>
> On 4/6/2023 9:12 AM, Steven Liu wrote:
> > @@ -372,6 +401,11 @@ static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream,
> > par->codec_id = AV_CODEC_ID_MPEG4;
> > ret = 3;
> > break;
> > + case FLV_CODECID_HEVC:
> > + par->codec_id = AV_CODEC_ID_HEVC;
> > + vstreami->need_parsing = AVSTREAM_PARSE_NONE;
>
> Why none? You should use AVSTREAM_PARSE_HEADERS, same as h264, as the
> container will not provide enough information about the bitstream in the
> absence of a decoder.
Ok, resubmit as
https://patchwork.ffmpeg.org/project/ffmpeg/patch/20230406122416.93934-1-lq@chinaffmpeg.org/
>
> > + ret = 3;
> > + break;
Thanks James
Steven
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [FFmpeg-devel] [PATCH v2 2/2] avformat/flvdec: support demux HEVC in Enhancing FLV
2023-04-06 12:30 ` Martin Storsjö
@ 2023-04-06 12:38 ` Steven Liu
2023-04-06 13:19 ` Martin Storsjö
0 siblings, 1 reply; 40+ messages in thread
From: Steven Liu @ 2023-04-06 12:38 UTC (permalink / raw)
To: FFmpeg development discussions and patches; +Cc: Steven Liu
Martin Storsjö <martin@martin.st> 于2023年4月6日周四 20:31写道:
>
> On Thu, 6 Apr 2023, Steven Liu wrote:
>
> > Signed-off-by: Steven Liu <lq@chinaffmpeg.org>
> > ---
> > libavformat/flvdec.c | 63 +++++++++++++++++++++++++++++++++++++++-----
> > 1 file changed, 56 insertions(+), 7 deletions(-)
>
> Even if the title of the linked document is "Enhancing RTMP, FLV" I kinda
> would expect the name of the concept/format to be more like "Enhanced FLV"
> (as the name of the repo is "enhanced-rtmp", not "enhancing-rtmp").
>
> So I'd kinda prefer to refer to it in that form in the commit subject and
> in the comment in the text. If you want to use literally the name used in
> the document, I guess that's "Enhancing RTMP, FLV" though.
Or submit three patches, BTW supprt the Enhanced rtmp?
>
> // Martin
>
Thanks Martin
Steven
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [FFmpeg-devel] [PATCH v2 2/2] avformat/flvdec: support demux HEVC in Enhancing FLV
2023-04-06 12:38 ` Steven Liu
@ 2023-04-06 13:19 ` Martin Storsjö
2023-04-07 2:51 ` Steven Liu
0 siblings, 1 reply; 40+ messages in thread
From: Martin Storsjö @ 2023-04-06 13:19 UTC (permalink / raw)
To: FFmpeg development discussions and patches; +Cc: Steven Liu
On Thu, 6 Apr 2023, Steven Liu wrote:
> Martin Storsjö <martin@martin.st> 于2023年4月6日周四 20:31写道:
>>
>> On Thu, 6 Apr 2023, Steven Liu wrote:
>>
>> > Signed-off-by: Steven Liu <lq@chinaffmpeg.org>
>> > ---
>> > libavformat/flvdec.c | 63 +++++++++++++++++++++++++++++++++++++++-----
>> > 1 file changed, 56 insertions(+), 7 deletions(-)
>>
>> Even if the title of the linked document is "Enhancing RTMP, FLV" I kinda
>> would expect the name of the concept/format to be more like "Enhanced FLV"
>> (as the name of the repo is "enhanced-rtmp", not "enhancing-rtmp").
>>
>> So I'd kinda prefer to refer to it in that form in the commit subject and
>> in the comment in the text. If you want to use literally the name used in
>> the document, I guess that's "Enhancing RTMP, FLV" though.
> Or submit three patches, BTW supprt the Enhanced rtmp?
I don't really understand what you mean here and how this is a response to
my comment?
Please respond with a bit more elaborate answer.
// Martin
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [FFmpeg-devel] [PATCH 1/2] avformat/flvenc: Add support for HEVC over flv in muxer
2023-04-06 12:12 [FFmpeg-devel] [PATCH 1/2] avformat/flvenc: Add support for HEVC over flv in muxer Steven Liu
2023-04-06 12:12 ` [FFmpeg-devel] [PATCH 2/2] avformat/flvdec: support demux HEVC in Enhancing FLV Steven Liu
@ 2023-04-06 14:44 ` Lance Wang
2023-04-06 15:10 ` Gyan Doshi
1 sibling, 1 reply; 40+ messages in thread
From: Lance Wang @ 2023-04-06 14:44 UTC (permalink / raw)
To: FFmpeg development discussions and patches
On Thu, Apr 6, 2023 at 8:14 PM Steven Liu <lq@chinaffmpeg.org> wrote:
> Implements HEVC according to enhanced RTMP spec found at
> https://github.com/veovera/enhanced-rtmp
>
>
I think It's document or draft and not specs, I haven't heard any
information for the
veovera software organization. So before implementation, please prove it's
recognized authority. Please see rfc2026.
> And it has beed supported by OBS, Simple Realtime Server.
> And the Enhancing FLV documentation Contributors include
> Jean-Baptiste Kempf (FFmpeg, VideoLAN).
> So this should be support by ffmpeg too.
>
> Signed-off-by: Steven Liu <lq@chinaffmpeg.org>
> ---
> libavformat/flv.h | 16 ++++++++++++++
> libavformat/flvenc.c | 50 +++++++++++++++++++++++++++++++++-----------
> 2 files changed, 54 insertions(+), 12 deletions(-)
>
> diff --git a/libavformat/flv.h b/libavformat/flv.h
> index 3571b90279..44d3b04ff9 100644
> --- a/libavformat/flv.h
> +++ b/libavformat/flv.h
> @@ -35,6 +35,12 @@
>
> #define FLV_VIDEO_FRAMETYPE_OFFSET 4
>
> +/* Extended VideoTagHeader
> + * defined in reference link:
> + *
> https://github.com/veovera/enhanced-rtmp/blob/main/enhanced-rtmp-v1.pdf
> + * */
> +#define FLV_IS_EX_HEADER 0x80
> +
> /* bitmasks to isolate specific values */
> #define FLV_AUDIO_CHANNEL_MASK 0x01
> #define FLV_AUDIO_SAMPLESIZE_MASK 0x02
> @@ -110,6 +116,16 @@ enum {
> FLV_CODECID_H264 = 7,
> FLV_CODECID_REALH263= 8,
> FLV_CODECID_MPEG4 = 9,
> + FLV_CODECID_HEVC = 10,
> +};
> +
> +enum {
> + PacketTypeSequenceStart = 0,
> + PacketTypeCodedFrames = 1,
> + PacketTypeSequenceEnd = 2,
> + PacketTypeCodedFramesX = 3,
> + PacketTypeMetadata = 4,
> + PacketTypeMPEG2TSSequenceStart = 5,
> };
>
> enum {
> diff --git a/libavformat/flvenc.c b/libavformat/flvenc.c
> index 64ea554dad..15a0f573f3 100644
> --- a/libavformat/flvenc.c
> +++ b/libavformat/flvenc.c
> @@ -28,6 +28,7 @@
> #include "libavcodec/mpeg4audio.h"
> #include "avio.h"
> #include "avc.h"
> +#include "hevc.h"
> #include "avformat.h"
> #include "flv.h"
> #include "internal.h"
> @@ -46,6 +47,7 @@ static const AVCodecTag flv_video_codec_ids[] = {
> { AV_CODEC_ID_VP6, FLV_CODECID_VP6 },
> { AV_CODEC_ID_VP6A, FLV_CODECID_VP6A },
> { AV_CODEC_ID_H264, FLV_CODECID_H264 },
> + { AV_CODEC_ID_HEVC, FLV_CODECID_HEVC },
> { AV_CODEC_ID_NONE, 0 }
> };
>
> @@ -492,7 +494,7 @@ static void flv_write_codec_header(AVFormatContext* s,
> AVCodecParameters* par, i
> FLVContext *flv = s->priv_data;
>
> if (par->codec_id == AV_CODEC_ID_AAC || par->codec_id ==
> AV_CODEC_ID_H264
> - || par->codec_id == AV_CODEC_ID_MPEG4) {
> + || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id ==
> AV_CODEC_ID_HEVC) {
> int64_t pos;
> avio_w8(pb,
> par->codec_type == AVMEDIA_TYPE_VIDEO ?
> @@ -535,10 +537,19 @@ static void flv_write_codec_header(AVFormatContext*
> s, AVCodecParameters* par, i
> }
> avio_write(pb, par->extradata, par->extradata_size);
> } else {
> - avio_w8(pb, par->codec_tag | FLV_FRAME_KEY); // flags
> - avio_w8(pb, 0); // AVC sequence header
> - avio_wb24(pb, 0); // composition time
> - ff_isom_write_avcc(pb, par->extradata, par->extradata_size);
> + if (par->codec_id == AV_CODEC_ID_HEVC) {
> + avio_w8(pb, FLV_IS_EX_HEADER | PacketTypeSequenceStart);
> // ExVideoTagHeader mode with PacketTypeSequenceStart
> + avio_write(pb, "hvc1", 4);
> + } else {
> + avio_w8(pb, par->codec_tag | FLV_FRAME_KEY); // flags
> + avio_w8(pb, 0); // AVC sequence header
> + avio_wb24(pb, 0); // composition time
> + }
> +
> + if (par->codec_id == AV_CODEC_ID_HEVC)
> + ff_isom_write_hvcc(pb, par->extradata,
> par->extradata_size, 0);
> + else
> + ff_isom_write_avcc(pb, par->extradata,
> par->extradata_size);
> }
> data_size = avio_tell(pb) - pos;
> avio_seek(pb, -data_size - 10, SEEK_CUR);
> @@ -628,7 +639,8 @@ static int flv_init(struct AVFormatContext *s)
> return unsupported_codec(s, "Video", par->codec_id);
>
> if (par->codec_id == AV_CODEC_ID_MPEG4 ||
> - par->codec_id == AV_CODEC_ID_H263) {
> + par->codec_id == AV_CODEC_ID_H263 ||
> + par->codec_id == AV_CODEC_ID_HEVC) {
> int error = s->strict_std_compliance >
> FF_COMPLIANCE_UNOFFICIAL;
> av_log(s, error ? AV_LOG_ERROR : AV_LOG_WARNING,
> "Codec %s is not supported in the official FLV
> specification,\n", avcodec_get_name(par->codec_id));
> @@ -784,8 +796,11 @@ end:
> for (i = 0; i < s->nb_streams; i++) {
> AVCodecParameters *par = s->streams[i]->codecpar;
> FLVStreamContext *sc = s->streams[i]->priv_data;
> - if (par->codec_type == AVMEDIA_TYPE_VIDEO &&
> - (par->codec_id == AV_CODEC_ID_H264 || par->codec_id
> == AV_CODEC_ID_MPEG4))
> + if (par->codec_id == AV_CODEC_ID_HEVC) {
> + avio_w8(pb, 0x82);
> + avio_write(pb, "hvc1", 4);
> + } else if (par->codec_type == AVMEDIA_TYPE_VIDEO &&
> + (par->codec_id == AV_CODEC_ID_H264 || par->codec_id
> == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC))
> put_eos_tag(pb, sc->last_ts, par->codec_id);
> }
> }
> @@ -836,13 +851,13 @@ static int flv_write_packet(AVFormatContext *s,
> AVPacket *pkt)
> if (par->codec_id == AV_CODEC_ID_VP6F || par->codec_id ==
> AV_CODEC_ID_VP6A ||
> par->codec_id == AV_CODEC_ID_VP6 || par->codec_id ==
> AV_CODEC_ID_AAC)
> flags_size = 2;
> - else if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id ==
> AV_CODEC_ID_MPEG4)
> + else if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id ==
> AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC)
> flags_size = 5;
> else
> flags_size = 1;
>
> if (par->codec_id == AV_CODEC_ID_AAC || par->codec_id ==
> AV_CODEC_ID_H264
> - || par->codec_id == AV_CODEC_ID_MPEG4) {
> + || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id ==
> AV_CODEC_ID_HEVC) {
> size_t side_size;
> uint8_t *side = av_packet_get_side_data(pkt,
> AV_PKT_DATA_NEW_EXTRADATA, &side_size);
> if (side && side_size > 0 && (side_size != par->extradata_size ||
> memcmp(side, par->extradata, side_size))) {
> @@ -862,7 +877,7 @@ static int flv_write_packet(AVFormatContext *s,
> AVPacket *pkt)
> "Packets are not in the proper order with respect to
> DTS\n");
> return AVERROR(EINVAL);
> }
> - if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id ==
> AV_CODEC_ID_MPEG4) {
> + if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id ==
> AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC) {
> if (pkt->pts == AV_NOPTS_VALUE) {
> av_log(s, AV_LOG_ERROR, "Packet is missing PTS\n");
> return AVERROR(EINVAL);
> @@ -907,6 +922,10 @@ static int flv_write_packet(AVFormatContext *s,
> AVPacket *pkt)
> if (par->extradata_size > 0 && *(uint8_t*)par->extradata != 1)
> if ((ret = ff_avc_parse_nal_units_buf(pkt->data, &data,
> &size)) < 0)
> return ret;
> + } else if (par->codec_id == AV_CODEC_ID_HEVC) {
> + if (par->extradata_size > 0 && *(uint8_t*)par->extradata != 1)
> + if ((ret = ff_hevc_annexb2mp4_buf(pkt->data, &data, &size, 0,
> NULL)) < 0)
> + return ret;
> } else if (par->codec_id == AV_CODEC_ID_AAC && pkt->size > 2 &&
> (AV_RB16(pkt->data) & 0xfff0) == 0xfff0) {
> if (!s->streams[pkt->stream_index]->nb_frames) {
> @@ -968,7 +987,12 @@ static int flv_write_packet(AVFormatContext *s,
> AVPacket *pkt)
> avio_wb32(pb, data_size + 11);
> } else {
> av_assert1(flags>=0);
> - avio_w8(pb,flags);
> + if (par->codec_id == AV_CODEC_ID_HEVC) {
> + avio_w8(pb, FLV_IS_EX_HEADER | PacketTypeCodedFrames); //
> ExVideoTagHeader mode with PacketTypeCodedFrames
> + avio_write(pb, "hvc1", 4);
> + } else {
> + avio_w8(pb, flags);
> + }
> if (par->codec_id == AV_CODEC_ID_VP6)
> avio_w8(pb,0);
> if (par->codec_id == AV_CODEC_ID_VP6F || par->codec_id ==
> AV_CODEC_ID_VP6A) {
> @@ -982,6 +1006,8 @@ static int flv_write_packet(AVFormatContext *s,
> AVPacket *pkt)
> else if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id ==
> AV_CODEC_ID_MPEG4) {
> avio_w8(pb, 1); // AVC NALU
> avio_wb24(pb, pkt->pts - pkt->dts);
> + } else if (par->codec_id == AV_CODEC_ID_HEVC) {
> + avio_wb24(pb, pkt->pts - pkt->dts);
> }
>
> avio_write(pb, data ? data : pkt->data, size);
> --
> 2.40.0
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
>
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [FFmpeg-devel] [PATCH 1/2] avformat/flvenc: Add support for HEVC over flv in muxer
2023-04-06 14:44 ` [FFmpeg-devel] [PATCH 1/2] avformat/flvenc: Add support for HEVC over flv in muxer Lance Wang
@ 2023-04-06 15:10 ` Gyan Doshi
2023-04-06 15:32 ` Jean-Baptiste Kempf
2023-04-06 17:03 ` Jan Ekström
0 siblings, 2 replies; 40+ messages in thread
From: Gyan Doshi @ 2023-04-06 15:10 UTC (permalink / raw)
To: ffmpeg-devel
On 2023-04-06 08:14 pm, Lance Wang wrote:
> On Thu, Apr 6, 2023 at 8:14 PM Steven Liu <lq@chinaffmpeg.org> wrote:
>
>> Implements HEVC according to enhanced RTMP spec found at
>> https://github.com/veovera/enhanced-rtmp
>>
>>
> I think It's document or draft and not specs, I haven't heard any
> information for the
> veovera software organization. So before implementation, please prove it's
> recognized authority. Please see rfc2026.
Their Github readme claims
"Additionally, Veovera has welcomed new members to the organization
including Adobe, Google and Veriskope."
I didn't find any public corroboration by these companies.
However, one of the authors is cited as having OBS affiliation and they
have indeed merged support:
https://www.phoronix.com/news/OBS-Studio-AV1-HEVC-RTMP
Since they claim jbk as a member, ping him.
Regards,
Gyan
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [FFmpeg-devel] [PATCH 1/2] avformat/flvenc: Add support for HEVC over flv in muxer
2023-04-06 15:10 ` Gyan Doshi
@ 2023-04-06 15:32 ` Jean-Baptiste Kempf
2023-04-06 17:03 ` Jan Ekström
1 sibling, 0 replies; 40+ messages in thread
From: Jean-Baptiste Kempf @ 2023-04-06 15:32 UTC (permalink / raw)
To: ffmpeg-devel
On Thu, 6 Apr 2023, at 17:10, Gyan Doshi wrote:
> On 2023-04-06 08:14 pm, Lance Wang wrote:
>> On Thu, Apr 6, 2023 at 8:14 PM Steven Liu <lq@chinaffmpeg.org> wrote:
>>
>>> Implements HEVC according to enhanced RTMP spec found at
>>> https://github.com/veovera/enhanced-rtmp
>>>
>>>
>> I think It's document or draft and not specs, I haven't heard any
>> information for the
>> veovera software organization. So before implementation, please prove it's
>> recognized authority. Please see rfc2026.
>
> Their Github readme claims
>
> "Additionally, Veovera has welcomed new members to the organization
> including Adobe, Google and Veriskope."
>
> I didn't find any public corroboration by these companies.
Technically, Veovera is the one doing the maintenance of Flash Media Server, given by Adobe.
So it's so far, the best authority on flv and RTMP.
But for me, all those are still drafts, and therefore need to wait a bit.
Also, audio extension is coming too. (Same system for FourCC)
jb
--
Jean-Baptiste Kempf - President
+33 672 704 734
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [FFmpeg-devel] [PATCH 1/2] avformat/flvenc: Add support for HEVC over flv in muxer
2023-04-06 15:10 ` Gyan Doshi
2023-04-06 15:32 ` Jean-Baptiste Kempf
@ 2023-04-06 17:03 ` Jan Ekström
2023-04-11 8:56 ` Neal Gompa
1 sibling, 1 reply; 40+ messages in thread
From: Jan Ekström @ 2023-04-06 17:03 UTC (permalink / raw)
To: FFmpeg development discussions and patches
On Thu, Apr 6, 2023 at 6:11 PM Gyan Doshi <ffmpeg@gyani.pro> wrote:
>
>
>
> On 2023-04-06 08:14 pm, Lance Wang wrote:
> > On Thu, Apr 6, 2023 at 8:14 PM Steven Liu <lq@chinaffmpeg.org> wrote:
> >
> >> Implements HEVC according to enhanced RTMP spec found at
> >> https://github.com/veovera/enhanced-rtmp
> >>
> >>
> > I think It's document or draft and not specs, I haven't heard any
> > information for the
> > veovera software organization. So before implementation, please prove it's
> > recognized authority. Please see rfc2026.
>
> Their Github readme claims
>
> "Additionally, Veovera has welcomed new members to the organization
> including Adobe, Google and Veriskope."
>
> I didn't find any public corroboration by these companies.
>
Yea, it seems like this was mostly done in the background (classic
corporations being corporations), but I think the most direct way to
notice that Google at least has acknowledged this extension is because
Youtube now seems to support AV1 live stream ingest via RTMP with
these extensions.
Jan
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [FFmpeg-devel] [PATCH v2 2/2] avformat/flvdec: support demux HEVC in Enhancing FLV
2023-04-06 13:19 ` Martin Storsjö
@ 2023-04-07 2:51 ` Steven Liu
2023-04-07 18:54 ` Martin Storsjö
0 siblings, 1 reply; 40+ messages in thread
From: Steven Liu @ 2023-04-07 2:51 UTC (permalink / raw)
To: FFmpeg development discussions and patches; +Cc: Steven Liu
Martin Storsjö <martin@martin.st> 于2023年4月6日周四 21:20写道:
>
> On Thu, 6 Apr 2023, Steven Liu wrote:
>
> > Martin Storsjö <martin@martin.st> 于2023年4月6日周四 20:31写道:
> >>
> >> On Thu, 6 Apr 2023, Steven Liu wrote:
> >>
> >> > Signed-off-by: Steven Liu <lq@chinaffmpeg.org>
> >> > ---
> >> > libavformat/flvdec.c | 63 +++++++++++++++++++++++++++++++++++++++-----
> >> > 1 file changed, 56 insertions(+), 7 deletions(-)
> >>
> >> Even if the title of the linked document is "Enhancing RTMP, FLV" I kinda
> >> would expect the name of the concept/format to be more like "Enhanced FLV"
> >> (as the name of the repo is "enhanced-rtmp", not "enhancing-rtmp").
> >>
> >> So I'd kinda prefer to refer to it in that form in the commit subject and
> >> in the comment in the text. If you want to use literally the name used in
> >> the document, I guess that's "Enhancing RTMP, FLV" though.
>
> > Or submit three patches, BTW supprt the Enhanced rtmp?
>
> I don't really understand what you mean here and how this is a response to
> my comment?
I mean, What should i do? Resubmit some patches for support the full
functions which describe in documents?
Or just modify comments in patch commit messages?
Thanks
Steven
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [FFmpeg-devel] [PATCH v2 2/2] avformat/flvdec: support demux HEVC in Enhancing FLV
2023-04-07 2:51 ` Steven Liu
@ 2023-04-07 18:54 ` Martin Storsjö
2023-04-08 3:22 ` [FFmpeg-devel] [PATCH v3 1/2] avformat/flvenc: Add support for HEVC over flv in muxer Steven Liu
0 siblings, 1 reply; 40+ messages in thread
From: Martin Storsjö @ 2023-04-07 18:54 UTC (permalink / raw)
To: FFmpeg development discussions and patches; +Cc: Steven Liu
On Fri, 7 Apr 2023, Steven Liu wrote:
> Martin Storsjö <martin@martin.st> 于2023年4月6日周四 21:20写道:
>>
>> On Thu, 6 Apr 2023, Steven Liu wrote:
>>
>> > Martin Storsjö <martin@martin.st> 于2023年4月6日周四 20:31写道:
>> >>
>> >> On Thu, 6 Apr 2023, Steven Liu wrote:
>> >>
>> >> > Signed-off-by: Steven Liu <lq@chinaffmpeg.org>
>> >> > ---
>> >> > libavformat/flvdec.c | 63 +++++++++++++++++++++++++++++++++++++++-----
>> >> > 1 file changed, 56 insertions(+), 7 deletions(-)
>> >>
>> >> Even if the title of the linked document is "Enhancing RTMP, FLV" I kinda
>> >> would expect the name of the concept/format to be more like "Enhanced FLV"
>> >> (as the name of the repo is "enhanced-rtmp", not "enhancing-rtmp").
>> >>
>> >> So I'd kinda prefer to refer to it in that form in the commit subject and
>> >> in the comment in the text. If you want to use literally the name used in
>> >> the document, I guess that's "Enhancing RTMP, FLV" though.
>>
>> > Or submit three patches, BTW supprt the Enhanced rtmp?
>>
>> I don't really understand what you mean here and how this is a response to
>> my comment?
>
> I mean, What should i do? Resubmit some patches for support the full
> functions which describe in documents?
> Or just modify comments in patch commit messages?
I'm just saying you should replace "Enhancing" with "Enhanced" in the
commit message and code comment.
// Martin
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 40+ messages in thread
* [FFmpeg-devel] [PATCH v3 1/2] avformat/flvenc: Add support for HEVC over flv in muxer
2023-04-07 18:54 ` Martin Storsjö
@ 2023-04-08 3:22 ` Steven Liu
2023-04-08 3:22 ` [FFmpeg-devel] [PATCH v3 2/2] avformat/flvdec: support demux HEVC in Enhanced FLV Steven Liu
0 siblings, 1 reply; 40+ messages in thread
From: Steven Liu @ 2023-04-08 3:22 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Steven Liu
Implements HEVC according to Enhanced FLV spec found at
https://github.com/veovera/enhanced-rtmp
And it has beed supported by OBS, Simple Realtime Server, mpegts.js.
And the enhanced FLV documentation contributors include
Jean-Baptiste Kempf (FFmpeg, VideoLAN).
So this should be support by ffmpeg too.
Signed-off-by: Steven Liu <lq@chinaffmpeg.org>
---
libavformat/flv.h | 16 ++++++++++++++
libavformat/flvenc.c | 50 +++++++++++++++++++++++++++++++++-----------
2 files changed, 54 insertions(+), 12 deletions(-)
diff --git a/libavformat/flv.h b/libavformat/flv.h
index 3571b90279..44d3b04ff9 100644
--- a/libavformat/flv.h
+++ b/libavformat/flv.h
@@ -35,6 +35,12 @@
#define FLV_VIDEO_FRAMETYPE_OFFSET 4
+/* Extended VideoTagHeader
+ * defined in reference link:
+ * https://github.com/veovera/enhanced-rtmp/blob/main/enhanced-rtmp-v1.pdf
+ * */
+#define FLV_IS_EX_HEADER 0x80
+
/* bitmasks to isolate specific values */
#define FLV_AUDIO_CHANNEL_MASK 0x01
#define FLV_AUDIO_SAMPLESIZE_MASK 0x02
@@ -110,6 +116,16 @@ enum {
FLV_CODECID_H264 = 7,
FLV_CODECID_REALH263= 8,
FLV_CODECID_MPEG4 = 9,
+ FLV_CODECID_HEVC = 10,
+};
+
+enum {
+ PacketTypeSequenceStart = 0,
+ PacketTypeCodedFrames = 1,
+ PacketTypeSequenceEnd = 2,
+ PacketTypeCodedFramesX = 3,
+ PacketTypeMetadata = 4,
+ PacketTypeMPEG2TSSequenceStart = 5,
};
enum {
diff --git a/libavformat/flvenc.c b/libavformat/flvenc.c
index 64ea554dad..15a0f573f3 100644
--- a/libavformat/flvenc.c
+++ b/libavformat/flvenc.c
@@ -28,6 +28,7 @@
#include "libavcodec/mpeg4audio.h"
#include "avio.h"
#include "avc.h"
+#include "hevc.h"
#include "avformat.h"
#include "flv.h"
#include "internal.h"
@@ -46,6 +47,7 @@ static const AVCodecTag flv_video_codec_ids[] = {
{ AV_CODEC_ID_VP6, FLV_CODECID_VP6 },
{ AV_CODEC_ID_VP6A, FLV_CODECID_VP6A },
{ AV_CODEC_ID_H264, FLV_CODECID_H264 },
+ { AV_CODEC_ID_HEVC, FLV_CODECID_HEVC },
{ AV_CODEC_ID_NONE, 0 }
};
@@ -492,7 +494,7 @@ static void flv_write_codec_header(AVFormatContext* s, AVCodecParameters* par, i
FLVContext *flv = s->priv_data;
if (par->codec_id == AV_CODEC_ID_AAC || par->codec_id == AV_CODEC_ID_H264
- || par->codec_id == AV_CODEC_ID_MPEG4) {
+ || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC) {
int64_t pos;
avio_w8(pb,
par->codec_type == AVMEDIA_TYPE_VIDEO ?
@@ -535,10 +537,19 @@ static void flv_write_codec_header(AVFormatContext* s, AVCodecParameters* par, i
}
avio_write(pb, par->extradata, par->extradata_size);
} else {
- avio_w8(pb, par->codec_tag | FLV_FRAME_KEY); // flags
- avio_w8(pb, 0); // AVC sequence header
- avio_wb24(pb, 0); // composition time
- ff_isom_write_avcc(pb, par->extradata, par->extradata_size);
+ if (par->codec_id == AV_CODEC_ID_HEVC) {
+ avio_w8(pb, FLV_IS_EX_HEADER | PacketTypeSequenceStart); // ExVideoTagHeader mode with PacketTypeSequenceStart
+ avio_write(pb, "hvc1", 4);
+ } else {
+ avio_w8(pb, par->codec_tag | FLV_FRAME_KEY); // flags
+ avio_w8(pb, 0); // AVC sequence header
+ avio_wb24(pb, 0); // composition time
+ }
+
+ if (par->codec_id == AV_CODEC_ID_HEVC)
+ ff_isom_write_hvcc(pb, par->extradata, par->extradata_size, 0);
+ else
+ ff_isom_write_avcc(pb, par->extradata, par->extradata_size);
}
data_size = avio_tell(pb) - pos;
avio_seek(pb, -data_size - 10, SEEK_CUR);
@@ -628,7 +639,8 @@ static int flv_init(struct AVFormatContext *s)
return unsupported_codec(s, "Video", par->codec_id);
if (par->codec_id == AV_CODEC_ID_MPEG4 ||
- par->codec_id == AV_CODEC_ID_H263) {
+ par->codec_id == AV_CODEC_ID_H263 ||
+ par->codec_id == AV_CODEC_ID_HEVC) {
int error = s->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL;
av_log(s, error ? AV_LOG_ERROR : AV_LOG_WARNING,
"Codec %s is not supported in the official FLV specification,\n", avcodec_get_name(par->codec_id));
@@ -784,8 +796,11 @@ end:
for (i = 0; i < s->nb_streams; i++) {
AVCodecParameters *par = s->streams[i]->codecpar;
FLVStreamContext *sc = s->streams[i]->priv_data;
- if (par->codec_type == AVMEDIA_TYPE_VIDEO &&
- (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4))
+ if (par->codec_id == AV_CODEC_ID_HEVC) {
+ avio_w8(pb, 0x82);
+ avio_write(pb, "hvc1", 4);
+ } else if (par->codec_type == AVMEDIA_TYPE_VIDEO &&
+ (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC))
put_eos_tag(pb, sc->last_ts, par->codec_id);
}
}
@@ -836,13 +851,13 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
if (par->codec_id == AV_CODEC_ID_VP6F || par->codec_id == AV_CODEC_ID_VP6A ||
par->codec_id == AV_CODEC_ID_VP6 || par->codec_id == AV_CODEC_ID_AAC)
flags_size = 2;
- else if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4)
+ else if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC)
flags_size = 5;
else
flags_size = 1;
if (par->codec_id == AV_CODEC_ID_AAC || par->codec_id == AV_CODEC_ID_H264
- || par->codec_id == AV_CODEC_ID_MPEG4) {
+ || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC) {
size_t side_size;
uint8_t *side = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &side_size);
if (side && side_size > 0 && (side_size != par->extradata_size || memcmp(side, par->extradata, side_size))) {
@@ -862,7 +877,7 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
"Packets are not in the proper order with respect to DTS\n");
return AVERROR(EINVAL);
}
- if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4) {
+ if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC) {
if (pkt->pts == AV_NOPTS_VALUE) {
av_log(s, AV_LOG_ERROR, "Packet is missing PTS\n");
return AVERROR(EINVAL);
@@ -907,6 +922,10 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
if (par->extradata_size > 0 && *(uint8_t*)par->extradata != 1)
if ((ret = ff_avc_parse_nal_units_buf(pkt->data, &data, &size)) < 0)
return ret;
+ } else if (par->codec_id == AV_CODEC_ID_HEVC) {
+ if (par->extradata_size > 0 && *(uint8_t*)par->extradata != 1)
+ if ((ret = ff_hevc_annexb2mp4_buf(pkt->data, &data, &size, 0, NULL)) < 0)
+ return ret;
} else if (par->codec_id == AV_CODEC_ID_AAC && pkt->size > 2 &&
(AV_RB16(pkt->data) & 0xfff0) == 0xfff0) {
if (!s->streams[pkt->stream_index]->nb_frames) {
@@ -968,7 +987,12 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
avio_wb32(pb, data_size + 11);
} else {
av_assert1(flags>=0);
- avio_w8(pb,flags);
+ if (par->codec_id == AV_CODEC_ID_HEVC) {
+ avio_w8(pb, FLV_IS_EX_HEADER | PacketTypeCodedFrames); // ExVideoTagHeader mode with PacketTypeCodedFrames
+ avio_write(pb, "hvc1", 4);
+ } else {
+ avio_w8(pb, flags);
+ }
if (par->codec_id == AV_CODEC_ID_VP6)
avio_w8(pb,0);
if (par->codec_id == AV_CODEC_ID_VP6F || par->codec_id == AV_CODEC_ID_VP6A) {
@@ -982,6 +1006,8 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
else if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4) {
avio_w8(pb, 1); // AVC NALU
avio_wb24(pb, pkt->pts - pkt->dts);
+ } else if (par->codec_id == AV_CODEC_ID_HEVC) {
+ avio_wb24(pb, pkt->pts - pkt->dts);
}
avio_write(pb, data ? data : pkt->data, size);
--
2.29.2
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 40+ messages in thread
* [FFmpeg-devel] [PATCH v3 2/2] avformat/flvdec: support demux HEVC in Enhanced FLV
2023-04-08 3:22 ` [FFmpeg-devel] [PATCH v3 1/2] avformat/flvenc: Add support for HEVC over flv in muxer Steven Liu
@ 2023-04-08 3:22 ` Steven Liu
0 siblings, 0 replies; 40+ messages in thread
From: Steven Liu @ 2023-04-08 3:22 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Steven Liu
Signed-off-by: Steven Liu <lq@chinaffmpeg.org>
---
libavformat/flvdec.c | 63 +++++++++++++++++++++++++++++++++++++++-----
1 file changed, 56 insertions(+), 7 deletions(-)
diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c
index d83edff727..8060c43772 100644
--- a/libavformat/flvdec.c
+++ b/libavformat/flvdec.c
@@ -79,6 +79,8 @@ typedef struct FLVContext {
int64_t last_ts;
int64_t time_offset;
int64_t time_pos;
+
+ uint8_t exheader;
} FLVContext;
/* AMF date type */
@@ -302,13 +304,26 @@ 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(AVFormatContext *s, AVCodecParameters *vpar, int flags)
{
int flv_codecid = flags & FLV_VIDEO_CODECID_MASK;
+ FLVContext *flv = s->priv_data;
if (!vpar->codec_id && !vpar->codec_tag)
return 1;
+ if (flv->exheader) {
+ uint8_t *codec_id_str = (uint8_t *)s->pb->buf_ptr;
+ uint32_t codec_id = codec_id_str[3] | codec_id_str[2] << 8 | codec_id_str[1] << 16 | codec_id_str[0] << 24;
+ switch(codec_id) {
+ case MKBETAG('h', 'v', 'c', '1'):
+ flv_codecid = FLV_CODECID_HEVC;
+ break;
+ default:
+ break;
+ }
+ }
+
switch (flv_codecid) {
case FLV_CODECID_H263:
return vpar->codec_id == AV_CODEC_ID_FLV1;
@@ -322,6 +337,8 @@ static int flv_same_video_codec(AVCodecParameters *vpar, int flags)
return vpar->codec_id == AV_CODEC_ID_VP6A;
case FLV_CODECID_H264:
return vpar->codec_id == AV_CODEC_ID_H264;
+ case FLV_CODECID_HEVC:
+ return vpar->codec_id == AV_CODEC_ID_HEVC;
default:
return vpar->codec_tag == flv_codecid;
}
@@ -331,9 +348,23 @@ static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream,
int flv_codecid, int read)
{
FFStream *const vstreami = ffstream(vstream);
+ FLVContext *flv = s->priv_data;
int ret = 0;
AVCodecParameters *par = vstream->codecpar;
enum AVCodecID old_codec_id = vstream->codecpar->codec_id;
+ flv_codecid &= FLV_VIDEO_CODECID_MASK;
+
+ if (flv->exheader) {
+ uint32_t codec_id = avio_rb32(s->pb);
+
+ switch(codec_id) {
+ case MKBETAG('h', 'v', 'c', '1'):
+ flv_codecid = FLV_CODECID_HEVC;
+ break;
+ default:
+ break;
+ }
+ }
switch (flv_codecid) {
case FLV_CODECID_H263:
par->codec_id = AV_CODEC_ID_FLV1;
@@ -372,6 +403,11 @@ static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream,
par->codec_id = AV_CODEC_ID_MPEG4;
ret = 3;
break;
+ case FLV_CODECID_HEVC:
+ par->codec_id = AV_CODEC_ID_HEVC;
+ vstreami->need_parsing = AVSTREAM_PARSE_HEADERS;
+ ret = 3;
+ break;
default:
avpriv_request_sample(s, "Video codec (%x)", flv_codecid);
par->codec_tag = flv_codecid;
@@ -796,6 +832,7 @@ static int flv_read_header(AVFormatContext *s)
s->start_time = 0;
flv->sum_flv_tag_size = 0;
flv->last_keyframe_stream_index = -1;
+ flv->exheader = 0;
return 0;
}
@@ -1071,6 +1108,11 @@ retry:
} else if (type == FLV_TAG_TYPE_VIDEO) {
stream_type = FLV_STREAM_TYPE_VIDEO;
flags = avio_r8(s->pb);
+ /*
+ * Reference Enhancing FLV 2023-03-v1.0.0-B.8
+ * https://github.com/veovera/enhanced-rtmp/blob/main/enhanced-rtmp-v1.pdf
+ * */
+ flv->exheader = (flags >> 7) & 1;
size--;
if ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_VIDEO_INFO_CMD)
goto skip;
@@ -1129,7 +1171,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(s, st->codecpar, flags)))
break;
} else if (stream_type == FLV_STREAM_TYPE_SUBTITLE) {
if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE)
@@ -1230,7 +1272,7 @@ retry_duration:
avcodec_parameters_free(&par);
}
} else if (stream_type == FLV_STREAM_TYPE_VIDEO) {
- int ret = flv_set_video_codec(s, st, flags & FLV_VIDEO_CODECID_MASK, 1);
+ int ret = flv_set_video_codec(s, st, flags, 1);
if (ret < 0)
return ret;
size -= ret;
@@ -1242,8 +1284,14 @@ 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_MPEG4) {
- int type = avio_r8(s->pb);
+ st->codecpar->codec_id == AV_CODEC_ID_MPEG4 ||
+ st->codecpar->codec_id == AV_CODEC_ID_HEVC) {
+ int type = 0;
+ if (flv->exheader) {
+ type = flags & 0x0F;
+ } else {
+ type = avio_r8(s->pb);
+ }
size--;
if (size < 0) {
@@ -1251,7 +1299,8 @@ 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_MPEG4
+ || (st->codecpar->codec_id == AV_CODEC_ID_HEVC && (flags & 0x0F))) {
// sign extension
int32_t cts = (avio_rb24(s->pb) + 0xff800000) ^ 0xff800000;
pts = av_sat_add64(dts, cts);
@@ -1267,7 +1316,7 @@ retry_duration:
}
}
if (type == 0 && (!st->codecpar->extradata || st->codecpar->codec_id == AV_CODEC_ID_AAC ||
- st->codecpar->codec_id == AV_CODEC_ID_H264)) {
+ st->codecpar->codec_id == AV_CODEC_ID_H264 || st->codecpar->codec_id == AV_CODEC_ID_HEVC)) {
AVDictionaryEntry *t;
if (st->codecpar->extradata) {
--
2.29.2
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [FFmpeg-devel] [PATCH 1/2] avformat/flvenc: Add support for HEVC over flv in muxer
2023-04-06 17:03 ` Jan Ekström
@ 2023-04-11 8:56 ` Neal Gompa
2023-04-11 9:24 ` Steven Liu
0 siblings, 1 reply; 40+ messages in thread
From: Neal Gompa @ 2023-04-11 8:56 UTC (permalink / raw)
To: FFmpeg development discussions and patches
On Thu, Apr 6, 2023 at 1:03 PM Jan Ekström <jeebjp@gmail.com> wrote:
>
> On Thu, Apr 6, 2023 at 6:11 PM Gyan Doshi <ffmpeg@gyani.pro> wrote:
> >
> >
> >
> > On 2023-04-06 08:14 pm, Lance Wang wrote:
> > > On Thu, Apr 6, 2023 at 8:14 PM Steven Liu <lq@chinaffmpeg.org> wrote:
> > >
> > >> Implements HEVC according to enhanced RTMP spec found at
> > >> https://github.com/veovera/enhanced-rtmp
> > >>
> > >>
> > > I think It's document or draft and not specs, I haven't heard any
> > > information for the
> > > veovera software organization. So before implementation, please prove it's
> > > recognized authority. Please see rfc2026.
> >
> > Their Github readme claims
> >
> > "Additionally, Veovera has welcomed new members to the organization
> > including Adobe, Google and Veriskope."
> >
> > I didn't find any public corroboration by these companies.
> >
>
> Yea, it seems like this was mostly done in the background (classic
> corporations being corporations), but I think the most direct way to
> notice that Google at least has acknowledged this extension is because
> Youtube now seems to support AV1 live stream ingest via RTMP with
> these extensions.
>
Notably though, these patches don't implement that, though. :(
--
真実はいつも一つ!/ Always, there's only one truth!
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [FFmpeg-devel] [PATCH 1/2] avformat/flvenc: Add support for HEVC over flv in muxer
2023-04-11 8:56 ` Neal Gompa
@ 2023-04-11 9:24 ` Steven Liu
2023-04-12 1:26 ` Neal Gompa
0 siblings, 1 reply; 40+ messages in thread
From: Steven Liu @ 2023-04-11 9:24 UTC (permalink / raw)
To: FFmpeg development discussions and patches
Neal Gompa <ngompa13@gmail.com> 于2023年4月11日周二 16:57写道:
>
> On Thu, Apr 6, 2023 at 1:03 PM Jan Ekström <jeebjp@gmail.com> wrote:
> >
> > On Thu, Apr 6, 2023 at 6:11 PM Gyan Doshi <ffmpeg@gyani.pro> wrote:
> > >
> > >
> > >
> > > On 2023-04-06 08:14 pm, Lance Wang wrote:
> > > > On Thu, Apr 6, 2023 at 8:14 PM Steven Liu <lq@chinaffmpeg.org> wrote:
> > > >
> > > >> Implements HEVC according to enhanced RTMP spec found at
> > > >> https://github.com/veovera/enhanced-rtmp
> > > >>
> > > >>
> > > > I think It's document or draft and not specs, I haven't heard any
> > > > information for the
> > > > veovera software organization. So before implementation, please prove it's
> > > > recognized authority. Please see rfc2026.
> > >
> > > Their Github readme claims
> > >
> > > "Additionally, Veovera has welcomed new members to the organization
> > > including Adobe, Google and Veriskope."
> > >
> > > I didn't find any public corroboration by these companies.
> > >
> >
> > Yea, it seems like this was mostly done in the background (classic
> > corporations being corporations), but I think the most direct way to
> > notice that Google at least has acknowledged this extension is because
> > Youtube now seems to support AV1 live stream ingest via RTMP with
> > these extensions.
> >
>
> Notably though, these patches don't implement that, though. :(
This is first step, if this patchset can be merge is means that the
av1,vp9 can be accpected too. :D
>
>
>
> --
> 真実はいつも一つ!/ Always, there's only one truth!
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [FFmpeg-devel] [PATCH 1/2] avformat/flvenc: Add support for HEVC over flv in muxer
2023-04-11 9:24 ` Steven Liu
@ 2023-04-12 1:26 ` Neal Gompa
2023-04-12 3:10 ` Steven Liu
` (4 more replies)
0 siblings, 5 replies; 40+ messages in thread
From: Neal Gompa @ 2023-04-12 1:26 UTC (permalink / raw)
To: FFmpeg development discussions and patches
On Tue, Apr 11, 2023 at 5:25 AM Steven Liu <lingjiujianke@gmail.com> wrote:
>
> Neal Gompa <ngompa13@gmail.com> 于2023年4月11日周二 16:57写道:
> >
> > On Thu, Apr 6, 2023 at 1:03 PM Jan Ekström <jeebjp@gmail.com> wrote:
> > >
> > > On Thu, Apr 6, 2023 at 6:11 PM Gyan Doshi <ffmpeg@gyani.pro> wrote:
> > > >
> > > >
> > > >
> > > > On 2023-04-06 08:14 pm, Lance Wang wrote:
> > > > > On Thu, Apr 6, 2023 at 8:14 PM Steven Liu <lq@chinaffmpeg.org> wrote:
> > > > >
> > > > >> Implements HEVC according to enhanced RTMP spec found at
> > > > >> https://github.com/veovera/enhanced-rtmp
> > > > >>
> > > > >>
> > > > > I think It's document or draft and not specs, I haven't heard any
> > > > > information for the
> > > > > veovera software organization. So before implementation, please prove it's
> > > > > recognized authority. Please see rfc2026.
> > > >
> > > > Their Github readme claims
> > > >
> > > > "Additionally, Veovera has welcomed new members to the organization
> > > > including Adobe, Google and Veriskope."
> > > >
> > > > I didn't find any public corroboration by these companies.
> > > >
> > >
> > > Yea, it seems like this was mostly done in the background (classic
> > > corporations being corporations), but I think the most direct way to
> > > notice that Google at least has acknowledged this extension is because
> > > Youtube now seems to support AV1 live stream ingest via RTMP with
> > > these extensions.
> > >
> >
> > Notably though, these patches don't implement that, though. :(
> This is first step, if this patchset can be merge is means that the
> av1,vp9 can be accpected too. :D
>
Could you submit a complete version when you respin v4? The only
endpoint I can reasonably test is YouTube, so not having AV1 support
makes it difficult for me to try it out...
--
真実はいつも一つ!/ Always, there's only one truth!
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [FFmpeg-devel] [PATCH 1/2] avformat/flvenc: Add support for HEVC over flv in muxer
2023-04-12 1:26 ` Neal Gompa
@ 2023-04-12 3:10 ` Steven Liu
2023-04-12 4:27 ` [FFmpeg-devel] [PATCH v4 1/4] " Steven Liu
` (3 subsequent siblings)
4 siblings, 0 replies; 40+ messages in thread
From: Steven Liu @ 2023-04-12 3:10 UTC (permalink / raw)
To: FFmpeg development discussions and patches
Neal Gompa <ngompa13@gmail.com> 于2023年4月12日周三 09:27写道:
>
> On Tue, Apr 11, 2023 at 5:25 AM Steven Liu <lingjiujianke@gmail.com> wrote:
> >
> > Neal Gompa <ngompa13@gmail.com> 于2023年4月11日周二 16:57写道:
> > >
> > > On Thu, Apr 6, 2023 at 1:03 PM Jan Ekström <jeebjp@gmail.com> wrote:
> > > >
> > > > On Thu, Apr 6, 2023 at 6:11 PM Gyan Doshi <ffmpeg@gyani.pro> wrote:
> > > > >
> > > > >
> > > > >
> > > > > On 2023-04-06 08:14 pm, Lance Wang wrote:
> > > > > > On Thu, Apr 6, 2023 at 8:14 PM Steven Liu <lq@chinaffmpeg.org> wrote:
> > > > > >
> > > > > >> Implements HEVC according to enhanced RTMP spec found at
> > > > > >> https://github.com/veovera/enhanced-rtmp
> > > > > >>
> > > > > >>
> > > > > > I think It's document or draft and not specs, I haven't heard any
> > > > > > information for the
> > > > > > veovera software organization. So before implementation, please prove it's
> > > > > > recognized authority. Please see rfc2026.
> > > > >
> > > > > Their Github readme claims
> > > > >
> > > > > "Additionally, Veovera has welcomed new members to the organization
> > > > > including Adobe, Google and Veriskope."
> > > > >
> > > > > I didn't find any public corroboration by these companies.
> > > > >
> > > >
> > > > Yea, it seems like this was mostly done in the background (classic
> > > > corporations being corporations), but I think the most direct way to
> > > > notice that Google at least has acknowledged this extension is because
> > > > Youtube now seems to support AV1 live stream ingest via RTMP with
> > > > these extensions.
> > > >
> > >
> > > Notably though, these patches don't implement that, though. :(
> > This is first step, if this patchset can be merge is means that the
> > av1,vp9 can be accpected too. :D
> >
>
> Could you submit a complete version when you respin v4? The only
> endpoint I can reasonably test is YouTube, so not having AV1 support
> makes it difficult for me to try it out...
you can test it by ossrs :D
I think i can submit new patchset after this patchset be merged :D
>
>
>
> --
> 真実はいつも一つ!/ Always, there's only one truth!
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 40+ messages in thread
* [FFmpeg-devel] [PATCH v4 1/4] avformat/flvenc: Add support for HEVC over flv in muxer
2023-04-12 1:26 ` Neal Gompa
2023-04-12 3:10 ` Steven Liu
@ 2023-04-12 4:27 ` Steven Liu
2023-04-12 4:27 ` [FFmpeg-devel] [PATCH v4 2/4] avformat/flvdec: support demux HEVC in Enhanced FLV Steven Liu
` (2 more replies)
2023-04-12 4:32 ` [FFmpeg-devel] [PATCH 1/2] avformat/flvenc: Add support for HEVC over flv in muxer Steven Liu
` (2 subsequent siblings)
4 siblings, 3 replies; 40+ messages in thread
From: Steven Liu @ 2023-04-12 4:27 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Steven Liu
Implements HEVC according to Enhanced FLV spec found at
https://github.com/veovera/enhanced-rtmp
And it has beed supported by OBS, Simple Realtime Server, mpegts.js.
And the enhanced FLV documentation contributors include
Jean-Baptiste Kempf (FFmpeg, VideoLAN).
So this should be support by ffmpeg too.
Signed-off-by: Steven Liu <lq@chinaffmpeg.org>
---
libavformat/flv.h | 16 ++++++++++++++
libavformat/flvenc.c | 50 +++++++++++++++++++++++++++++++++-----------
2 files changed, 54 insertions(+), 12 deletions(-)
diff --git a/libavformat/flv.h b/libavformat/flv.h
index 3571b90279..44d3b04ff9 100644
--- a/libavformat/flv.h
+++ b/libavformat/flv.h
@@ -35,6 +35,12 @@
#define FLV_VIDEO_FRAMETYPE_OFFSET 4
+/* Extended VideoTagHeader
+ * defined in reference link:
+ * https://github.com/veovera/enhanced-rtmp/blob/main/enhanced-rtmp-v1.pdf
+ * */
+#define FLV_IS_EX_HEADER 0x80
+
/* bitmasks to isolate specific values */
#define FLV_AUDIO_CHANNEL_MASK 0x01
#define FLV_AUDIO_SAMPLESIZE_MASK 0x02
@@ -110,6 +116,16 @@ enum {
FLV_CODECID_H264 = 7,
FLV_CODECID_REALH263= 8,
FLV_CODECID_MPEG4 = 9,
+ FLV_CODECID_HEVC = 10,
+};
+
+enum {
+ PacketTypeSequenceStart = 0,
+ PacketTypeCodedFrames = 1,
+ PacketTypeSequenceEnd = 2,
+ PacketTypeCodedFramesX = 3,
+ PacketTypeMetadata = 4,
+ PacketTypeMPEG2TSSequenceStart = 5,
};
enum {
diff --git a/libavformat/flvenc.c b/libavformat/flvenc.c
index fbf7eabaf8..0f26ff99e8 100644
--- a/libavformat/flvenc.c
+++ b/libavformat/flvenc.c
@@ -28,6 +28,7 @@
#include "libavcodec/mpeg4audio.h"
#include "avio.h"
#include "avc.h"
+#include "hevc.h"
#include "avformat.h"
#include "flv.h"
#include "internal.h"
@@ -46,6 +47,7 @@ static const AVCodecTag flv_video_codec_ids[] = {
{ AV_CODEC_ID_VP6, FLV_CODECID_VP6 },
{ AV_CODEC_ID_VP6A, FLV_CODECID_VP6A },
{ AV_CODEC_ID_H264, FLV_CODECID_H264 },
+ { AV_CODEC_ID_HEVC, FLV_CODECID_HEVC },
{ AV_CODEC_ID_NONE, 0 }
};
@@ -492,7 +494,7 @@ static void flv_write_codec_header(AVFormatContext* s, AVCodecParameters* par, i
FLVContext *flv = s->priv_data;
if (par->codec_id == AV_CODEC_ID_AAC || par->codec_id == AV_CODEC_ID_H264
- || par->codec_id == AV_CODEC_ID_MPEG4) {
+ || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC) {
int64_t pos;
avio_w8(pb,
par->codec_type == AVMEDIA_TYPE_VIDEO ?
@@ -535,10 +537,19 @@ static void flv_write_codec_header(AVFormatContext* s, AVCodecParameters* par, i
}
avio_write(pb, par->extradata, par->extradata_size);
} else {
- avio_w8(pb, par->codec_tag | FLV_FRAME_KEY); // flags
- avio_w8(pb, 0); // AVC sequence header
- avio_wb24(pb, 0); // composition time
- ff_isom_write_avcc(pb, par->extradata, par->extradata_size);
+ if (par->codec_id == AV_CODEC_ID_HEVC) {
+ avio_w8(pb, FLV_IS_EX_HEADER | PacketTypeSequenceStart); // ExVideoTagHeader mode with PacketTypeSequenceStart
+ avio_write(pb, "hvc1", 4);
+ } else {
+ avio_w8(pb, par->codec_tag | FLV_FRAME_KEY); // flags
+ avio_w8(pb, 0); // AVC sequence header
+ avio_wb24(pb, 0); // composition time
+ }
+
+ if (par->codec_id == AV_CODEC_ID_HEVC)
+ ff_isom_write_hvcc(pb, par->extradata, par->extradata_size, 0);
+ else
+ ff_isom_write_avcc(pb, par->extradata, par->extradata_size);
}
data_size = avio_tell(pb) - pos;
avio_seek(pb, -data_size - 10, SEEK_CUR);
@@ -628,7 +639,8 @@ static int flv_init(struct AVFormatContext *s)
return unsupported_codec(s, "Video", par->codec_id);
if (par->codec_id == AV_CODEC_ID_MPEG4 ||
- par->codec_id == AV_CODEC_ID_H263) {
+ par->codec_id == AV_CODEC_ID_H263 ||
+ par->codec_id == AV_CODEC_ID_HEVC) {
int error = s->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL;
av_log(s, error ? AV_LOG_ERROR : AV_LOG_WARNING,
"Codec %s is not supported in the official FLV specification,\n", avcodec_get_name(par->codec_id));
@@ -784,8 +796,11 @@ end:
for (i = 0; i < s->nb_streams; i++) {
AVCodecParameters *par = s->streams[i]->codecpar;
FLVStreamContext *sc = s->streams[i]->priv_data;
- if (par->codec_type == AVMEDIA_TYPE_VIDEO &&
- (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4))
+ if (par->codec_id == AV_CODEC_ID_HEVC) {
+ avio_w8(pb, 0x82);
+ avio_write(pb, "hvc1", 4);
+ } else if (par->codec_type == AVMEDIA_TYPE_VIDEO &&
+ (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC))
put_eos_tag(pb, sc->last_ts, par->codec_id);
}
}
@@ -836,13 +851,13 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
if (par->codec_id == AV_CODEC_ID_VP6F || par->codec_id == AV_CODEC_ID_VP6A ||
par->codec_id == AV_CODEC_ID_VP6 || par->codec_id == AV_CODEC_ID_AAC)
flags_size = 2;
- else if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4)
+ else if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC)
flags_size = 5;
else
flags_size = 1;
if (par->codec_id == AV_CODEC_ID_AAC || par->codec_id == AV_CODEC_ID_H264
- || par->codec_id == AV_CODEC_ID_MPEG4) {
+ || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC) {
size_t side_size;
uint8_t *side = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &side_size);
if (side && side_size > 0 && (side_size != par->extradata_size || memcmp(side, par->extradata, side_size))) {
@@ -862,7 +877,7 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
"Packets are not in the proper order with respect to DTS\n");
return AVERROR(EINVAL);
}
- if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4) {
+ if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC) {
if (pkt->pts == AV_NOPTS_VALUE) {
av_log(s, AV_LOG_ERROR, "Packet is missing PTS\n");
return AVERROR(EINVAL);
@@ -907,6 +922,10 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
if (par->extradata_size > 0 && *(uint8_t*)par->extradata != 1)
if ((ret = ff_avc_parse_nal_units_buf(pkt->data, &data, &size)) < 0)
return ret;
+ } else if (par->codec_id == AV_CODEC_ID_HEVC) {
+ if (par->extradata_size > 0 && *(uint8_t*)par->extradata != 1)
+ if ((ret = ff_hevc_annexb2mp4_buf(pkt->data, &data, &size, 0, NULL)) < 0)
+ return ret;
} else if (par->codec_id == AV_CODEC_ID_AAC && pkt->size > 2 &&
(AV_RB16(pkt->data) & 0xfff0) == 0xfff0) {
if (!s->streams[pkt->stream_index]->nb_frames) {
@@ -968,7 +987,12 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
avio_wb32(pb, data_size + 11);
} else {
av_assert1(flags>=0);
- avio_w8(pb,flags);
+ if (par->codec_id == AV_CODEC_ID_HEVC) {
+ avio_w8(pb, FLV_IS_EX_HEADER | PacketTypeCodedFrames); // ExVideoTagHeader mode with PacketTypeCodedFrames
+ avio_write(pb, "hvc1", 4);
+ } else {
+ avio_w8(pb, flags);
+ }
if (par->codec_id == AV_CODEC_ID_VP6)
avio_w8(pb,0);
if (par->codec_id == AV_CODEC_ID_VP6F || par->codec_id == AV_CODEC_ID_VP6A) {
@@ -982,6 +1006,8 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
else if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4) {
avio_w8(pb, 1); // AVC NALU
avio_wb24(pb, pkt->pts - pkt->dts);
+ } else if (par->codec_id == AV_CODEC_ID_HEVC) {
+ avio_wb24(pb, pkt->pts - pkt->dts);
}
avio_write(pb, data ? data : pkt->data, size);
--
2.40.0
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 40+ messages in thread
* [FFmpeg-devel] [PATCH v4 2/4] avformat/flvdec: support demux HEVC in Enhanced FLV
2023-04-12 4:27 ` [FFmpeg-devel] [PATCH v4 1/4] " Steven Liu
@ 2023-04-12 4:27 ` Steven Liu
2023-04-12 4:27 ` [FFmpeg-devel] [PATCH v4 3/4] avformat/flvenc: support mux av1 " Steven Liu
2023-04-12 4:27 ` [FFmpeg-devel] [PATCH v4 4/4] avformat/flvdec: support demux " Steven Liu
2 siblings, 0 replies; 40+ messages in thread
From: Steven Liu @ 2023-04-12 4:27 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Steven Liu
Signed-off-by: Steven Liu <lq@chinaffmpeg.org>
---
libavformat/flvdec.c | 63 +++++++++++++++++++++++++++++++++++++++-----
1 file changed, 56 insertions(+), 7 deletions(-)
diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c
index d83edff727..8060c43772 100644
--- a/libavformat/flvdec.c
+++ b/libavformat/flvdec.c
@@ -79,6 +79,8 @@ typedef struct FLVContext {
int64_t last_ts;
int64_t time_offset;
int64_t time_pos;
+
+ uint8_t exheader;
} FLVContext;
/* AMF date type */
@@ -302,13 +304,26 @@ 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(AVFormatContext *s, AVCodecParameters *vpar, int flags)
{
int flv_codecid = flags & FLV_VIDEO_CODECID_MASK;
+ FLVContext *flv = s->priv_data;
if (!vpar->codec_id && !vpar->codec_tag)
return 1;
+ if (flv->exheader) {
+ uint8_t *codec_id_str = (uint8_t *)s->pb->buf_ptr;
+ uint32_t codec_id = codec_id_str[3] | codec_id_str[2] << 8 | codec_id_str[1] << 16 | codec_id_str[0] << 24;
+ switch(codec_id) {
+ case MKBETAG('h', 'v', 'c', '1'):
+ flv_codecid = FLV_CODECID_HEVC;
+ break;
+ default:
+ break;
+ }
+ }
+
switch (flv_codecid) {
case FLV_CODECID_H263:
return vpar->codec_id == AV_CODEC_ID_FLV1;
@@ -322,6 +337,8 @@ static int flv_same_video_codec(AVCodecParameters *vpar, int flags)
return vpar->codec_id == AV_CODEC_ID_VP6A;
case FLV_CODECID_H264:
return vpar->codec_id == AV_CODEC_ID_H264;
+ case FLV_CODECID_HEVC:
+ return vpar->codec_id == AV_CODEC_ID_HEVC;
default:
return vpar->codec_tag == flv_codecid;
}
@@ -331,9 +348,23 @@ static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream,
int flv_codecid, int read)
{
FFStream *const vstreami = ffstream(vstream);
+ FLVContext *flv = s->priv_data;
int ret = 0;
AVCodecParameters *par = vstream->codecpar;
enum AVCodecID old_codec_id = vstream->codecpar->codec_id;
+ flv_codecid &= FLV_VIDEO_CODECID_MASK;
+
+ if (flv->exheader) {
+ uint32_t codec_id = avio_rb32(s->pb);
+
+ switch(codec_id) {
+ case MKBETAG('h', 'v', 'c', '1'):
+ flv_codecid = FLV_CODECID_HEVC;
+ break;
+ default:
+ break;
+ }
+ }
switch (flv_codecid) {
case FLV_CODECID_H263:
par->codec_id = AV_CODEC_ID_FLV1;
@@ -372,6 +403,11 @@ static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream,
par->codec_id = AV_CODEC_ID_MPEG4;
ret = 3;
break;
+ case FLV_CODECID_HEVC:
+ par->codec_id = AV_CODEC_ID_HEVC;
+ vstreami->need_parsing = AVSTREAM_PARSE_HEADERS;
+ ret = 3;
+ break;
default:
avpriv_request_sample(s, "Video codec (%x)", flv_codecid);
par->codec_tag = flv_codecid;
@@ -796,6 +832,7 @@ static int flv_read_header(AVFormatContext *s)
s->start_time = 0;
flv->sum_flv_tag_size = 0;
flv->last_keyframe_stream_index = -1;
+ flv->exheader = 0;
return 0;
}
@@ -1071,6 +1108,11 @@ retry:
} else if (type == FLV_TAG_TYPE_VIDEO) {
stream_type = FLV_STREAM_TYPE_VIDEO;
flags = avio_r8(s->pb);
+ /*
+ * Reference Enhancing FLV 2023-03-v1.0.0-B.8
+ * https://github.com/veovera/enhanced-rtmp/blob/main/enhanced-rtmp-v1.pdf
+ * */
+ flv->exheader = (flags >> 7) & 1;
size--;
if ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_VIDEO_INFO_CMD)
goto skip;
@@ -1129,7 +1171,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(s, st->codecpar, flags)))
break;
} else if (stream_type == FLV_STREAM_TYPE_SUBTITLE) {
if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE)
@@ -1230,7 +1272,7 @@ retry_duration:
avcodec_parameters_free(&par);
}
} else if (stream_type == FLV_STREAM_TYPE_VIDEO) {
- int ret = flv_set_video_codec(s, st, flags & FLV_VIDEO_CODECID_MASK, 1);
+ int ret = flv_set_video_codec(s, st, flags, 1);
if (ret < 0)
return ret;
size -= ret;
@@ -1242,8 +1284,14 @@ 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_MPEG4) {
- int type = avio_r8(s->pb);
+ st->codecpar->codec_id == AV_CODEC_ID_MPEG4 ||
+ st->codecpar->codec_id == AV_CODEC_ID_HEVC) {
+ int type = 0;
+ if (flv->exheader) {
+ type = flags & 0x0F;
+ } else {
+ type = avio_r8(s->pb);
+ }
size--;
if (size < 0) {
@@ -1251,7 +1299,8 @@ 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_MPEG4
+ || (st->codecpar->codec_id == AV_CODEC_ID_HEVC && (flags & 0x0F))) {
// sign extension
int32_t cts = (avio_rb24(s->pb) + 0xff800000) ^ 0xff800000;
pts = av_sat_add64(dts, cts);
@@ -1267,7 +1316,7 @@ retry_duration:
}
}
if (type == 0 && (!st->codecpar->extradata || st->codecpar->codec_id == AV_CODEC_ID_AAC ||
- st->codecpar->codec_id == AV_CODEC_ID_H264)) {
+ st->codecpar->codec_id == AV_CODEC_ID_H264 || st->codecpar->codec_id == AV_CODEC_ID_HEVC)) {
AVDictionaryEntry *t;
if (st->codecpar->extradata) {
--
2.40.0
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 40+ messages in thread
* [FFmpeg-devel] [PATCH v4 3/4] avformat/flvenc: support mux av1 in Enhanced FLV
2023-04-12 4:27 ` [FFmpeg-devel] [PATCH v4 1/4] " Steven Liu
2023-04-12 4:27 ` [FFmpeg-devel] [PATCH v4 2/4] avformat/flvdec: support demux HEVC in Enhanced FLV Steven Liu
@ 2023-04-12 4:27 ` Steven Liu
2023-04-12 4:27 ` [FFmpeg-devel] [PATCH v4 4/4] avformat/flvdec: support demux " Steven Liu
2 siblings, 0 replies; 40+ messages in thread
From: Steven Liu @ 2023-04-12 4:27 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Steven Liu
Signed-off-by: Steven Liu <lq@chinaffmpeg.org>
---
libavformat/flvenc.c | 24 +++++++++++++++++++-----
1 file changed, 19 insertions(+), 5 deletions(-)
diff --git a/libavformat/flvenc.c b/libavformat/flvenc.c
index 0f26ff99e8..f58ab7a3b0 100644
--- a/libavformat/flvenc.c
+++ b/libavformat/flvenc.c
@@ -48,6 +48,7 @@ static const AVCodecTag flv_video_codec_ids[] = {
{ AV_CODEC_ID_VP6A, FLV_CODECID_VP6A },
{ AV_CODEC_ID_H264, FLV_CODECID_H264 },
{ AV_CODEC_ID_HEVC, FLV_CODECID_HEVC },
+ { AV_CODEC_ID_AV1, FLV_CODECID_AV1 },
{ AV_CODEC_ID_NONE, 0 }
};
@@ -494,7 +495,8 @@ static void flv_write_codec_header(AVFormatContext* s, AVCodecParameters* par, i
FLVContext *flv = s->priv_data;
if (par->codec_id == AV_CODEC_ID_AAC || par->codec_id == AV_CODEC_ID_H264
- || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC) {
+ || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC
+ || par->codec_id == AV_CODEC_ID_AV1) {
int64_t pos;
avio_w8(pb,
par->codec_type == AVMEDIA_TYPE_VIDEO ?
@@ -540,6 +542,9 @@ static void flv_write_codec_header(AVFormatContext* s, AVCodecParameters* par, i
if (par->codec_id == AV_CODEC_ID_HEVC) {
avio_w8(pb, FLV_IS_EX_HEADER | PacketTypeSequenceStart); // ExVideoTagHeader mode with PacketTypeSequenceStart
avio_write(pb, "hvc1", 4);
+ } else if (par->codec_id == AV_CODEC_ID_AV1) {
+ avio_w8(pb, FLV_IS_EX_HEADER | PacketTypeSequenceStart);
+ avio_write(pb, "av01", 4);
} else {
avio_w8(pb, par->codec_tag | FLV_FRAME_KEY); // flags
avio_w8(pb, 0); // AVC sequence header
@@ -548,6 +553,8 @@ static void flv_write_codec_header(AVFormatContext* s, AVCodecParameters* par, i
if (par->codec_id == AV_CODEC_ID_HEVC)
ff_isom_write_hvcc(pb, par->extradata, par->extradata_size, 0);
+ else if (par->codec_id == AV_CODEC_ID_AV1)
+ ff_isom_write_av1c(pb, par->extradata, par->extradata_size, 1);
else
ff_isom_write_avcc(pb, par->extradata, par->extradata_size);
}
@@ -640,7 +647,8 @@ static int flv_init(struct AVFormatContext *s)
if (par->codec_id == AV_CODEC_ID_MPEG4 ||
par->codec_id == AV_CODEC_ID_H263 ||
- par->codec_id == AV_CODEC_ID_HEVC) {
+ par->codec_id == AV_CODEC_ID_HEVC ||
+ par->codec_id == AV_CODEC_ID_AV1) {
int error = s->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL;
av_log(s, error ? AV_LOG_ERROR : AV_LOG_WARNING,
"Codec %s is not supported in the official FLV specification,\n", avcodec_get_name(par->codec_id));
@@ -851,13 +859,15 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
if (par->codec_id == AV_CODEC_ID_VP6F || par->codec_id == AV_CODEC_ID_VP6A ||
par->codec_id == AV_CODEC_ID_VP6 || par->codec_id == AV_CODEC_ID_AAC)
flags_size = 2;
- else if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC)
+ else if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4 ||
+ par->codec_id == AV_CODEC_ID_HEVC || par->codec_id == AV_CODEC_ID_AV1)
flags_size = 5;
else
flags_size = 1;
if (par->codec_id == AV_CODEC_ID_AAC || par->codec_id == AV_CODEC_ID_H264
- || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC) {
+ || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC
+ || par->codec_id == AV_CODEC_ID_AV1) {
size_t side_size;
uint8_t *side = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &side_size);
if (side && side_size > 0 && (side_size != par->extradata_size || memcmp(side, par->extradata, side_size))) {
@@ -877,7 +887,8 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
"Packets are not in the proper order with respect to DTS\n");
return AVERROR(EINVAL);
}
- if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC) {
+ if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4 ||
+ par->codec_id == AV_CODEC_ID_HEVC || par->codec_id == AV_CODEC_ID_AV1) {
if (pkt->pts == AV_NOPTS_VALUE) {
av_log(s, AV_LOG_ERROR, "Packet is missing PTS\n");
return AVERROR(EINVAL);
@@ -990,6 +1001,9 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
if (par->codec_id == AV_CODEC_ID_HEVC) {
avio_w8(pb, FLV_IS_EX_HEADER | PacketTypeCodedFrames); // ExVideoTagHeader mode with PacketTypeCodedFrames
avio_write(pb, "hvc1", 4);
+ } else if (par->codec_id == AV_CODEC_ID_AV1) {
+ avio_w8(pb, FLV_IS_EX_HEADER | PacketTypeCodedFrames);
+ avio_write(pb, "av01", 4);
} else {
avio_w8(pb, flags);
}
--
2.40.0
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 40+ messages in thread
* [FFmpeg-devel] [PATCH v4 4/4] avformat/flvdec: support demux av1 in Enhanced FLV
2023-04-12 4:27 ` [FFmpeg-devel] [PATCH v4 1/4] " Steven Liu
2023-04-12 4:27 ` [FFmpeg-devel] [PATCH v4 2/4] avformat/flvdec: support demux HEVC in Enhanced FLV Steven Liu
2023-04-12 4:27 ` [FFmpeg-devel] [PATCH v4 3/4] avformat/flvenc: support mux av1 " Steven Liu
@ 2023-04-12 4:27 ` Steven Liu
2 siblings, 0 replies; 40+ messages in thread
From: Steven Liu @ 2023-04-12 4:27 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Steven Liu
Signed-off-by: Steven Liu <lq@chinaffmpeg.org>
---
libavformat/flv.h | 1 +
libavformat/flvdec.c | 20 ++++++++++++++++++--
libavformat/flvenc.c | 1 +
3 files changed, 20 insertions(+), 2 deletions(-)
diff --git a/libavformat/flv.h b/libavformat/flv.h
index 44d3b04ff9..398a958e60 100644
--- a/libavformat/flv.h
+++ b/libavformat/flv.h
@@ -117,6 +117,7 @@ enum {
FLV_CODECID_REALH263= 8,
FLV_CODECID_MPEG4 = 9,
FLV_CODECID_HEVC = 10,
+ FLV_CODECID_AV1 = 11,
};
enum {
diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c
index 8060c43772..525c5b2e97 100644
--- a/libavformat/flvdec.c
+++ b/libavformat/flvdec.c
@@ -319,6 +319,9 @@ static int flv_same_video_codec(AVFormatContext *s, AVCodecParameters *vpar, int
case MKBETAG('h', 'v', 'c', '1'):
flv_codecid = FLV_CODECID_HEVC;
break;
+ case MKBETAG('a', 'v', '0', '1'):
+ flv_codecid = FLV_CODECID_AV1;
+ break;
default:
break;
}
@@ -339,6 +342,8 @@ static int flv_same_video_codec(AVFormatContext *s, AVCodecParameters *vpar, int
return vpar->codec_id == AV_CODEC_ID_H264;
case FLV_CODECID_HEVC:
return vpar->codec_id == AV_CODEC_ID_HEVC;
+ case FLV_CODECID_AV1:
+ return vpar->codec_id == AV_CODEC_ID_AV1;
default:
return vpar->codec_tag == flv_codecid;
}
@@ -361,6 +366,9 @@ static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream,
case MKBETAG('h', 'v', 'c', '1'):
flv_codecid = FLV_CODECID_HEVC;
break;
+ case MKBETAG('a', 'v', '0', '1'):
+ flv_codecid = FLV_CODECID_AV1;
+ break;
default:
break;
}
@@ -408,6 +416,12 @@ static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream,
vstreami->need_parsing = AVSTREAM_PARSE_HEADERS;
ret = 3;
break;
+ case FLV_CODECID_AV1:
+ par->codec_id = AV_CODEC_ID_AV1;
+ vstreami->need_parsing = AVSTREAM_PARSE_HEADERS;
+ ret = 3;
+ break;
+
default:
avpriv_request_sample(s, "Video codec (%x)", flv_codecid);
par->codec_tag = flv_codecid;
@@ -1285,7 +1299,8 @@ 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_MPEG4 ||
- st->codecpar->codec_id == AV_CODEC_ID_HEVC) {
+ st->codecpar->codec_id == AV_CODEC_ID_HEVC ||
+ st->codecpar->codec_id == AV_CODEC_ID_AV1) {
int type = 0;
if (flv->exheader) {
type = flags & 0x0F;
@@ -1316,7 +1331,8 @@ retry_duration:
}
}
if (type == 0 && (!st->codecpar->extradata || 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_H264 || st->codecpar->codec_id == AV_CODEC_ID_HEVC ||
+ st->codecpar->codec_id == AV_CODEC_ID_AV1)) {
AVDictionaryEntry *t;
if (st->codecpar->extradata) {
diff --git a/libavformat/flvenc.c b/libavformat/flvenc.c
index f58ab7a3b0..36ed55d231 100644
--- a/libavformat/flvenc.c
+++ b/libavformat/flvenc.c
@@ -29,6 +29,7 @@
#include "avio.h"
#include "avc.h"
#include "hevc.h"
+#include "av1.h"
#include "avformat.h"
#include "flv.h"
#include "internal.h"
--
2.40.0
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [FFmpeg-devel] [PATCH 1/2] avformat/flvenc: Add support for HEVC over flv in muxer
2023-04-12 1:26 ` Neal Gompa
2023-04-12 3:10 ` Steven Liu
2023-04-12 4:27 ` [FFmpeg-devel] [PATCH v4 1/4] " Steven Liu
@ 2023-04-12 4:32 ` Steven Liu
2023-04-12 4:42 ` Steven Liu
2023-04-12 4:37 ` [FFmpeg-devel] [PATCH v5 1/4] " Steven Liu
2023-04-12 7:30 ` [FFmpeg-devel] [PATCH v6 1/4] avformat/flvenc: Add support for HEVC over flv in muxer Steven Liu
4 siblings, 1 reply; 40+ messages in thread
From: Steven Liu @ 2023-04-12 4:32 UTC (permalink / raw)
To: FFmpeg development discussions and patches
Neal Gompa <ngompa13@gmail.com> 于2023年4月12日周三 09:27写道:
> Could you submit a complete version when you respin v4? The only
> endpoint I can reasonably test is YouTube, so not having AV1 support
> makes it difficult for me to try it out...
Try this patchset please.
https://patchwork.ffmpeg.org/project/ffmpeg/list/?series=8723
>
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 40+ messages in thread
* [FFmpeg-devel] [PATCH v5 1/4] avformat/flvenc: Add support for HEVC over flv in muxer
2023-04-12 1:26 ` Neal Gompa
` (2 preceding siblings ...)
2023-04-12 4:32 ` [FFmpeg-devel] [PATCH 1/2] avformat/flvenc: Add support for HEVC over flv in muxer Steven Liu
@ 2023-04-12 4:37 ` Steven Liu
2023-04-12 4:37 ` [FFmpeg-devel] [PATCH v5 2/4] avformat/flvdec: support demux HEVC in Enhancing FLV Steven Liu
` (2 more replies)
2023-04-12 7:30 ` [FFmpeg-devel] [PATCH v6 1/4] avformat/flvenc: Add support for HEVC over flv in muxer Steven Liu
4 siblings, 3 replies; 40+ messages in thread
From: Steven Liu @ 2023-04-12 4:37 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Steven Liu
Implements HEVC according to Enhanced FLV spec found at
https://github.com/veovera/enhanced-rtmp
And it has beed supported by OBS, Simple Realtime Server, mpegts.js.
And the enhanced FLV documentation contributors include
Jean-Baptiste Kempf (FFmpeg, VideoLAN).
So this should be support by ffmpeg too.
Signed-off-by: Steven Liu <lq@chinaffmpeg.org>
---
libavformat/flv.h | 16 ++++++++++++++
libavformat/flvenc.c | 50 +++++++++++++++++++++++++++++++++-----------
2 files changed, 54 insertions(+), 12 deletions(-)
diff --git a/libavformat/flv.h b/libavformat/flv.h
index 3571b90279..44d3b04ff9 100644
--- a/libavformat/flv.h
+++ b/libavformat/flv.h
@@ -35,6 +35,12 @@
#define FLV_VIDEO_FRAMETYPE_OFFSET 4
+/* Extended VideoTagHeader
+ * defined in reference link:
+ * https://github.com/veovera/enhanced-rtmp/blob/main/enhanced-rtmp-v1.pdf
+ * */
+#define FLV_IS_EX_HEADER 0x80
+
/* bitmasks to isolate specific values */
#define FLV_AUDIO_CHANNEL_MASK 0x01
#define FLV_AUDIO_SAMPLESIZE_MASK 0x02
@@ -110,6 +116,16 @@ enum {
FLV_CODECID_H264 = 7,
FLV_CODECID_REALH263= 8,
FLV_CODECID_MPEG4 = 9,
+ FLV_CODECID_HEVC = 10,
+};
+
+enum {
+ PacketTypeSequenceStart = 0,
+ PacketTypeCodedFrames = 1,
+ PacketTypeSequenceEnd = 2,
+ PacketTypeCodedFramesX = 3,
+ PacketTypeMetadata = 4,
+ PacketTypeMPEG2TSSequenceStart = 5,
};
enum {
diff --git a/libavformat/flvenc.c b/libavformat/flvenc.c
index fbf7eabaf8..0f26ff99e8 100644
--- a/libavformat/flvenc.c
+++ b/libavformat/flvenc.c
@@ -28,6 +28,7 @@
#include "libavcodec/mpeg4audio.h"
#include "avio.h"
#include "avc.h"
+#include "hevc.h"
#include "avformat.h"
#include "flv.h"
#include "internal.h"
@@ -46,6 +47,7 @@ static const AVCodecTag flv_video_codec_ids[] = {
{ AV_CODEC_ID_VP6, FLV_CODECID_VP6 },
{ AV_CODEC_ID_VP6A, FLV_CODECID_VP6A },
{ AV_CODEC_ID_H264, FLV_CODECID_H264 },
+ { AV_CODEC_ID_HEVC, FLV_CODECID_HEVC },
{ AV_CODEC_ID_NONE, 0 }
};
@@ -492,7 +494,7 @@ static void flv_write_codec_header(AVFormatContext* s, AVCodecParameters* par, i
FLVContext *flv = s->priv_data;
if (par->codec_id == AV_CODEC_ID_AAC || par->codec_id == AV_CODEC_ID_H264
- || par->codec_id == AV_CODEC_ID_MPEG4) {
+ || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC) {
int64_t pos;
avio_w8(pb,
par->codec_type == AVMEDIA_TYPE_VIDEO ?
@@ -535,10 +537,19 @@ static void flv_write_codec_header(AVFormatContext* s, AVCodecParameters* par, i
}
avio_write(pb, par->extradata, par->extradata_size);
} else {
- avio_w8(pb, par->codec_tag | FLV_FRAME_KEY); // flags
- avio_w8(pb, 0); // AVC sequence header
- avio_wb24(pb, 0); // composition time
- ff_isom_write_avcc(pb, par->extradata, par->extradata_size);
+ if (par->codec_id == AV_CODEC_ID_HEVC) {
+ avio_w8(pb, FLV_IS_EX_HEADER | PacketTypeSequenceStart); // ExVideoTagHeader mode with PacketTypeSequenceStart
+ avio_write(pb, "hvc1", 4);
+ } else {
+ avio_w8(pb, par->codec_tag | FLV_FRAME_KEY); // flags
+ avio_w8(pb, 0); // AVC sequence header
+ avio_wb24(pb, 0); // composition time
+ }
+
+ if (par->codec_id == AV_CODEC_ID_HEVC)
+ ff_isom_write_hvcc(pb, par->extradata, par->extradata_size, 0);
+ else
+ ff_isom_write_avcc(pb, par->extradata, par->extradata_size);
}
data_size = avio_tell(pb) - pos;
avio_seek(pb, -data_size - 10, SEEK_CUR);
@@ -628,7 +639,8 @@ static int flv_init(struct AVFormatContext *s)
return unsupported_codec(s, "Video", par->codec_id);
if (par->codec_id == AV_CODEC_ID_MPEG4 ||
- par->codec_id == AV_CODEC_ID_H263) {
+ par->codec_id == AV_CODEC_ID_H263 ||
+ par->codec_id == AV_CODEC_ID_HEVC) {
int error = s->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL;
av_log(s, error ? AV_LOG_ERROR : AV_LOG_WARNING,
"Codec %s is not supported in the official FLV specification,\n", avcodec_get_name(par->codec_id));
@@ -784,8 +796,11 @@ end:
for (i = 0; i < s->nb_streams; i++) {
AVCodecParameters *par = s->streams[i]->codecpar;
FLVStreamContext *sc = s->streams[i]->priv_data;
- if (par->codec_type == AVMEDIA_TYPE_VIDEO &&
- (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4))
+ if (par->codec_id == AV_CODEC_ID_HEVC) {
+ avio_w8(pb, 0x82);
+ avio_write(pb, "hvc1", 4);
+ } else if (par->codec_type == AVMEDIA_TYPE_VIDEO &&
+ (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC))
put_eos_tag(pb, sc->last_ts, par->codec_id);
}
}
@@ -836,13 +851,13 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
if (par->codec_id == AV_CODEC_ID_VP6F || par->codec_id == AV_CODEC_ID_VP6A ||
par->codec_id == AV_CODEC_ID_VP6 || par->codec_id == AV_CODEC_ID_AAC)
flags_size = 2;
- else if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4)
+ else if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC)
flags_size = 5;
else
flags_size = 1;
if (par->codec_id == AV_CODEC_ID_AAC || par->codec_id == AV_CODEC_ID_H264
- || par->codec_id == AV_CODEC_ID_MPEG4) {
+ || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC) {
size_t side_size;
uint8_t *side = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &side_size);
if (side && side_size > 0 && (side_size != par->extradata_size || memcmp(side, par->extradata, side_size))) {
@@ -862,7 +877,7 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
"Packets are not in the proper order with respect to DTS\n");
return AVERROR(EINVAL);
}
- if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4) {
+ if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC) {
if (pkt->pts == AV_NOPTS_VALUE) {
av_log(s, AV_LOG_ERROR, "Packet is missing PTS\n");
return AVERROR(EINVAL);
@@ -907,6 +922,10 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
if (par->extradata_size > 0 && *(uint8_t*)par->extradata != 1)
if ((ret = ff_avc_parse_nal_units_buf(pkt->data, &data, &size)) < 0)
return ret;
+ } else if (par->codec_id == AV_CODEC_ID_HEVC) {
+ if (par->extradata_size > 0 && *(uint8_t*)par->extradata != 1)
+ if ((ret = ff_hevc_annexb2mp4_buf(pkt->data, &data, &size, 0, NULL)) < 0)
+ return ret;
} else if (par->codec_id == AV_CODEC_ID_AAC && pkt->size > 2 &&
(AV_RB16(pkt->data) & 0xfff0) == 0xfff0) {
if (!s->streams[pkt->stream_index]->nb_frames) {
@@ -968,7 +987,12 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
avio_wb32(pb, data_size + 11);
} else {
av_assert1(flags>=0);
- avio_w8(pb,flags);
+ if (par->codec_id == AV_CODEC_ID_HEVC) {
+ avio_w8(pb, FLV_IS_EX_HEADER | PacketTypeCodedFrames); // ExVideoTagHeader mode with PacketTypeCodedFrames
+ avio_write(pb, "hvc1", 4);
+ } else {
+ avio_w8(pb, flags);
+ }
if (par->codec_id == AV_CODEC_ID_VP6)
avio_w8(pb,0);
if (par->codec_id == AV_CODEC_ID_VP6F || par->codec_id == AV_CODEC_ID_VP6A) {
@@ -982,6 +1006,8 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
else if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4) {
avio_w8(pb, 1); // AVC NALU
avio_wb24(pb, pkt->pts - pkt->dts);
+ } else if (par->codec_id == AV_CODEC_ID_HEVC) {
+ avio_wb24(pb, pkt->pts - pkt->dts);
}
avio_write(pb, data ? data : pkt->data, size);
--
2.40.0
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 40+ messages in thread
* [FFmpeg-devel] [PATCH v5 2/4] avformat/flvdec: support demux HEVC in Enhancing FLV
2023-04-12 4:37 ` [FFmpeg-devel] [PATCH v5 1/4] " Steven Liu
@ 2023-04-12 4:37 ` Steven Liu
2023-04-12 4:37 ` [FFmpeg-devel] [PATCH v5 3/4] avformat/flvenc: support mux av1 in Enhanced FLV Steven Liu
2023-04-12 4:37 ` [FFmpeg-devel] [PATCH v5 4/4] avformat/flvdec: support demux " Steven Liu
2 siblings, 0 replies; 40+ messages in thread
From: Steven Liu @ 2023-04-12 4:37 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Steven Liu
Signed-off-by: Steven Liu <lq@chinaffmpeg.org>
---
libavformat/flvdec.c | 63 +++++++++++++++++++++++++++++++++++++++-----
1 file changed, 56 insertions(+), 7 deletions(-)
diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c
index d83edff727..8060c43772 100644
--- a/libavformat/flvdec.c
+++ b/libavformat/flvdec.c
@@ -79,6 +79,8 @@ typedef struct FLVContext {
int64_t last_ts;
int64_t time_offset;
int64_t time_pos;
+
+ uint8_t exheader;
} FLVContext;
/* AMF date type */
@@ -302,13 +304,26 @@ 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(AVFormatContext *s, AVCodecParameters *vpar, int flags)
{
int flv_codecid = flags & FLV_VIDEO_CODECID_MASK;
+ FLVContext *flv = s->priv_data;
if (!vpar->codec_id && !vpar->codec_tag)
return 1;
+ if (flv->exheader) {
+ uint8_t *codec_id_str = (uint8_t *)s->pb->buf_ptr;
+ uint32_t codec_id = codec_id_str[3] | codec_id_str[2] << 8 | codec_id_str[1] << 16 | codec_id_str[0] << 24;
+ switch(codec_id) {
+ case MKBETAG('h', 'v', 'c', '1'):
+ flv_codecid = FLV_CODECID_HEVC;
+ break;
+ default:
+ break;
+ }
+ }
+
switch (flv_codecid) {
case FLV_CODECID_H263:
return vpar->codec_id == AV_CODEC_ID_FLV1;
@@ -322,6 +337,8 @@ static int flv_same_video_codec(AVCodecParameters *vpar, int flags)
return vpar->codec_id == AV_CODEC_ID_VP6A;
case FLV_CODECID_H264:
return vpar->codec_id == AV_CODEC_ID_H264;
+ case FLV_CODECID_HEVC:
+ return vpar->codec_id == AV_CODEC_ID_HEVC;
default:
return vpar->codec_tag == flv_codecid;
}
@@ -331,9 +348,23 @@ static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream,
int flv_codecid, int read)
{
FFStream *const vstreami = ffstream(vstream);
+ FLVContext *flv = s->priv_data;
int ret = 0;
AVCodecParameters *par = vstream->codecpar;
enum AVCodecID old_codec_id = vstream->codecpar->codec_id;
+ flv_codecid &= FLV_VIDEO_CODECID_MASK;
+
+ if (flv->exheader) {
+ uint32_t codec_id = avio_rb32(s->pb);
+
+ switch(codec_id) {
+ case MKBETAG('h', 'v', 'c', '1'):
+ flv_codecid = FLV_CODECID_HEVC;
+ break;
+ default:
+ break;
+ }
+ }
switch (flv_codecid) {
case FLV_CODECID_H263:
par->codec_id = AV_CODEC_ID_FLV1;
@@ -372,6 +403,11 @@ static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream,
par->codec_id = AV_CODEC_ID_MPEG4;
ret = 3;
break;
+ case FLV_CODECID_HEVC:
+ par->codec_id = AV_CODEC_ID_HEVC;
+ vstreami->need_parsing = AVSTREAM_PARSE_HEADERS;
+ ret = 3;
+ break;
default:
avpriv_request_sample(s, "Video codec (%x)", flv_codecid);
par->codec_tag = flv_codecid;
@@ -796,6 +832,7 @@ static int flv_read_header(AVFormatContext *s)
s->start_time = 0;
flv->sum_flv_tag_size = 0;
flv->last_keyframe_stream_index = -1;
+ flv->exheader = 0;
return 0;
}
@@ -1071,6 +1108,11 @@ retry:
} else if (type == FLV_TAG_TYPE_VIDEO) {
stream_type = FLV_STREAM_TYPE_VIDEO;
flags = avio_r8(s->pb);
+ /*
+ * Reference Enhancing FLV 2023-03-v1.0.0-B.8
+ * https://github.com/veovera/enhanced-rtmp/blob/main/enhanced-rtmp-v1.pdf
+ * */
+ flv->exheader = (flags >> 7) & 1;
size--;
if ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_VIDEO_INFO_CMD)
goto skip;
@@ -1129,7 +1171,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(s, st->codecpar, flags)))
break;
} else if (stream_type == FLV_STREAM_TYPE_SUBTITLE) {
if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE)
@@ -1230,7 +1272,7 @@ retry_duration:
avcodec_parameters_free(&par);
}
} else if (stream_type == FLV_STREAM_TYPE_VIDEO) {
- int ret = flv_set_video_codec(s, st, flags & FLV_VIDEO_CODECID_MASK, 1);
+ int ret = flv_set_video_codec(s, st, flags, 1);
if (ret < 0)
return ret;
size -= ret;
@@ -1242,8 +1284,14 @@ 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_MPEG4) {
- int type = avio_r8(s->pb);
+ st->codecpar->codec_id == AV_CODEC_ID_MPEG4 ||
+ st->codecpar->codec_id == AV_CODEC_ID_HEVC) {
+ int type = 0;
+ if (flv->exheader) {
+ type = flags & 0x0F;
+ } else {
+ type = avio_r8(s->pb);
+ }
size--;
if (size < 0) {
@@ -1251,7 +1299,8 @@ 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_MPEG4
+ || (st->codecpar->codec_id == AV_CODEC_ID_HEVC && (flags & 0x0F))) {
// sign extension
int32_t cts = (avio_rb24(s->pb) + 0xff800000) ^ 0xff800000;
pts = av_sat_add64(dts, cts);
@@ -1267,7 +1316,7 @@ retry_duration:
}
}
if (type == 0 && (!st->codecpar->extradata || st->codecpar->codec_id == AV_CODEC_ID_AAC ||
- st->codecpar->codec_id == AV_CODEC_ID_H264)) {
+ st->codecpar->codec_id == AV_CODEC_ID_H264 || st->codecpar->codec_id == AV_CODEC_ID_HEVC)) {
AVDictionaryEntry *t;
if (st->codecpar->extradata) {
--
2.40.0
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 40+ messages in thread
* [FFmpeg-devel] [PATCH v5 3/4] avformat/flvenc: support mux av1 in Enhanced FLV
2023-04-12 4:37 ` [FFmpeg-devel] [PATCH v5 1/4] " Steven Liu
2023-04-12 4:37 ` [FFmpeg-devel] [PATCH v5 2/4] avformat/flvdec: support demux HEVC in Enhancing FLV Steven Liu
@ 2023-04-12 4:37 ` Steven Liu
2023-04-12 4:37 ` [FFmpeg-devel] [PATCH v5 4/4] avformat/flvdec: support demux " Steven Liu
2 siblings, 0 replies; 40+ messages in thread
From: Steven Liu @ 2023-04-12 4:37 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Steven Liu
Signed-off-by: Steven Liu <lq@chinaffmpeg.org>
---
libavformat/flvenc.c | 25 ++++++++++++++++++++-----
1 file changed, 20 insertions(+), 5 deletions(-)
diff --git a/libavformat/flvenc.c b/libavformat/flvenc.c
index 0f26ff99e8..3c8f6ee66f 100644
--- a/libavformat/flvenc.c
+++ b/libavformat/flvenc.c
@@ -28,6 +28,7 @@
#include "libavcodec/mpeg4audio.h"
#include "avio.h"
#include "avc.h"
+#include "av1.h"
#include "hevc.h"
#include "avformat.h"
#include "flv.h"
@@ -48,6 +49,7 @@ static const AVCodecTag flv_video_codec_ids[] = {
{ AV_CODEC_ID_VP6A, FLV_CODECID_VP6A },
{ AV_CODEC_ID_H264, FLV_CODECID_H264 },
{ AV_CODEC_ID_HEVC, FLV_CODECID_HEVC },
+ { AV_CODEC_ID_AV1, FLV_CODECID_AV1 },
{ AV_CODEC_ID_NONE, 0 }
};
@@ -494,7 +496,8 @@ static void flv_write_codec_header(AVFormatContext* s, AVCodecParameters* par, i
FLVContext *flv = s->priv_data;
if (par->codec_id == AV_CODEC_ID_AAC || par->codec_id == AV_CODEC_ID_H264
- || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC) {
+ || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC
+ || par->codec_id == AV_CODEC_ID_AV1) {
int64_t pos;
avio_w8(pb,
par->codec_type == AVMEDIA_TYPE_VIDEO ?
@@ -540,6 +543,9 @@ static void flv_write_codec_header(AVFormatContext* s, AVCodecParameters* par, i
if (par->codec_id == AV_CODEC_ID_HEVC) {
avio_w8(pb, FLV_IS_EX_HEADER | PacketTypeSequenceStart); // ExVideoTagHeader mode with PacketTypeSequenceStart
avio_write(pb, "hvc1", 4);
+ } else if (par->codec_id == AV_CODEC_ID_AV1) {
+ avio_w8(pb, FLV_IS_EX_HEADER | PacketTypeSequenceStart);
+ avio_write(pb, "av01", 4);
} else {
avio_w8(pb, par->codec_tag | FLV_FRAME_KEY); // flags
avio_w8(pb, 0); // AVC sequence header
@@ -548,6 +554,8 @@ static void flv_write_codec_header(AVFormatContext* s, AVCodecParameters* par, i
if (par->codec_id == AV_CODEC_ID_HEVC)
ff_isom_write_hvcc(pb, par->extradata, par->extradata_size, 0);
+ else if (par->codec_id == AV_CODEC_ID_AV1)
+ ff_isom_write_av1c(pb, par->extradata, par->extradata_size, 1);
else
ff_isom_write_avcc(pb, par->extradata, par->extradata_size);
}
@@ -640,7 +648,8 @@ static int flv_init(struct AVFormatContext *s)
if (par->codec_id == AV_CODEC_ID_MPEG4 ||
par->codec_id == AV_CODEC_ID_H263 ||
- par->codec_id == AV_CODEC_ID_HEVC) {
+ par->codec_id == AV_CODEC_ID_HEVC ||
+ par->codec_id == AV_CODEC_ID_AV1) {
int error = s->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL;
av_log(s, error ? AV_LOG_ERROR : AV_LOG_WARNING,
"Codec %s is not supported in the official FLV specification,\n", avcodec_get_name(par->codec_id));
@@ -851,13 +860,15 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
if (par->codec_id == AV_CODEC_ID_VP6F || par->codec_id == AV_CODEC_ID_VP6A ||
par->codec_id == AV_CODEC_ID_VP6 || par->codec_id == AV_CODEC_ID_AAC)
flags_size = 2;
- else if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC)
+ else if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4 ||
+ par->codec_id == AV_CODEC_ID_HEVC || par->codec_id == AV_CODEC_ID_AV1)
flags_size = 5;
else
flags_size = 1;
if (par->codec_id == AV_CODEC_ID_AAC || par->codec_id == AV_CODEC_ID_H264
- || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC) {
+ || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC
+ || par->codec_id == AV_CODEC_ID_AV1) {
size_t side_size;
uint8_t *side = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &side_size);
if (side && side_size > 0 && (side_size != par->extradata_size || memcmp(side, par->extradata, side_size))) {
@@ -877,7 +888,8 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
"Packets are not in the proper order with respect to DTS\n");
return AVERROR(EINVAL);
}
- if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC) {
+ if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4 ||
+ par->codec_id == AV_CODEC_ID_HEVC || par->codec_id == AV_CODEC_ID_AV1) {
if (pkt->pts == AV_NOPTS_VALUE) {
av_log(s, AV_LOG_ERROR, "Packet is missing PTS\n");
return AVERROR(EINVAL);
@@ -990,6 +1002,9 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
if (par->codec_id == AV_CODEC_ID_HEVC) {
avio_w8(pb, FLV_IS_EX_HEADER | PacketTypeCodedFrames); // ExVideoTagHeader mode with PacketTypeCodedFrames
avio_write(pb, "hvc1", 4);
+ } else if (par->codec_id == AV_CODEC_ID_AV1) {
+ avio_w8(pb, FLV_IS_EX_HEADER | PacketTypeCodedFrames);
+ avio_write(pb, "av01", 4);
} else {
avio_w8(pb, flags);
}
--
2.40.0
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 40+ messages in thread
* [FFmpeg-devel] [PATCH v5 4/4] avformat/flvdec: support demux av1 in Enhanced FLV
2023-04-12 4:37 ` [FFmpeg-devel] [PATCH v5 1/4] " Steven Liu
2023-04-12 4:37 ` [FFmpeg-devel] [PATCH v5 2/4] avformat/flvdec: support demux HEVC in Enhancing FLV Steven Liu
2023-04-12 4:37 ` [FFmpeg-devel] [PATCH v5 3/4] avformat/flvenc: support mux av1 in Enhanced FLV Steven Liu
@ 2023-04-12 4:37 ` Steven Liu
2 siblings, 0 replies; 40+ messages in thread
From: Steven Liu @ 2023-04-12 4:37 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Steven Liu
Signed-off-by: Steven Liu <lq@chinaffmpeg.org>
---
libavformat/flv.h | 1 +
libavformat/flvdec.c | 20 ++++++++++++++++++--
2 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/libavformat/flv.h b/libavformat/flv.h
index 44d3b04ff9..398a958e60 100644
--- a/libavformat/flv.h
+++ b/libavformat/flv.h
@@ -117,6 +117,7 @@ enum {
FLV_CODECID_REALH263= 8,
FLV_CODECID_MPEG4 = 9,
FLV_CODECID_HEVC = 10,
+ FLV_CODECID_AV1 = 11,
};
enum {
diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c
index 8060c43772..525c5b2e97 100644
--- a/libavformat/flvdec.c
+++ b/libavformat/flvdec.c
@@ -319,6 +319,9 @@ static int flv_same_video_codec(AVFormatContext *s, AVCodecParameters *vpar, int
case MKBETAG('h', 'v', 'c', '1'):
flv_codecid = FLV_CODECID_HEVC;
break;
+ case MKBETAG('a', 'v', '0', '1'):
+ flv_codecid = FLV_CODECID_AV1;
+ break;
default:
break;
}
@@ -339,6 +342,8 @@ static int flv_same_video_codec(AVFormatContext *s, AVCodecParameters *vpar, int
return vpar->codec_id == AV_CODEC_ID_H264;
case FLV_CODECID_HEVC:
return vpar->codec_id == AV_CODEC_ID_HEVC;
+ case FLV_CODECID_AV1:
+ return vpar->codec_id == AV_CODEC_ID_AV1;
default:
return vpar->codec_tag == flv_codecid;
}
@@ -361,6 +366,9 @@ static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream,
case MKBETAG('h', 'v', 'c', '1'):
flv_codecid = FLV_CODECID_HEVC;
break;
+ case MKBETAG('a', 'v', '0', '1'):
+ flv_codecid = FLV_CODECID_AV1;
+ break;
default:
break;
}
@@ -408,6 +416,12 @@ static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream,
vstreami->need_parsing = AVSTREAM_PARSE_HEADERS;
ret = 3;
break;
+ case FLV_CODECID_AV1:
+ par->codec_id = AV_CODEC_ID_AV1;
+ vstreami->need_parsing = AVSTREAM_PARSE_HEADERS;
+ ret = 3;
+ break;
+
default:
avpriv_request_sample(s, "Video codec (%x)", flv_codecid);
par->codec_tag = flv_codecid;
@@ -1285,7 +1299,8 @@ 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_MPEG4 ||
- st->codecpar->codec_id == AV_CODEC_ID_HEVC) {
+ st->codecpar->codec_id == AV_CODEC_ID_HEVC ||
+ st->codecpar->codec_id == AV_CODEC_ID_AV1) {
int type = 0;
if (flv->exheader) {
type = flags & 0x0F;
@@ -1316,7 +1331,8 @@ retry_duration:
}
}
if (type == 0 && (!st->codecpar->extradata || 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_H264 || st->codecpar->codec_id == AV_CODEC_ID_HEVC ||
+ st->codecpar->codec_id == AV_CODEC_ID_AV1)) {
AVDictionaryEntry *t;
if (st->codecpar->extradata) {
--
2.40.0
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [FFmpeg-devel] [PATCH 1/2] avformat/flvenc: Add support for HEVC over flv in muxer
2023-04-12 4:32 ` [FFmpeg-devel] [PATCH 1/2] avformat/flvenc: Add support for HEVC over flv in muxer Steven Liu
@ 2023-04-12 4:42 ` Steven Liu
0 siblings, 0 replies; 40+ messages in thread
From: Steven Liu @ 2023-04-12 4:42 UTC (permalink / raw)
To: FFmpeg development discussions and patches
Steven Liu <lingjiujianke@gmail.com> 于2023年4月12日周三 12:32写道:
>
> Neal Gompa <ngompa13@gmail.com> 于2023年4月12日周三 09:27写道:
> > Could you submit a complete version when you respin v4? The only
> > endpoint I can reasonably test is YouTube, so not having AV1 support
> > makes it difficult for me to try it out...
> Try this patchset please.
> https://patchwork.ffmpeg.org/project/ffmpeg/list/?series=8723
Ignore this patchset, i resubmit a v5 fix compiling error at the third patch
You can try the v5 version.
Thanks
Steven
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 40+ messages in thread
* [FFmpeg-devel] [PATCH v6 1/4] avformat/flvenc: Add support for HEVC over flv in muxer
2023-04-12 1:26 ` Neal Gompa
` (3 preceding siblings ...)
2023-04-12 4:37 ` [FFmpeg-devel] [PATCH v5 1/4] " Steven Liu
@ 2023-04-12 7:30 ` Steven Liu
2023-04-12 7:30 ` [FFmpeg-devel] [PATCH v6 2/4] avformat/flvdec: support demux HEVC in Enhancing FLV Steven Liu
` (3 more replies)
4 siblings, 4 replies; 40+ messages in thread
From: Steven Liu @ 2023-04-12 7:30 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Steven Liu
Implements HEVC according to Enhanced FLV spec found at
https://github.com/veovera/enhanced-rtmp
And it has beed supported by OBS, Simple Realtime Server, mpegts.js.
And the enhanced FLV documentation contributors include
Jean-Baptiste Kempf (FFmpeg, VideoLAN).
So this should be support by ffmpeg too.
Signed-off-by: Steven Liu <lq@chinaffmpeg.org>
---
libavformat/flv.h | 16 ++++++++++++
libavformat/flvenc.c | 62 +++++++++++++++++++++++++++++++++-----------
2 files changed, 63 insertions(+), 15 deletions(-)
diff --git a/libavformat/flv.h b/libavformat/flv.h
index 3571b90279..44d3b04ff9 100644
--- a/libavformat/flv.h
+++ b/libavformat/flv.h
@@ -35,6 +35,12 @@
#define FLV_VIDEO_FRAMETYPE_OFFSET 4
+/* Extended VideoTagHeader
+ * defined in reference link:
+ * https://github.com/veovera/enhanced-rtmp/blob/main/enhanced-rtmp-v1.pdf
+ * */
+#define FLV_IS_EX_HEADER 0x80
+
/* bitmasks to isolate specific values */
#define FLV_AUDIO_CHANNEL_MASK 0x01
#define FLV_AUDIO_SAMPLESIZE_MASK 0x02
@@ -110,6 +116,16 @@ enum {
FLV_CODECID_H264 = 7,
FLV_CODECID_REALH263= 8,
FLV_CODECID_MPEG4 = 9,
+ FLV_CODECID_HEVC = 10,
+};
+
+enum {
+ PacketTypeSequenceStart = 0,
+ PacketTypeCodedFrames = 1,
+ PacketTypeSequenceEnd = 2,
+ PacketTypeCodedFramesX = 3,
+ PacketTypeMetadata = 4,
+ PacketTypeMPEG2TSSequenceStart = 5,
};
enum {
diff --git a/libavformat/flvenc.c b/libavformat/flvenc.c
index fbf7eabaf8..620ad08ca1 100644
--- a/libavformat/flvenc.c
+++ b/libavformat/flvenc.c
@@ -28,6 +28,7 @@
#include "libavcodec/mpeg4audio.h"
#include "avio.h"
#include "avc.h"
+#include "hevc.h"
#include "avformat.h"
#include "flv.h"
#include "internal.h"
@@ -46,6 +47,7 @@ static const AVCodecTag flv_video_codec_ids[] = {
{ AV_CODEC_ID_VP6, FLV_CODECID_VP6 },
{ AV_CODEC_ID_VP6A, FLV_CODECID_VP6A },
{ AV_CODEC_ID_H264, FLV_CODECID_H264 },
+ { AV_CODEC_ID_HEVC, FLV_CODECID_HEVC },
{ AV_CODEC_ID_NONE, 0 }
};
@@ -238,16 +240,24 @@ static void put_timestamp(AVIOContext *pb, int64_t ts) {
static void put_eos_tag(AVIOContext *pb, unsigned ts, enum AVCodecID codec_id)
{
uint32_t tag = ff_codec_get_tag(flv_video_codec_ids, codec_id);
+ uint32_t flvtag_size = 16; /* Size of FLV tag */
/* ub[4] FrameType = 1, ub[4] CodecId */
tag |= 1 << 4;
avio_w8(pb, FLV_TAG_TYPE_VIDEO);
avio_wb24(pb, 5); /* Tag Data Size */
put_timestamp(pb, ts);
avio_wb24(pb, 0); /* StreamId = 0 */
- avio_w8(pb, tag);
- avio_w8(pb, 2); /* AVC end of sequence */
- avio_wb24(pb, 0); /* Always 0 for AVC EOS. */
- avio_wb32(pb, 16); /* Size of FLV tag */
+ if (codec_id == AV_CODEC_ID_HEVC) {
+ avio_w8(pb, FLV_IS_EX_HEADER | PacketTypeSequenceEnd);
+ avio_write(pb, "hvc1", 4);
+ flvtag_size = 19;
+ } else {
+ avio_w8(pb, tag);
+ avio_w8(pb, 2); /* AVC end of sequence */
+ flvtag_size = 16;
+ }
+ avio_wb24(pb, 0); /* Always 0 for EOS. */
+ avio_wb32(pb, flvtag_size); /* Size of FLV tag */
}
static void put_amf_double(AVIOContext *pb, double d)
@@ -492,7 +502,7 @@ static void flv_write_codec_header(AVFormatContext* s, AVCodecParameters* par, i
FLVContext *flv = s->priv_data;
if (par->codec_id == AV_CODEC_ID_AAC || par->codec_id == AV_CODEC_ID_H264
- || par->codec_id == AV_CODEC_ID_MPEG4) {
+ || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC) {
int64_t pos;
avio_w8(pb,
par->codec_type == AVMEDIA_TYPE_VIDEO ?
@@ -535,10 +545,19 @@ static void flv_write_codec_header(AVFormatContext* s, AVCodecParameters* par, i
}
avio_write(pb, par->extradata, par->extradata_size);
} else {
- avio_w8(pb, par->codec_tag | FLV_FRAME_KEY); // flags
- avio_w8(pb, 0); // AVC sequence header
- avio_wb24(pb, 0); // composition time
- ff_isom_write_avcc(pb, par->extradata, par->extradata_size);
+ if (par->codec_id == AV_CODEC_ID_HEVC) {
+ avio_w8(pb, FLV_IS_EX_HEADER | PacketTypeSequenceStart); // ExVideoTagHeader mode with PacketTypeSequenceStart
+ avio_write(pb, "hvc1", 4);
+ } else {
+ avio_w8(pb, par->codec_tag | FLV_FRAME_KEY); // flags
+ avio_w8(pb, 0); // AVC sequence header
+ avio_wb24(pb, 0); // composition time
+ }
+
+ if (par->codec_id == AV_CODEC_ID_HEVC)
+ ff_isom_write_hvcc(pb, par->extradata, par->extradata_size, 0);
+ else
+ ff_isom_write_avcc(pb, par->extradata, par->extradata_size);
}
data_size = avio_tell(pb) - pos;
avio_seek(pb, -data_size - 10, SEEK_CUR);
@@ -628,7 +647,8 @@ static int flv_init(struct AVFormatContext *s)
return unsupported_codec(s, "Video", par->codec_id);
if (par->codec_id == AV_CODEC_ID_MPEG4 ||
- par->codec_id == AV_CODEC_ID_H263) {
+ par->codec_id == AV_CODEC_ID_H263 ||
+ par->codec_id == AV_CODEC_ID_HEVC) {
int error = s->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL;
av_log(s, error ? AV_LOG_ERROR : AV_LOG_WARNING,
"Codec %s is not supported in the official FLV specification,\n", avcodec_get_name(par->codec_id));
@@ -785,7 +805,8 @@ end:
AVCodecParameters *par = s->streams[i]->codecpar;
FLVStreamContext *sc = s->streams[i]->priv_data;
if (par->codec_type == AVMEDIA_TYPE_VIDEO &&
- (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4))
+ (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4 ||
+ par->codec_id == AV_CODEC_ID_HEVC))
put_eos_tag(pb, sc->last_ts, par->codec_id);
}
}
@@ -836,13 +857,13 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
if (par->codec_id == AV_CODEC_ID_VP6F || par->codec_id == AV_CODEC_ID_VP6A ||
par->codec_id == AV_CODEC_ID_VP6 || par->codec_id == AV_CODEC_ID_AAC)
flags_size = 2;
- else if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4)
+ else if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC)
flags_size = 5;
else
flags_size = 1;
if (par->codec_id == AV_CODEC_ID_AAC || par->codec_id == AV_CODEC_ID_H264
- || par->codec_id == AV_CODEC_ID_MPEG4) {
+ || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC) {
size_t side_size;
uint8_t *side = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &side_size);
if (side && side_size > 0 && (side_size != par->extradata_size || memcmp(side, par->extradata, side_size))) {
@@ -862,7 +883,7 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
"Packets are not in the proper order with respect to DTS\n");
return AVERROR(EINVAL);
}
- if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4) {
+ if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC) {
if (pkt->pts == AV_NOPTS_VALUE) {
av_log(s, AV_LOG_ERROR, "Packet is missing PTS\n");
return AVERROR(EINVAL);
@@ -907,6 +928,10 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
if (par->extradata_size > 0 && *(uint8_t*)par->extradata != 1)
if ((ret = ff_avc_parse_nal_units_buf(pkt->data, &data, &size)) < 0)
return ret;
+ } else if (par->codec_id == AV_CODEC_ID_HEVC) {
+ if (par->extradata_size > 0 && *(uint8_t*)par->extradata != 1)
+ if ((ret = ff_hevc_annexb2mp4_buf(pkt->data, &data, &size, 0, NULL)) < 0)
+ return ret;
} else if (par->codec_id == AV_CODEC_ID_AAC && pkt->size > 2 &&
(AV_RB16(pkt->data) & 0xfff0) == 0xfff0) {
if (!s->streams[pkt->stream_index]->nb_frames) {
@@ -968,7 +993,12 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
avio_wb32(pb, data_size + 11);
} else {
av_assert1(flags>=0);
- avio_w8(pb,flags);
+ if (par->codec_id == AV_CODEC_ID_HEVC) {
+ avio_w8(pb, FLV_IS_EX_HEADER | PacketTypeCodedFrames); // ExVideoTagHeader mode with PacketTypeCodedFrames
+ avio_write(pb, "hvc1", 4);
+ } else {
+ avio_w8(pb, flags);
+ }
if (par->codec_id == AV_CODEC_ID_VP6)
avio_w8(pb,0);
if (par->codec_id == AV_CODEC_ID_VP6F || par->codec_id == AV_CODEC_ID_VP6A) {
@@ -982,6 +1012,8 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
else if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4) {
avio_w8(pb, 1); // AVC NALU
avio_wb24(pb, pkt->pts - pkt->dts);
+ } else if (par->codec_id == AV_CODEC_ID_HEVC) {
+ avio_wb24(pb, pkt->pts - pkt->dts);
}
avio_write(pb, data ? data : pkt->data, size);
--
2.40.0
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 40+ messages in thread
* [FFmpeg-devel] [PATCH v6 2/4] avformat/flvdec: support demux HEVC in Enhancing FLV
2023-04-12 7:30 ` [FFmpeg-devel] [PATCH v6 1/4] avformat/flvenc: Add support for HEVC over flv in muxer Steven Liu
@ 2023-04-12 7:30 ` Steven Liu
2023-04-12 7:30 ` [FFmpeg-devel] [PATCH v6 3/4] avformat/flvenc: support mux av1 in Enhanced FLV Steven Liu
` (2 subsequent siblings)
3 siblings, 0 replies; 40+ messages in thread
From: Steven Liu @ 2023-04-12 7:30 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Steven Liu
Signed-off-by: Steven Liu <lq@chinaffmpeg.org>
---
libavformat/flvdec.c | 63 +++++++++++++++++++++++++++++++++++++++-----
1 file changed, 56 insertions(+), 7 deletions(-)
diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c
index d83edff727..8060c43772 100644
--- a/libavformat/flvdec.c
+++ b/libavformat/flvdec.c
@@ -79,6 +79,8 @@ typedef struct FLVContext {
int64_t last_ts;
int64_t time_offset;
int64_t time_pos;
+
+ uint8_t exheader;
} FLVContext;
/* AMF date type */
@@ -302,13 +304,26 @@ 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(AVFormatContext *s, AVCodecParameters *vpar, int flags)
{
int flv_codecid = flags & FLV_VIDEO_CODECID_MASK;
+ FLVContext *flv = s->priv_data;
if (!vpar->codec_id && !vpar->codec_tag)
return 1;
+ if (flv->exheader) {
+ uint8_t *codec_id_str = (uint8_t *)s->pb->buf_ptr;
+ uint32_t codec_id = codec_id_str[3] | codec_id_str[2] << 8 | codec_id_str[1] << 16 | codec_id_str[0] << 24;
+ switch(codec_id) {
+ case MKBETAG('h', 'v', 'c', '1'):
+ flv_codecid = FLV_CODECID_HEVC;
+ break;
+ default:
+ break;
+ }
+ }
+
switch (flv_codecid) {
case FLV_CODECID_H263:
return vpar->codec_id == AV_CODEC_ID_FLV1;
@@ -322,6 +337,8 @@ static int flv_same_video_codec(AVCodecParameters *vpar, int flags)
return vpar->codec_id == AV_CODEC_ID_VP6A;
case FLV_CODECID_H264:
return vpar->codec_id == AV_CODEC_ID_H264;
+ case FLV_CODECID_HEVC:
+ return vpar->codec_id == AV_CODEC_ID_HEVC;
default:
return vpar->codec_tag == flv_codecid;
}
@@ -331,9 +348,23 @@ static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream,
int flv_codecid, int read)
{
FFStream *const vstreami = ffstream(vstream);
+ FLVContext *flv = s->priv_data;
int ret = 0;
AVCodecParameters *par = vstream->codecpar;
enum AVCodecID old_codec_id = vstream->codecpar->codec_id;
+ flv_codecid &= FLV_VIDEO_CODECID_MASK;
+
+ if (flv->exheader) {
+ uint32_t codec_id = avio_rb32(s->pb);
+
+ switch(codec_id) {
+ case MKBETAG('h', 'v', 'c', '1'):
+ flv_codecid = FLV_CODECID_HEVC;
+ break;
+ default:
+ break;
+ }
+ }
switch (flv_codecid) {
case FLV_CODECID_H263:
par->codec_id = AV_CODEC_ID_FLV1;
@@ -372,6 +403,11 @@ static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream,
par->codec_id = AV_CODEC_ID_MPEG4;
ret = 3;
break;
+ case FLV_CODECID_HEVC:
+ par->codec_id = AV_CODEC_ID_HEVC;
+ vstreami->need_parsing = AVSTREAM_PARSE_HEADERS;
+ ret = 3;
+ break;
default:
avpriv_request_sample(s, "Video codec (%x)", flv_codecid);
par->codec_tag = flv_codecid;
@@ -796,6 +832,7 @@ static int flv_read_header(AVFormatContext *s)
s->start_time = 0;
flv->sum_flv_tag_size = 0;
flv->last_keyframe_stream_index = -1;
+ flv->exheader = 0;
return 0;
}
@@ -1071,6 +1108,11 @@ retry:
} else if (type == FLV_TAG_TYPE_VIDEO) {
stream_type = FLV_STREAM_TYPE_VIDEO;
flags = avio_r8(s->pb);
+ /*
+ * Reference Enhancing FLV 2023-03-v1.0.0-B.8
+ * https://github.com/veovera/enhanced-rtmp/blob/main/enhanced-rtmp-v1.pdf
+ * */
+ flv->exheader = (flags >> 7) & 1;
size--;
if ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_VIDEO_INFO_CMD)
goto skip;
@@ -1129,7 +1171,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(s, st->codecpar, flags)))
break;
} else if (stream_type == FLV_STREAM_TYPE_SUBTITLE) {
if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE)
@@ -1230,7 +1272,7 @@ retry_duration:
avcodec_parameters_free(&par);
}
} else if (stream_type == FLV_STREAM_TYPE_VIDEO) {
- int ret = flv_set_video_codec(s, st, flags & FLV_VIDEO_CODECID_MASK, 1);
+ int ret = flv_set_video_codec(s, st, flags, 1);
if (ret < 0)
return ret;
size -= ret;
@@ -1242,8 +1284,14 @@ 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_MPEG4) {
- int type = avio_r8(s->pb);
+ st->codecpar->codec_id == AV_CODEC_ID_MPEG4 ||
+ st->codecpar->codec_id == AV_CODEC_ID_HEVC) {
+ int type = 0;
+ if (flv->exheader) {
+ type = flags & 0x0F;
+ } else {
+ type = avio_r8(s->pb);
+ }
size--;
if (size < 0) {
@@ -1251,7 +1299,8 @@ 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_MPEG4
+ || (st->codecpar->codec_id == AV_CODEC_ID_HEVC && (flags & 0x0F))) {
// sign extension
int32_t cts = (avio_rb24(s->pb) + 0xff800000) ^ 0xff800000;
pts = av_sat_add64(dts, cts);
@@ -1267,7 +1316,7 @@ retry_duration:
}
}
if (type == 0 && (!st->codecpar->extradata || st->codecpar->codec_id == AV_CODEC_ID_AAC ||
- st->codecpar->codec_id == AV_CODEC_ID_H264)) {
+ st->codecpar->codec_id == AV_CODEC_ID_H264 || st->codecpar->codec_id == AV_CODEC_ID_HEVC)) {
AVDictionaryEntry *t;
if (st->codecpar->extradata) {
--
2.40.0
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 40+ messages in thread
* [FFmpeg-devel] [PATCH v6 3/4] avformat/flvenc: support mux av1 in Enhanced FLV
2023-04-12 7:30 ` [FFmpeg-devel] [PATCH v6 1/4] avformat/flvenc: Add support for HEVC over flv in muxer Steven Liu
2023-04-12 7:30 ` [FFmpeg-devel] [PATCH v6 2/4] avformat/flvdec: support demux HEVC in Enhancing FLV Steven Liu
@ 2023-04-12 7:30 ` Steven Liu
2023-04-12 7:31 ` [FFmpeg-devel] [PATCH v6 4/4] avformat/flvdec: support demux " Steven Liu
2023-04-13 0:41 ` [FFmpeg-devel] [PATCH v6 1/4] avformat/flvenc: Add support for HEVC over flv in muxer Jean-Baptiste Kempf
3 siblings, 0 replies; 40+ messages in thread
From: Steven Liu @ 2023-04-12 7:30 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Steven Liu
Signed-off-by: Steven Liu <lq@chinaffmpeg.org>
---
libavformat/flv.h | 1 +
libavformat/flvenc.c | 32 ++++++++++++++++++++++++++------
2 files changed, 27 insertions(+), 6 deletions(-)
diff --git a/libavformat/flv.h b/libavformat/flv.h
index 44d3b04ff9..398a958e60 100644
--- a/libavformat/flv.h
+++ b/libavformat/flv.h
@@ -117,6 +117,7 @@ enum {
FLV_CODECID_REALH263= 8,
FLV_CODECID_MPEG4 = 9,
FLV_CODECID_HEVC = 10,
+ FLV_CODECID_AV1 = 11,
};
enum {
diff --git a/libavformat/flvenc.c b/libavformat/flvenc.c
index 620ad08ca1..b570fa91be 100644
--- a/libavformat/flvenc.c
+++ b/libavformat/flvenc.c
@@ -28,6 +28,7 @@
#include "libavcodec/mpeg4audio.h"
#include "avio.h"
#include "avc.h"
+#include "av1.h"
#include "hevc.h"
#include "avformat.h"
#include "flv.h"
@@ -48,6 +49,7 @@ static const AVCodecTag flv_video_codec_ids[] = {
{ AV_CODEC_ID_VP6A, FLV_CODECID_VP6A },
{ AV_CODEC_ID_H264, FLV_CODECID_H264 },
{ AV_CODEC_ID_HEVC, FLV_CODECID_HEVC },
+ { AV_CODEC_ID_AV1, FLV_CODECID_AV1 },
{ AV_CODEC_ID_NONE, 0 }
};
@@ -251,6 +253,11 @@ static void put_eos_tag(AVIOContext *pb, unsigned ts, enum AVCodecID codec_id)
avio_w8(pb, FLV_IS_EX_HEADER | PacketTypeSequenceEnd);
avio_write(pb, "hvc1", 4);
flvtag_size = 19;
+ } else if (codec_id == AV_CODEC_ID_AV1) {
+ avio_w8(pb, FLV_IS_EX_HEADER | PacketTypeSequenceEnd);
+ avio_write(pb, "av01", 4);
+ flvtag_size = 19;
+
} else {
avio_w8(pb, tag);
avio_w8(pb, 2); /* AVC end of sequence */
@@ -502,7 +509,8 @@ static void flv_write_codec_header(AVFormatContext* s, AVCodecParameters* par, i
FLVContext *flv = s->priv_data;
if (par->codec_id == AV_CODEC_ID_AAC || par->codec_id == AV_CODEC_ID_H264
- || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC) {
+ || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC
+ || par->codec_id == AV_CODEC_ID_AV1) {
int64_t pos;
avio_w8(pb,
par->codec_type == AVMEDIA_TYPE_VIDEO ?
@@ -548,6 +556,9 @@ static void flv_write_codec_header(AVFormatContext* s, AVCodecParameters* par, i
if (par->codec_id == AV_CODEC_ID_HEVC) {
avio_w8(pb, FLV_IS_EX_HEADER | PacketTypeSequenceStart); // ExVideoTagHeader mode with PacketTypeSequenceStart
avio_write(pb, "hvc1", 4);
+ } else if (par->codec_id == AV_CODEC_ID_AV1) {
+ avio_w8(pb, FLV_IS_EX_HEADER | PacketTypeSequenceStart);
+ avio_write(pb, "av01", 4);
} else {
avio_w8(pb, par->codec_tag | FLV_FRAME_KEY); // flags
avio_w8(pb, 0); // AVC sequence header
@@ -556,6 +567,8 @@ static void flv_write_codec_header(AVFormatContext* s, AVCodecParameters* par, i
if (par->codec_id == AV_CODEC_ID_HEVC)
ff_isom_write_hvcc(pb, par->extradata, par->extradata_size, 0);
+ else if (par->codec_id == AV_CODEC_ID_AV1)
+ ff_isom_write_av1c(pb, par->extradata, par->extradata_size, 1);
else
ff_isom_write_avcc(pb, par->extradata, par->extradata_size);
}
@@ -648,7 +661,8 @@ static int flv_init(struct AVFormatContext *s)
if (par->codec_id == AV_CODEC_ID_MPEG4 ||
par->codec_id == AV_CODEC_ID_H263 ||
- par->codec_id == AV_CODEC_ID_HEVC) {
+ par->codec_id == AV_CODEC_ID_HEVC ||
+ par->codec_id == AV_CODEC_ID_AV1) {
int error = s->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL;
av_log(s, error ? AV_LOG_ERROR : AV_LOG_WARNING,
"Codec %s is not supported in the official FLV specification,\n", avcodec_get_name(par->codec_id));
@@ -806,7 +820,7 @@ end:
FLVStreamContext *sc = s->streams[i]->priv_data;
if (par->codec_type == AVMEDIA_TYPE_VIDEO &&
(par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4 ||
- par->codec_id == AV_CODEC_ID_HEVC))
+ par->codec_id == AV_CODEC_ID_HEVC || par->codec_id == AV_CODEC_ID_AV1))
put_eos_tag(pb, sc->last_ts, par->codec_id);
}
}
@@ -857,13 +871,15 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
if (par->codec_id == AV_CODEC_ID_VP6F || par->codec_id == AV_CODEC_ID_VP6A ||
par->codec_id == AV_CODEC_ID_VP6 || par->codec_id == AV_CODEC_ID_AAC)
flags_size = 2;
- else if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC)
+ else if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4 ||
+ par->codec_id == AV_CODEC_ID_HEVC || par->codec_id == AV_CODEC_ID_AV1)
flags_size = 5;
else
flags_size = 1;
if (par->codec_id == AV_CODEC_ID_AAC || par->codec_id == AV_CODEC_ID_H264
- || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC) {
+ || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC
+ || par->codec_id == AV_CODEC_ID_AV1) {
size_t side_size;
uint8_t *side = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &side_size);
if (side && side_size > 0 && (side_size != par->extradata_size || memcmp(side, par->extradata, side_size))) {
@@ -883,7 +899,8 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
"Packets are not in the proper order with respect to DTS\n");
return AVERROR(EINVAL);
}
- if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC) {
+ if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4 ||
+ par->codec_id == AV_CODEC_ID_HEVC || par->codec_id == AV_CODEC_ID_AV1) {
if (pkt->pts == AV_NOPTS_VALUE) {
av_log(s, AV_LOG_ERROR, "Packet is missing PTS\n");
return AVERROR(EINVAL);
@@ -996,6 +1013,9 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
if (par->codec_id == AV_CODEC_ID_HEVC) {
avio_w8(pb, FLV_IS_EX_HEADER | PacketTypeCodedFrames); // ExVideoTagHeader mode with PacketTypeCodedFrames
avio_write(pb, "hvc1", 4);
+ } else if (par->codec_id == AV_CODEC_ID_AV1) {
+ avio_w8(pb, FLV_IS_EX_HEADER | PacketTypeCodedFrames);
+ avio_write(pb, "av01", 4);
} else {
avio_w8(pb, flags);
}
--
2.40.0
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 40+ messages in thread
* [FFmpeg-devel] [PATCH v6 4/4] avformat/flvdec: support demux av1 in Enhanced FLV
2023-04-12 7:30 ` [FFmpeg-devel] [PATCH v6 1/4] avformat/flvenc: Add support for HEVC over flv in muxer Steven Liu
2023-04-12 7:30 ` [FFmpeg-devel] [PATCH v6 2/4] avformat/flvdec: support demux HEVC in Enhancing FLV Steven Liu
2023-04-12 7:30 ` [FFmpeg-devel] [PATCH v6 3/4] avformat/flvenc: support mux av1 in Enhanced FLV Steven Liu
@ 2023-04-12 7:31 ` Steven Liu
2023-04-13 0:41 ` [FFmpeg-devel] [PATCH v6 1/4] avformat/flvenc: Add support for HEVC over flv in muxer Jean-Baptiste Kempf
3 siblings, 0 replies; 40+ messages in thread
From: Steven Liu @ 2023-04-12 7:31 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Steven Liu
Signed-off-by: Steven Liu <lq@chinaffmpeg.org>
---
libavformat/flvdec.c | 20 ++++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c
index 8060c43772..525c5b2e97 100644
--- a/libavformat/flvdec.c
+++ b/libavformat/flvdec.c
@@ -319,6 +319,9 @@ static int flv_same_video_codec(AVFormatContext *s, AVCodecParameters *vpar, int
case MKBETAG('h', 'v', 'c', '1'):
flv_codecid = FLV_CODECID_HEVC;
break;
+ case MKBETAG('a', 'v', '0', '1'):
+ flv_codecid = FLV_CODECID_AV1;
+ break;
default:
break;
}
@@ -339,6 +342,8 @@ static int flv_same_video_codec(AVFormatContext *s, AVCodecParameters *vpar, int
return vpar->codec_id == AV_CODEC_ID_H264;
case FLV_CODECID_HEVC:
return vpar->codec_id == AV_CODEC_ID_HEVC;
+ case FLV_CODECID_AV1:
+ return vpar->codec_id == AV_CODEC_ID_AV1;
default:
return vpar->codec_tag == flv_codecid;
}
@@ -361,6 +366,9 @@ static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream,
case MKBETAG('h', 'v', 'c', '1'):
flv_codecid = FLV_CODECID_HEVC;
break;
+ case MKBETAG('a', 'v', '0', '1'):
+ flv_codecid = FLV_CODECID_AV1;
+ break;
default:
break;
}
@@ -408,6 +416,12 @@ static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream,
vstreami->need_parsing = AVSTREAM_PARSE_HEADERS;
ret = 3;
break;
+ case FLV_CODECID_AV1:
+ par->codec_id = AV_CODEC_ID_AV1;
+ vstreami->need_parsing = AVSTREAM_PARSE_HEADERS;
+ ret = 3;
+ break;
+
default:
avpriv_request_sample(s, "Video codec (%x)", flv_codecid);
par->codec_tag = flv_codecid;
@@ -1285,7 +1299,8 @@ 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_MPEG4 ||
- st->codecpar->codec_id == AV_CODEC_ID_HEVC) {
+ st->codecpar->codec_id == AV_CODEC_ID_HEVC ||
+ st->codecpar->codec_id == AV_CODEC_ID_AV1) {
int type = 0;
if (flv->exheader) {
type = flags & 0x0F;
@@ -1316,7 +1331,8 @@ retry_duration:
}
}
if (type == 0 && (!st->codecpar->extradata || 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_H264 || st->codecpar->codec_id == AV_CODEC_ID_HEVC ||
+ st->codecpar->codec_id == AV_CODEC_ID_AV1)) {
AVDictionaryEntry *t;
if (st->codecpar->extradata) {
--
2.40.0
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [FFmpeg-devel] [PATCH v6 1/4] avformat/flvenc: Add support for HEVC over flv in muxer
2023-04-12 7:30 ` [FFmpeg-devel] [PATCH v6 1/4] avformat/flvenc: Add support for HEVC over flv in muxer Steven Liu
` (2 preceding siblings ...)
2023-04-12 7:31 ` [FFmpeg-devel] [PATCH v6 4/4] avformat/flvdec: support demux " Steven Liu
@ 2023-04-13 0:41 ` Jean-Baptiste Kempf
2023-04-13 6:29 ` [FFmpeg-devel] [PATCH v7 " Steven Liu
2023-04-13 6:41 ` [FFmpeg-devel] [PATCH v6 1/4] avformat/flvenc: Add support for HEVC over flv in muxer Steven Liu
3 siblings, 2 replies; 40+ messages in thread
From: Jean-Baptiste Kempf @ 2023-04-13 0:41 UTC (permalink / raw)
To: ffmpeg-devel
Hello,
On Wed, 12 Apr 2023, at 03:30, Steven Liu wrote:
> Implements HEVC according to Enhanced FLV spec found at
> https://github.com/veovera/enhanced-rtmp
The spec is not final, so please wait before merging this :)
But it looks good.
> libavformat/flv.h | 16 ++++++++++++
> @@ -110,6 +116,16 @@ enum {
> FLV_CODECID_H264 = 7,
> FLV_CODECID_REALH263= 8,
> FLV_CODECID_MPEG4 = 9,
> + FLV_CODECID_HEVC = 10,
By adding this to the enum, if there a risk that invalid streams, aka using 10 inside the bitstream get decoded too? (Instead of using the fourcc)
--
Jean-Baptiste Kempf - President
+33 672 704 734
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 40+ messages in thread
* [FFmpeg-devel] [PATCH v7 1/4] avformat/flvenc: Add support for HEVC over flv in muxer
2023-04-13 0:41 ` [FFmpeg-devel] [PATCH v6 1/4] avformat/flvenc: Add support for HEVC over flv in muxer Jean-Baptiste Kempf
@ 2023-04-13 6:29 ` Steven Liu
2023-04-13 6:29 ` [FFmpeg-devel] [PATCH v7 2/4] avformat/flvdec: support demux hevc in enhanced flv Steven Liu
` (2 more replies)
2023-04-13 6:41 ` [FFmpeg-devel] [PATCH v6 1/4] avformat/flvenc: Add support for HEVC over flv in muxer Steven Liu
1 sibling, 3 replies; 40+ messages in thread
From: Steven Liu @ 2023-04-13 6:29 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Steven Liu
Implements HEVC according to Enhanced FLV spec found at
https://github.com/veovera/enhanced-rtmp
And it has beed supported by OBS, Simple Realtime Server, mpegts.js.
And the enhanced FLV documentation contributors include
Jean-Baptiste Kempf (FFmpeg, VideoLAN).
So this should be support by ffmpeg too.
Signed-off-by: Steven Liu <lq@chinaffmpeg.org>
---
libavformat/flv.h | 15 +++++++++++++++
libavformat/flvenc.c | 41 +++++++++++++++++++++++++++++++----------
2 files changed, 46 insertions(+), 10 deletions(-)
diff --git a/libavformat/flv.h b/libavformat/flv.h
index 3571b90279..91e0a4140c 100644
--- a/libavformat/flv.h
+++ b/libavformat/flv.h
@@ -35,6 +35,12 @@
#define FLV_VIDEO_FRAMETYPE_OFFSET 4
+/* Extended VideoTagHeader
+ * defined in reference link:
+ * https://github.com/veovera/enhanced-rtmp/blob/main/enhanced-rtmp-v1.pdf
+ * */
+#define FLV_IS_EX_HEADER 0x80
+
/* bitmasks to isolate specific values */
#define FLV_AUDIO_CHANNEL_MASK 0x01
#define FLV_AUDIO_SAMPLESIZE_MASK 0x02
@@ -112,6 +118,15 @@ enum {
FLV_CODECID_MPEG4 = 9,
};
+enum {
+ PacketTypeSequenceStart = 0,
+ PacketTypeCodedFrames = 1,
+ PacketTypeSequenceEnd = 2,
+ PacketTypeCodedFramesX = 3,
+ PacketTypeMetadata = 4,
+ PacketTypeMPEG2TSSequenceStart = 5,
+};
+
enum {
FLV_FRAME_KEY = 1 << FLV_VIDEO_FRAMETYPE_OFFSET, ///< key frame (for AVC, a seekable frame)
FLV_FRAME_INTER = 2 << FLV_VIDEO_FRAMETYPE_OFFSET, ///< inter frame (for AVC, a non-seekable frame)
diff --git a/libavformat/flvenc.c b/libavformat/flvenc.c
index fbf7eabaf8..57a26245ff 100644
--- a/libavformat/flvenc.c
+++ b/libavformat/flvenc.c
@@ -28,6 +28,7 @@
#include "libavcodec/mpeg4audio.h"
#include "avio.h"
#include "avc.h"
+#include "hevc.h"
#include "avformat.h"
#include "flv.h"
#include "internal.h"
@@ -46,6 +47,7 @@ static const AVCodecTag flv_video_codec_ids[] = {
{ AV_CODEC_ID_VP6, FLV_CODECID_VP6 },
{ AV_CODEC_ID_VP6A, FLV_CODECID_VP6A },
{ AV_CODEC_ID_H264, FLV_CODECID_H264 },
+ { AV_CODEC_ID_HEVC, MKBETAG('h', 'v', 'c', '1') },
{ AV_CODEC_ID_NONE, 0 }
};
@@ -492,7 +494,7 @@ static void flv_write_codec_header(AVFormatContext* s, AVCodecParameters* par, i
FLVContext *flv = s->priv_data;
if (par->codec_id == AV_CODEC_ID_AAC || par->codec_id == AV_CODEC_ID_H264
- || par->codec_id == AV_CODEC_ID_MPEG4) {
+ || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC) {
int64_t pos;
avio_w8(pb,
par->codec_type == AVMEDIA_TYPE_VIDEO ?
@@ -535,10 +537,19 @@ static void flv_write_codec_header(AVFormatContext* s, AVCodecParameters* par, i
}
avio_write(pb, par->extradata, par->extradata_size);
} else {
- avio_w8(pb, par->codec_tag | FLV_FRAME_KEY); // flags
- avio_w8(pb, 0); // AVC sequence header
- avio_wb24(pb, 0); // composition time
- ff_isom_write_avcc(pb, par->extradata, par->extradata_size);
+ if (par->codec_id == AV_CODEC_ID_HEVC) {
+ avio_w8(pb, FLV_IS_EX_HEADER | PacketTypeSequenceStart); // ExVideoTagHeader mode with PacketTypeSequenceStart
+ avio_write(pb, "hvc1", 4);
+ } else {
+ avio_w8(pb, par->codec_tag | FLV_FRAME_KEY); // flags
+ avio_w8(pb, 0); // AVC sequence header
+ avio_wb24(pb, 0); // composition time
+ }
+
+ if (par->codec_id == AV_CODEC_ID_HEVC)
+ ff_isom_write_hvcc(pb, par->extradata, par->extradata_size, 0);
+ else
+ ff_isom_write_avcc(pb, par->extradata, par->extradata_size);
}
data_size = avio_tell(pb) - pos;
avio_seek(pb, -data_size - 10, SEEK_CUR);
@@ -628,7 +639,8 @@ static int flv_init(struct AVFormatContext *s)
return unsupported_codec(s, "Video", par->codec_id);
if (par->codec_id == AV_CODEC_ID_MPEG4 ||
- par->codec_id == AV_CODEC_ID_H263) {
+ par->codec_id == AV_CODEC_ID_H263 ||
+ par->codec_id == AV_CODEC_ID_HEVC) {
int error = s->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL;
av_log(s, error ? AV_LOG_ERROR : AV_LOG_WARNING,
"Codec %s is not supported in the official FLV specification,\n", avcodec_get_name(par->codec_id));
@@ -836,13 +848,13 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
if (par->codec_id == AV_CODEC_ID_VP6F || par->codec_id == AV_CODEC_ID_VP6A ||
par->codec_id == AV_CODEC_ID_VP6 || par->codec_id == AV_CODEC_ID_AAC)
flags_size = 2;
- else if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4)
+ else if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC)
flags_size = 5;
else
flags_size = 1;
if (par->codec_id == AV_CODEC_ID_AAC || par->codec_id == AV_CODEC_ID_H264
- || par->codec_id == AV_CODEC_ID_MPEG4) {
+ || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC) {
size_t side_size;
uint8_t *side = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &side_size);
if (side && side_size > 0 && (side_size != par->extradata_size || memcmp(side, par->extradata, side_size))) {
@@ -862,7 +874,7 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
"Packets are not in the proper order with respect to DTS\n");
return AVERROR(EINVAL);
}
- if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4) {
+ if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC) {
if (pkt->pts == AV_NOPTS_VALUE) {
av_log(s, AV_LOG_ERROR, "Packet is missing PTS\n");
return AVERROR(EINVAL);
@@ -907,6 +919,10 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
if (par->extradata_size > 0 && *(uint8_t*)par->extradata != 1)
if ((ret = ff_avc_parse_nal_units_buf(pkt->data, &data, &size)) < 0)
return ret;
+ } else if (par->codec_id == AV_CODEC_ID_HEVC) {
+ if (par->extradata_size > 0 && *(uint8_t*)par->extradata != 1)
+ if ((ret = ff_hevc_annexb2mp4_buf(pkt->data, &data, &size, 0, NULL)) < 0)
+ return ret;
} else if (par->codec_id == AV_CODEC_ID_AAC && pkt->size > 2 &&
(AV_RB16(pkt->data) & 0xfff0) == 0xfff0) {
if (!s->streams[pkt->stream_index]->nb_frames) {
@@ -968,7 +984,12 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
avio_wb32(pb, data_size + 11);
} else {
av_assert1(flags>=0);
- avio_w8(pb,flags);
+ if (par->codec_id == AV_CODEC_ID_HEVC) {
+ avio_w8(pb, FLV_IS_EX_HEADER | PacketTypeCodedFramesX); // ExVideoTagHeader mode with PacketTypeCodedFramesX
+ avio_write(pb, "hvc1", 4);
+ } else {
+ avio_w8(pb, flags);
+ }
if (par->codec_id == AV_CODEC_ID_VP6)
avio_w8(pb,0);
if (par->codec_id == AV_CODEC_ID_VP6F || par->codec_id == AV_CODEC_ID_VP6A) {
--
2.40.0
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 40+ messages in thread
* [FFmpeg-devel] [PATCH v7 2/4] avformat/flvdec: support demux hevc in enhanced flv
2023-04-13 6:29 ` [FFmpeg-devel] [PATCH v7 " Steven Liu
@ 2023-04-13 6:29 ` Steven Liu
2023-04-13 6:29 ` [FFmpeg-devel] [PATCH v7 3/4] avformat/flvenc: support mux av1 " Steven Liu
2023-04-13 6:29 ` [FFmpeg-devel] [PATCH v7 4/4] avformat/flvdec: support demux " Steven Liu
2 siblings, 0 replies; 40+ messages in thread
From: Steven Liu @ 2023-04-13 6:29 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Steven Liu
Signed-off-by: Steven Liu <lq@chinaffmpeg.org>
---
libavformat/flvdec.c | 55 ++++++++++++++++++++++++++++++++++++++------
1 file changed, 48 insertions(+), 7 deletions(-)
diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c
index d83edff727..0b6218f65b 100644
--- a/libavformat/flvdec.c
+++ b/libavformat/flvdec.c
@@ -79,6 +79,8 @@ typedef struct FLVContext {
int64_t last_ts;
int64_t time_offset;
int64_t time_pos;
+
+ uint8_t exheader;
} FLVContext;
/* AMF date type */
@@ -302,13 +304,25 @@ 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(AVFormatContext *s, AVCodecParameters *vpar, int flags)
{
int flv_codecid = flags & FLV_VIDEO_CODECID_MASK;
+ FLVContext *flv = s->priv_data;
if (!vpar->codec_id && !vpar->codec_tag)
return 1;
+ if (flv->exheader) {
+ uint8_t *codec_id_str = (uint8_t *)s->pb->buf_ptr;
+ uint32_t codec_id = codec_id_str[3] | codec_id_str[2] << 8 | codec_id_str[1] << 16 | codec_id_str[0] << 24;
+ switch(codec_id) {
+ case MKBETAG('h', 'v', 'c', '1'):
+ return vpar->codec_id == AV_CODEC_ID_HEVC;
+ default:
+ break;
+ }
+ }
+
switch (flv_codecid) {
case FLV_CODECID_H263:
return vpar->codec_id == AV_CODEC_ID_FLV1;
@@ -331,9 +345,24 @@ static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream,
int flv_codecid, int read)
{
FFStream *const vstreami = ffstream(vstream);
+ FLVContext *flv = s->priv_data;
int ret = 0;
AVCodecParameters *par = vstream->codecpar;
enum AVCodecID old_codec_id = vstream->codecpar->codec_id;
+ flv_codecid &= FLV_VIDEO_CODECID_MASK;
+
+ if (flv->exheader) {
+ uint32_t codec_id = avio_rb32(s->pb);
+
+ switch(codec_id) {
+ case MKBETAG('h', 'v', 'c', '1'):
+ par->codec_id = AV_CODEC_ID_HEVC;
+ vstreami->need_parsing = AVSTREAM_PARSE_HEADERS;
+ return 4;
+ default:
+ break;
+ }
+ }
switch (flv_codecid) {
case FLV_CODECID_H263:
par->codec_id = AV_CODEC_ID_FLV1;
@@ -796,6 +825,7 @@ static int flv_read_header(AVFormatContext *s)
s->start_time = 0;
flv->sum_flv_tag_size = 0;
flv->last_keyframe_stream_index = -1;
+ flv->exheader = 0;
return 0;
}
@@ -1071,6 +1101,11 @@ retry:
} else if (type == FLV_TAG_TYPE_VIDEO) {
stream_type = FLV_STREAM_TYPE_VIDEO;
flags = avio_r8(s->pb);
+ /*
+ * Reference Enhancing FLV 2023-03-v1.0.0-B.8
+ * https://github.com/veovera/enhanced-rtmp/blob/main/enhanced-rtmp-v1.pdf
+ * */
+ flv->exheader = (flags >> 7) & 1;
size--;
if ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_VIDEO_INFO_CMD)
goto skip;
@@ -1129,7 +1164,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(s, st->codecpar, flags)))
break;
} else if (stream_type == FLV_STREAM_TYPE_SUBTITLE) {
if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE)
@@ -1230,7 +1265,7 @@ retry_duration:
avcodec_parameters_free(&par);
}
} else if (stream_type == FLV_STREAM_TYPE_VIDEO) {
- int ret = flv_set_video_codec(s, st, flags & FLV_VIDEO_CODECID_MASK, 1);
+ int ret = flv_set_video_codec(s, st, flags, 1);
if (ret < 0)
return ret;
size -= ret;
@@ -1242,9 +1277,15 @@ 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_MPEG4) {
- int type = avio_r8(s->pb);
- size--;
+ st->codecpar->codec_id == AV_CODEC_ID_MPEG4 ||
+ st->codecpar->codec_id == AV_CODEC_ID_HEVC) {
+ int type = 0;
+ if (flv->exheader) {
+ type = flags & 0x0F;
+ } else {
+ type = avio_r8(s->pb);
+ size--;
+ }
if (size < 0) {
ret = AVERROR_INVALIDDATA;
@@ -1267,7 +1308,7 @@ retry_duration:
}
}
if (type == 0 && (!st->codecpar->extradata || st->codecpar->codec_id == AV_CODEC_ID_AAC ||
- st->codecpar->codec_id == AV_CODEC_ID_H264)) {
+ st->codecpar->codec_id == AV_CODEC_ID_H264 || st->codecpar->codec_id == AV_CODEC_ID_HEVC)) {
AVDictionaryEntry *t;
if (st->codecpar->extradata) {
--
2.40.0
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 40+ messages in thread
* [FFmpeg-devel] [PATCH v7 3/4] avformat/flvenc: support mux av1 in enhanced flv
2023-04-13 6:29 ` [FFmpeg-devel] [PATCH v7 " Steven Liu
2023-04-13 6:29 ` [FFmpeg-devel] [PATCH v7 2/4] avformat/flvdec: support demux hevc in enhanced flv Steven Liu
@ 2023-04-13 6:29 ` Steven Liu
2023-04-13 6:29 ` [FFmpeg-devel] [PATCH v7 4/4] avformat/flvdec: support demux " Steven Liu
2 siblings, 0 replies; 40+ messages in thread
From: Steven Liu @ 2023-04-13 6:29 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Steven Liu
Signed-off-by: Steven Liu <lq@chinaffmpeg.org>
---
libavformat/flvenc.c | 25 ++++++++++++++++++++-----
1 file changed, 20 insertions(+), 5 deletions(-)
diff --git a/libavformat/flvenc.c b/libavformat/flvenc.c
index 57a26245ff..7b43ecaefa 100644
--- a/libavformat/flvenc.c
+++ b/libavformat/flvenc.c
@@ -28,6 +28,7 @@
#include "libavcodec/mpeg4audio.h"
#include "avio.h"
#include "avc.h"
+#include "av1.h"
#include "hevc.h"
#include "avformat.h"
#include "flv.h"
@@ -48,6 +49,7 @@ static const AVCodecTag flv_video_codec_ids[] = {
{ AV_CODEC_ID_VP6A, FLV_CODECID_VP6A },
{ AV_CODEC_ID_H264, FLV_CODECID_H264 },
{ AV_CODEC_ID_HEVC, MKBETAG('h', 'v', 'c', '1') },
+ { AV_CODEC_ID_AV1, MKBETAG('a', 'v', '0', '1') },
{ AV_CODEC_ID_NONE, 0 }
};
@@ -494,7 +496,8 @@ static void flv_write_codec_header(AVFormatContext* s, AVCodecParameters* par, i
FLVContext *flv = s->priv_data;
if (par->codec_id == AV_CODEC_ID_AAC || par->codec_id == AV_CODEC_ID_H264
- || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC) {
+ || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC
+ || par->codec_id == AV_CODEC_ID_AV1) {
int64_t pos;
avio_w8(pb,
par->codec_type == AVMEDIA_TYPE_VIDEO ?
@@ -540,6 +543,9 @@ static void flv_write_codec_header(AVFormatContext* s, AVCodecParameters* par, i
if (par->codec_id == AV_CODEC_ID_HEVC) {
avio_w8(pb, FLV_IS_EX_HEADER | PacketTypeSequenceStart); // ExVideoTagHeader mode with PacketTypeSequenceStart
avio_write(pb, "hvc1", 4);
+ } else if (par->codec_id == AV_CODEC_ID_AV1) {
+ avio_w8(pb, FLV_IS_EX_HEADER | PacketTypeSequenceStart);
+ avio_write(pb, "av01", 4);
} else {
avio_w8(pb, par->codec_tag | FLV_FRAME_KEY); // flags
avio_w8(pb, 0); // AVC sequence header
@@ -548,6 +554,8 @@ static void flv_write_codec_header(AVFormatContext* s, AVCodecParameters* par, i
if (par->codec_id == AV_CODEC_ID_HEVC)
ff_isom_write_hvcc(pb, par->extradata, par->extradata_size, 0);
+ else if (par->codec_id == AV_CODEC_ID_AV1)
+ ff_isom_write_av1c(pb, par->extradata, par->extradata_size, 1);
else
ff_isom_write_avcc(pb, par->extradata, par->extradata_size);
}
@@ -640,7 +648,8 @@ static int flv_init(struct AVFormatContext *s)
if (par->codec_id == AV_CODEC_ID_MPEG4 ||
par->codec_id == AV_CODEC_ID_H263 ||
- par->codec_id == AV_CODEC_ID_HEVC) {
+ par->codec_id == AV_CODEC_ID_HEVC ||
+ par->codec_id == AV_CODEC_ID_AV1) {
int error = s->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL;
av_log(s, error ? AV_LOG_ERROR : AV_LOG_WARNING,
"Codec %s is not supported in the official FLV specification,\n", avcodec_get_name(par->codec_id));
@@ -848,13 +857,15 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
if (par->codec_id == AV_CODEC_ID_VP6F || par->codec_id == AV_CODEC_ID_VP6A ||
par->codec_id == AV_CODEC_ID_VP6 || par->codec_id == AV_CODEC_ID_AAC)
flags_size = 2;
- else if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC)
+ else if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4 ||
+ par->codec_id == AV_CODEC_ID_HEVC || par->codec_id == AV_CODEC_ID_AV1)
flags_size = 5;
else
flags_size = 1;
if (par->codec_id == AV_CODEC_ID_AAC || par->codec_id == AV_CODEC_ID_H264
- || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC) {
+ || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC
+ || par->codec_id == AV_CODEC_ID_AV1) {
size_t side_size;
uint8_t *side = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &side_size);
if (side && side_size > 0 && (side_size != par->extradata_size || memcmp(side, par->extradata, side_size))) {
@@ -874,7 +885,8 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
"Packets are not in the proper order with respect to DTS\n");
return AVERROR(EINVAL);
}
- if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4 || par->codec_id == AV_CODEC_ID_HEVC) {
+ if (par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4 ||
+ par->codec_id == AV_CODEC_ID_HEVC || par->codec_id == AV_CODEC_ID_AV1) {
if (pkt->pts == AV_NOPTS_VALUE) {
av_log(s, AV_LOG_ERROR, "Packet is missing PTS\n");
return AVERROR(EINVAL);
@@ -987,6 +999,9 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
if (par->codec_id == AV_CODEC_ID_HEVC) {
avio_w8(pb, FLV_IS_EX_HEADER | PacketTypeCodedFramesX); // ExVideoTagHeader mode with PacketTypeCodedFramesX
avio_write(pb, "hvc1", 4);
+ } else if (par->codec_id == AV_CODEC_ID_AV1) {
+ avio_w8(pb, FLV_IS_EX_HEADER | PacketTypeCodedFrames);
+ avio_write(pb, "av01", 4);
} else {
avio_w8(pb, flags);
}
--
2.40.0
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 40+ messages in thread
* [FFmpeg-devel] [PATCH v7 4/4] avformat/flvdec: support demux av1 in enhanced flv
2023-04-13 6:29 ` [FFmpeg-devel] [PATCH v7 " Steven Liu
2023-04-13 6:29 ` [FFmpeg-devel] [PATCH v7 2/4] avformat/flvdec: support demux hevc in enhanced flv Steven Liu
2023-04-13 6:29 ` [FFmpeg-devel] [PATCH v7 3/4] avformat/flvenc: support mux av1 " Steven Liu
@ 2023-04-13 6:29 ` Steven Liu
2 siblings, 0 replies; 40+ messages in thread
From: Steven Liu @ 2023-04-13 6:29 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Steven Liu
Signed-off-by: Steven Liu <lq@chinaffmpeg.org>
---
libavformat/flvdec.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c
index 0b6218f65b..e68a6c5215 100644
--- a/libavformat/flvdec.c
+++ b/libavformat/flvdec.c
@@ -318,6 +318,8 @@ static int flv_same_video_codec(AVFormatContext *s, AVCodecParameters *vpar, int
switch(codec_id) {
case MKBETAG('h', 'v', 'c', '1'):
return vpar->codec_id == AV_CODEC_ID_HEVC;
+ case MKBETAG('a', 'v', '0', '1'):
+ return vpar->codec_id == AV_CODEC_ID_AV1;
default:
break;
}
@@ -359,6 +361,10 @@ static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream,
par->codec_id = AV_CODEC_ID_HEVC;
vstreami->need_parsing = AVSTREAM_PARSE_HEADERS;
return 4;
+ case MKBETAG('a', 'v', '0', '1'):
+ par->codec_id = AV_CODEC_ID_AV1;
+ vstreami->need_parsing = AVSTREAM_PARSE_HEADERS;
+ return 4;
default:
break;
}
@@ -1278,7 +1284,8 @@ 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_MPEG4 ||
- st->codecpar->codec_id == AV_CODEC_ID_HEVC) {
+ st->codecpar->codec_id == AV_CODEC_ID_HEVC ||
+ st->codecpar->codec_id == AV_CODEC_ID_AV1) {
int type = 0;
if (flv->exheader) {
type = flags & 0x0F;
@@ -1308,7 +1315,8 @@ retry_duration:
}
}
if (type == 0 && (!st->codecpar->extradata || 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_H264 || st->codecpar->codec_id == AV_CODEC_ID_HEVC ||
+ st->codecpar->codec_id == AV_CODEC_ID_AV1)) {
AVDictionaryEntry *t;
if (st->codecpar->extradata) {
--
2.40.0
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [FFmpeg-devel] [PATCH v6 1/4] avformat/flvenc: Add support for HEVC over flv in muxer
2023-04-13 0:41 ` [FFmpeg-devel] [PATCH v6 1/4] avformat/flvenc: Add support for HEVC over flv in muxer Jean-Baptiste Kempf
2023-04-13 6:29 ` [FFmpeg-devel] [PATCH v7 " Steven Liu
@ 2023-04-13 6:41 ` Steven Liu
1 sibling, 0 replies; 40+ messages in thread
From: Steven Liu @ 2023-04-13 6:41 UTC (permalink / raw)
To: FFmpeg development discussions and patches
Jean-Baptiste Kempf <jb@videolan.org> 于2023年4月13日周四 08:42写道:
>
> Hello,
>
> On Wed, 12 Apr 2023, at 03:30, Steven Liu wrote:
> > Implements HEVC according to Enhanced FLV spec found at
> > https://github.com/veovera/enhanced-rtmp
>
> The spec is not final, so please wait before merging this :)
> But it looks good.
>
> > libavformat/flv.h | 16 ++++++++++++
>
> > @@ -110,6 +116,16 @@ enum {
> > FLV_CODECID_H264 = 7,
> > FLV_CODECID_REALH263= 8,
> > FLV_CODECID_MPEG4 = 9,
> > + FLV_CODECID_HEVC = 10,
>
> By adding this to the enum, if there a risk that invalid streams, aka using 10 inside the bitstream get decoded too? (Instead of using the fourcc)
Okay, Just use fourcc for enhanced flv, new patchset resubmit:
https://patchwork.ffmpeg.org/project/ffmpeg/list/?series=8732
Thanks
Steven
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 40+ messages in thread
end of thread, other threads:[~2023-04-13 6:41 UTC | newest]
Thread overview: 40+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-04-06 12:12 [FFmpeg-devel] [PATCH 1/2] avformat/flvenc: Add support for HEVC over flv in muxer Steven Liu
2023-04-06 12:12 ` [FFmpeg-devel] [PATCH 2/2] avformat/flvdec: support demux HEVC in Enhancing FLV Steven Liu
2023-04-06 12:18 ` James Almer
2023-04-06 12:24 ` [FFmpeg-devel] [PATCH v2 " Steven Liu
2023-04-06 12:30 ` Martin Storsjö
2023-04-06 12:38 ` Steven Liu
2023-04-06 13:19 ` Martin Storsjö
2023-04-07 2:51 ` Steven Liu
2023-04-07 18:54 ` Martin Storsjö
2023-04-08 3:22 ` [FFmpeg-devel] [PATCH v3 1/2] avformat/flvenc: Add support for HEVC over flv in muxer Steven Liu
2023-04-08 3:22 ` [FFmpeg-devel] [PATCH v3 2/2] avformat/flvdec: support demux HEVC in Enhanced FLV Steven Liu
2023-04-06 12:30 ` [FFmpeg-devel] [PATCH 2/2] avformat/flvdec: support demux HEVC in Enhancing FLV Steven Liu
2023-04-06 14:44 ` [FFmpeg-devel] [PATCH 1/2] avformat/flvenc: Add support for HEVC over flv in muxer Lance Wang
2023-04-06 15:10 ` Gyan Doshi
2023-04-06 15:32 ` Jean-Baptiste Kempf
2023-04-06 17:03 ` Jan Ekström
2023-04-11 8:56 ` Neal Gompa
2023-04-11 9:24 ` Steven Liu
2023-04-12 1:26 ` Neal Gompa
2023-04-12 3:10 ` Steven Liu
2023-04-12 4:27 ` [FFmpeg-devel] [PATCH v4 1/4] " Steven Liu
2023-04-12 4:27 ` [FFmpeg-devel] [PATCH v4 2/4] avformat/flvdec: support demux HEVC in Enhanced FLV Steven Liu
2023-04-12 4:27 ` [FFmpeg-devel] [PATCH v4 3/4] avformat/flvenc: support mux av1 " Steven Liu
2023-04-12 4:27 ` [FFmpeg-devel] [PATCH v4 4/4] avformat/flvdec: support demux " Steven Liu
2023-04-12 4:32 ` [FFmpeg-devel] [PATCH 1/2] avformat/flvenc: Add support for HEVC over flv in muxer Steven Liu
2023-04-12 4:42 ` Steven Liu
2023-04-12 4:37 ` [FFmpeg-devel] [PATCH v5 1/4] " Steven Liu
2023-04-12 4:37 ` [FFmpeg-devel] [PATCH v5 2/4] avformat/flvdec: support demux HEVC in Enhancing FLV Steven Liu
2023-04-12 4:37 ` [FFmpeg-devel] [PATCH v5 3/4] avformat/flvenc: support mux av1 in Enhanced FLV Steven Liu
2023-04-12 4:37 ` [FFmpeg-devel] [PATCH v5 4/4] avformat/flvdec: support demux " Steven Liu
2023-04-12 7:30 ` [FFmpeg-devel] [PATCH v6 1/4] avformat/flvenc: Add support for HEVC over flv in muxer Steven Liu
2023-04-12 7:30 ` [FFmpeg-devel] [PATCH v6 2/4] avformat/flvdec: support demux HEVC in Enhancing FLV Steven Liu
2023-04-12 7:30 ` [FFmpeg-devel] [PATCH v6 3/4] avformat/flvenc: support mux av1 in Enhanced FLV Steven Liu
2023-04-12 7:31 ` [FFmpeg-devel] [PATCH v6 4/4] avformat/flvdec: support demux " Steven Liu
2023-04-13 0:41 ` [FFmpeg-devel] [PATCH v6 1/4] avformat/flvenc: Add support for HEVC over flv in muxer Jean-Baptiste Kempf
2023-04-13 6:29 ` [FFmpeg-devel] [PATCH v7 " Steven Liu
2023-04-13 6:29 ` [FFmpeg-devel] [PATCH v7 2/4] avformat/flvdec: support demux hevc in enhanced flv Steven Liu
2023-04-13 6:29 ` [FFmpeg-devel] [PATCH v7 3/4] avformat/flvenc: support mux av1 " Steven Liu
2023-04-13 6:29 ` [FFmpeg-devel] [PATCH v7 4/4] avformat/flvdec: support demux " Steven Liu
2023-04-13 6:41 ` [FFmpeg-devel] [PATCH v6 1/4] avformat/flvenc: Add support for HEVC over flv in muxer Steven Liu
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
This inbox may be cloned and mirrored by anyone:
git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git
# If you have public-inbox 1.1+ installed, you may
# initialize and index your mirror using the following commands:
public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
ffmpegdev@gitmailbox.com
public-inbox-index ffmpegdev
Example config snippet for mirrors.
AGPL code for this site: git clone https://public-inbox.org/public-inbox.git