This will be useful when adding more video codecs later.
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);
//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();
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();
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());
}
}
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) {
}
// 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.
class QSurface;
class QuickSyncEncoderImpl;
class RefCountedFrame;
-class X264Encoder;
+class VideoCodecInterface;
namespace movit {
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.
}
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;
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.
--- /dev/null
+// 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)
#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();
}