implement entire project in nodes
Project items are now represented directly in nodes opening up more versatility and possibilities. This is the first iteration of this and will be buggy. Need to test thoroughly.
This commit is contained in:
@@ -21,7 +21,6 @@
|
||||
#ifndef COLORPROCESSORCACHE_H
|
||||
#define COLORPROCESSORCACHE_H
|
||||
|
||||
#include "project/item/footage/stream.h"
|
||||
#include "render/colorprocessor.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
@@ -18,6 +18,7 @@ set(OLIVE_SOURCES
|
||||
${OLIVE_SOURCES}
|
||||
render/job/acceleratedjob.cpp
|
||||
render/job/acceleratedjob.h
|
||||
render/job/footagejob.h
|
||||
render/job/generatejob.h
|
||||
render/job/samplejob.h
|
||||
render/job/shaderjob.h
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2020 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#ifndef FOOTAGEJOB_H
|
||||
#define FOOTAGEJOB_H
|
||||
|
||||
#include "project/item/footage/footage.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
class FootageJob
|
||||
{
|
||||
public:
|
||||
FootageJob() = default;
|
||||
|
||||
FootageJob(const Footage::StreamReference& ref, const TimeRange& range) :
|
||||
footage_(ref),
|
||||
range_(range)
|
||||
{
|
||||
}
|
||||
|
||||
const Footage::StreamReference& footage() const
|
||||
{
|
||||
return footage_;
|
||||
}
|
||||
|
||||
const TimeRange& range() const
|
||||
{
|
||||
return range_;
|
||||
}
|
||||
|
||||
private:
|
||||
Footage::StreamReference footage_;
|
||||
|
||||
TimeRange range_;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Q_DECLARE_METATYPE(olive::FootageJob)
|
||||
|
||||
#endif // FOOTAGEJOB_H
|
||||
@@ -437,10 +437,12 @@ void OpenGLRenderer::Blit(QVariant s, ShaderJob job, Texture *destination, Video
|
||||
case NodeValue::kRational:
|
||||
case NodeValue::kFont:
|
||||
case NodeValue::kFile:
|
||||
case NodeValue::kVideoStreamProperties:
|
||||
case NodeValue::kAudioStreamProperties:
|
||||
case NodeValue::kShaderJob:
|
||||
case NodeValue::kSampleJob:
|
||||
case NodeValue::kGenerateJob:
|
||||
case NodeValue::kFootage:
|
||||
case NodeValue::kFootageJob:
|
||||
case NodeValue::kNone:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -151,12 +151,7 @@ Project *PlaybackCache::GetProject() const
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Sequence* sequence = static_cast<Sequence*>(viewer->parent());
|
||||
if (!sequence) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return sequence->project();
|
||||
return viewer->project();
|
||||
}
|
||||
|
||||
void PlaybackCache::RemoveRangeFromJobs(const TimeRange &remove)
|
||||
|
||||
@@ -59,7 +59,7 @@ void PreviewAutoCacher::SetPaused(bool paused)
|
||||
}
|
||||
}
|
||||
|
||||
void PreviewAutoCacher::GenerateHashes(ViewerOutput *viewer, FrameHashCache* cache, const QVector<rational> ×, qint64 job_time)
|
||||
void PreviewAutoCacher::GenerateHashes(Sequence *viewer, FrameHashCache* cache, const QVector<rational> ×, qint64 job_time)
|
||||
{
|
||||
std::vector<QByteArray> existing_hashes;
|
||||
|
||||
@@ -289,6 +289,9 @@ void PreviewAutoCacher::AddNode(Node *node)
|
||||
// Copy node
|
||||
Node* copy = node->copy();
|
||||
|
||||
// Add to project
|
||||
copy->setParent(&copied_project_);
|
||||
|
||||
// Insert into map
|
||||
copy_map_.insert(node, copy);
|
||||
|
||||
@@ -339,8 +342,8 @@ void PreviewAutoCacher::UpdateAudioParams()
|
||||
|
||||
void PreviewAutoCacher::SetPlayhead(const rational &playhead)
|
||||
{
|
||||
cache_range_ = TimeRange(playhead - Config::Current()["DiskCacheBehind"].value<rational>(),
|
||||
playhead + Config::Current()["DiskCacheAhead"].value<rational>());
|
||||
cache_range_ = TimeRange(playhead - Config::Current()[QStringLiteral("DiskCacheBehind")].value<rational>(),
|
||||
playhead + Config::Current()[QStringLiteral("DiskCacheAhead")].value<rational>());
|
||||
|
||||
has_changed_ = true;
|
||||
use_custom_range_ = false;
|
||||
@@ -588,7 +591,7 @@ void PreviewAutoCacher::ForceCacheRange(const TimeRange &range)
|
||||
RequeueFrames();
|
||||
}
|
||||
|
||||
void PreviewAutoCacher::SetViewerNode(ViewerOutput *viewer_node)
|
||||
void PreviewAutoCacher::SetViewerNode(Sequence *viewer_node)
|
||||
{
|
||||
if (viewer_node_ == viewer_node) {
|
||||
return;
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "node/graph.h"
|
||||
#include "node/node.h"
|
||||
#include "node/output/viewer/viewer.h"
|
||||
#include "project/project.h"
|
||||
#include "render/colormanager.h"
|
||||
#include "threading/threadticketwatcher.h"
|
||||
|
||||
@@ -28,7 +29,7 @@ public:
|
||||
/**
|
||||
* @brief Set the viewer node to auto-cache
|
||||
*/
|
||||
void SetViewerNode(ViewerOutput *viewer_node);
|
||||
void SetViewerNode(Sequence *viewer_node);
|
||||
|
||||
/**
|
||||
* @brief If the mouse is held during the next cache invalidation, cache anyway
|
||||
@@ -91,7 +92,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
static void GenerateHashes(ViewerOutput* viewer, FrameHashCache *cache, const QVector<rational>& times, qint64 job_time);
|
||||
static void GenerateHashes(Sequence *viewer, FrameHashCache *cache, const QVector<rational>& times, qint64 job_time);
|
||||
|
||||
void TryRender();
|
||||
|
||||
@@ -131,11 +132,13 @@ private:
|
||||
NodeOutput output;
|
||||
};
|
||||
|
||||
ViewerOutput* viewer_node_;
|
||||
Sequence* viewer_node_;
|
||||
|
||||
Project copied_project_;
|
||||
|
||||
QVector<QueuedJob> graph_update_queue_;
|
||||
QHash<Node*, Node*> copy_map_;
|
||||
ViewerOutput* copied_viewer_node_;
|
||||
Sequence* copied_viewer_node_;
|
||||
|
||||
bool paused_;
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
#define RENDERCACHE_H
|
||||
|
||||
#include "codec/decoder.h"
|
||||
#include "project/item/footage/stream.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
@@ -40,7 +39,7 @@ private:
|
||||
|
||||
};
|
||||
|
||||
using DecoderCache = RenderCache<Stream*, DecoderPtr>;
|
||||
using DecoderCache = RenderCache<Decoder::CodecStream, DecoderPtr>;
|
||||
using ShaderCache = RenderCache<QString, QVariant>;
|
||||
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#ifndef RENDERCONTEXT_H
|
||||
#define RENDERCONTEXT_H
|
||||
|
||||
#include <QMutex>
|
||||
#include <QObject>
|
||||
#include <QVariant>
|
||||
|
||||
|
||||
@@ -94,13 +94,13 @@ QByteArray RenderManager::Hash(const Node *n, const VideoParams ¶ms, const r
|
||||
hasher.addData(reinterpret_cast<const char*>(&format), sizeof(VideoParams::Format));
|
||||
|
||||
if (n) {
|
||||
n->Hash(hasher, time);
|
||||
n->Hash(Node::kDefaultOutput, hasher, time);
|
||||
}
|
||||
|
||||
return hasher.result();
|
||||
}
|
||||
|
||||
RenderTicketPtr RenderManager::RenderFrame(ViewerOutput* viewer, ColorManager* color_manager,
|
||||
RenderTicketPtr RenderManager::RenderFrame(Sequence* viewer, ColorManager* color_manager,
|
||||
const rational& time, RenderMode::Mode mode,
|
||||
FrameHashCache* cache, bool prioritize)
|
||||
{
|
||||
@@ -118,7 +118,7 @@ RenderTicketPtr RenderManager::RenderFrame(ViewerOutput* viewer, ColorManager* c
|
||||
prioritize);
|
||||
}
|
||||
|
||||
RenderTicketPtr RenderManager::RenderFrame(ViewerOutput* viewer, ColorManager* color_manager,
|
||||
RenderTicketPtr RenderManager::RenderFrame(Sequence* viewer, ColorManager* color_manager,
|
||||
const rational& time, RenderMode::Mode mode,
|
||||
const VideoParams &video_params, const AudioParams &audio_params,
|
||||
const QSize& force_size,
|
||||
@@ -157,12 +157,12 @@ RenderTicketPtr RenderManager::RenderFrame(ViewerOutput* viewer, ColorManager* c
|
||||
return ticket;
|
||||
}
|
||||
|
||||
RenderTicketPtr RenderManager::RenderAudio(ViewerOutput* viewer, const TimeRange& r, bool generate_waveforms, bool prioritize)
|
||||
RenderTicketPtr RenderManager::RenderAudio(Sequence* viewer, const TimeRange& r, bool generate_waveforms, bool prioritize)
|
||||
{
|
||||
return RenderAudio(viewer, r, viewer->audio_params(), generate_waveforms, prioritize);
|
||||
}
|
||||
|
||||
RenderTicketPtr RenderManager::RenderAudio(ViewerOutput* viewer, const TimeRange &r, const AudioParams ¶ms, bool generate_waveforms, bool prioritize)
|
||||
RenderTicketPtr RenderManager::RenderAudio(Sequence* viewer, const TimeRange &r, const AudioParams ¶ms, bool generate_waveforms, bool prioritize)
|
||||
{
|
||||
// Create ticket
|
||||
RenderTicketPtr ticket = std::make_shared<RenderTicket>();
|
||||
|
||||
@@ -80,10 +80,10 @@ public:
|
||||
*
|
||||
* This function is thread-safe.
|
||||
*/
|
||||
RenderTicketPtr RenderFrame(ViewerOutput* viewer, ColorManager* color_manager,
|
||||
RenderTicketPtr RenderFrame(Sequence *viewer, ColorManager* color_manager,
|
||||
const rational& time, RenderMode::Mode mode,
|
||||
FrameHashCache* cache = nullptr, bool prioritize = false);
|
||||
RenderTicketPtr RenderFrame(ViewerOutput* viewer, ColorManager* color_manager,
|
||||
RenderTicketPtr RenderFrame(Sequence* viewer, ColorManager* color_manager,
|
||||
const rational& time, RenderMode::Mode mode,
|
||||
const VideoParams& video_params, const AudioParams& audio_params,
|
||||
const QSize& force_size,
|
||||
@@ -101,8 +101,8 @@ public:
|
||||
*
|
||||
* This function is thread-safe.
|
||||
*/
|
||||
RenderTicketPtr RenderAudio(ViewerOutput* viewer, const TimeRange& r, const AudioParams& params, bool generate_waveforms, bool prioritize = false);
|
||||
RenderTicketPtr RenderAudio(ViewerOutput* viewer, const TimeRange& r, bool generate_waveforms, bool prioritize = false);
|
||||
RenderTicketPtr RenderAudio(Sequence* viewer, const TimeRange& r, const AudioParams& params, bool generate_waveforms, bool prioritize = false);
|
||||
RenderTicketPtr RenderAudio(Sequence *viewer, const TimeRange& r, bool generate_waveforms, bool prioritize = false);
|
||||
|
||||
RenderTicketPtr SaveFrameToCache(FrameHashCache* cache, FramePtr frame, const QByteArray& hash, bool prioritize = false);
|
||||
|
||||
|
||||
@@ -54,11 +54,11 @@ void RenderProcessor::Run()
|
||||
switch (type) {
|
||||
case RenderManager::kTypeVideo:
|
||||
{
|
||||
ViewerOutput* viewer = Node::ValueToPtr<ViewerOutput>(ticket_->property("viewer"));
|
||||
Sequence* viewer = Node::ValueToPtr<Sequence>(ticket_->property("viewer"));
|
||||
const VideoParams& video_params = ticket_->property("vparam").value<VideoParams>();
|
||||
rational time = ticket_->property("time").value<rational>();
|
||||
|
||||
NodeValueTable table = ProcessInput(viewer, ViewerOutput::kTextureInput,
|
||||
NodeValueTable table = ProcessInput(viewer, Sequence::kTextureInput,
|
||||
TimeRange(time, time + video_params.time_base()));
|
||||
|
||||
TexturePtr texture = table.Get(NodeValue::kTexture).value<TexturePtr>();
|
||||
@@ -130,10 +130,10 @@ void RenderProcessor::Run()
|
||||
}
|
||||
case RenderManager::kTypeAudio:
|
||||
{
|
||||
ViewerOutput* viewer = Node::ValueToPtr<ViewerOutput>(ticket_->property("viewer"));
|
||||
Sequence* viewer = Node::ValueToPtr<Sequence>(ticket_->property("viewer"));
|
||||
TimeRange time = ticket_->property("time").value<TimeRange>();
|
||||
|
||||
NodeValueTable table = ProcessInput(viewer, ViewerOutput::kSamplesInput, time);
|
||||
NodeValueTable table = ProcessInput(viewer, Sequence::kSamplesInput, time);
|
||||
|
||||
ticket_->Finish(table.Get(NodeValue::kSamples), IsCancelled());
|
||||
break;
|
||||
@@ -153,9 +153,9 @@ void RenderProcessor::Run()
|
||||
}
|
||||
}
|
||||
|
||||
DecoderPtr RenderProcessor::ResolveDecoderFromInput(Stream *stream)
|
||||
DecoderPtr RenderProcessor::ResolveDecoderFromInput(const QString& decoder_id, const Decoder::CodecStream &stream)
|
||||
{
|
||||
if (!stream) {
|
||||
if (!stream.IsValid()) {
|
||||
qWarning() << "Attempted to resolve the decoder of a null stream";
|
||||
return nullptr;
|
||||
}
|
||||
@@ -166,13 +166,13 @@ DecoderPtr RenderProcessor::ResolveDecoderFromInput(Stream *stream)
|
||||
|
||||
if (!decoder) {
|
||||
// No decoder
|
||||
decoder = Decoder::CreateFromID(stream->footage()->decoder());
|
||||
decoder = Decoder::CreateFromID(decoder_id);
|
||||
|
||||
if (decoder->Open(stream)) {
|
||||
decoder_cache_->insert(stream, decoder);
|
||||
} else {
|
||||
qWarning() << "Failed to open decoder for" << stream->footage()->filename()
|
||||
<< "::" << stream->index();
|
||||
qWarning() << "Failed to open decoder for" << stream.filename()
|
||||
<< "::" << stream.stream();
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
@@ -262,32 +262,35 @@ NodeValueTable RenderProcessor::GenerateBlockTable(const Track *track, const Tim
|
||||
}
|
||||
}
|
||||
|
||||
QVariant RenderProcessor::ProcessVideoFootage(VideoStream *video_stream, const rational &input_time)
|
||||
QVariant RenderProcessor::ProcessVideoFootage(const Footage::StreamReference &stream, const rational &input_time)
|
||||
{
|
||||
TexturePtr value = nullptr;
|
||||
|
||||
// Check the still frame cache. On large frames such as high resolution still images, uploading
|
||||
// and color managing them for every frame is a waste of time, so we implement a small cache here
|
||||
// to optimize such a situation
|
||||
const VideoParams& video_params = ticket_->property("vparam").value<VideoParams>();
|
||||
const VideoParams& render_params = ticket_->property("vparam").value<VideoParams>();
|
||||
VideoParams stream_params = stream.video_params();
|
||||
|
||||
ColorManager* color_manager = Node::ValueToPtr<ColorManager>(ticket_->property("colormanager"));
|
||||
|
||||
// See if we can make this divider larger (i.e. if the fooage is smaller)
|
||||
int footage_divider = video_params.divider();
|
||||
int footage_divider = render_params.divider();
|
||||
while (footage_divider > 1
|
||||
&& VideoParams::GetScaledDimension(video_stream->width(), footage_divider-1) < video_params.effective_width()
|
||||
&& VideoParams::GetScaledDimension(video_stream->height(), footage_divider-1) < video_params.effective_height()) {
|
||||
&& VideoParams::GetScaledDimension(stream_params.width(), footage_divider-1) < render_params.effective_width()
|
||||
&& VideoParams::GetScaledDimension(stream_params.height(), footage_divider-1) < render_params.effective_height()) {
|
||||
footage_divider--;
|
||||
}
|
||||
|
||||
Stream stream_data = stream.GetStream();
|
||||
|
||||
StillImageCache::EntryPtr want_entry = std::make_shared<StillImageCache::Entry>(
|
||||
nullptr,
|
||||
video_stream,
|
||||
ColorProcessor::GenerateID(color_manager, video_stream->colorspace(), color_manager->GetReferenceColorSpace()),
|
||||
video_stream->premultiplied_alpha(),
|
||||
stream,
|
||||
ColorProcessor::GenerateID(color_manager, stream.video_colorspace(), color_manager->GetReferenceColorSpace()),
|
||||
stream_data.premultiplied_alpha(),
|
||||
footage_divider,
|
||||
(video_stream->video_type() == VideoStream::kVideoTypeStill) ? 0 : input_time,
|
||||
(stream_data.video_type() == Stream::kVideoTypeStill) ? 0 : input_time,
|
||||
true);
|
||||
|
||||
bool found_existing = false;
|
||||
@@ -324,11 +327,31 @@ QVariant RenderProcessor::ProcessVideoFootage(VideoStream *video_stream, const r
|
||||
|
||||
still_image_cache_->mutex()->unlock();
|
||||
|
||||
DecoderPtr decoder = ResolveDecoderFromInput(video_stream);
|
||||
QString decoder_id = stream.footage()->decoder();
|
||||
|
||||
DecoderPtr decoder = nullptr;
|
||||
|
||||
if (stream_data.video_type() == Stream::kVideoTypeVideo) {
|
||||
decoder = ResolveDecoderFromInput(decoder_id, Decoder::GetCodecStreamFromStreamReference(stream));
|
||||
} else {
|
||||
// Since image sequences involve multiple files, we don't engage the decoder cache
|
||||
decoder = Decoder::CreateFromID(decoder_id);
|
||||
|
||||
QString frame_filename;
|
||||
|
||||
if (stream_data.video_type() == Stream::kVideoTypeImageSequence) {
|
||||
int64_t frame_number = stream.GetTimeInTimebaseUnits(input_time);
|
||||
frame_filename = Decoder::TransformImageSequenceFileName(stream.filename(), frame_number);
|
||||
} else {
|
||||
frame_filename = stream.filename();
|
||||
}
|
||||
|
||||
// Decoder will close automatically since it's a stream_ptr
|
||||
decoder->Open(Decoder::CodecStream(frame_filename, stream.index()));
|
||||
}
|
||||
|
||||
if (decoder) {
|
||||
FramePtr frame = decoder->RetrieveVideo(input_time,
|
||||
footage_divider);
|
||||
FramePtr frame = decoder->RetrieveVideo((stream_data.video_type() == Stream::kVideoTypeVideo) ? input_time : Decoder::kAnyTimecode, footage_divider);
|
||||
|
||||
if (frame) {
|
||||
// Return a texture from the derived class
|
||||
@@ -339,15 +362,17 @@ QVariant RenderProcessor::ProcessVideoFootage(VideoStream *video_stream, const r
|
||||
// We convert to our rendering pixel format, since that will always be float-based which
|
||||
// is necessary for correct color conversion
|
||||
VideoParams managed_params = frame->video_params();
|
||||
managed_params.set_format(video_params.format());
|
||||
managed_params.set_format(render_params.format());
|
||||
managed_params.set_pixel_aspect_ratio(stream_data.pixel_aspect_ratio());
|
||||
managed_params.set_interlacing(stream_data.interlacing());
|
||||
value = render_ctx_->CreateTexture(managed_params);
|
||||
|
||||
ColorProcessorPtr processor = ColorProcessor::Create(color_manager,
|
||||
video_stream->colorspace(),
|
||||
stream.video_colorspace(),
|
||||
color_manager->GetReferenceColorSpace());
|
||||
|
||||
render_ctx_->BlitColorManaged(processor, unmanaged_texture,
|
||||
video_stream->premultiplied_alpha(),
|
||||
stream_data.premultiplied_alpha(),
|
||||
value.get());
|
||||
|
||||
still_image_cache_->mutex()->lock();
|
||||
@@ -366,16 +391,18 @@ QVariant RenderProcessor::ProcessVideoFootage(VideoStream *video_stream, const r
|
||||
return QVariant::fromValue(value);
|
||||
}
|
||||
|
||||
QVariant RenderProcessor::ProcessAudioFootage(AudioStream *stream, const TimeRange &input_time)
|
||||
QVariant RenderProcessor::ProcessAudioFootage(const Footage::StreamReference &stream, const TimeRange &input_time)
|
||||
{
|
||||
QVariant value;
|
||||
|
||||
DecoderPtr decoder = ResolveDecoderFromInput(stream);
|
||||
DecoderPtr decoder = ResolveDecoderFromInput(stream.footage()->decoder(), Decoder::GetCodecStreamFromStreamReference(stream));
|
||||
|
||||
if (decoder) {
|
||||
const AudioParams& audio_params = ticket_->property("aparam").value<AudioParams>();
|
||||
|
||||
SampleBufferPtr frame = decoder->RetrieveAudio(input_time, audio_params, &IsCancelled());
|
||||
SampleBufferPtr frame = decoder->RetrieveAudio(input_time, audio_params,
|
||||
stream.footage()->project()->cache_path(),
|
||||
&IsCancelled());
|
||||
|
||||
if (frame) {
|
||||
value = QVariant::fromValue(frame);
|
||||
|
||||
@@ -43,9 +43,9 @@ public:
|
||||
protected:
|
||||
virtual NodeValueTable GenerateBlockTable(const Track *track, const TimeRange &range) override;
|
||||
|
||||
virtual QVariant ProcessVideoFootage(VideoStream* video_stream, const rational &input_time) override;
|
||||
virtual QVariant ProcessVideoFootage(const Footage::StreamReference &stream, const rational &input_time) override;
|
||||
|
||||
virtual QVariant ProcessAudioFootage(AudioStream* stream, const TimeRange &input_time) override;
|
||||
virtual QVariant ProcessAudioFootage(const Footage::StreamReference &stream, const TimeRange &input_time) override;
|
||||
|
||||
virtual QVariant ProcessShader(const Node *node, const TimeRange &range, const ShaderJob& job) override;
|
||||
|
||||
@@ -62,7 +62,7 @@ private:
|
||||
|
||||
void Run();
|
||||
|
||||
DecoderPtr ResolveDecoderFromInput(Stream* stream);
|
||||
DecoderPtr ResolveDecoderFromInput(const QString &decoder_id, const Decoder::CodecStream& stream);
|
||||
|
||||
RenderTicketPtr ticket_;
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include <QWaitCondition>
|
||||
|
||||
#include "common/rational.h"
|
||||
#include "project/item/footage/videostream.h"
|
||||
#include "project/item/footage/footage.h"
|
||||
#include "render/texture.h"
|
||||
|
||||
namespace olive {
|
||||
@@ -14,7 +14,7 @@ class StillImageCache
|
||||
{
|
||||
public:
|
||||
struct Entry {
|
||||
Entry(TexturePtr t, VideoStream* s, const QString& cs, bool a, int d, const rational& i, bool w)
|
||||
Entry(TexturePtr t, const Footage::StreamReference& s, const QString& cs, bool a, int d, const rational& i, bool w)
|
||||
{
|
||||
texture = t;
|
||||
stream = s;
|
||||
@@ -26,7 +26,7 @@ public:
|
||||
}
|
||||
|
||||
TexturePtr texture;
|
||||
VideoStream* stream;
|
||||
Footage::StreamReference stream;
|
||||
QString colorspace;
|
||||
bool alpha_is_associated;
|
||||
int divider;
|
||||
|
||||
Reference in New Issue
Block a user