]> git.sesse.net Git - nageru/blobdiff - nageru/video_encoder.cpp
Support --record-x264-video with AV1 HTTP output.
[nageru] / nageru / video_encoder.cpp
index 8138e76a42c99a7cf984d030ea7241423d99599d..31c6b4d8e24834d960205a3790e8dcc02169d88f 100644 (file)
@@ -12,6 +12,9 @@ extern "C" {
 }
 
 #include "audio_encoder.h"
+#ifdef HAVE_AV1
+#include "av1_encoder.h"
+#endif
 #include "defs.h"
 #include "shared/ffmpeg_raii.h"
 #include "flags.h"
@@ -61,8 +64,14 @@ VideoEncoder::VideoEncoder(ResourcePool *resource_pool, QSurface *surface, const
        if (global_flags.x264_video_to_http || global_flags.x264_video_to_disk) {
                x264_encoder.reset(new X264Encoder(oformat, /*use_separate_disk_params=*/false));
        }
-       X264Encoder *http_encoder = x264_encoder.get();
-       X264Encoder *disk_encoder = x264_encoder.get();
+       VideoCodecInterface *http_encoder = x264_encoder.get();
+       VideoCodecInterface *disk_encoder = x264_encoder.get();
+#ifdef HAVE_AV1
+       if (global_flags.av1_video_to_http) {
+               av1_encoder.reset(new AV1Encoder(oformat));
+               http_encoder = av1_encoder.get();
+       }
+#endif
        if (global_flags.x264_separate_disk_encode) {
                x264_disk_encoder.reset(new X264Encoder(oformat, /*use_separate_disk_params=*/true));
                disk_encoder = x264_disk_encoder.get();
@@ -77,6 +86,11 @@ VideoEncoder::VideoEncoder(ResourcePool *resource_pool, QSurface *surface, const
        if (global_flags.x264_video_to_http) {
                x264_encoder->add_mux(stream_mux.get());
        }
+#ifdef HAVE_AV1
+       if (global_flags.av1_video_to_http) {
+               av1_encoder->add_mux(stream_mux.get());
+       }
+#endif
 }
 
 VideoEncoder::~VideoEncoder()
@@ -191,7 +205,7 @@ RefCountedGLsync VideoEncoder::end_frame()
 void VideoEncoder::open_output_stream()
 {
        AVFormatContext *avctx = avformat_alloc_context();
-       avctx->oformat = oformat;
+       avctx->oformat = const_cast<decltype(avctx->oformat)>(oformat);  // const_cast is a hack to work in FFmpeg both before and after 5.0.
 
        uint8_t *buf = (uint8_t *)av_malloc(MUX_BUFFER_SIZE);
        avctx->pb = avio_alloc_context(buf, MUX_BUFFER_SIZE, 1, this, nullptr, nullptr, nullptr);
@@ -201,6 +215,8 @@ void VideoEncoder::open_output_stream()
        Mux::Codec video_codec;
        if (global_flags.uncompressed_video_to_http) {
                video_codec = Mux::CODEC_NV12;
+       } else if (global_flags.av1_video_to_http) {
+               video_codec = Mux::CODEC_AV1;
        } else {
                video_codec = Mux::CODEC_H264;
        }
@@ -208,8 +224,12 @@ void VideoEncoder::open_output_stream()
        avctx->flags = AVFMT_FLAG_CUSTOM_IO;
 
        string video_extradata;
-       if (global_flags.x264_video_to_http || global_flags.x264_video_to_disk) {
+       if (global_flags.x264_video_to_http) {
                video_extradata = x264_encoder->get_global_headers();
+#ifdef HAVE_AV1
+       } else if (global_flags.av1_video_to_http) {
+               video_extradata = av1_encoder->get_global_headers();
+#endif
        }
 
        stream_mux.reset(new Mux(avctx, width, height, video_codec, video_extradata, stream_audio_encoder->get_codec_parameters().get(),