renderer/decoder: use same background mechanism to conform audio as well

This commit is contained in:
itsmattkc
2020-02-19 16:45:34 +11:00
parent 5166f6a54a
commit e68e89c40b
16 changed files with 239 additions and 18 deletions
@@ -49,6 +49,8 @@ void AudioBackend::DecompileInternal()
void AudioBackend::ConnectWorkerToThis(RenderWorker *worker)
{
AudioRenderBackend::ConnectWorkerToThis(worker);
connect(worker, &RenderWorker::CompletedCache, this, &AudioBackend::ThreadCompletedCache);
}
+65
View File
@@ -5,10 +5,12 @@
#include "audiorenderworker.h"
#include "common/filefunctions.h"
#include "render/indexmanager.h"
AudioRenderBackend::AudioRenderBackend(QObject *parent) :
RenderBackend(parent)
{
connect(IndexManager::instance(), &IndexManager::StreamConformAppended, this, &AudioRenderBackend::ConformUpdated);
}
void AudioRenderBackend::SetParameters(const AudioRenderingParams &params)
@@ -74,3 +76,66 @@ bool AudioRenderBackend::CanRender()
{
return params_.is_valid();
}
void AudioRenderBackend::ConnectWorkerToThis(RenderWorker *worker)
{
AudioRenderWorker* arw = static_cast<AudioRenderWorker*>(worker);
connect(arw, &AudioRenderWorker::ConformUnavailable, this, &AudioRenderBackend::ConformUnavailable, Qt::QueuedConnection);
}
void AudioRenderBackend::ConformUnavailable(StreamPtr stream, const TimeRange &range, const rational &stream_time, const AudioRenderingParams& params)
{
ConformWaitInfo info = {stream, params, range, stream_time};
if (conform_wait_info_.contains(info)) {
return;
}
qDebug() << "Waiting for conformed" << stream.get() << "time" << stream_time.toDouble() << "for frame" << range.in();
AudioStreamPtr audio_stream = std::static_pointer_cast<AudioStream>(stream);
if (IndexManager::instance()->IsConforming(audio_stream, params)) {
conform_wait_info_.append(info);
} else if (audio_stream->has_conformed_version(params)) {
// Index JUST finished, requeue this time
InvalidateCache(range);
} else {
// Start indexing process
conform_wait_info_.append(info);
IndexManager::instance()->StartConformingStream(audio_stream, params);
}
}
void AudioRenderBackend::ConformUpdated(Stream *stream, const AudioRenderingParams &params)
{
qDebug() << "Got conform updated in ARB";
for (int i=0;i<conform_wait_info_.size();i++) {
const ConformWaitInfo& info = conform_wait_info_.at(i);
if (info.stream.get() == stream
&& info.params == params) {
InvalidateCache(info.affected_range);
conform_wait_info_.removeAt(i);
i--;
}
}
}
bool AudioRenderBackend::ConformWaitInfo::operator==(const AudioRenderBackend::ConformWaitInfo &rhs) const
{
return rhs.params == params
&& rhs.stream == stream
&& rhs.stream_time == stream_time
&& rhs.affected_range == affected_range;
}
+18
View File
@@ -38,9 +38,27 @@ protected:
virtual bool CanRender() override;
virtual void ConnectWorkerToThis(RenderWorker* worker) override;
private:
struct ConformWaitInfo {
StreamPtr stream;
AudioRenderingParams params;
TimeRange affected_range;
rational stream_time;
bool operator==(const ConformWaitInfo& rhs) const;
};
QList<ConformWaitInfo> conform_wait_info_;
AudioRenderingParams params_;
private slots:
void ConformUnavailable(StreamPtr stream, const TimeRange& range, const rational& stream_time, const AudioRenderingParams &params);
void ConformUpdated(Stream *stream, const AudioRenderingParams& params);
};
#endif // AUDIORENDERBACKEND_H
+6 -1
View File
@@ -25,7 +25,12 @@ void AudioRenderWorker::CloseInternal()
FramePtr AudioRenderWorker::RetrieveFromDecoder(DecoderPtr decoder, const TimeRange &range)
{
return decoder->RetrieveAudio(range.in(), range.out() - range.in(), audio_params_);
if (decoder->HasConformedVersion(audio_params_)) {
return decoder->RetrieveAudio(range.in(), range.out() - range.in(), audio_params_);
} else {
emit ConformUnavailable(decoder->stream(), CurrentPath().range(), range.out(), audio_params_);
return nullptr;
}
}
NodeValueTable AudioRenderWorker::RenderBlock(const TrackOutput *track, const TimeRange &range)
+3
View File
@@ -11,6 +11,9 @@ public:
void SetParameters(const AudioRenderingParams& audio_params);
signals:
void ConformUnavailable(StreamPtr stream, const TimeRange& range, const rational& stream_time, const AudioRenderingParams& params);
protected:
virtual bool InitInternal() override;
+9 -6
View File
@@ -443,12 +443,8 @@ void RenderBackend::FootageUnavailable(StreamPtr stream, Decoder::RetrieveState
FootageWaitInfo info = {stream, range, stream_time};
foreach (const FootageWaitInfo& compare, footage_wait_info_) {
if (info.stream == compare.stream
&& info.stream_time == compare.stream_time
&& info.affected_range == compare.affected_range) {
return;
}
if (footage_wait_info_.contains(info)) {
return;
}
qDebug() << "Waiting for" << stream.get() << "time" << stream_time.toDouble() << "for frame" << range.in();
@@ -513,3 +509,10 @@ void RenderBackend::IndexUpdated(Stream* stream)
}
}
}
bool RenderBackend::FootageWaitInfo::operator==(const RenderBackend::FootageWaitInfo &rhs) const
{
return rhs.stream == stream
&& rhs.stream_time == stream_time
&& rhs.affected_range == affected_range;
}
+2
View File
@@ -149,6 +149,8 @@ private:
StreamPtr stream;
TimeRange affected_range;
rational stream_time;
bool operator==(const FootageWaitInfo& rhs) const;
};
QList<FootageWaitInfo> footage_wait_info_;
+38 -6
View File
@@ -31,7 +31,7 @@ void IndexManager::StartIndexingStream(StreamPtr stream)
}
IndexTask* index_task = new IndexTask(stream);
threads_.append({stream, index_task});
indexing_.append({stream, index_task});
connect(stream.get(), &Stream::IndexChanged, this, &IndexManager::StreamIndexUpdatedEvent, Qt::QueuedConnection);
connect(index_task, &IndexTask::Succeeded, this, &IndexManager::IndexTaskFinished, Qt::QueuedConnection);
@@ -39,9 +39,24 @@ void IndexManager::StartIndexingStream(StreamPtr stream)
TaskManager::instance()->AddTask(index_task);
}
bool IndexManager::IsIndexing(StreamPtr stream)
void IndexManager::StartConformingStream(AudioStreamPtr stream, const AudioRenderingParams &params)
{
foreach (const StreamThreadPair& stp, threads_) {
if (IsConforming(stream, params)) {
return;
}
ConformTask* conform_task = new ConformTask(stream, params);
conforming_.append({stream, params, conform_task});
connect(stream.get(), &AudioStream::ConformAppended, this, &IndexManager::StreamConformAppendedEvent, Qt::QueuedConnection);
connect(conform_task, &ConformTask::Succeeded, this, &IndexManager::IndexTaskFinished, Qt::QueuedConnection);
TaskManager::instance()->AddTask(conform_task);
}
bool IndexManager::IsIndexing(StreamPtr stream) const
{
foreach (const IndexPair& stp, indexing_) {
if (stp.stream == stream) {
return true;
}
@@ -50,14 +65,25 @@ bool IndexManager::IsIndexing(StreamPtr stream)
return false;
}
bool IndexManager::IsConforming(AudioStreamPtr stream, const AudioRenderingParams &params) const
{
foreach (const ConformPair& cfp, conforming_) {
if (cfp.stream == stream && cfp.params == params) {
return true;
}
}
return false;
}
void IndexManager::IndexTaskFinished()
{
for (int i=0;i<threads_.size();i++) {
const StreamThreadPair& stp = threads_.at(i);
for (int i=0;i<indexing_.size();i++) {
const IndexPair& stp = indexing_.at(i);
if (stp.task == sender()) {
//emit StreamIndexUpdated(stp.stream.get());
threads_.removeAt(i);
indexing_.removeAt(i);
return;
}
}
@@ -67,3 +93,9 @@ void IndexManager::StreamIndexUpdatedEvent()
{
emit StreamIndexUpdated(static_cast<Stream*>(sender()));
}
void IndexManager::StreamConformAppendedEvent(const AudioRenderingParams &params)
{
qDebug() << "Got stream conform appended event";
emit StreamConformAppended(static_cast<Stream*>(sender()), params);
}
+17 -3
View File
@@ -4,6 +4,7 @@
#include <QObject>
#include "project/item/footage/stream.h"
#include "task/conform/conform.h"
#include "task/index/index.h"
class IndexManager : public QObject
@@ -16,29 +17,42 @@ public:
static IndexManager* instance();
static void DestroyInstance();
bool IsIndexing(StreamPtr stream);
bool IsIndexing(StreamPtr stream) const;
bool IsConforming(AudioStreamPtr stream, const AudioRenderingParams& params) const;
public slots:
void StartIndexingStream(StreamPtr stream);
void StartConformingStream(AudioStreamPtr stream, const AudioRenderingParams& params);
signals:
void StreamIndexUpdated(Stream* stream);
void StreamConformAppended(Stream* stream, const AudioRenderingParams& params);
private:
static IndexManager* instance_;
struct StreamThreadPair {
struct IndexPair {
StreamPtr stream;
IndexTask* task;
};
QList<StreamThreadPair> threads_;
struct ConformPair {
StreamPtr stream;
AudioRenderingParams params;
ConformTask* task;
};
QList<IndexPair> indexing_;
QList<ConformPair> conforming_;
private slots:
void IndexTaskFinished();
void StreamIndexUpdatedEvent();
void StreamConformAppendedEvent(const AudioRenderingParams& params);
};
#endif // INDEXMANAGER_H