Merge branch 'cache-update'

This commit is contained in:
itsmattkc
2022-09-15 16:10:25 -07:00
77 changed files with 2334 additions and 1597 deletions
+4 -3
View File
@@ -93,11 +93,12 @@ void AudioMonitor::PushSampleBuffer(const SampleBuffer &d)
SetUpdateLoop(true);
}
void AudioMonitor::StartWaveform(const AudioVisualWaveform *waveform, const rational &start, int playback_speed)
void AudioMonitor::StartWaveform(const AudioWaveformCache *waveform, const rational &start, int playback_speed)
{
Stop();
if (start >= waveform->length()) {
waveform_length_ = waveform->length();
if (start >= waveform_length_) {
return;
}
@@ -242,7 +243,7 @@ void AudioMonitor::paintGL()
if (waveform_) {
UpdateValuesFromWaveform(v, delta_time);
if (waveform_time_ >= waveform_->length()) {
if (waveform_time_ >= waveform_length_) {
Stop();
}
}
+5 -4
View File
@@ -28,7 +28,7 @@
#include "audio/audiovisualwaveform.h"
#include "common/define.h"
#include "render/audioparams.h"
#include "render/audioplaybackcache.h"
#include "render/audiowaveformcache.h"
namespace olive {
@@ -45,7 +45,7 @@ public:
return waveform_;
}
static void StartWaveformOnAll(const AudioVisualWaveform *waveform, const rational& start, int playback_speed)
static void StartWaveformOnAll(const AudioWaveformCache *waveform, const rational& start, int playback_speed)
{
foreach (AudioMonitor *m, instances_) {
m->StartWaveform(waveform, start, playback_speed);
@@ -73,7 +73,7 @@ public slots:
void PushSampleBuffer(const SampleBuffer &samples);
void StartWaveform(const AudioVisualWaveform *waveform, const rational& start, int playback_speed);
void StartWaveform(const AudioWaveformCache *waveform, const rational& start, int playback_speed);
protected:
virtual void paintGL() override;
@@ -97,8 +97,9 @@ private:
qint64 last_time_;
const AudioVisualWaveform* waveform_;
const AudioWaveformCache* waveform_;
rational waveform_time_;
rational waveform_length_;
int playback_speed_;
@@ -26,7 +26,6 @@
#include <QScrollBar>
#include <QSplitter>
#include "common/functiontimer.h"
#include "common/timecodefunctions.h"
#include "node/output/viewer/viewer.h"
#include "widget/nodeparamview/nodeparamviewundo.h"
+3 -4
View File
@@ -26,7 +26,6 @@
#include <QPainter>
#include <QStyleOptionGraphicsItem>
#include "common/flipmodifiers.h"
#include "common/qtutils.h"
#include "config/config.h"
#include "core.h"
@@ -434,7 +433,7 @@ void NodeViewItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
return;
}
event->setModifiers(FlipControlAndShiftModifiers(event->modifiers()));
event->setModifiers(QtUtils::FlipControlAndShiftModifiers(event->modifiers()));
QGraphicsRectItem::mousePressEvent(event);
}
@@ -445,7 +444,7 @@ void NodeViewItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
return;
}
event->setModifiers(FlipControlAndShiftModifiers(event->modifiers()));
event->setModifiers(QtUtils::FlipControlAndShiftModifiers(event->modifiers()));
QGraphicsRectItem::mouseMoveEvent(event);
}
@@ -457,7 +456,7 @@ void NodeViewItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
return;
}
event->setModifiers(FlipControlAndShiftModifiers(event->modifiers()));
event->setModifiers(QtUtils::FlipControlAndShiftModifiers(event->modifiers()));
QGraphicsRectItem::mouseReleaseEvent(event);
}
-1
View File
@@ -20,7 +20,6 @@
#include "nodeviewscene.h"
#include "common/functiontimer.h"
#include "core.h"
#include "node/project/sequence/sequence.h"
#include "nodeviewedge.h"
@@ -64,6 +64,9 @@ rational TimeScaledObject::SceneToTime(const double &x, const double &x_scale, c
if (round) {
rounded_x_mvmt = qRound64(unscaled_time);
} else if (unscaled_time < 0) {
// "floor" to zero
rounded_x_mvmt = qCeil(unscaled_time);
} else {
rounded_x_mvmt = qFloor(unscaled_time);
}
+99 -4
View File
@@ -54,6 +54,7 @@
#include "undo/timelineundoworkarea.h"
#include "widget/menu/menu.h"
#include "widget/menu/menushared.h"
#include "widget/nodeparamview/nodeparamviewundo.h"
#include "widget/nodeparamview/nodeparamview.h"
#include "widget/nodeview/nodeviewundo.h"
#include "widget/timeruler/timeruler.h"
@@ -1109,6 +1110,27 @@ void TimelineWidget::ShowContextMenu()
menu.addSeparator();
if (ClipBlock *clip = dynamic_cast<ClipBlock*>(selected.first())) {
{
Menu *cache_menu = new Menu(tr("Cache"), &menu);
menu.addMenu(cache_menu);
QAction *autocache_action = cache_menu->addAction(tr("Auto-Cache"));
autocache_action->setCheckable(true);
autocache_action->setChecked(clip->IsAutocaching());
connect(autocache_action, &QAction::triggered, this, &TimelineWidget::SetSelectedClipsAutocaching);
cache_menu->addSeparator();
auto cache_clip = cache_menu->addAction(tr("Cache All"));
connect(cache_clip, &QAction::triggered, this, &TimelineWidget::CacheClips);
auto cache_inout = cache_menu->addAction(tr("Cache In/Out"));
connect(cache_inout, &QAction::triggered, this, &TimelineWidget::CacheClipsInOut);
auto cache_discard = cache_menu->addAction(tr("Discard"));
connect(cache_discard, &QAction::triggered, this, &TimelineWidget::CacheDiscard);
}
if (clip->connected_viewer()) {
QAction *reveal_in_footage_viewer = menu.addAction(tr("Reveal in Footage Viewer"));
reveal_in_footage_viewer->setData(reinterpret_cast<quintptr>(clip->connected_viewer()));
@@ -1134,9 +1156,20 @@ void TimelineWidget::ShowContextMenu()
toggle_audio_units->setChecked(use_audio_time_units_);
connect(toggle_audio_units, &QAction::triggered, this, &TimelineWidget::SetUseAudioTimeUnits);
{
Menu *thumbnail_menu = new Menu(tr("Show Thumbnails"), &menu);
menu.addMenu(thumbnail_menu);
thumbnail_menu->AddActionWithData(tr("Disabled"), Timeline::kThumbnailOff, OLIVE_CONFIG("TimelineThumbnailMode"));
thumbnail_menu->AddActionWithData(tr("Only At In Points"), Timeline::kThumbnailInOut, OLIVE_CONFIG("TimelineThumbnailMode"));
thumbnail_menu->AddActionWithData(tr("Enabled"), Timeline::kThumbnailOn, OLIVE_CONFIG("TimelineThumbnailMode"));
connect(thumbnail_menu, &Menu::triggered, this, &TimelineWidget::SetViewThumbnailsEnabled);
}
QAction* show_waveforms = menu.addAction(tr("Show Waveforms"));
show_waveforms->setCheckable(true);
show_waveforms->setChecked(views_.first()->view()->GetShowWaveforms());
show_waveforms->setChecked(OLIVE_CONFIG("TimelineWaveformMode").toInt() == Timeline::kWaveformsEnabled);
connect(show_waveforms, &QAction::triggered, this, &TimelineWidget::SetViewWaveformsEnabled);
menu.addSeparator();
@@ -1200,9 +1233,14 @@ void TimelineWidget::AddableObjectChanged()
void TimelineWidget::SetViewWaveformsEnabled(bool e)
{
foreach (TimelineAndTrackView* tview, views_) {
tview->view()->SetShowWaveforms(e);
}
OLIVE_CONFIG("TimelineWaveformMode") = e ? Timeline::kWaveformsEnabled : Timeline::kWaveformsDisabled;
UpdateViewports();
}
void TimelineWidget::SetViewThumbnailsEnabled(QAction *action)
{
OLIVE_CONFIG("TimelineThumbnailMode") = action->data();
UpdateViewports();
}
void TimelineWidget::FrameRateChanged()
@@ -1276,6 +1314,63 @@ void TimelineWidget::TrackAboutToBeDeleted(Track *track)
}
}
void TimelineWidget::SetSelectedClipsAutocaching(bool e)
{
MultiUndoCommand *command = new MultiUndoCommand();
for (Block *b : selected_blocks_) {
if (ClipBlock *clip = dynamic_cast<ClipBlock*>(b)) {
command->add_child(new NodeParamSetStandardValueCommand(NodeKeyframeTrackReference(NodeInput(clip, ClipBlock::kAutoCacheInput)), e));
}
}
Core::instance()->undo_stack()->pushIfHasChildren(command);
}
void TimelineWidget::CacheClips()
{
for (Block *b : selected_blocks_) {
if (ClipBlock *clip = dynamic_cast<ClipBlock*>(b)) {
clip->RequestInvalidatedFromConnected(true);
}
}
}
void TimelineWidget::CacheClipsInOut()
{
if (!this->sequence() || !this->sequence()->GetWorkArea()->enabled()) {
return;
}
TimeTargetObject tto;
tto.SetTimeTarget(this->sequence());
const TimeRange &r = this->sequence()->GetWorkArea()->range();
for (Block *b : qAsConst(selected_blocks_)) {
if (ClipBlock *clip = dynamic_cast<ClipBlock*>(b)) {
if (Node *connected = clip->GetConnectedOutput(clip->kBufferIn)) {
TimeRange adjusted = tto.GetAdjustedTime(this->sequence(), connected, r, true);
clip->RequestInvalidatedFromConnected(true, adjusted);
}
}
}
}
void TimelineWidget::CacheDiscard()
{
if (QMessageBox::question(this, tr("Discard Cache"),
tr("This will discard all cache for this clip. "
"If the clip has auto-cache enabled, it will be recached immediately. "
"This cannot be undone.\n\n"
"Do you wish to continue?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
for (Block *b : selected_blocks_) {
if (ClipBlock *clip = dynamic_cast<ClipBlock*>(b)) {
clip->DiscardCache();
}
}
}
}
void TimelineWidget::AddGhost(TimelineViewGhostItem *ghost)
{
ghost_items_.append(ghost);
@@ -423,6 +423,8 @@ private slots:
void SetViewWaveformsEnabled(bool e);
void SetViewThumbnailsEnabled(QAction *action);
void FrameRateChanged();
void SampleRateChanged();
@@ -436,6 +438,12 @@ private slots:
void TrackAboutToBeDeleted(Track *track);
void SetSelectedClipsAutocaching(bool e);
void CacheClips();
void CacheClipsInOut();
void CacheDiscard();
};
}
+9 -1
View File
@@ -401,6 +401,8 @@ void ImportTool::DropGhosts(bool insert)
}
}
std::list<ClipBlock*> imported_clips;
if (dst_graph) {
QVector<Block*> block_items(parent()->GetGhostItems().size());
@@ -471,6 +473,8 @@ void ImportTool::DropGhosts(bool insert)
Block::Link(block_items.at(j), clip);
}
}
imported_clips.push_back(clip);
} else if (track_type == Track::kSubtitle) {
Subtitle src = ghost->GetData(TimelineViewGhostItem::kAttachedFootage).value<Subtitle>();
SubtitleBlock *sub = new SubtitleBlock();
@@ -498,6 +502,11 @@ void ImportTool::DropGhosts(bool insert)
Core::instance()->undo_stack()->pushIfHasChildren(command);
while (!imported_clips.empty()) {
imported_clips.front()->RequestInvalidatedFromConnected();
imported_clips.pop_front();
}
parent()->ClearGhosts();
dragged_footage_.clear();
}
@@ -514,7 +523,6 @@ TimelineViewGhostItem* ImportTool::CreateGhost(const TimeRange &range, const rat
snap_points_.push_back(ghost->GetIn());
snap_points_.push_back(ghost->GetOut());
ghost->SetMode(Timeline::kMove);
parent()->AddGhost(ghost);
+5 -5
View File
@@ -24,7 +24,6 @@
#include <QToolTip>
#include "common/clamp.h"
#include "common/flipmodifiers.h"
#include "common/qtutils.h"
#include "common/range.h"
#include "common/timecodefunctions.h"
@@ -410,7 +409,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
@@ -485,7 +484,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));
}
}
@@ -500,7 +499,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
@@ -572,6 +571,7 @@ void PointerTool::ProcessDrag(const TimelineCoordinate &mouse_pos)
break;
case Timeline::kTrimIn:
ghost->SetInAdjustment(time_movement);
ghost->SetMediaInAdjustment(time_movement);
break;
case Timeline::kTrimOut:
ghost->SetOutAdjustment(time_movement);
@@ -707,7 +707,7 @@ void PointerTool::FinishDrag(TimelineViewMouseEvent *event)
block = new_block;
if (ClipBlock *new_clip = dynamic_cast<ClipBlock*>(block)) {
new_clip->waveform() = static_cast<ClipBlock*>(p.block)->waveform();
new_clip->AddCachePassthroughFrom(static_cast<ClipBlock*>(p.block));
}
}
@@ -29,24 +29,20 @@ namespace olive {
//
// BlockSplitCommand
//
void BlockSplitCommand::prepare()
{
reconnect_tree_command_ = new MultiUndoCommand();
new_block_ = static_cast<Block*>(Node::CopyNodeInGraph(block_, reconnect_tree_command_));
}
void BlockSplitCommand::redo()
{
old_length_ = block_->length();
Q_ASSERT(point_ > block_->in() && point_ < block_->out());
if (!reconnect_tree_command_) {
reconnect_tree_command_ = new MultiUndoCommand();
new_block_ = static_cast<Block*>(Node::CopyNodeInGraph(block_, reconnect_tree_command_));
}
reconnect_tree_command_->redo_now();
if (ClipBlock *new_clip = dynamic_cast<ClipBlock*>(new_block_)) {
ClipBlock *old_clip = static_cast<ClipBlock*>(block_);
new_clip->waveform() = old_clip->waveform();
}
// Determine our new lengths
rational new_length = point_ - block_->in();
rational new_part_length = block_->out() - point_;
@@ -61,6 +57,11 @@ void BlockSplitCommand::redo()
// Insert new block
track->InsertBlockAfter(new_block(), block_);
if (ClipBlock *new_clip = dynamic_cast<ClipBlock*>(new_block_)) {
ClipBlock *old_clip = static_cast<ClipBlock*>(block_);
new_clip->AddCachePassthroughFrom(old_clip);
}
// If the block had an out transition, we move it to the new block
moved_transition_ = NodeInput();
@@ -54,6 +54,8 @@ public:
}
protected:
virtual void prepare() override;
virtual void redo() override;
virtual void undo() override;
+79 -12
View File
@@ -28,7 +28,6 @@
#include <QPen>
#include "config/config.h"
#include "common/flipmodifiers.h"
#include "common/qtutils.h"
#include "common/timecodefunctions.h"
#include "node/project/footage/footage.h"
@@ -47,7 +46,6 @@ TimelineView::TimelineView(Qt::Alignment vertical_alignment, QWidget *parent) :
ghosts_(nullptr),
show_beam_cursor_(false),
connected_track_list_(nullptr),
show_waveforms_(true),
transition_overlay_out_(nullptr),
transition_overlay_in_(nullptr)
{
@@ -315,9 +313,9 @@ void TimelineView::drawForeground(QPainter *painter, const QRectF &rect)
qreal old_opacity = painter->opacity();
painter->setOpacity(0.5);
rational in = ghost->GetAdjustedIn(), out = ghost->GetAdjustedOut();
DrawBlock(painter, false, attached, track_top, track_height, in, out);
DrawBlock(painter, true, attached, track_top, track_height, in, out);
rational in = ghost->GetAdjustedIn(), out = ghost->GetAdjustedOut(), media_in = ghost->GetAdjustedMediaIn();
DrawBlock(painter, false, attached, track_top, track_height, in, out, media_in);
DrawBlock(painter, true, attached, track_top, track_height, in, out, media_in);
painter->setOpacity(old_opacity);
}
@@ -466,7 +464,7 @@ void TimelineView::DrawBlocks(QPainter *painter, bool foreground)
}
}
void TimelineView::DrawBlock(QPainter *painter, bool foreground, Block *block, qreal block_top, qreal block_height, const rational &in, const rational &out)
void TimelineView::DrawBlock(QPainter *painter, bool foreground, Block *block, qreal block_top, qreal block_height, const rational &in, const rational &out, const rational &media_in)
{
if (dynamic_cast<ClipBlock*>(block) || dynamic_cast<TransitionBlock*>(block)) {
@@ -486,7 +484,6 @@ void TimelineView::DrawBlock(QPainter *painter, bool foreground, Block *block, q
int text_height = fm.height();
int text_padding = text_height/4; // This ties into the track minimum height being 1.5
int text_total_height = text_height + text_padding + text_padding;
Q_UNUSED(text_total_height)
if (foreground) {
painter->setBrush(Qt::NoBrush);
@@ -521,12 +518,61 @@ void TimelineView::DrawBlock(QPainter *painter, bool foreground, Block *block, q
painter->drawRect(r);
if (ClipBlock *clip = dynamic_cast<ClipBlock*>(block)) {
QRect preview_rect = r.toRect();
// Draw clip thumbnails
if (clip->GetTrackType() == Track::kVideo
&& OLIVE_CONFIG("TimelineThumbnailMode").toInt() != Timeline::kThumbnailOff
&& preview_rect.height() > r.height()/3) {
if (const FrameHashCache *thumbs = clip->thumbnails()) {
// Start thumbnails underneath clip name
preview_rect.adjust(0, text_total_height, 0, 0);
QRect thumb_rect;
painter->setRenderHint(QPainter::SmoothPixmapTransform);
painter->setClipRect(preview_rect);
if (OLIVE_CONFIG("TimelineThumbnailMode") == Timeline::kThumbnailOn) {
Sequence *s = clip->track()->sequence();
int width = s->GetVideoParams().width();
int height = s->GetVideoParams().height();
int start;
if (height > 0) { // Prevent divide by zero/invalid params
double scale = double(preview_rect.height())/double(height);
thumb_rect.setWidth(width * scale);
start = (((preview_rect.left() - int(qFloor(block_in))) / thumb_rect.width()) * thumb_rect.width()) + qFloor(block_in);
} else {
start = preview_rect.left();
}
for (int i=start; i<preview_rect.right(); i+=thumb_rect.width()+1) {
rational time_here = SceneToTime(i - block_in, GetScale(), connected_track_list_->parent()->GetVideoParams().frame_rate_as_time_base()) + media_in;
DrawThumbnail(painter, thumbs, time_here, i, preview_rect, &thumb_rect);
}
} else {
rational time = clip->media_range().in();
time = Timecode::snap_time_to_timebase(time, thumbs->GetTimebase(), Timecode::kFloor);
DrawThumbnail(painter, thumbs, time, block_left, preview_rect, &thumb_rect);
}
painter->setClipping(false);
}
}
// Draw waveform
if (show_waveforms_) {
QRect waveform_rect = r.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()));
if (clip->GetTrackType() == Track::kAudio
&& OLIVE_CONFIG("TimelineWaveformMode").toInt() == Timeline::kWaveformsEnabled) {
if (const AudioWaveformCache *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);
wave->Draw(painter, preview_rect, this->GetScale(), waveform_start);
}
}
// Draw zebra stripes and markers
@@ -594,6 +640,13 @@ void TimelineView::DrawBlock(QPainter *painter, bool foreground, Block *block, q
}
}
}
if (const FrameHashCache *cache = clip->connected_video_cache()) {
if (cache->HasValidatedRanges()) {
QRect cache_rect = r.adjusted(0, r.height() - PlaybackCache::GetCacheIndicatorHeight(), 0, 0).toRect();
cache->Draw(painter, clip->media_in(), GetScale(), cache_rect);
}
}
}
// For transitions, show lines representing a transition
@@ -686,6 +739,20 @@ qreal TimelineView::GetTimelineRightBound() const
return GetTimelineLeftBound() + viewport()->width();
}
void TimelineView::DrawThumbnail(QPainter *painter, const FrameHashCache *thumbs, const rational &time, int x, const QRect &preview_rect, QRect *thumb_rect) const
{
QString thumbnail = thumbs->GetValidCacheFilename(time);
if (!thumbnail.isEmpty()) {
QImage img;
if (img.load(thumbnail, "jpg")) {
double scale = double(preview_rect.height())/double(img.height());
*thumb_rect = QRect(x, preview_rect.top(), img.width() * scale, preview_rect.height());
painter->drawImage(*thumb_rect, img);
}
}
}
int TimelineView::GetTrackY(int track_index) const
{
if (!connected_track_list_ || !connected_track_list_->GetTrackCount()) {
+5 -15
View File
@@ -73,17 +73,6 @@ public:
Block* GetItemAtScenePos(const rational& time, int track_index) const;
bool GetShowWaveforms() const
{
return show_waveforms_;
}
void SetShowWaveforms(bool e)
{
show_waveforms_ = e;
viewport()->update();
}
signals:
void MousePressed(TimelineViewMouseEvent* event);
void MouseMoved(TimelineViewMouseEvent* event);
@@ -126,10 +115,11 @@ private:
void DrawBlocks(QPainter* painter, bool foreground);
void DrawBlock(QPainter *painter, bool foreground, Block *block, qreal top, qreal height, const rational &in, const rational &out);
void DrawBlock(QPainter *painter, bool foreground, Block *block, qreal top, qreal height, const rational &in, const rational &out, const rational &media_in);
void DrawBlock(QPainter *painter, bool foreground, Block *block, qreal top, qreal height)
{
DrawBlock(painter, foreground, block, top, height, block->in(), block->out());
ClipBlock *cb = dynamic_cast<ClipBlock*>(block);
DrawBlock(painter, foreground, block, top, height, block->in(), block->out(), cb ? cb->media_in() : 0);
}
void DrawZebraStripes(QPainter *painter, const QRectF &r);
@@ -142,6 +132,8 @@ private:
qreal GetTimelineRightBound() const;
void DrawThumbnail(QPainter *painter, const FrameHashCache *thumbs, const rational &time, int x, const QRect &preview_rect, QRect *thumb_rect) const;
QHash<Track::Reference, TimeRangeList>* selections_;
QVector<TimelineViewGhostItem*>* ghosts_;
@@ -152,8 +144,6 @@ private:
TrackList* connected_track_list_;
bool show_waveforms_;
ClipBlock *transition_overlay_out_;
ClipBlock *transition_overlay_in_;
+11 -34
View File
@@ -46,7 +46,6 @@ TimeRuler::TimeRuler(bool text_visible, bool cache_status_visible, QWidget* pare
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);
// Text height is used to calculate widget height
cache_status_height_ = text_height() / 4;
// Get the "minimum" space allowed between two line markers on the ruler (in screen pixels)
// Mediocre but reliable way of scaling UI objects by font/DPI size
@@ -180,7 +179,7 @@ void TimeRuler::drawForeground(QPainter *p, const QRectF &rect)
int line_bottom = height();
if (show_cache_status_) {
line_bottom -= cache_status_height_;
line_bottom -= PlaybackCache::GetCacheIndicatorHeight();
}
int long_height = fm.height();
@@ -252,40 +251,18 @@ void TimeRuler::drawForeground(QPainter *p, const QRectF &rect)
}
// If cache status is enabled
if (show_cache_status_ && playback_cache_) {
if (show_cache_status_ && playback_cache_ && playback_cache_->HasValidatedRanges()) {
// FIXME: Hardcoded to get video length, if we ever need audio length, this will have to change
int h = PlaybackCache::GetCacheIndicatorHeight();
QRect cache_rect(0, height() - h, width(), h);
if (ViewerOutput *viewer = dynamic_cast<ViewerOutput*>(playback_cache_->parent())) {
rational len = viewer->GetVideoLength();
int lim_left = GetScroll();
int lim_right = lim_left + width();
int right = TimeToScene(viewer->GetVideoLength());
cache_rect.setWidth(std::max(0, right));
}
int cache_screen_length = TimeToScene(len);
if (cache_screen_length > 0) {
int cache_y = height() - cache_status_height_;
p->fillRect(0, cache_y, cache_screen_length, cache_status_height_, Qt::green);
foreach (const TimeRange& range, playback_cache_->GetInvalidatedRanges(len)) {
int range_left = TimeToScene(range.in());
if (range_left >= width()) {
continue;
}
int range_right = TimeToScene(range.out());
if (range_right < 0) {
continue;
}
int adjusted_left = qMax(lim_left, range_left);
p->fillRect(adjusted_left,
cache_y,
qMin(lim_right, range_right) - adjusted_left,
cache_status_height_,
Qt::red);
}
}
if (cache_rect.width() > 0) {
playback_cache_->Draw(p, SceneToTime(GetScroll()), GetScale(), cache_rect);
}
}
@@ -337,7 +314,7 @@ void TimeRuler::UpdateHeight()
// Add cache status height
if (show_cache_status_) {
height += cache_status_height_;
height += PlaybackCache::GetCacheIndicatorHeight();
}
// Add marker height
-2
View File
@@ -53,8 +53,6 @@ private:
int CacheStatusHeight() const;
int cache_status_height_;
int minimum_gap_between_lines_;
bool text_visible_;
+10 -6
View File
@@ -47,13 +47,13 @@ AudioWaveformView::AudioWaveformView(QWidget *parent) :
setAlignment(Qt::AlignLeft | Qt::AlignTop);
}
void AudioWaveformView::SetViewer(AudioPlaybackCache *playback)
void AudioWaveformView::SetViewer(ViewerOutput *playback)
{
if (playback_) {
pool_.clear();
pool_.waitForDone();
disconnect(playback_, &AudioPlaybackCache::Validated, this, static_cast<void(AudioWaveformView::*)()>(&AudioWaveformView::update));
disconnect(playback_, &ViewerOutput::ConnectedWaveformChanged, this, static_cast<void(AudioWaveformView::*)()>(&AudioWaveformView::update));
SetTimebase(0);
}
@@ -61,9 +61,9 @@ void AudioWaveformView::SetViewer(AudioPlaybackCache *playback)
playback_ = playback;
if (playback_) {
connect(playback_, &AudioPlaybackCache::Validated, this, static_cast<void(AudioWaveformView::*)()>(&AudioWaveformView::update));
connect(playback_, &ViewerOutput::ConnectedWaveformChanged, this, static_cast<void(AudioWaveformView::*)()>(&AudioWaveformView::update));
SetTimebase(playback_->GetParameters().sample_rate_as_time_base());
SetTimebase(playback_->GetAudioParams().sample_rate_as_time_base());
}
}
@@ -75,8 +75,12 @@ void AudioWaveformView::drawForeground(QPainter *p, const QRectF &rect)
return;
}
const AudioParams& params = playback_->GetParameters();
const AudioWaveformCache *wave = playback_->GetConnectedWaveform();
if (!wave) {
return;
}
const AudioParams& params = wave->GetParameters();
if (!params.is_valid()) {
return;
}
@@ -87,7 +91,7 @@ void AudioWaveformView::drawForeground(QPainter *p, const QRectF &rect)
// Draw waveform
p->setPen(QColor(64, 255, 160)); // FIXME: Hardcoded color
AudioVisualWaveform::DrawWaveform(p, rect.toRect(), GetScale(), playback_->visual(), SceneToTime(GetScroll()));
wave->Draw(p, rect.toRect(), GetScale(), SceneToTime(GetScroll()));
// Draw playhead
p->setPen(PLAYHEAD_COLOR);
+2 -2
View File
@@ -36,7 +36,7 @@ class AudioWaveformView : public SeekableWidget
public:
AudioWaveformView(QWidget* parent = nullptr);
void SetViewer(AudioPlaybackCache *playback);
void SetViewer(ViewerOutput *playback);
protected:
virtual void drawForeground(QPainter *painter, const QRectF &rect) override;
@@ -44,7 +44,7 @@ protected:
private:
QThreadPool pool_;
AudioPlaybackCache *playback_;
ViewerOutput *playback_;
};
+22 -26
View File
@@ -147,6 +147,9 @@ ViewerWidget::ViewerWidget(QWidget *parent) :
instances_.append(this);
auto_cacher_ = new PreviewAutoCacher(this);
connect(display_widget_, &ViewerDisplayWidget::ColorProcessorChanged, auto_cacher_, &PreviewAutoCacher::SetDisplayColorProcessor);
UpdateWaveformViewFromMode();
connect(Core::instance(), &Core::ColorPickerEnabled, this, &ViewerWidget::SetSignalCursorColorEnabled);
@@ -193,7 +196,7 @@ void ViewerWidget::TimeChangedEvent(const rational &time)
}
// Send time to auto-cacher
auto_cacher_.SetPlayhead(time);
auto_cacher_->SetPlayhead(time);
last_time_ = time;
}
@@ -231,7 +234,7 @@ void ViewerWidget::ConnectNodeEvent(ViewerOutput *n)
UpdateWaveformViewFromMode();
waveform_view_->SetViewer(GetConnectedNode()->audio_playback_cache());
waveform_view_->SetViewer(GetConnectedNode());
UpdateRendererVideoParameters();
UpdateRendererAudioParameters();
@@ -278,7 +281,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));
}
@@ -382,13 +385,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()->GetWorkArea()->enabled()) {
auto_cacher_.ForceCacheRange(GetConnectedNode()->GetWorkArea()->range());
auto_cacher_->ForceCacheRange(GetConnectedNode()->GetWorkArea()->range());
} else {
QMessageBox::warning(this,
tr("Error"),
@@ -455,12 +458,7 @@ void ViewerWidget::SetEmptyImage()
void ViewerWidget::UpdateAutoCacher()
{
auto_cacher_.SetPlayhead(GetTime());
}
void ViewerWidget::ClearVideoAutoCacherQueue()
{
auto_cacher_.CancelVideoTasks();
auto_cacher_->SetPlayhead(GetTime());
}
void ViewerWidget::DecrementPrequeuedAudio()
@@ -582,7 +580,7 @@ void ViewerWidget::RequestNextDryRun()
} else {
RenderTicketWatcher *watcher = new RenderTicketWatcher(this);
connect(watcher, &RenderTicketWatcher::Finished, this, &ViewerWidget::DryRunFinished);
watcher->SetTicket(auto_cacher_.GetSingleFrame(next_time, true));
watcher->SetTicket(auto_cacher_->GetSingleFrame(next_time, true));
dry_run_next_frame_ += playback_speed_;
dry_run_watchers_.append(watcher);
}
@@ -629,7 +627,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)));
watcher->SetTicket(auto_cacher_->GetRangeOfAudio(TimeRange(audio_playback_queue_time_, queue_end)));
audio_playback_queue_time_ = queue_end;
}
@@ -746,7 +744,7 @@ void ViewerWidget::ForceRequeueFromCurrentTime()
// Allow half a second for requeue to complete
static const rational kRequeueWaitTime(1);
ClearVideoAutoCacherQueue();
auto_cacher_->ClearSingleFrameRenders();
queue_watchers_.clear();
int queue = DeterminePlaybackQueueSize();
playback_queue_next_frame_ = GetTimestamp() + playback_speed_ * Timecode::time_to_timestamp(kRequeueWaitTime, timebase(), Timecode::kFloor);;
@@ -785,9 +783,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()) {
ClearVideoAutoCacherQueue();
}
auto_cacher_->ClearSingleFrameRenders();
watcher->SetTicket(GetFrame(time));
} else {
@@ -816,10 +812,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_.SetAudioPaused(true);
viewer->auto_cacher_->SetRendersPaused(true);
}
RenderManager::instance()->SetAggressiveGarbageCollection(true);
@@ -907,6 +901,7 @@ void ViewerWidget::PauseInternal()
qDeleteAll(queue_watchers_);
queue_watchers_.clear();
auto_cacher_->ClearSingleFrameRenders();
playback_backup_timer_.stop();
@@ -920,7 +915,7 @@ void ViewerWidget::PauseInternal()
UpdateAudioProcessor();
foreach (ViewerWidget* viewer, instances_) {
viewer->auto_cacher_.SetAudioPaused(false);
viewer->auto_cacher_->SetRendersPaused(false);
}
UpdateTextureFromNode();
@@ -945,7 +940,7 @@ void ViewerWidget::PushScrubbedAudio()
if (ignore_scrub_ == 0) {
// Get audio src device from renderer
const AudioParams& params = GetConnectedNode()->audio_playback_cache()->GetParameters();
const AudioParams& params = GetConnectedNode()->GetAudioParams();
if (params.is_valid()) {
// NOTE: Hardcoded scrubbing interval (20ms)
@@ -954,7 +949,7 @@ void ViewerWidget::PushScrubbedAudio()
RenderTicketWatcher *watcher = new RenderTicketWatcher();
connect(watcher, &RenderTicketWatcher::Finished, this, &ViewerWidget::ReceivedAudioBufferForScrubbing);
audio_scrub_watchers_.push_back(watcher);
watcher->SetTicket(auto_cacher_.GetRangeOfAudio(TimeRange(GetTime(), GetTime() + interval)));
watcher->SetTicket(auto_cacher_->GetRangeOfAudio(TimeRange(GetTime(), GetTime() + interval)));
}
}
}
@@ -1033,7 +1028,7 @@ RenderTicketPtr ViewerWidget::GetFrame(const rational &t)
if (!QFileInfo::exists(cache_fn)) {
// Frame hasn't been cached, start render job
return auto_cacher_.GetSingleFrame(t);
return auto_cacher_->GetSingleFrame(t);
} else {
// Frame has been cached, grab the frame
RenderTicketPtr ticket = std::make_shared<RenderTicket>();
@@ -1061,7 +1056,7 @@ void ViewerWidget::FinishPlayPreprocess()
}
prequeued_audio_.clear();
AudioMonitor::StartWaveformOnAll(&GetConnectedNode()->audio_playback_cache()->visual(),
AudioMonitor::StartWaveformOnAll(GetConnectedNode()->GetConnectedWaveform(),
GetTime(), playback_speed_);
}
@@ -1298,6 +1293,7 @@ void ViewerWidget::ShowContextMenu(const QPoint &pos)
menu.addSeparator();
/* TEMP: Hide sequence cache options. Want to see if clip caching supersedes it.
{
Menu* cache_menu = new Menu(tr("Cache"), &menu);
menu.addMenu(cache_menu);
@@ -1309,7 +1305,7 @@ void ViewerWidget::ShowContextMenu(const QPoint &pos)
// Cache In/Out Sequence
QAction* cache_inout_sequence = cache_menu->addAction(tr("Cache Sequence In/Out"));
connect(cache_inout_sequence, &QAction::triggered, this, &ViewerWidget::CacheSequenceInOut);
}
}*/
menu.addSeparator();
+1 -3
View File
@@ -226,8 +226,6 @@ private:
void UpdateAutoCacher();
void ClearVideoAutoCacherQueue();
void DecrementPrequeuedAudio();
void ArmForRecording();
@@ -274,7 +272,7 @@ private:
int prequeue_length_;
int prequeue_count_;
PreviewAutoCacher auto_cacher_;
PreviewAutoCacher *auto_cacher_;
QVector<RenderTicketWatcher*> queue_watchers_;
+1
View File
@@ -34,6 +34,7 @@
#include <QScreen>
#include <QTextEdit>
#include "common/define.h"
#include "common/html.h"
#include "common/qtutils.h"
#include "config/config.h"