ui: draw clip cache on timeline
This commit is contained in:
@@ -292,6 +292,8 @@ void ClipBlock::InputConnectedEvent(const QString &input, int element, Node *out
|
|||||||
if (input == kBufferIn) {
|
if (input == kBufferIn) {
|
||||||
connect(output->thumbnail_cache(), &FrameHashCache::Validated, this, &Block::PreviewChanged);
|
connect(output->thumbnail_cache(), &FrameHashCache::Validated, this, &Block::PreviewChanged);
|
||||||
connect(output->waveform_cache(), &AudioPlaybackCache::Validated, this, &Block::PreviewChanged);
|
connect(output->waveform_cache(), &AudioPlaybackCache::Validated, this, &Block::PreviewChanged);
|
||||||
|
connect(output->video_frame_cache(), &FrameHashCache::Validated, this, &Block::PreviewChanged);
|
||||||
|
connect(output->audio_playback_cache(), &AudioPlaybackCache::Validated, this, &Block::PreviewChanged);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -302,6 +304,8 @@ void ClipBlock::InputDisconnectedEvent(const QString &input, int element, Node *
|
|||||||
if (input == kBufferIn) {
|
if (input == kBufferIn) {
|
||||||
disconnect(output->thumbnail_cache(), &FrameHashCache::Validated, this, &Block::PreviewChanged);
|
disconnect(output->thumbnail_cache(), &FrameHashCache::Validated, this, &Block::PreviewChanged);
|
||||||
disconnect(output->waveform_cache(), &AudioPlaybackCache::Validated, this, &Block::PreviewChanged);
|
disconnect(output->waveform_cache(), &AudioPlaybackCache::Validated, this, &Block::PreviewChanged);
|
||||||
|
disconnect(output->video_frame_cache(), &FrameHashCache::Validated, this, &Block::PreviewChanged);
|
||||||
|
disconnect(output->audio_playback_cache(), &AudioPlaybackCache::Validated, this, &Block::PreviewChanged);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -122,6 +122,15 @@ public:
|
|||||||
return block_links_;
|
return block_links_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const FrameHashCache *connected_video_cache() const
|
||||||
|
{
|
||||||
|
if (Node *n = GetConnectedOutput(kBufferIn)) {
|
||||||
|
return n->video_frame_cache();
|
||||||
|
} else {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const FrameHashCache *thumbnails()
|
const FrameHashCache *thumbnails()
|
||||||
{
|
{
|
||||||
if (Node *n = GetConnectedOutput(kBufferIn)) {
|
if (Node *n = GetConnectedOutput(kBufferIn)) {
|
||||||
|
|||||||
@@ -127,6 +127,32 @@ void PlaybackCache::SaveState()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PlaybackCache::Draw(QPainter *p, const rational &start, double scale, const QRect &rect) const
|
||||||
|
{
|
||||||
|
p->fillRect(rect, Qt::red);
|
||||||
|
|
||||||
|
foreach (const TimeRange& range, GetValidatedRanges()) {
|
||||||
|
int range_left = rect.left() + (range.in() - start).toDouble() * scale;
|
||||||
|
if (range_left >= rect.right()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int range_right = rect.left() + (range.out() - start).toDouble() * scale;
|
||||||
|
if (range_right < rect.left()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int adjusted_left = std::max(range_left, rect.left());
|
||||||
|
int adjusted_right = std::min(range_right, rect.right());
|
||||||
|
|
||||||
|
p->fillRect(adjusted_left,
|
||||||
|
rect.top(),
|
||||||
|
adjusted_right - adjusted_left,
|
||||||
|
rect.height(),
|
||||||
|
Qt::green);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void PlaybackCache::InvalidateAll()
|
void PlaybackCache::InvalidateAll()
|
||||||
{
|
{
|
||||||
Invalidate(TimeRange(0, RATIONAL_MAX));
|
Invalidate(TimeRange(0, RATIONAL_MAX));
|
||||||
@@ -156,7 +182,7 @@ PlaybackCache::PlaybackCache(QObject *parent) :
|
|||||||
uuid_ = QUuid::createUuid();
|
uuid_ = QUuid::createUuid();
|
||||||
}
|
}
|
||||||
|
|
||||||
TimeRangeList PlaybackCache::GetInvalidatedRanges(TimeRange intersecting)
|
TimeRangeList PlaybackCache::GetInvalidatedRanges(TimeRange intersecting) const
|
||||||
{
|
{
|
||||||
TimeRangeList invalidated;
|
TimeRangeList invalidated;
|
||||||
|
|
||||||
@@ -174,7 +200,7 @@ TimeRangeList PlaybackCache::GetInvalidatedRanges(TimeRange intersecting)
|
|||||||
return invalidated;
|
return invalidated;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PlaybackCache::HasInvalidatedRanges(const TimeRange &intersecting)
|
bool PlaybackCache::HasInvalidatedRanges(const TimeRange &intersecting) const
|
||||||
{
|
{
|
||||||
return !validated_.contains(intersecting);
|
return !validated_.contains(intersecting);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
#include <QPainter>
|
||||||
#include <QUuid>
|
#include <QUuid>
|
||||||
|
|
||||||
#include "common/jobtime.h"
|
#include "common/jobtime.h"
|
||||||
@@ -43,14 +44,14 @@ public:
|
|||||||
const QUuid &GetUuid() const { return uuid_; }
|
const QUuid &GetUuid() const { return uuid_; }
|
||||||
void SetUuid(const QUuid &u) { uuid_ = u; }
|
void SetUuid(const QUuid &u) { uuid_ = u; }
|
||||||
|
|
||||||
TimeRangeList GetInvalidatedRanges(TimeRange intersecting);
|
TimeRangeList GetInvalidatedRanges(TimeRange intersecting) const;
|
||||||
TimeRangeList GetInvalidatedRanges(const rational &length)
|
TimeRangeList GetInvalidatedRanges(const rational &length) const
|
||||||
{
|
{
|
||||||
return GetInvalidatedRanges(TimeRange(0, length));
|
return GetInvalidatedRanges(TimeRange(0, length));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HasInvalidatedRanges(const TimeRange &intersecting);
|
bool HasInvalidatedRanges(const TimeRange &intersecting) const;
|
||||||
bool HasInvalidatedRanges(const rational &length)
|
bool HasInvalidatedRanges(const rational &length) const
|
||||||
{
|
{
|
||||||
return HasInvalidatedRanges(TimeRange(0, length));
|
return HasInvalidatedRanges(TimeRange(0, length));
|
||||||
}
|
}
|
||||||
@@ -59,6 +60,7 @@ public:
|
|||||||
|
|
||||||
void Invalidate(const TimeRange& r);
|
void Invalidate(const TimeRange& r);
|
||||||
|
|
||||||
|
bool HasValidatedRanges() const { return !validated_.isEmpty(); }
|
||||||
const TimeRangeList &GetValidatedRanges() const { return validated_; }
|
const TimeRangeList &GetValidatedRanges() const { return validated_; }
|
||||||
|
|
||||||
Node *parent() const;
|
Node *parent() const;
|
||||||
@@ -69,6 +71,13 @@ public:
|
|||||||
void LoadState();
|
void LoadState();
|
||||||
void SaveState();
|
void SaveState();
|
||||||
|
|
||||||
|
void Draw(QPainter *painter, const rational &start, double scale, const QRect &rect) const;
|
||||||
|
|
||||||
|
static int GetCacheIndicatorHeight()
|
||||||
|
{
|
||||||
|
return QFontMetrics(QFont()).height()/4;
|
||||||
|
}
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void InvalidateAll();
|
void InvalidateAll();
|
||||||
|
|
||||||
|
|||||||
@@ -603,6 +603,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
|
// For transitions, show lines representing a transition
|
||||||
|
|||||||
@@ -46,7 +46,6 @@ TimeRuler::TimeRuler(bool text_visible, bool cache_status_visible, QWidget* pare
|
|||||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);
|
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);
|
||||||
|
|
||||||
// Text height is used to calculate widget height
|
// 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)
|
// 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
|
// Mediocre but reliable way of scaling UI objects by font/DPI size
|
||||||
@@ -181,7 +180,7 @@ void TimeRuler::drawForeground(QPainter *p, const QRectF &rect)
|
|||||||
int line_bottom = height();
|
int line_bottom = height();
|
||||||
|
|
||||||
if (show_cache_status_) {
|
if (show_cache_status_) {
|
||||||
line_bottom -= cache_status_height_;
|
line_bottom -= PlaybackCache::GetCacheIndicatorHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
int long_height = fm.height();
|
int long_height = fm.height();
|
||||||
@@ -255,38 +254,16 @@ void TimeRuler::drawForeground(QPainter *p, const QRectF &rect)
|
|||||||
// If cache status is enabled
|
// If cache status is enabled
|
||||||
if (show_cache_status_ && playback_cache_) {
|
if (show_cache_status_ && playback_cache_) {
|
||||||
// FIXME: Hardcoded to get video length, if we ever need audio length, this will have to change
|
// 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())) {
|
if (ViewerOutput *viewer = dynamic_cast<ViewerOutput*>(playback_cache_->parent())) {
|
||||||
rational len = viewer->GetVideoLength();
|
int right = TimeToScene(viewer->GetVideoLength());
|
||||||
int lim_left = GetScroll();
|
cache_rect.setWidth(std::max(0, right));
|
||||||
int lim_right = lim_left + width();
|
}
|
||||||
|
|
||||||
int cache_screen_length = TimeToScene(len);
|
if (cache_rect.width() > 0) {
|
||||||
|
playback_cache_->Draw(p, SceneToTime(GetScroll()), GetScale(), cache_rect);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -338,7 +315,7 @@ void TimeRuler::UpdateHeight()
|
|||||||
|
|
||||||
// Add cache status height
|
// Add cache status height
|
||||||
if (show_cache_status_) {
|
if (show_cache_status_) {
|
||||||
height += cache_status_height_;
|
height += PlaybackCache::GetCacheIndicatorHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add marker height
|
// Add marker height
|
||||||
|
|||||||
@@ -53,8 +53,6 @@ private:
|
|||||||
|
|
||||||
int CacheStatusHeight() const;
|
int CacheStatusHeight() const;
|
||||||
|
|
||||||
int cache_status_height_;
|
|
||||||
|
|
||||||
int minimum_gap_between_lines_;
|
int minimum_gap_between_lines_;
|
||||||
|
|
||||||
bool text_visible_;
|
bool text_visible_;
|
||||||
|
|||||||
Reference in New Issue
Block a user