render: return to caching partial waveforms
This commit is contained in:
@@ -31,15 +31,25 @@ void AudioWaveformCache::WriteWaveform(const TimeRange &range, const TimeRangeLi
|
||||
{
|
||||
// Write each valid range to the segments
|
||||
foreach (const TimeRange& r, valid_ranges) {
|
||||
#ifdef AVW_USE_LIST
|
||||
// Write visual
|
||||
TimeRangeList::util_remove(&waveforms_, r);
|
||||
|
||||
if (waveform) {
|
||||
TimeRangeWithWaveform wv = r;
|
||||
rational local_start = r.in() - range.in();
|
||||
wv.waveform = waveform->Mid(local_start, r.length());
|
||||
if (local_start != 0) {
|
||||
wv.waveform = waveform->Mid(local_start, r.length());
|
||||
} else {
|
||||
wv.waveform = *waveform;
|
||||
}
|
||||
waveforms_.append(wv);
|
||||
}
|
||||
#else
|
||||
if (waveform) {
|
||||
waveforms_.OverwriteSums(*waveform, r.in(), r.in() - range.in(), r.length());
|
||||
}
|
||||
#endif
|
||||
|
||||
Validate(r);
|
||||
}
|
||||
@@ -50,6 +60,7 @@ void AudioWaveformCache::Draw(QPainter *painter, const QRect &rect, const double
|
||||
rational end = start_time + rational::fromDouble(rect.width() / scale);
|
||||
TimeRange draw_range(start_time, end);
|
||||
|
||||
#ifdef AVW_USE_LIST
|
||||
foreach (const TimeRangeWithWaveform &wv, waveforms_) {
|
||||
if (wv.OverlapsWith(draw_range)) {
|
||||
rational substart = std::max(wv.in(), draw_range.in());
|
||||
@@ -63,10 +74,14 @@ void AudioWaveformCache::Draw(QPainter *painter, const QRect &rect, const double
|
||||
AudioVisualWaveform::DrawWaveform(painter, subrect, scale, wv.waveform, local_start);
|
||||
}
|
||||
}
|
||||
#else
|
||||
AudioVisualWaveform::DrawWaveform(painter, rect, scale, waveforms_, start_time);
|
||||
#endif
|
||||
}
|
||||
|
||||
AudioVisualWaveform::Sample AudioWaveformCache::GetSummaryFromTime(const rational &start, const rational &length) const
|
||||
{
|
||||
#ifdef AVW_USE_LIST
|
||||
QMap<rational, AudioVisualWaveform::Sample> sample;
|
||||
|
||||
TimeRange acquire(start, start+length);
|
||||
@@ -85,10 +100,14 @@ AudioVisualWaveform::Sample AudioWaveformCache::GetSummaryFromTime(const rationa
|
||||
}
|
||||
|
||||
return result;
|
||||
#else
|
||||
return waveforms_.GetSummaryFromTime(start, length);
|
||||
#endif
|
||||
}
|
||||
|
||||
rational AudioWaveformCache::length() const
|
||||
{
|
||||
#ifdef AVW_USE_LIST
|
||||
rational len = 0;
|
||||
|
||||
foreach (const TimeRangeWithWaveform &wv, waveforms_) {
|
||||
@@ -96,6 +115,9 @@ rational AudioWaveformCache::length() const
|
||||
}
|
||||
|
||||
return len;
|
||||
#else
|
||||
return waveforms_.length();
|
||||
#endif
|
||||
}
|
||||
|
||||
void AudioWaveformCache::SetPassthrough(PlaybackCache *cache)
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
#include "audio/audiovisualwaveform.h"
|
||||
#include "playbackcache.h"
|
||||
|
||||
//#define AVW_USE_LIST
|
||||
|
||||
namespace olive {
|
||||
|
||||
class AudioWaveformCache : public PlaybackCache
|
||||
@@ -35,7 +37,11 @@ public:
|
||||
void WriteWaveform(const TimeRange &range, const TimeRangeList &valid_ranges, const AudioVisualWaveform *waveform);
|
||||
|
||||
const AudioParams &GetParameters() const { return params_; }
|
||||
void SetParameters(const AudioParams &p) { params_ = p; }
|
||||
void SetParameters(const AudioParams &p)
|
||||
{
|
||||
params_ = p;
|
||||
waveforms_.set_channel_count(p.channel_count());
|
||||
}
|
||||
|
||||
void Draw(QPainter* painter, const QRect &rect, const double &scale, const rational &start_time) const;
|
||||
|
||||
@@ -46,6 +52,7 @@ public:
|
||||
virtual void SetPassthrough(PlaybackCache *cache) override;
|
||||
|
||||
private:
|
||||
#ifdef AVW_USE_LIST
|
||||
class TimeRangeWithWaveform : public TimeRange
|
||||
{
|
||||
public:
|
||||
@@ -77,6 +84,9 @@ private:
|
||||
};
|
||||
|
||||
QVector<TimeRangeWithWaveform> waveforms_;
|
||||
#else
|
||||
AudioVisualWaveform waveforms_;
|
||||
#endif
|
||||
|
||||
AudioParams params_;
|
||||
|
||||
|
||||
@@ -156,17 +156,17 @@ void PreviewAutoCacher::AudioRendered()
|
||||
AudioVisualWaveform waveform = watcher->GetTicket()->property("waveform").value<AudioVisualWaveform>();
|
||||
|
||||
SampleBuffer buf = watcher->Get().value<SampleBuffer>();
|
||||
node->audio_playback_cache()->SetParameters(buf.audio_params());
|
||||
node->waveform_cache()->SetParameters(buf.audio_params());
|
||||
|
||||
bool incomplete = watcher->GetTicket()->property("incomplete").toBool();
|
||||
|
||||
if (AudioPlaybackCache *pcm = dynamic_cast<AudioPlaybackCache*>(cache)) {
|
||||
// WritePCM is tolerant to its buffer being null, it will just write silence instead
|
||||
pcm->SetParameters(buf.audio_params());
|
||||
pcm->WritePCM(range,
|
||||
valid_ranges,
|
||||
watcher->Get().value<SampleBuffer>());
|
||||
} else if (AudioWaveformCache *wave = dynamic_cast<AudioWaveformCache*>(cache)) {
|
||||
wave->SetParameters(buf.audio_params());
|
||||
if (!incomplete) {
|
||||
wave->WriteWaveform(range, valid_ranges, &waveform);
|
||||
}
|
||||
@@ -653,14 +653,31 @@ void PreviewAutoCacher::TryRender()
|
||||
while (!pending_audio_jobs_.empty() && running_audio_tasks_.size() < max_tasks) {
|
||||
AudioJob &d = pending_audio_jobs_.front();
|
||||
|
||||
bool pop = true;
|
||||
|
||||
// Start job
|
||||
if (Node *copy = copy_map_.value(d.node)) {
|
||||
RenderAudio(copy, d.range, d.cache);
|
||||
TimeRange &queued_range = d.range;
|
||||
TimeRange use_range = queued_range;
|
||||
|
||||
if (dynamic_cast<AudioWaveformCache*>(d.cache)) {
|
||||
rational new_out = std::min(use_range.in() + AudioVisualWaveform::kMinimumSampleRate.flipped(), use_range.out());
|
||||
|
||||
if (new_out != use_range.out()) {
|
||||
use_range.set_out(new_out);
|
||||
queued_range.set_in(new_out);
|
||||
pop = false;
|
||||
}
|
||||
}
|
||||
|
||||
RenderAudio(copy, use_range, d.cache);
|
||||
} else {
|
||||
qCritical() << "Failed to find node copy for audio job";
|
||||
}
|
||||
|
||||
pending_audio_jobs_.pop_front();
|
||||
if (pop) {
|
||||
pending_audio_jobs_.pop_front();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user