]> git.sesse.net Git - nageru/commitdiff
Make an interface to wrap X264Encoder.
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Tue, 19 Jul 2022 12:21:13 +0000 (14:21 +0200)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Tue, 19 Jul 2022 12:30:49 +0000 (14:30 +0200)
This will be useful when adding more video codecs later.

nageru/quicksync_encoder.cpp
nageru/quicksync_encoder.h
nageru/quicksync_encoder_impl.h
nageru/video_codec_interface.h [new file with mode: 0644]
nageru/x264_encoder.h

index c1621892178c562b70a19b4c4b1be9cf320024ca..19565ad506263112aae7768ef169c0b059fbc127 100644 (file)
@@ -1435,8 +1435,8 @@ void QuickSyncEncoderImpl::release_gl_resources()
        has_released_gl_resources = true;
 }
 
-QuickSyncEncoderImpl::QuickSyncEncoderImpl(const std::string &filename, ResourcePool *resource_pool, QSurface *surface, const string &va_display, int width, int height, const AVOutputFormat *oformat, X264Encoder *http_encoder, X264Encoder *disk_encoder, DiskSpaceEstimator *disk_space_estimator)
-       : current_storage_frame(0), resource_pool(resource_pool), surface(surface), x264_http_encoder(http_encoder), x264_disk_encoder(disk_encoder), frame_width(width), frame_height(height), disk_space_estimator(disk_space_estimator)
+QuickSyncEncoderImpl::QuickSyncEncoderImpl(const std::string &filename, ResourcePool *resource_pool, QSurface *surface, const string &va_display, int width, int height, const AVOutputFormat *oformat, VideoCodecInterface *http_encoder, VideoCodecInterface *disk_encoder, DiskSpaceEstimator *disk_space_estimator)
+       : current_storage_frame(0), resource_pool(resource_pool), surface(surface), http_encoder(http_encoder), disk_encoder(disk_encoder), frame_width(width), frame_height(height), disk_space_estimator(disk_space_estimator)
 {
        file_audio_encoder.reset(new AudioEncoder(AUDIO_OUTPUT_CODEC_NAME, DEFAULT_AUDIO_OUTPUT_BIT_RATE, oformat));
        open_output_file(filename);
@@ -1448,11 +1448,11 @@ QuickSyncEncoderImpl::QuickSyncEncoderImpl(const std::string &filename, Resource
        //print_input();
 
        if (global_flags.x264_video_to_http || global_flags.x264_video_to_disk) {
-               assert(x264_http_encoder != nullptr);
-               assert(x264_disk_encoder != nullptr);
+               assert(http_encoder != nullptr);
+               assert(disk_encoder != nullptr);
        } else {
-               assert(x264_http_encoder == nullptr);
-               assert(x264_disk_encoder == nullptr);
+               assert(http_encoder == nullptr);
+               assert(disk_encoder == nullptr);
        }
 
        enable_zerocopy_if_possible();
@@ -1733,7 +1733,7 @@ void QuickSyncEncoderImpl::open_output_file(const std::string &filename)
 
        string video_extradata;  // FIXME: See other comment about global headers.
        if (global_flags.x264_video_to_disk) {
-               video_extradata = x264_disk_encoder->get_global_headers();
+               video_extradata = disk_encoder->get_global_headers();
        }
 
        current_file_mux_metrics.reset();
@@ -1749,7 +1749,7 @@ void QuickSyncEncoderImpl::open_output_file(const std::string &filename)
        metric_current_file_start_time_seconds = get_timestamp_for_metrics();
 
        if (global_flags.x264_video_to_disk) {
-               x264_disk_encoder->add_mux(file_mux.get());
+               disk_encoder->add_mux(file_mux.get());
        }
 }
 
@@ -1912,10 +1912,10 @@ void QuickSyncEncoderImpl::pass_frame(QuickSyncEncoderImpl::PendingFrame frame,
        if (global_flags.uncompressed_video_to_http) {
                add_packet_for_uncompressed_frame(pts, duration, data);
        } else if (global_flags.x264_video_to_http || global_flags.x264_video_to_disk) {
-               x264_http_encoder->add_frame(pts, duration, frame.ycbcr_coefficients, data, received_ts);
+               http_encoder->add_frame(pts, duration, frame.ycbcr_coefficients, data, received_ts);
        }
        if (global_flags.x264_separate_disk_encode) {
-               x264_disk_encoder->add_frame(pts, duration, frame.ycbcr_coefficients, data, received_ts);
+               disk_encoder->add_frame(pts, duration, frame.ycbcr_coefficients, data, received_ts);
        }
 
        if (v4l_output != nullptr) {
@@ -2017,7 +2017,7 @@ void QuickSyncEncoderImpl::encode_frame(QuickSyncEncoderImpl::PendingFrame frame
 }
 
 // Proxy object.
-QuickSyncEncoder::QuickSyncEncoder(const std::string &filename, ResourcePool *resource_pool, QSurface *surface, const string &va_display, int width, int height, const AVOutputFormat *oformat, X264Encoder *http_encoder, X264Encoder *disk_encoder, DiskSpaceEstimator *disk_space_estimator)
+QuickSyncEncoder::QuickSyncEncoder(const std::string &filename, ResourcePool *resource_pool, QSurface *surface, const string &va_display, int width, int height, const AVOutputFormat *oformat, VideoCodecInterface *http_encoder, VideoCodecInterface *disk_encoder, DiskSpaceEstimator *disk_space_estimator)
        : impl(new QuickSyncEncoderImpl(filename, resource_pool, surface, va_display, width, height, oformat, http_encoder, disk_encoder, disk_space_estimator)) {}
 
 // Must be defined here because unique_ptr<> destructor needs to know the impl.
index 97109ce48ebb6bf985eb406d347c63576ae19716..9f59c2c929b124d01666365a1ac9c551fc59f44a 100644 (file)
@@ -50,7 +50,7 @@ class Mux;
 class QSurface;
 class QuickSyncEncoderImpl;
 class RefCountedFrame;
-class X264Encoder;
+class VideoCodecInterface;
 
 namespace movit {
 class ResourcePool;
@@ -63,7 +63,7 @@ class ResourcePool;
 // This class is _not_ thread-safe, except where mentioned.
 class QuickSyncEncoder {
 public:
-        QuickSyncEncoder(const std::string &filename, movit::ResourcePool *resource_pool, QSurface *surface, const std::string &va_display, int width, int height, const AVOutputFormat *oformat, X264Encoder *http_encoder, X264Encoder *disk_encoder, DiskSpaceEstimator *disk_space_estimator);
+        QuickSyncEncoder(const std::string &filename, movit::ResourcePool *resource_pool, QSurface *surface, const std::string &va_display, int width, int height, const AVOutputFormat *oformat, VideoCodecInterface *http_encoder, VideoCodecInterface *disk_encoder, DiskSpaceEstimator *disk_space_estimator);
         ~QuickSyncEncoder();
 
        void set_stream_mux(Mux *mux);  // Does not take ownership. Must be called unless x264 is used for the stream.
index 50741152f4a11801f613af5986eb1793a6480ff1..3d777dcf578034756f36c7fd44e8e169f8a58c04 100644 (file)
@@ -39,11 +39,11 @@ class ResourcePool;
 }
 class DiskSpaceEstimator;
 class QSurface;
-class X264Encoder;
+class VideoCodecInterface;
 
 class QuickSyncEncoderImpl {
 public:
-       QuickSyncEncoderImpl(const std::string &filename, movit::ResourcePool *resource_pool, QSurface *surface, const std::string &va_display, int width, int height, const AVOutputFormat *oformat, X264Encoder *http_encoder, X264Encoder *disk_encoder, DiskSpaceEstimator *disk_space_estimator);
+       QuickSyncEncoderImpl(const std::string &filename, movit::ResourcePool *resource_pool, QSurface *surface, const std::string &va_display, int width, int height, const AVOutputFormat *oformat, VideoCodecInterface *http_encoder, VideoCodecInterface *disk_encoder, DiskSpaceEstimator *disk_space_estimator);
        ~QuickSyncEncoderImpl();
        void add_audio(int64_t pts, std::vector<float> audio);
        bool is_zerocopy() const;
@@ -171,8 +171,8 @@ private:
        std::mutex file_audio_encoder_mutex;
        std::unique_ptr<AudioEncoder> file_audio_encoder;
 
-       X264Encoder *x264_http_encoder;  // nullptr if not using x264.
-       X264Encoder *x264_disk_encoder;
+       VideoCodecInterface *http_encoder;  // nullptr if not using x264.
+       VideoCodecInterface *disk_encoder;
        std::unique_ptr<V4LOutput> v4l_output;  // nullptr if not using V4L2 output.
 
        Mux* stream_mux = nullptr;  // To HTTP.
diff --git a/nageru/video_codec_interface.h b/nageru/video_codec_interface.h
new file mode 100644 (file)
index 0000000..00524d7
--- /dev/null
@@ -0,0 +1,32 @@
+// Common interface for low-level video codecs. Not to be confused
+// with VideoEncoder (which is a higher-level orchestration class).
+
+#ifndef _VIDEO_CODEC_INTERFACE_H
+#define _VIDEO_CODEC_INTERFACE_H 1
+
+#include <stdint.h>
+#include <string>
+
+#include <movit/image_format.h>
+
+#include "print_latency.h"
+
+class Mux;
+
+class VideoCodecInterface {
+public:
+       // Called after the last frame. Will block; once this returns,
+       // the last data is flushed.
+       virtual ~VideoCodecInterface() {}
+
+       // Must be called before first frame. Does not take ownership.
+       virtual void add_mux(Mux *mux) = 0;
+
+       // <data> is taken to be raw NV12 data of WIDTHxHEIGHT resolution.
+       // Does not block.
+       virtual void add_frame(int64_t pts, int64_t duration, movit::YCbCrLumaCoefficients ycbcr_coefficients, const uint8_t *data, const ReceivedTimestamps &received_ts) = 0;
+
+       virtual std::string get_global_headers() const = 0;
+};
+
+#endif  // !defined(_VIDEO_CODEC_INTERFACE_H)
index 3aeca64a6ca92a4efb0aed021dea22b5c5847a3f..d767ac3942c5db5d2212bf7a49b8abdb70294867 100644 (file)
@@ -35,27 +35,28 @@ extern "C" {
 #include "defs.h"
 #include "shared/metrics.h"
 #include "print_latency.h"
+#include "video_codec_interface.h"
 #include "x264_dynamic.h"
 
 class Mux;
 class X264SpeedControl;
 
-class X264Encoder {
+class X264Encoder : public VideoCodecInterface {
 public:
        X264Encoder(const AVOutputFormat *oformat, bool use_separate_disk_params);  // Does not take ownership.
 
        // Called after the last frame. Will block; once this returns,
        // the last data is flushed.
-       ~X264Encoder();
+       ~X264Encoder() override;
 
        // Must be called before first frame. Does not take ownership.
-       void add_mux(Mux *mux) { muxes.push_back(mux); }
+       void add_mux(Mux *mux) override { muxes.push_back(mux); }
 
        // <data> is taken to be raw NV12 data of WIDTHxHEIGHT resolution.
        // Does not block.
-       void add_frame(int64_t pts, int64_t duration, movit::YCbCrLumaCoefficients ycbcr_coefficients, const uint8_t *data, const ReceivedTimestamps &received_ts);
+       void add_frame(int64_t pts, int64_t duration, movit::YCbCrLumaCoefficients ycbcr_coefficients, const uint8_t *data, const ReceivedTimestamps &received_ts) override;
 
-       std::string get_global_headers() const {
+       std::string get_global_headers() const override {
                while (!x264_init_done) {
                        sched_yield();
                }