Merge branch 'master' into typos
This commit is contained in:
@@ -26,6 +26,11 @@ const uint64_t &AudioParams::channel_layout() const
|
||||
return channel_layout_;
|
||||
}
|
||||
|
||||
rational AudioParams::time_base() const
|
||||
{
|
||||
return rational(1, sample_rate());
|
||||
}
|
||||
|
||||
AudioRenderingParams::AudioRenderingParams() :
|
||||
format_(SampleFormat::SAMPLE_FMT_INVALID)
|
||||
{
|
||||
|
||||
@@ -14,6 +14,7 @@ public:
|
||||
|
||||
const int& sample_rate() const;
|
||||
const uint64_t& channel_layout() const;
|
||||
rational time_base() const;
|
||||
|
||||
private:
|
||||
int sample_rate_;
|
||||
|
||||
@@ -27,6 +27,8 @@ void AudioRenderBackend::SetParameters(const AudioRenderingParams ¶ms)
|
||||
|
||||
// Regenerate the cache ID
|
||||
RegenerateCacheID();
|
||||
|
||||
emit ParamsChanged();
|
||||
}
|
||||
|
||||
void AudioRenderBackend::ConnectViewer(ViewerOutput *node)
|
||||
@@ -98,6 +100,18 @@ void AudioRenderBackend::ConnectWorkerToThis(RenderWorker *worker)
|
||||
connect(arw, &AudioRenderWorker::ConformUnavailable, this, &AudioRenderBackend::ConformUnavailable, Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
TimeRange AudioRenderBackend::PopNextFrameFromQueue()
|
||||
{
|
||||
TimeRange range = cache_queue_.first();
|
||||
|
||||
// Limit range per worker to 2 seconds (FIXME: arbitrary, should be tweaked, maybe even in config?)
|
||||
range.set_out(qMin(range.out(), range.in() + rational(2)));
|
||||
|
||||
cache_queue_.RemoveTimeRange(range);
|
||||
|
||||
return range;
|
||||
}
|
||||
|
||||
void AudioRenderBackend::ConformUnavailable(StreamPtr stream, const TimeRange &range, const rational &stream_time, const AudioRenderingParams& params)
|
||||
{
|
||||
ConformWaitInfo info = {stream, params, range, stream_time};
|
||||
|
||||
@@ -24,6 +24,9 @@ public:
|
||||
|
||||
QString CachePathName();
|
||||
|
||||
signals:
|
||||
void ParamsChanged();
|
||||
|
||||
protected:
|
||||
virtual void ConnectViewer(ViewerOutput* node) override;
|
||||
|
||||
@@ -44,6 +47,8 @@ protected:
|
||||
|
||||
virtual void ConnectWorkerToThis(RenderWorker* worker) override;
|
||||
|
||||
virtual TimeRange PopNextFrameFromQueue() override;
|
||||
|
||||
QHash<Node*, Node*> copy_map_;
|
||||
|
||||
private:
|
||||
|
||||
@@ -397,6 +397,10 @@ void OpenGLProxy::TextureToBuffer(const QVariant &tex_in, void *buffer)
|
||||
{
|
||||
OpenGLTextureCache::ReferencePtr texture = tex_in.value<OpenGLTextureCache::ReferencePtr>();
|
||||
|
||||
if (!texture) {
|
||||
return;
|
||||
}
|
||||
|
||||
QOpenGLFunctions* f = QOpenGLContext::currentContext()->functions();
|
||||
buffer_.Attach(texture->texture());
|
||||
buffer_.Bind();
|
||||
|
||||
@@ -87,95 +87,41 @@ bool RenderWorker::IsStarted()
|
||||
return started_;
|
||||
}
|
||||
|
||||
NodeValueTable RenderWorker::ProcessNode(const NodeDependency& dep)
|
||||
{
|
||||
const Node* node = dep.node();
|
||||
|
||||
if (node->IsTrack()) {
|
||||
// If the range is not wholly contained in this Block, we'll need to do some extra processing
|
||||
return RenderBlock(static_cast<const TrackOutput*>(node), dep.range());
|
||||
}
|
||||
|
||||
// FIXME: Cache certain values here if we've already processed them before
|
||||
|
||||
// Generate database of input values of node
|
||||
NodeValueDatabase database = GenerateDatabase(node, dep.range());
|
||||
|
||||
// By this point, the node should have all the inputs it needs to render correctly
|
||||
NodeValueTable table = node->Value(database);
|
||||
|
||||
// Check if we have a shader for this output
|
||||
RunNodeAccelerated(node, dep.range(), database, &table);
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
NodeValueTable RenderWorker::ProcessInput(const NodeInput *input, const TimeRange& range)
|
||||
{
|
||||
if (input->IsConnected()) {
|
||||
// Value will equal something from the connected node, follow it
|
||||
return ProcessNode(NodeDependency(input->get_connected_node(), range));
|
||||
} else {
|
||||
// Push onto the table the value at this time from the input
|
||||
QVariant input_value = input->get_value_at_time(range.in());
|
||||
|
||||
NodeValueTable table;
|
||||
table.Push(input->data_type(), input_value);
|
||||
return table;
|
||||
}
|
||||
}
|
||||
|
||||
void RenderWorker::ReportUnavailableFootage(StreamPtr stream, Decoder::RetrieveState state, const rational& stream_time)
|
||||
{
|
||||
emit FootageUnavailable(stream, state, path_.range(), stream_time);
|
||||
}
|
||||
|
||||
void RenderWorker::InputProcessingEvent(NodeInput* input, const TimeRange& input_time, NodeValueTable *table)
|
||||
{
|
||||
// Exception for Footage types where we actually retrieve some Footage data from a decoder
|
||||
if (input->data_type() == NodeParam::kFootage) {
|
||||
StreamPtr stream = ResolveStreamFromInput(input);
|
||||
|
||||
if (stream) {
|
||||
DecoderPtr decoder = ResolveDecoderFromInput(stream);
|
||||
|
||||
if (decoder) {
|
||||
|
||||
Decoder::RetrieveState state = decoder->GetRetrieveState(input_time.out());
|
||||
|
||||
if (state == Decoder::kReady) {
|
||||
FrameToValue(decoder, stream, input_time, table);
|
||||
} else {
|
||||
ReportUnavailableFootage(stream, state, input_time.out());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RenderWorker::ProcessNodeEvent(const Node *node, const TimeRange &range, const NodeValueDatabase &input_params, NodeValueTable* output_params)
|
||||
{
|
||||
// Check if we have a shader for this output
|
||||
RunNodeAccelerated(node, range, input_params, output_params);
|
||||
}
|
||||
|
||||
const NodeDependency &RenderWorker::CurrentPath() const
|
||||
{
|
||||
return path_;
|
||||
}
|
||||
|
||||
|
||||
#include "common/functiontimer.h"
|
||||
NodeValueDatabase RenderWorker::GenerateDatabase(const Node* node, const TimeRange &range)
|
||||
{
|
||||
NodeValueDatabase database;
|
||||
|
||||
// We need to insert tables into the database for each input
|
||||
foreach (NodeParam* param, node->parameters()) {
|
||||
if (IsCancelled()) {
|
||||
return NodeValueDatabase();
|
||||
}
|
||||
|
||||
if (param->type() == NodeParam::kInput) {
|
||||
NodeInput* input = static_cast<NodeInput*>(param);
|
||||
TimeRange input_time = node->InputTimeAdjustment(input, range);
|
||||
|
||||
NodeValueTable table = ProcessInput(input, input_time);
|
||||
|
||||
// Exception for Footage types where we actually retrieve some Footage data from a decoder
|
||||
if (input->data_type() == NodeParam::kFootage) {
|
||||
StreamPtr stream = ResolveStreamFromInput(input);
|
||||
|
||||
if (stream) {
|
||||
DecoderPtr decoder = ResolveDecoderFromInput(stream);
|
||||
|
||||
if (decoder) {
|
||||
|
||||
Decoder::RetrieveState state = decoder->GetRetrieveState(input_time.out());
|
||||
|
||||
if (state == Decoder::kReady) {
|
||||
FrameToValue(decoder, stream, input_time, &table);
|
||||
} else {
|
||||
ReportUnavailableFootage(stream, state, input_time.out());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
database.Insert(input, table);
|
||||
}
|
||||
}
|
||||
|
||||
return database;
|
||||
}
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include "common/cancelableobject.h"
|
||||
#include "common/constructors.h"
|
||||
#include "node/output/track/track.h"
|
||||
#include "node/node.h"
|
||||
#include "decodercache.h"
|
||||
#include "node/node.h"
|
||||
#include "node/output/track/track.h"
|
||||
#include "node/traverser.h"
|
||||
|
||||
class RenderWorker : public QObject, public CancelableObject
|
||||
class RenderWorker : public QObject, public NodeTraverser
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
@@ -38,24 +38,21 @@ protected:
|
||||
|
||||
virtual void RunNodeAccelerated(const Node *node, const TimeRange& range, const NodeValueDatabase &input_params, NodeValueTable* output_params);
|
||||
|
||||
StreamPtr ResolveStreamFromInput(NodeInput* input);
|
||||
DecoderPtr ResolveDecoderFromInput(StreamPtr stream);
|
||||
|
||||
virtual void FrameToValue(DecoderPtr decoder, StreamPtr stream, const TimeRange &range, NodeValueTable* table) = 0;
|
||||
|
||||
NodeValueTable ProcessNode(const NodeDependency &dep);
|
||||
|
||||
virtual NodeValueTable RenderBlock(const TrackOutput *track, const TimeRange& range) = 0;
|
||||
|
||||
NodeValueTable ProcessInput(const NodeInput* input, const TimeRange &range);
|
||||
|
||||
virtual void ReportUnavailableFootage(StreamPtr stream, Decoder::RetrieveState state, const rational& stream_time);
|
||||
|
||||
virtual void InputProcessingEvent(NodeInput *input, const TimeRange &input_time, NodeValueTable* table) override;
|
||||
|
||||
virtual void ProcessNodeEvent(const Node *node, const TimeRange &range, const NodeValueDatabase &input_params, NodeValueTable* output_params) override;
|
||||
|
||||
StreamPtr ResolveStreamFromInput(NodeInput* input);
|
||||
|
||||
DecoderPtr ResolveDecoderFromInput(StreamPtr stream);
|
||||
|
||||
const NodeDependency& CurrentPath() const;
|
||||
|
||||
private:
|
||||
NodeValueDatabase GenerateDatabase(const Node *node, const TimeRange &range);
|
||||
|
||||
bool started_;
|
||||
|
||||
DecoderCache* decoder_cache_;
|
||||
|
||||
@@ -179,6 +179,8 @@ void VideoRenderWorker::HashNodeRecursively(QCryptographicHash *hash, const Node
|
||||
if (stream->type() == Stream::kVideo) {
|
||||
hash->addData(QStringLiteral("%1/%2").arg(QString::number(input_time.numerator()),
|
||||
QString::number(input_time.denominator())).toUtf8());
|
||||
|
||||
hash->addData(QString::number(static_cast<VideoStream*>(stream.get())->start_time()).toUtf8());
|
||||
/*Decoder::RetrieveState state = decoder->GetRetrieveState(input_time);
|
||||
|
||||
if (state == Decoder::kReady) {
|
||||
|
||||
Reference in New Issue
Block a user