X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=quicksync_encoder.cpp;h=7d211798a504d07e91137e77a77815732ebad3a1;hb=1462715cd71d8f61b9e53b31c34d591d150f2df3;hp=b2316dab550235b8ac9c6f5a2ec944b94d9c1823;hpb=8e3e40723b72bbf0c233167cee60b4959d6b08e7;p=nageru diff --git a/quicksync_encoder.cpp b/quicksync_encoder.cpp index b2316da..7d21179 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, AudioEncoder *stream_audio_encoder); ~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); @@ -274,7 +273,7 @@ private: QSurface *surface; unique_ptr file_audio_encoder; - unique_ptr stream_audio_encoder; + AudioEncoder *stream_audio_encoder; Mux* stream_mux; // To HTTP. unique_ptr file_mux; // To local disk. @@ -1652,9 +1651,7 @@ void QuickSyncEncoderImpl::save_codeddata(storage_task task) } file_audio_encoder->encode_audio(audio, audio_pts + global_delay()); - if (stream_audio_encoder) { - stream_audio_encoder->encode_audio(audio, audio_pts + global_delay()); - } + stream_audio_encoder->encode_audio(audio, audio_pts + global_delay()); if (audio_pts == task.pts) break; } @@ -1733,15 +1730,12 @@ namespace { } // namespace -QuickSyncEncoderImpl::QuickSyncEncoderImpl(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) +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) { - 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 })); - } 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 })); - } + 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()); frame_width_mbaligned = (frame_width + 15) & (~15); frame_height_mbaligned = (frame_height + 15) & (~15); @@ -1937,6 +1931,7 @@ void QuickSyncEncoderImpl::shutdown() release_encode(); deinit_va(); + file_mux.reset(); is_shutdown = true; } @@ -1958,11 +1953,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; @@ -2058,10 +2048,8 @@ void QuickSyncEncoderImpl::encode_remaining_audio() pending_audio_frames.clear(); // Encode any leftover audio in the queues, and also any delayed frames. + // Note: stream_audio_encoder is not owned by us, so don't call encode_last_audio(). file_audio_encoder->encode_last_audio(); - if (stream_audio_encoder) { - stream_audio_encoder->encode_last_audio(); - } } void QuickSyncEncoderImpl::add_packet_for_uncompressed_frame(int64_t pts, int64_t duration, const uint8_t *data) @@ -2183,8 +2171,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, AudioEncoder *stream_audio_encoder) + : impl(new QuickSyncEncoderImpl(filename, surface, va_display, width, height, stream_mux, stream_audio_encoder)) {} // Must be defined here because unique_ptr<> destructor needs to know the impl. QuickSyncEncoder::~QuickSyncEncoder() {} @@ -2208,13 +2196,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(); -}