diff --git a/app/codec/encoder.h b/app/codec/encoder.h index e6a8fb76e..3b7bfdb39 100644 --- a/app/codec/encoder.h +++ b/app/codec/encoder.h @@ -6,6 +6,7 @@ #include "codec/frame.h" #include "common/constructors.h" +#include "common/timerange.h" #include "render/audioparams.h" #include "render/videoparams.h" @@ -82,7 +83,7 @@ public: public slots: void Open(); void WriteFrame(FramePtr frame); - virtual void WriteAudio(const AudioRenderingParams& pcm_info, const QString& pcm_filename) = 0; + virtual void WriteAudio(const AudioRenderingParams& pcm_info, const QString& pcm_filename, const TimeRange &range) = 0; void Close(); signals: diff --git a/app/codec/ffmpeg/ffmpegencoder.cpp b/app/codec/ffmpeg/ffmpegencoder.cpp index b837d0f7f..97c7bdda0 100644 --- a/app/codec/ffmpeg/ffmpegencoder.cpp +++ b/app/codec/ffmpeg/ffmpegencoder.cpp @@ -17,7 +17,7 @@ FFmpegEncoder::FFmpegEncoder(const EncodingParams ¶ms) : { } -void FFmpegEncoder::WriteAudio(const AudioRenderingParams &pcm_info, const QString &pcm_filename) +void FFmpegEncoder::WriteAudio(const AudioRenderingParams &pcm_info, const QString &pcm_filename, const TimeRange& range) { QFile pcm(pcm_filename); if (pcm.open(QFile::ReadOnly)) { @@ -60,11 +60,25 @@ void FFmpegEncoder::WriteAudio(const AudioRenderingParams &pcm_info, const QStri av_frame_get_buffer(frame, 0); int sample_counter = 0; - while (!pcm.atEnd()) { + // Go to start range if one was set + if (range.in() > 0) { + pcm.seek(pcm_info.time_to_bytes(range.in())); + } + + int end_in_bytes = pcm_info.time_to_bytes(range.out()); + + while (true) { int samples_needed = static_cast(frame->nb_samples + swr_get_delay(swr_ctx, pcm_info.sample_rate())); + int max_read = pcm_info.samples_to_bytes(samples_needed); + + // Limit read to end if necessary + if (pcm.pos() + max_read > end_in_bytes) { + max_read = end_in_bytes - pcm.pos(); + } + QByteArray input_data; - input_data = pcm.read(pcm_info.samples_to_bytes(samples_needed)); + input_data = pcm.read(max_read); const char* input_data_array = input_data.constData(); samples_needed = pcm_info.bytes_to_samples(input_data.size()); @@ -80,6 +94,10 @@ void FFmpegEncoder::WriteAudio(const AudioRenderingParams &pcm_info, const QStri sample_counter += converted; WriteAVFrame(frame, audio_codec_ctx_, audio_stream_); + + if (pcm.atEnd() || pcm.pos() == end_in_bytes) { + break; + } } av_frame_free(&frame); diff --git a/app/codec/ffmpeg/ffmpegencoder.h b/app/codec/ffmpeg/ffmpegencoder.h index 6bd59e734..4fcac8bc0 100644 --- a/app/codec/ffmpeg/ffmpegencoder.h +++ b/app/codec/ffmpeg/ffmpegencoder.h @@ -17,7 +17,7 @@ public: FFmpegEncoder(const EncodingParams ¶ms); public slots: - virtual void WriteAudio(const AudioRenderingParams& pcm_info, const QString& pcm_filename) override; + virtual void WriteAudio(const AudioRenderingParams& pcm_info, const QString& pcm_filename, const TimeRange &range) override; protected: virtual bool OpenInternal() override; diff --git a/app/render/backend/exporter.cpp b/app/render/backend/exporter.cpp index e0069f86c..32c87bacb 100644 --- a/app/render/backend/exporter.cpp +++ b/app/render/backend/exporter.cpp @@ -22,6 +22,8 @@ Exporter::Exporter(ViewerOutput* viewer, connect(&debug_timer_, &QTimer::timeout, this, &Exporter::DebugTimerMessage); connect(this, &Exporter::ExportEnded, this, &Exporter::deleteLater); + + export_range_ = TimeRange(0, viewer_node_->Length()); } void Exporter::EnableVideo(const VideoRenderingParams &video_params, const QMatrix4x4 &transform, ColorProcessorPtr color_processor) @@ -40,6 +42,11 @@ void Exporter::EnableAudio(const AudioRenderingParams &audio_params) audio_done_ = false; } +void Exporter::OverrideExportRange(const TimeRange &range) +{ + export_range_ = range; +} + bool Exporter::GetExportStatus() const { return export_status_; @@ -210,7 +217,8 @@ void Exporter::AudioRendered() "WriteAudio", Qt::QueuedConnection, Q_ARG(const AudioRenderingParams&, audio_backend_->params()), - Q_ARG(const QString&, cache_fn)); + Q_ARG(const QString&, cache_fn), + Q_ARG(const TimeRange&, export_range_)); // We don't need the audio backend anymore audio_backend_->deleteLater(); diff --git a/app/render/backend/exporter.h b/app/render/backend/exporter.h index f372a4c14..2bbbb18f4 100644 --- a/app/render/backend/exporter.h +++ b/app/render/backend/exporter.h @@ -23,6 +23,8 @@ public: void EnableVideo(const VideoRenderingParams& video_params, const QMatrix4x4& transform, ColorProcessorPtr color_processor); void EnableAudio(const AudioRenderingParams& audio_params); + void OverrideExportRange(const TimeRange& range); + bool GetExportStatus() const; const QString& GetExportError() const; @@ -57,6 +59,8 @@ protected: bool audio_done_; + TimeRange export_range_; + private: void ExportSucceeded();