diff mbox series

[FFmpeg-devel,v6,3/4] avformat/flvenc: support mux av1 in Enhanced FLV

Message ID 20230412073100.53743-3-lq@chinaffmpeg.org
State New
Headers show
Series [FFmpeg-devel,v6,1/4] avformat/flvenc: Add support for HEVC over flv in muxer | expand

Checks

Context Check Description
yinshiyou/make_loongarch64 success Make finished
yinshiyou/make_fate_loongarch64 success Make fate finished
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished

Commit Message

Liu Steven April 12, 2023, 7:30 a.m. UTC
Signed-off-by: Steven Liu <lq@chinaffmpeg.org>
---
 libavformat/flv.h    |  1 +
 libavformat/flvenc.c | 32 ++++++++++++++++++++++++++------
 2 files changed, 27 insertions(+), 6 deletions(-)
diff mbox series

Patch

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);
         }