ffmpegencoder: added range support to audio encoding

There isn't UI for this yet, but sending a time range to the encoder will now
encode just that range of audio.
This commit is contained in:
itsmattkc
2020-03-31 13:55:57 +11:00
parent be6bea234b
commit 9603f90072
5 changed files with 37 additions and 6 deletions
+2 -1
View File
@@ -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:
+21 -3
View File
@@ -17,7 +17,7 @@ FFmpegEncoder::FFmpegEncoder(const EncodingParams &params) :
{
}
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<int>(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);
+1 -1
View File
@@ -17,7 +17,7 @@ public:
FFmpegEncoder(const EncodingParams &params);
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;
+9 -1
View File
@@ -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();
+4
View File
@@ -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();