export: fixed audio exporting with new renderer system
This commit is contained in:
Vendored
+4
-5
@@ -27,10 +27,9 @@
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
|
||||
CacheTask::CacheTask(ViewerOutput* viewer, int divider, bool in_out_only) :
|
||||
RenderTask(viewer),
|
||||
in_out_only_(in_out_only),
|
||||
divider_(divider)
|
||||
CacheTask::CacheTask(ViewerOutput* viewer, const VideoRenderingParams& vparams, const AudioRenderingParams &aparams, bool in_out_only) :
|
||||
RenderTask(viewer, vparams, aparams),
|
||||
in_out_only_(in_out_only)
|
||||
{
|
||||
SetTitle(tr("Caching \"%1\"").arg(viewer->media_name()));
|
||||
}
|
||||
@@ -49,7 +48,7 @@ bool CacheTask::Run()
|
||||
}
|
||||
}
|
||||
|
||||
Render(range_to_cache, RenderMode::kOffline, QMatrix4x4(), false, divider_);
|
||||
Render(range_to_cache, QMatrix4x4(), false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Vendored
+4
-3
@@ -31,7 +31,10 @@ class CacheTask : public RenderTask
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CacheTask(ViewerOutput* viewer, int divider, bool in_out_only);
|
||||
CacheTask(ViewerOutput* viewer,
|
||||
const VideoRenderingParams &vparams,
|
||||
const AudioRenderingParams &aparams,
|
||||
bool in_out_only);
|
||||
|
||||
public slots:
|
||||
virtual bool Run() override;
|
||||
@@ -44,8 +47,6 @@ protected:
|
||||
private:
|
||||
bool in_out_only_;
|
||||
|
||||
int divider_;
|
||||
|
||||
};
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
|
||||
@@ -28,7 +28,7 @@ OLIVE_NAMESPACE_ENTER
|
||||
ExportTask::ExportTask(ViewerOutput* viewer_node,
|
||||
ColorManager* color_manager,
|
||||
const ExportParams& params) :
|
||||
RenderTask(viewer_node),
|
||||
RenderTask(viewer_node, params.video_params(), params.audio_params()),
|
||||
color_manager_(color_manager),
|
||||
params_(params)
|
||||
{
|
||||
@@ -80,9 +80,14 @@ bool ExportTask::Run()
|
||||
params_.color_transform());
|
||||
}
|
||||
|
||||
if (params_.audio_enabled()) {
|
||||
audio_data_.SetParameters(audio_params());
|
||||
}
|
||||
|
||||
// Start render process
|
||||
TimeRangeList ranges;
|
||||
ranges.InsertTimeRange(range);
|
||||
Render(ranges, RenderMode::kOnline, mat, true, 1);
|
||||
Render(ranges, mat, params_.audio_enabled());
|
||||
|
||||
bool success = true;
|
||||
|
||||
@@ -95,6 +100,11 @@ bool ExportTask::Run()
|
||||
}
|
||||
}
|
||||
|
||||
if (params_.audio_enabled()) {
|
||||
// Write audio data now
|
||||
encoder_->WriteAudio(audio_params(), audio_data_.GetCacheFilename());
|
||||
}
|
||||
|
||||
encoder_->Close();
|
||||
|
||||
encoder_->deleteLater();
|
||||
@@ -104,8 +114,6 @@ bool ExportTask::Run()
|
||||
|
||||
void FrameColorConvert(ColorProcessorPtr processor, FramePtr frame)
|
||||
{
|
||||
qDebug() << "Converting" << frame->timestamp() << "from" << frame->format();
|
||||
|
||||
// OCIO conversion requires a frame in 32F format
|
||||
if (frame->format() != PixelFormat::PIX_FMT_RGBA32F) {
|
||||
frame = PixelFormat::ConvertPixelFormat(frame, PixelFormat::PIX_FMT_RGBA32F);
|
||||
@@ -153,4 +161,17 @@ void ExportTask::FrameDownloaded(const QByteArray &hash, const QLinkedList<ratio
|
||||
}
|
||||
}
|
||||
|
||||
void ExportTask::AudioDownloaded(const TimeRange &range, SampleBufferPtr samples)
|
||||
{
|
||||
TimeRange adjusted_range = range;
|
||||
|
||||
if (params_.has_custom_range()) {
|
||||
adjusted_range -= params_.custom_range().in();
|
||||
}
|
||||
|
||||
qDebug() << "Downloaded audio" << adjusted_range;
|
||||
|
||||
audio_data_.WritePCM(adjusted_range, samples);
|
||||
}
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
|
||||
@@ -43,6 +43,8 @@ protected:
|
||||
|
||||
virtual void FrameDownloaded(const QByteArray& hash, const QLinkedList<rational>& times) override;
|
||||
|
||||
virtual void AudioDownloaded(const TimeRange& range, SampleBufferPtr samples) override;
|
||||
|
||||
private:
|
||||
QHash<QByteArray, FramePtr> rendered_frame_;
|
||||
|
||||
@@ -60,6 +62,8 @@ private:
|
||||
|
||||
int64_t frame_time_;
|
||||
|
||||
AudioPlaybackCache audio_data_;
|
||||
|
||||
};
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
|
||||
+65
-34
@@ -25,10 +25,11 @@
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
|
||||
RenderTask::RenderTask(ViewerOutput* viewer) :
|
||||
viewer_(viewer)
|
||||
RenderTask::RenderTask(ViewerOutput* viewer, const VideoRenderingParams &vparams, const AudioRenderingParams &aparams) :
|
||||
viewer_(viewer),
|
||||
video_params_(vparams),
|
||||
audio_params_(aparams)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
struct TimeHashFuturePair {
|
||||
@@ -46,50 +47,52 @@ struct HashFrameFuturePair {
|
||||
QFuture<FramePtr> frame_future;
|
||||
};
|
||||
|
||||
struct RangeSampleFuturePair {
|
||||
TimeRange range;
|
||||
QFuture<SampleBufferPtr> sample_future;
|
||||
};
|
||||
|
||||
struct HashDownloadFuturePair {
|
||||
QByteArray hash;
|
||||
QFuture<void> download_future;
|
||||
};
|
||||
|
||||
void RenderTask::Render(TimeRangeList range_to_cache,
|
||||
RenderMode::Mode mode,
|
||||
void RenderTask::Render(const TimeRangeList& range_to_cache,
|
||||
const QMatrix4x4& mat,
|
||||
bool audio_enabled,
|
||||
int divider)
|
||||
bool audio_enabled)
|
||||
{
|
||||
OpenGLBackend backend;
|
||||
|
||||
PixelFormat::Format format = PixelFormat::instance()->GetConfiguredFormatForMode(mode);
|
||||
|
||||
backend.SetAudioMode(audio_enabled ? RenderBackend::kAudioRender : RenderBackend::kAudioDisabled);
|
||||
backend.SetAutomaticAudio(false);
|
||||
backend.SetViewerNode(viewer_);
|
||||
backend.SetPixelFormat(format);
|
||||
backend.SetMode(mode);
|
||||
backend.SetDivider(divider);
|
||||
backend.SetSampleFormat(SampleFormat::kInternalFormat);
|
||||
backend.SetVideoParams(video_params_);
|
||||
backend.SetAudioParams(audio_params_);
|
||||
backend.SetVideoDownloadMatrix(mat);
|
||||
|
||||
// Get hashes for each frame
|
||||
QLinkedList<TimeHashFuturePair> hash_list;
|
||||
|
||||
while (!range_to_cache.isEmpty()) {
|
||||
const TimeRange& range = range_to_cache.first();
|
||||
{
|
||||
TimeRangeList range_list = range_to_cache;
|
||||
while (!range_list.isEmpty()) {
|
||||
const TimeRange& range = range_list.first();
|
||||
|
||||
const rational& timebase = viewer_->video_params().time_base();
|
||||
const rational& timebase = viewer_->video_params().time_base();
|
||||
|
||||
rational time = range.in();
|
||||
rational snapped = Timecode::snap_time_to_timebase(time, timebase);
|
||||
rational next;
|
||||
rational time = range.in();
|
||||
rational snapped = Timecode::snap_time_to_timebase(time, timebase);
|
||||
rational next;
|
||||
|
||||
if (snapped > time) {
|
||||
next = snapped;
|
||||
snapped -= timebase;
|
||||
} else {
|
||||
next = snapped + timebase;
|
||||
if (snapped > time) {
|
||||
next = snapped;
|
||||
snapped -= timebase;
|
||||
} else {
|
||||
next = snapped + timebase;
|
||||
}
|
||||
|
||||
hash_list.append({snapped, backend.Hash(snapped, false)});
|
||||
range_list.RemoveTimeRange(TimeRange(snapped, next));
|
||||
}
|
||||
|
||||
hash_list.append({snapped, backend.Hash(snapped, false)});
|
||||
range_to_cache.RemoveTimeRange(TimeRange(snapped, next));
|
||||
}
|
||||
|
||||
// Determine any duplicates
|
||||
@@ -130,12 +133,18 @@ void RenderTask::Render(TimeRangeList range_to_cache,
|
||||
}
|
||||
}
|
||||
|
||||
QLinkedList<RangeSampleFuturePair> audio_lookup_table;
|
||||
if (audio_enabled) {
|
||||
foreach (const TimeRange& r, range_to_cache) {
|
||||
QList<TimeRange> ranges = RenderBackend::SplitRangeIntoChunks(r);
|
||||
|
||||
foreach (const TimeRange& split, ranges) {
|
||||
audio_lookup_table.append({split, backend.RenderAudio(split, false)});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Start downloading frames that have finished
|
||||
OIIO::TypeDesc output_desc = PixelFormat::GetOIIOTypeDesc(format);
|
||||
OIIO::ImageSpec output_spec(viewer()->video_params().width() / divider,
|
||||
viewer()->video_params().height() / divider,
|
||||
PixelFormat::ChannelCount(format),
|
||||
output_desc);
|
||||
|
||||
int counter = 0;
|
||||
int nb_frames = render_lookup_table.size();
|
||||
@@ -145,8 +154,12 @@ void RenderTask::Render(TimeRangeList range_to_cache,
|
||||
// Iterators
|
||||
QLinkedList<HashFrameFuturePair>::iterator i;
|
||||
QLinkedList<HashDownloadFuturePair>::iterator j;
|
||||
QLinkedList<RangeSampleFuturePair>::iterator k;
|
||||
|
||||
while (!render_lookup_table.isEmpty()
|
||||
|| !download_futures.isEmpty()
|
||||
|| !audio_lookup_table.isEmpty()) {
|
||||
|
||||
while (!render_lookup_table.isEmpty() || !download_futures.isEmpty()) {
|
||||
i = render_lookup_table.begin();
|
||||
|
||||
while (i != render_lookup_table.end()) {
|
||||
@@ -178,7 +191,25 @@ void RenderTask::Render(TimeRangeList range_to_cache,
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
if (audio_enabled) {
|
||||
k = audio_lookup_table.begin();
|
||||
|
||||
while (k != audio_lookup_table.end()) {
|
||||
if (k->sample_future.isFinished()) {
|
||||
AudioDownloaded(k->range, k->sample_future.result());
|
||||
|
||||
k = audio_lookup_table.erase(k);
|
||||
} else {
|
||||
k++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RenderTask::AudioDownloaded(const TimeRange &, SampleBufferPtr)
|
||||
{
|
||||
}
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
|
||||
@@ -31,23 +31,39 @@ OLIVE_NAMESPACE_ENTER
|
||||
class RenderTask : public Task
|
||||
{
|
||||
public:
|
||||
RenderTask(ViewerOutput* viewer);
|
||||
RenderTask(ViewerOutput* viewer, const VideoRenderingParams &vparams, const AudioRenderingParams &aparams);
|
||||
|
||||
protected:
|
||||
void Render(TimeRangeList range_to_cache, RenderMode::Mode mode, const QMatrix4x4 &mat, bool audio_enabled, int divider);
|
||||
void Render(const TimeRangeList &range_to_cache, const QMatrix4x4 &mat, bool audio_enabled);
|
||||
|
||||
virtual QFuture<void> DownloadFrame(FramePtr frame, const QByteArray &hash) = 0;
|
||||
|
||||
virtual void FrameDownloaded(const QByteArray& hash, const QLinkedList<rational>& times) = 0;
|
||||
|
||||
virtual void AudioDownloaded(const TimeRange& range, SampleBufferPtr samples);
|
||||
|
||||
ViewerOutput* viewer() const
|
||||
{
|
||||
return viewer_;
|
||||
}
|
||||
|
||||
virtual QFuture<void> DownloadFrame(FramePtr frame, const QByteArray &hash) = 0;
|
||||
VideoRenderingParams video_params() const
|
||||
{
|
||||
return video_params_;
|
||||
}
|
||||
|
||||
virtual void FrameDownloaded(const QByteArray& hash, const QLinkedList<rational>& times) = 0;
|
||||
AudioRenderingParams audio_params() const
|
||||
{
|
||||
return audio_params_;
|
||||
}
|
||||
|
||||
private:
|
||||
ViewerOutput* viewer_;
|
||||
|
||||
VideoRenderingParams video_params_;
|
||||
|
||||
AudioRenderingParams audio_params_;
|
||||
|
||||
};
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
|
||||
Reference in New Issue
Block a user