cache waveforms at clip level

This commit is contained in:
itsmattkc
2022-05-22 20:54:59 -07:00
parent b99fb32954
commit f124ad3178
21 changed files with 429 additions and 329 deletions
+4 -4
View File
@@ -406,7 +406,7 @@ void PointerTool::InitiateDragInternal(Block *clicked_item,
bool multitrim_enabled = IsClipTrimmable(clicked_item, clips, trim_mode);
// Create ghosts for trimming
foreach (Block* clip_item, clips) {
for (Block* clip_item : clips) {
if (clip_item != clicked_item
&& (!multitrim_enabled || !IsClipTrimmable(clip_item, clips, trim_mode))) {
// Either multitrim is disabled or this clip is NOT the earliest/latest in its track. We
@@ -481,7 +481,7 @@ void PointerTool::InitiateDragInternal(Block *clicked_item,
// I'm only including it to prevent any potentially unintended behavior.
if (clips.size() == 1 && !(modifiers & Qt::AltModifier)) {
if (ClipBlock *adjacent_clip = dynamic_cast<ClipBlock*>(adjacent)) {
foreach (Block *adjacent_link, adjacent_clip->block_links()) {
for (Block *adjacent_link : adjacent_clip->block_links()) {
adjacent_ghosts.append(AddGhostFromBlock(adjacent_link, flipped_mode));
}
}
@@ -496,7 +496,7 @@ void PointerTool::InitiateDragInternal(Block *clicked_item,
// expected to fill the remaining space (no gap needs to be created)
ghost->SetData(TimelineViewGhostItem::kTrimIsARollEdit, static_cast<bool>(adjacent));
foreach (TimelineViewGhostItem *adjacent_ghost, adjacent_ghosts) {
for (TimelineViewGhostItem *adjacent_ghost : adjacent_ghosts) {
if (adjacent_ghost) {
if (treat_trim_as_slide) {
// We're sliding a transition rather than a pure trim/roll
@@ -699,7 +699,7 @@ void PointerTool::FinishDrag(TimelineViewMouseEvent *event)
// Place the copy instead of the original block
block = static_cast<Block*>(Node::CopyNodeInGraph(block, command));
if (ClipBlock *new_clip = dynamic_cast<ClipBlock*>(block)) {
new_clip->waveform() = static_cast<ClipBlock*>(p.block)->waveform();
new_clip->set_waveform(static_cast<ClipBlock*>(p.block)->waveform());
}
}
@@ -44,7 +44,7 @@ void BlockSplitCommand::redo()
if (ClipBlock *new_clip = dynamic_cast<ClipBlock*>(new_block_)) {
ClipBlock *old_clip = static_cast<ClipBlock*>(block_);
new_clip->waveform() = old_clip->waveform();
new_clip->set_waveform(old_clip->waveform());
}
// Determine our new lengths
@@ -47,6 +47,7 @@ TimelineView::TimelineView(Qt::Alignment vertical_alignment, QWidget *parent) :
ghosts_(nullptr),
show_beam_cursor_(false),
connected_track_list_(nullptr),
show_thumbnails_(true),
show_waveforms_(true),
transition_overlay_out_(nullptr),
transition_overlay_in_(nullptr)
@@ -519,12 +520,32 @@ void TimelineView::DrawBlock(QPainter *painter, bool foreground, Block *block, q
painter->drawRect(r);
if (ClipBlock *clip = dynamic_cast<ClipBlock*>(block)) {
QRect preview_rect = r.adjusted(0, text_total_height, 0, 0).toRect();
// Draw clip thumbnails
if (clip->GetTrackType() == Track::kVideo && show_thumbnails_ && preview_rect.height() > r.height()/3) {
const int kTempThumbWidth = 120;
const int kTempThumbHeight = 68;
QRect thumb_rect;
painter->setClipRect(preview_rect);
for (int i=preview_rect.left(); i<preview_rect.right(); i+=thumb_rect.width()+1) {
double scale = double(preview_rect.height())/double(kTempThumbHeight);
thumb_rect = QRect(i, preview_rect.top(), kTempThumbWidth * scale, preview_rect.height());
painter->fillRect(thumb_rect, Qt::red);
}
painter->setClipping(false);
}
// Draw waveform
if (show_waveforms_) {
QRect waveform_rect = r.adjusted(0, text_total_height, 0, 0).toRect();
painter->setPen(shadow_color);
AudioVisualWaveform::DrawWaveform(painter, waveform_rect, this->GetScale(), clip->waveform(),
SceneToTime(block_left - block_in, GetScale(), connected_track_list_->parent()->GetAudioParams().sample_rate_as_time_base()) + media_in);
if (clip->GetTrackType() == Track::kAudio && show_waveforms_) {
if (const AudioVisualWaveform *wave = clip->waveform()) {
rational waveform_start = SceneToTime(block_left - block_in, GetScale(), connected_track_list_->parent()->GetAudioParams().sample_rate_as_time_base()) + media_in;
painter->setPen(shadow_color);
AudioVisualWaveform::DrawWaveform(painter, preview_rect, this->GetScale(), *wave, waveform_start);
}
}
// Draw zebra stripes and markers
@@ -153,6 +153,7 @@ private:
TrackList* connected_track_list_;
bool show_thumbnails_;
bool show_waveforms_;
ClipBlock *transition_overlay_out_;
+14 -14
View File
@@ -147,6 +147,8 @@ ViewerWidget::ViewerWidget(QWidget *parent) :
setAcceptDrops(true);
auto_cacher_ = new PreviewAutoCacher(this);
connect(Core::instance(), &Core::ColorPickerEnabled, this, &ViewerWidget::SetSignalCursorColorEnabled);
connect(this, &ViewerWidget::CursorColor, Core::instance(), &Core::ColorPickerColorEmitted);
connect(AudioManager::instance(), &AudioManager::OutputParamsChanged, this, &ViewerWidget::UpdateAudioProcessor);
@@ -191,7 +193,7 @@ void ViewerWidget::TimeChangedEvent(const rational &time)
}
// Send time to auto-cacher
auto_cacher_.SetPlayhead(time);
auto_cacher_->SetPlayhead(time);
last_time_ = time;
}
@@ -275,7 +277,7 @@ void ViewerWidget::DisconnectNodeEvent(ViewerOutput *n)
void ViewerWidget::ConnectedNodeChangeEvent(ViewerOutput *n)
{
auto_cacher_.SetViewerNode(n);
auto_cacher_->SetViewerNode(n);
display_widget_->SetSubtitleTracks(dynamic_cast<Sequence*>(n));
}
@@ -369,13 +371,13 @@ void ViewerWidget::SetFullScreen(QScreen *screen)
void ViewerWidget::CacheEntireSequence()
{
auto_cacher_.ForceCacheRange(TimeRange(0, GetConnectedNode()->GetVideoLength()));
auto_cacher_->ForceCacheRange(TimeRange(0, GetConnectedNode()->GetVideoLength()));
}
void ViewerWidget::CacheSequenceInOut()
{
if (GetConnectedNode() && GetConnectedNode()->GetTimelinePoints()->workarea()->enabled()) {
auto_cacher_.ForceCacheRange(GetConnectedNode()->GetTimelinePoints()->workarea()->range());
auto_cacher_->ForceCacheRange(GetConnectedNode()->GetTimelinePoints()->workarea()->range());
} else {
QMessageBox::warning(this,
tr("Error"),
@@ -442,12 +444,12 @@ void ViewerWidget::SetEmptyImage()
void ViewerWidget::UpdateAutoCacher()
{
auto_cacher_.SetPlayhead(GetTime());
auto_cacher_->SetPlayhead(GetTime());
}
void ViewerWidget::ClearVideoAutoCacherQueue()
{
auto_cacher_.CancelVideoTasks();
auto_cacher_->CancelVideoTasks();
}
void ViewerWidget::DecrementPrequeuedAudio()
@@ -549,7 +551,7 @@ void ViewerWidget::QueueNextAudioBuffer()
RenderTicketWatcher *watcher = new RenderTicketWatcher(this);
connect(watcher, &RenderTicketWatcher::Finished, this, &ViewerWidget::ReceivedAudioBufferForPlayback);
audio_playback_queue_.push_back(watcher);
watcher->SetTicket(auto_cacher_.GetRangeOfAudio(TimeRange(audio_playback_queue_time_, queue_end), RenderTicketPriority::kHigh));
watcher->SetTicket(auto_cacher_->GetRangeOfAudio(TimeRange(audio_playback_queue_time_, queue_end), RenderTicketPriority::kHigh));
audio_playback_queue_time_ = queue_end;
}
@@ -685,7 +687,7 @@ void ViewerWidget::UpdateTextureFromNode()
nonqueue_watchers_.append(watcher);
// Clear queue because we want this frame more than any others
if (!GetConnectedNode()->video_frame_cache()->IsEnabled() && !auto_cacher_.IsRenderingCustomRange()) {
if (!GetConnectedNode()->video_frame_cache()->IsAutomatic() && !auto_cacher_->IsRenderingCustomRange()) {
ClearVideoAutoCacherQueue();
}
@@ -716,10 +718,8 @@ void ViewerWidget::PlayInternal(int speed, bool in_to_out_only)
foreach (ViewerWidget* viewer, instances_) {
if (viewer != this) {
viewer->PauseInternal();
viewer->ClearVideoAutoCacherQueue();
viewer->auto_cacher_->SetRendersPaused(true);
}
viewer->auto_cacher_.SetAudioPaused(true);
}
// Disarm recording if armed
@@ -823,7 +823,7 @@ void ViewerWidget::PauseInternal()
UpdateAudioProcessor();
foreach (ViewerWidget* viewer, instances_) {
viewer->auto_cacher_.SetAudioPaused(false);
viewer->auto_cacher_->SetRendersPaused(false);
}
UpdateTextureFromNode();
@@ -848,7 +848,7 @@ void ViewerWidget::PushScrubbedAudio()
RenderTicketWatcher *watcher = new RenderTicketWatcher();
connect(watcher, &RenderTicketWatcher::Finished, this, &ViewerWidget::ReceivedAudioBufferForScrubbing);
watcher->SetTicket(auto_cacher_.GetRangeOfAudio(TimeRange(GetTime(), GetTime() + interval), RenderTicketPriority::kHigh));
watcher->SetTicket(auto_cacher_->GetRangeOfAudio(TimeRange(GetTime(), GetTime() + interval), RenderTicketPriority::kHigh));
}
}
}
@@ -922,7 +922,7 @@ RenderTicketPtr ViewerWidget::GetFrame(const rational &t, RenderTicketPriority p
if (!QFileInfo::exists(cache_fn)) {
// Frame hasn't been cached, start render job
return auto_cacher_.GetSingleFrame(t, priority);
return auto_cacher_->GetSingleFrame(t, priority);
} else {
// Frame has been cached, grab the frame
RenderTicketPtr ticket = std::make_shared<RenderTicket>();
+1 -1
View File
@@ -255,7 +255,7 @@ private:
int prequeue_length_;
int prequeue_count_;
PreviewAutoCacher auto_cacher_;
PreviewAutoCacher *auto_cacher_;
QVector<RenderTicketWatcher*> queue_watchers_;