From 2804eb55c7d4f9f6d70203d106d0f1e69b19c2ee Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Sat, 23 Apr 2016 23:32:42 +0200 Subject: [PATCH] Fix a circular initialization issue with AudioEncoder. --- audio_encoder.cpp | 3 +-- audio_encoder.h | 5 ++++- quicksync_encoder.cpp | 36 ++++++++++++------------------------ quicksync_encoder.h | 6 +----- video_encoder.cpp | 8 +++----- 5 files changed, 21 insertions(+), 37 deletions(-) diff --git a/audio_encoder.cpp b/audio_encoder.cpp index 7f14d40..2b735e4 100644 --- a/audio_encoder.cpp +++ b/audio_encoder.cpp @@ -21,8 +21,7 @@ extern "C" { using namespace std; -AudioEncoder::AudioEncoder(const string &codec_name, int bit_rate, const vector &muxes) - : muxes(muxes) +AudioEncoder::AudioEncoder(const string &codec_name, int bit_rate) { AVCodec *codec = avcodec_find_encoder_by_name(codec_name.c_str()); if (codec == nullptr) { diff --git a/audio_encoder.h b/audio_encoder.h index c49cf9f..682cc47 100644 --- a/audio_encoder.h +++ b/audio_encoder.h @@ -16,9 +16,12 @@ extern "C" { class AudioEncoder { public: - AudioEncoder(const std::string &codec_name, int bit_rate, const std::vector &muxes); + AudioEncoder(const std::string &codec_name, int bit_rate); ~AudioEncoder(); + void add_mux(Mux *mux) { // Does not take ownership. + muxes.push_back(mux); + } void encode_audio(const std::vector &audio, int64_t audio_pts); void encode_last_audio(); diff --git a/quicksync_encoder.cpp b/quicksync_encoder.cpp index b2316da..b3a832c 100644 --- a/quicksync_encoder.cpp +++ b/quicksync_encoder.cpp @@ -193,14 +193,12 @@ FrameReorderer::Frame FrameReorderer::get_first_frame() class QuickSyncEncoderImpl { public: - QuickSyncEncoderImpl(QSurface *surface, const string &va_display, int width, int height, Mux *stream_mux); + QuickSyncEncoderImpl(const std::string &filename, QSurface *surface, const string &va_display, int width, int height, Mux *stream_mux); ~QuickSyncEncoderImpl(); void add_audio(int64_t pts, vector audio); bool begin_frame(GLuint *y_tex, GLuint *cbcr_tex); RefCountedGLsync end_frame(int64_t pts, int64_t duration, const vector &input_frames); void shutdown(); - void open_output_file(const std::string &filename); - void close_output_file(); private: struct storage_task { @@ -220,6 +218,7 @@ private: return int64_t(ip_period - 1) * (TIMEBASE / MAX_FPS); } + void open_output_file(const std::string &filename); void encode_thread_func(); void encode_remaining_frames_as_p(int encoding_frame_num, int gop_start_display_frame_num, int64_t last_dts); void add_packet_for_uncompressed_frame(int64_t pts, int64_t duration, const uint8_t *data); @@ -1733,14 +1732,17 @@ namespace { } // namespace -QuickSyncEncoderImpl::QuickSyncEncoderImpl(QSurface *surface, const string &va_display, int width, int height, Mux *stream_mux) +QuickSyncEncoderImpl::QuickSyncEncoderImpl(const std::string &filename, QSurface *surface, const string &va_display, int width, int height, Mux *stream_mux) : current_storage_frame(0), surface(surface), 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); + file_audio_encoder->add_mux(file_mux.get()); if (global_flags.stream_audio_codec_name.empty()) { - file_audio_encoder.reset(new AudioEncoder(AUDIO_OUTPUT_CODEC_NAME, DEFAULT_AUDIO_OUTPUT_BIT_RATE, { file_mux.get(), stream_mux })); + file_audio_encoder->add_mux(stream_mux); } else { - file_audio_encoder.reset(new AudioEncoder(AUDIO_OUTPUT_CODEC_NAME, DEFAULT_AUDIO_OUTPUT_BIT_RATE, { file_mux.get() })); - stream_audio_encoder.reset(new AudioEncoder(global_flags.stream_audio_codec_name, global_flags.stream_audio_codec_bitrate, { stream_mux })); + stream_audio_encoder.reset(new AudioEncoder(global_flags.stream_audio_codec_name, global_flags.stream_audio_codec_bitrate)); + stream_audio_encoder->add_mux(stream_mux); } frame_width_mbaligned = (frame_width + 15) & (~15); @@ -1937,6 +1939,7 @@ void QuickSyncEncoderImpl::shutdown() release_encode(); deinit_va(); + file_mux.reset(); is_shutdown = true; } @@ -1958,11 +1961,6 @@ void QuickSyncEncoderImpl::open_output_file(const std::string &filename) file_mux.reset(new Mux(avctx, frame_width, frame_height, Mux::CODEC_H264, file_audio_encoder->get_codec(), TIMEBASE, DEFAULT_AUDIO_OUTPUT_BIT_RATE, nullptr)); } -void QuickSyncEncoderImpl::close_output_file() -{ - file_mux.reset(); -} - void QuickSyncEncoderImpl::encode_thread_func() { int64_t last_dts = -1; @@ -2183,8 +2181,8 @@ void QuickSyncEncoderImpl::encode_frame(QuickSyncEncoderImpl::PendingFrame frame } // Proxy object. -QuickSyncEncoder::QuickSyncEncoder(QSurface *surface, const string &va_display, int width, int height, Mux *stream_mux) - : impl(new QuickSyncEncoderImpl(surface, va_display, width, height, stream_mux)) {} +QuickSyncEncoder::QuickSyncEncoder(const std::string &filename, QSurface *surface, const string &va_display, int width, int height, Mux *stream_mux) + : impl(new QuickSyncEncoderImpl(filename, surface, va_display, width, height, stream_mux)) {} // Must be defined here because unique_ptr<> destructor needs to know the impl. QuickSyncEncoder::~QuickSyncEncoder() {} @@ -2208,13 +2206,3 @@ void QuickSyncEncoder::shutdown() { impl->shutdown(); } - -void QuickSyncEncoder::open_output_file(const std::string &filename) -{ - impl->open_output_file(filename); -} - -void QuickSyncEncoder::close_output_file() -{ - impl->close_output_file(); -} diff --git a/quicksync_encoder.h b/quicksync_encoder.h index 495ddae..994987e 100644 --- a/quicksync_encoder.h +++ b/quicksync_encoder.h @@ -45,7 +45,7 @@ class QSurface; // .cpp file. class QuickSyncEncoder { public: - QuickSyncEncoder(QSurface *surface, const std::string &va_display, int width, int height, Mux *stream_mux); + QuickSyncEncoder(const std::string &filename, QSurface *surface, const std::string &va_display, int width, int height, Mux *stream_mux); ~QuickSyncEncoder(); void add_audio(int64_t pts, std::vector audio); @@ -53,10 +53,6 @@ public: RefCountedGLsync end_frame(int64_t pts, int64_t duration, const std::vector &input_frames); void shutdown(); // Blocking. - // You can only have one going at the same time. - void open_output_file(const std::string &filename); - void close_output_file(); - private: std::unique_ptr impl; }; diff --git a/video_encoder.cpp b/video_encoder.cpp index 8fd9723..ed9a93e 100644 --- a/video_encoder.cpp +++ b/video_encoder.cpp @@ -38,8 +38,8 @@ VideoEncoder::VideoEncoder(QSurface *surface, const std::string &va_display, int { open_output_stream(); - quicksync_encoder.reset(new QuickSyncEncoder(surface, va_display, width, height, stream_mux.get())); - quicksync_encoder->open_output_file(generate_local_dump_filename(/*frame=*/0).c_str()); + string filename = generate_local_dump_filename(/*frame=*/0); + quicksync_encoder.reset(new QuickSyncEncoder(filename, surface, va_display, width, height, stream_mux.get())); } VideoEncoder::~VideoEncoder() @@ -52,10 +52,8 @@ void VideoEncoder::do_cut(int frame) { string filename = generate_local_dump_filename(frame); printf("Starting new recording: %s\n", filename.c_str()); - quicksync_encoder->close_output_file(); quicksync_encoder->shutdown(); - quicksync_encoder.reset(new QuickSyncEncoder(surface, va_display, width, height, stream_mux.get())); - quicksync_encoder->open_output_file(filename.c_str()); + quicksync_encoder.reset(new QuickSyncEncoder(filename, surface, va_display, width, height, stream_mux.get())); } void VideoEncoder::add_audio(int64_t pts, std::vector audio) -- 2.39.2