From: Steinar H. Gunderson Date: Sat, 23 Apr 2016 21:45:39 +0000 (+0200) Subject: Move X264Encoder out of QuickSyncEncoder. This completes independent restart of the... X-Git-Tag: 1.3.0~58 X-Git-Url: https://git.sesse.net/?p=nageru;a=commitdiff_plain;h=3f34da3ebb9a6fd1ed267f9186d17433321a9214 Move X264Encoder out of QuickSyncEncoder. This completes independent restart of the file mux from the stream (sans bugs). --- diff --git a/quicksync_encoder.cpp b/quicksync_encoder.cpp index 7d21179..41ace54 100644 --- a/quicksync_encoder.cpp +++ b/quicksync_encoder.cpp @@ -193,7 +193,7 @@ FrameReorderer::Frame FrameReorderer::get_first_frame() class QuickSyncEncoderImpl { public: - QuickSyncEncoderImpl(const std::string &filename, QSurface *surface, const string &va_display, int width, int height, Mux *stream_mux, AudioEncoder *stream_audio_encoder); + QuickSyncEncoderImpl(const std::string &filename, QSurface *surface, const string &va_display, int width, int height, Mux *stream_mux, AudioEncoder *stream_audio_encoder, X264Encoder *x264_encoder); ~QuickSyncEncoderImpl(); void add_audio(int64_t pts, vector audio); bool begin_frame(GLuint *y_tex, GLuint *cbcr_tex); @@ -275,12 +275,12 @@ private: unique_ptr file_audio_encoder; AudioEncoder *stream_audio_encoder; + unique_ptr reorderer; + X264Encoder *x264_encoder; // nullptr if not using x264. + Mux* stream_mux; // To HTTP. unique_ptr file_mux; // To local disk. - unique_ptr reorderer; - unique_ptr x264_encoder; // nullptr if not using x264. - Display *x11_display = nullptr; // Encoder parameters @@ -1730,8 +1730,8 @@ namespace { } // namespace -QuickSyncEncoderImpl::QuickSyncEncoderImpl(const std::string &filename, QSurface *surface, const string &va_display, int width, int height, Mux *stream_mux, AudioEncoder *stream_audio_encoder) - : current_storage_frame(0), surface(surface), stream_audio_encoder(stream_audio_encoder), stream_mux(stream_mux), frame_width(width), frame_height(height) +QuickSyncEncoderImpl::QuickSyncEncoderImpl(const std::string &filename, QSurface *surface, const string &va_display, int width, int height, Mux *stream_mux, AudioEncoder *stream_audio_encoder, X264Encoder *x264_encoder) + : current_storage_frame(0), surface(surface), stream_audio_encoder(stream_audio_encoder), x264_encoder(x264_encoder), stream_mux(stream_mux), frame_width(width), frame_height(height) { file_audio_encoder.reset(new AudioEncoder(AUDIO_OUTPUT_CODEC_NAME, DEFAULT_AUDIO_OUTPUT_BIT_RATE)); open_output_file(filename); @@ -1747,7 +1747,9 @@ QuickSyncEncoderImpl::QuickSyncEncoderImpl(const std::string &filename, QSurface reorderer.reset(new FrameReorderer(ip_period - 1, frame_width, frame_height)); } if (global_flags.x264_video_to_http) { - x264_encoder.reset(new X264Encoder(stream_mux)); + assert(x264_encoder != nullptr); + } else { + assert(x264_encoder == nullptr); } init_va(va_display); @@ -1919,7 +1921,6 @@ void QuickSyncEncoderImpl::shutdown() frame_queue_nonempty.notify_all(); } encode_thread.join(); - x264_encoder.reset(); { unique_lock lock(storage_task_queue_mutex); storage_thread_should_quit = true; @@ -2171,8 +2172,8 @@ void QuickSyncEncoderImpl::encode_frame(QuickSyncEncoderImpl::PendingFrame frame } // Proxy object. -QuickSyncEncoder::QuickSyncEncoder(const std::string &filename, QSurface *surface, const string &va_display, int width, int height, Mux *stream_mux, AudioEncoder *stream_audio_encoder) - : impl(new QuickSyncEncoderImpl(filename, surface, va_display, width, height, stream_mux, stream_audio_encoder)) {} +QuickSyncEncoder::QuickSyncEncoder(const std::string &filename, QSurface *surface, const string &va_display, int width, int height, Mux *stream_mux, AudioEncoder *stream_audio_encoder, X264Encoder *x264_encoder) + : impl(new QuickSyncEncoderImpl(filename, surface, va_display, width, height, stream_mux, stream_audio_encoder, x264_encoder)) {} // Must be defined here because unique_ptr<> destructor needs to know the impl. QuickSyncEncoder::~QuickSyncEncoder() {} diff --git a/quicksync_encoder.h b/quicksync_encoder.h index 9ec7c85..40bf15e 100644 --- a/quicksync_encoder.h +++ b/quicksync_encoder.h @@ -40,13 +40,14 @@ class AudioEncoder; class Mux; class QuickSyncEncoderImpl; class QSurface; +class X264Encoder; // This is just a pimpl, because including anything X11-related in a .h file // tends to trip up Qt. All the real logic is in QuickSyncEncoderImpl, defined in the // .cpp file. class QuickSyncEncoder { public: - QuickSyncEncoder(const std::string &filename, QSurface *surface, const std::string &va_display, int width, int height, Mux *stream_mux, AudioEncoder *stream_audio_encoder); + QuickSyncEncoder(const std::string &filename, QSurface *surface, const std::string &va_display, int width, int height, Mux *stream_mux, AudioEncoder *stream_audio_encoder, X264Encoder *x264_encoder); ~QuickSyncEncoder(); void add_audio(int64_t pts, std::vector audio); diff --git a/video_encoder.cpp b/video_encoder.cpp index 0df3b4f..2576529 100644 --- a/video_encoder.cpp +++ b/video_encoder.cpp @@ -9,6 +9,7 @@ #include "httpd.h" #include "timebase.h" #include "quicksync_encoder.h" +#include "x264_encoder.h" using namespace std; @@ -45,8 +46,12 @@ VideoEncoder::VideoEncoder(QSurface *surface, const std::string &va_display, int } stream_audio_encoder->add_mux(stream_mux.get()); + if (global_flags.x264_video_to_http) { + x264_encoder.reset(new X264Encoder(stream_mux.get())); + } + string filename = generate_local_dump_filename(/*frame=*/0); - quicksync_encoder.reset(new QuickSyncEncoder(filename, surface, va_display, width, height, stream_mux.get(), stream_audio_encoder.get())); + quicksync_encoder.reset(new QuickSyncEncoder(filename, surface, va_display, width, height, stream_mux.get(), stream_audio_encoder.get(), x264_encoder.get())); } VideoEncoder::~VideoEncoder() @@ -60,7 +65,7 @@ void VideoEncoder::do_cut(int frame) string filename = generate_local_dump_filename(frame); printf("Starting new recording: %s\n", filename.c_str()); quicksync_encoder->shutdown(); - quicksync_encoder.reset(new QuickSyncEncoder(filename, surface, va_display, width, height, stream_mux.get(), stream_audio_encoder.get())); + quicksync_encoder.reset(new QuickSyncEncoder(filename, surface, va_display, width, height, stream_mux.get(), stream_audio_encoder.get(), x264_encoder.get())); } void VideoEncoder::add_audio(int64_t pts, std::vector audio) diff --git a/video_encoder.h b/video_encoder.h index bf203f1..81c4899 100644 --- a/video_encoder.h +++ b/video_encoder.h @@ -18,6 +18,7 @@ class HTTPD; class QSurface; class QuickSyncEncoder; +class X264Encoder; class VideoEncoder : public KeyFrameSignalReceiver { public: @@ -49,6 +50,7 @@ private: std::unique_ptr stream_mux; // To HTTP. std::unique_ptr stream_audio_encoder; + std::unique_ptr x264_encoder; // nullptr if not using x264. // While Mux object is constructing, is true, // and the header is being collected into stream_mux_header.