@@ -290,7 +290,7 @@ bool FFmpegEncoder::WriteAudio(const SampleBuffer &audio)
|
||||
size_t end = audio.sample_count();
|
||||
const size_t max_frame = 48000;
|
||||
|
||||
while (start < end) {
|
||||
while (result && start < end) {
|
||||
// Create input buffer
|
||||
uint8_t** input_data = nullptr;
|
||||
size_t input_sample_count = std::min(end - start, max_frame);
|
||||
|
||||
@@ -458,15 +458,26 @@ void ClipBlock::InputValueChangedEvent(const QString &input, int element)
|
||||
}
|
||||
}
|
||||
|
||||
TimeRange ClipBlock::InputTimeAdjustment(const QString& input, int element, const TimeRange& input_time) const
|
||||
TimeRange ClipBlock::InputTimeAdjustment(const QString& input, int element, const TimeRange& input_time, bool clamp) const
|
||||
{
|
||||
Q_UNUSED(element)
|
||||
|
||||
if (input == kBufferIn) {
|
||||
return TimeRange(SequenceToMediaTime(input_time.in()), SequenceToMediaTime(input_time.out()));
|
||||
rational in = input_time.in();
|
||||
rational out = input_time.out();
|
||||
|
||||
if (clamp) {
|
||||
in = std::max(in, rational(0));
|
||||
out = std::min(out, length());
|
||||
}
|
||||
|
||||
in = SequenceToMediaTime(in);
|
||||
out = SequenceToMediaTime(out);
|
||||
|
||||
return TimeRange(in, out);
|
||||
}
|
||||
|
||||
return super::InputTimeAdjustment(input, element, input_time);
|
||||
return super::InputTimeAdjustment(input, element, input_time, clamp);
|
||||
}
|
||||
|
||||
TimeRange ClipBlock::OutputTimeAdjustment(const QString& input, int element, const TimeRange& input_time) const
|
||||
@@ -540,7 +551,7 @@ void ClipBlock::ConnectedToPreviewEvent()
|
||||
|
||||
TimeRange ClipBlock::media_range() const
|
||||
{
|
||||
return InputTimeAdjustment(kBufferIn, -1, TimeRange(0, length()));
|
||||
return InputTimeAdjustment(kBufferIn, -1, TimeRange(0, length()), false);
|
||||
}
|
||||
|
||||
MultiCamNode *ClipBlock::FindMulticam()
|
||||
|
||||
@@ -68,7 +68,7 @@ public:
|
||||
|
||||
virtual void InvalidateCache(const TimeRange& range, const QString& from, int element, InvalidateCacheOptions options) override;
|
||||
|
||||
virtual TimeRange InputTimeAdjustment(const QString& input, int element, const TimeRange& input_time) const override;
|
||||
virtual TimeRange InputTimeAdjustment(const QString& input, int element, const TimeRange& input_time, bool clamp) const override;
|
||||
|
||||
virtual TimeRange OutputTimeAdjustment(const QString& input, int element, const TimeRange& input_time) const override;
|
||||
|
||||
|
||||
@@ -287,7 +287,7 @@ void TransitionBlock::InputDisconnectedEvent(const QString &input, int element,
|
||||
}
|
||||
}
|
||||
|
||||
TimeRange TransitionBlock::InputTimeAdjustment(const QString &input, int element, const TimeRange &input_time) const
|
||||
TimeRange TransitionBlock::InputTimeAdjustment(const QString &input, int element, const TimeRange &input_time, bool clamp) const
|
||||
{
|
||||
if (input == kInBlockInput || input == kOutBlockInput) {
|
||||
Block* block = dynamic_cast<Block*>(GetConnectedOutput(input));
|
||||
@@ -296,7 +296,7 @@ TimeRange TransitionBlock::InputTimeAdjustment(const QString &input, int element
|
||||
}
|
||||
}
|
||||
|
||||
return super::InputTimeAdjustment(input, element, input_time);
|
||||
return super::InputTimeAdjustment(input, element, input_time, clamp);
|
||||
}
|
||||
|
||||
TimeRange TransitionBlock::OutputTimeAdjustment(const QString &input, int element, const TimeRange &input_time) const
|
||||
|
||||
@@ -83,7 +83,7 @@ protected:
|
||||
|
||||
virtual void InputDisconnectedEvent(const QString& input, int element, Node *output) override;
|
||||
|
||||
virtual TimeRange InputTimeAdjustment(const QString& input, int element, const TimeRange& input_time) const override;
|
||||
virtual TimeRange InputTimeAdjustment(const QString& input, int element, const TimeRange& input_time, bool clamp) const override;
|
||||
|
||||
virtual TimeRange OutputTimeAdjustment(const QString& input, int element, const TimeRange& input_time) const override;
|
||||
|
||||
|
||||
+2
-2
@@ -959,7 +959,7 @@ void Node::InvalidateCache(const TimeRange &range, const QString &from, int elem
|
||||
SendInvalidateCache(range, options);
|
||||
}
|
||||
|
||||
TimeRange Node::InputTimeAdjustment(const QString &, int, const TimeRange &input_time) const
|
||||
TimeRange Node::InputTimeAdjustment(const QString &, int, const TimeRange &input_time, bool clamp) const
|
||||
{
|
||||
// Default behavior is no time adjustment at all
|
||||
return input_time;
|
||||
@@ -1727,7 +1727,7 @@ TimeRange Node::TransformTimeTo(TimeRange time, Node *target, TransformTimeDirec
|
||||
if (dir == kTransformTowardsInput) {
|
||||
for (auto it=path.crbegin(); it!=path.crend(); it++) {
|
||||
const NodeInput &i = (*it);
|
||||
time = i.node()->InputTimeAdjustment(i.input(), i.element(), time);
|
||||
time = i.node()->InputTimeAdjustment(i.input(), i.element(), time, false);
|
||||
}
|
||||
} else {
|
||||
// Traverse in output direction
|
||||
|
||||
+1
-1
@@ -907,7 +907,7 @@ public:
|
||||
* If this node modifies the `time` (i.e. a clip converting sequence time to media time), this function should be
|
||||
* overridden to do so. Also make sure to override OutputTimeAdjustment() to provide the inverse function.
|
||||
*/
|
||||
virtual TimeRange InputTimeAdjustment(const QString& input, int element, const TimeRange& input_time) const;
|
||||
virtual TimeRange InputTimeAdjustment(const QString& input, int element, const TimeRange& input_time, bool clamp) const;
|
||||
|
||||
/**
|
||||
* @brief The inverse of InputTimeAdjustment()
|
||||
|
||||
@@ -146,7 +146,7 @@ void Track::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeVal
|
||||
}
|
||||
}
|
||||
|
||||
TimeRange Track::InputTimeAdjustment(const QString& input, int element, const TimeRange& input_time) const
|
||||
TimeRange Track::InputTimeAdjustment(const QString& input, int element, const TimeRange& input_time, bool clamp) const
|
||||
{
|
||||
if (input == kBlockInput && element >= 0) {
|
||||
int cache_index = GetCacheIndexFromArrayIndex(element);
|
||||
@@ -156,7 +156,7 @@ TimeRange Track::InputTimeAdjustment(const QString& input, int element, const Ti
|
||||
}
|
||||
}
|
||||
|
||||
return Node::InputTimeAdjustment(input, element, input_time);
|
||||
return Node::InputTimeAdjustment(input, element, input_time, clamp);
|
||||
}
|
||||
|
||||
TimeRange Track::OutputTimeAdjustment(const QString& input, int element, const TimeRange& input_time) const
|
||||
@@ -647,16 +647,16 @@ void Track::ProcessAudioTrack(const NodeValueRow &value, const NodeGlobals &glob
|
||||
TimeRange range_for_block(qMax(b->in(), range.in()),
|
||||
qMin(b->out(), range.out()));
|
||||
|
||||
qint64 source_offset = 0;
|
||||
qint64 destination_offset = globals.aparams().time_to_samples(range_for_block.in() - range.in());
|
||||
qint64 max_dest_sz = globals.aparams().time_to_samples(range_for_block.length());
|
||||
|
||||
// Destination buffer
|
||||
SampleBuffer samples_from_this_block = it->second.toSamples();
|
||||
ClipBlock *clip_cast = dynamic_cast<ClipBlock*>(b);
|
||||
|
||||
if (samples_from_this_block.is_allocated()) {
|
||||
// If this is a clip, we might have extra speed/reverse information
|
||||
if (clip_cast) {
|
||||
if (ClipBlock *clip_cast = dynamic_cast<ClipBlock*>(b)) {
|
||||
double speed_value = clip_cast->speed();
|
||||
bool reversed = clip_cast->reverse();
|
||||
|
||||
@@ -711,11 +711,11 @@ void Track::ProcessAudioTrack(const NodeValueRow &value, const NodeGlobals &glob
|
||||
}
|
||||
}
|
||||
|
||||
qint64 copy_length = qMin(max_dest_sz, qint64(samples_from_this_block.sample_count() - destination_offset));
|
||||
qint64 copy_length = qMin(max_dest_sz, qint64(samples_from_this_block.sample_count() - source_offset));
|
||||
|
||||
// Copy samples into destination buffer
|
||||
for (int i=0; i<samples_from_this_block.audio_params().channel_count(); i++) {
|
||||
block_range_buffer.set(i, samples_from_this_block.data(i) + destination_offset, destination_offset, copy_length);
|
||||
block_range_buffer.set(i, samples_from_this_block.data(i) + source_offset, destination_offset, copy_length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ public:
|
||||
virtual ActiveElements GetActiveElementsAtTime(const QString &input, const TimeRange &r) const override;
|
||||
virtual void Value(const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
|
||||
|
||||
virtual TimeRange InputTimeAdjustment(const QString& input, int element, const TimeRange& input_time) const override;
|
||||
virtual TimeRange InputTimeAdjustment(const QString& input, int element, const TimeRange& input_time, bool clamp = false) const override;
|
||||
|
||||
virtual TimeRange OutputTimeAdjustment(const QString& input, int element, const TimeRange& input_time) const override;
|
||||
|
||||
|
||||
@@ -227,11 +227,11 @@ void ViewerOutput::InvalidateCache(const TimeRange& range, const QString& from,
|
||||
if (from == kTextureInput) {
|
||||
//connected->thumbnail_cache()->Request(range.Intersected(max_range), PlaybackCache::kPreviewsOnly);
|
||||
if (autocache_input_video_) {
|
||||
TimeRange max_range = InputTimeAdjustment(from, element, TimeRange(0, GetVideoLength()));
|
||||
TimeRange max_range = InputTimeAdjustment(from, element, TimeRange(0, GetVideoLength()), false);
|
||||
connected->video_frame_cache()->Request(range.Intersected(max_range));
|
||||
}
|
||||
} else if (from == kSamplesInput) {
|
||||
TimeRange max_range = InputTimeAdjustment(from, element, TimeRange(0, GetAudioLength()));
|
||||
TimeRange max_range = InputTimeAdjustment(from, element, TimeRange(0, GetAudioLength()), false);
|
||||
if (waveform_requests_enabled_) {
|
||||
connected->waveform_cache()->Request(range.Intersected(max_range));
|
||||
}
|
||||
@@ -394,7 +394,7 @@ void ViewerOutput::SetWaveformEnabled(bool e)
|
||||
{
|
||||
if ((waveform_requests_enabled_ = e)) {
|
||||
if (Node *connected = this->GetConnectedSampleOutput()) {
|
||||
TimeRange max_range = InputTimeAdjustment(kSamplesInput, -1, TimeRange(0, GetAudioLength()));
|
||||
TimeRange max_range = InputTimeAdjustment(kSamplesInput, -1, TimeRange(0, GetAudioLength()), false);
|
||||
TimeRangeList invalid = connected->waveform_cache()->GetInvalidatedRanges(max_range);
|
||||
for (const TimeRange &r : invalid) {
|
||||
connected->waveform_cache()->Request(r);
|
||||
|
||||
@@ -46,12 +46,12 @@ void TimeOffsetNode::Retranslate()
|
||||
SetInputName(kInputInput, QStringLiteral("Input"));
|
||||
}
|
||||
|
||||
TimeRange TimeOffsetNode::InputTimeAdjustment(const QString &input, int element, const TimeRange &input_time) const
|
||||
TimeRange TimeOffsetNode::InputTimeAdjustment(const QString &input, int element, const TimeRange &input_time, bool clamp) const
|
||||
{
|
||||
if (input == kInputInput) {
|
||||
return TimeRange(GetRemappedTime(input_time.in()), GetRemappedTime(input_time.out()));
|
||||
} else {
|
||||
return super::InputTimeAdjustment(input, element, input_time);
|
||||
return super::InputTimeAdjustment(input, element, input_time, clamp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ public:
|
||||
return tr("Offset time passing through the graph.");
|
||||
}
|
||||
|
||||
virtual TimeRange InputTimeAdjustment(const QString& input, int element, const TimeRange& input_time) const override;
|
||||
virtual TimeRange InputTimeAdjustment(const QString& input, int element, const TimeRange& input_time, bool clamp) const override;
|
||||
virtual TimeRange OutputTimeAdjustment(const QString& input, int element, const TimeRange& input_time) const override;
|
||||
|
||||
virtual void Retranslate() override;
|
||||
|
||||
@@ -58,12 +58,12 @@ QString TimeRemapNode::Description() const
|
||||
return tr("Arbitrarily remap time through the nodes.");
|
||||
}
|
||||
|
||||
TimeRange TimeRemapNode::InputTimeAdjustment(const QString &input, int element, const TimeRange &input_time) const
|
||||
TimeRange TimeRemapNode::InputTimeAdjustment(const QString &input, int element, const TimeRange &input_time, bool clamp) const
|
||||
{
|
||||
if (input == kInputInput) {
|
||||
return TimeRange(GetRemappedTime(input_time.in()), GetRemappedTime(input_time.out()));
|
||||
} else {
|
||||
return super::InputTimeAdjustment(input, element, input_time);
|
||||
return super::InputTimeAdjustment(input, element, input_time, clamp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ public:
|
||||
virtual QVector<CategoryID> Category() const override;
|
||||
virtual QString Description() const override;
|
||||
|
||||
virtual TimeRange InputTimeAdjustment(const QString& input, int element, const TimeRange& input_time) const override;
|
||||
virtual TimeRange InputTimeAdjustment(const QString& input, int element, const TimeRange& input_time, bool clamp) const override;
|
||||
virtual TimeRange OutputTimeAdjustment(const QString& input, int element, const TimeRange& input_time) const override;
|
||||
|
||||
virtual void Retranslate() override;
|
||||
|
||||
@@ -189,7 +189,7 @@ NodeValueTable NodeTraverser::ProcessInput(const Node* node, const QString& inpu
|
||||
// If input is connected, retrieve value directly
|
||||
if (node->IsInputConnectedForRender(input)) {
|
||||
|
||||
TimeRange adjusted_range = node->InputTimeAdjustment(input, -1, range);
|
||||
TimeRange adjusted_range = node->InputTimeAdjustment(input, -1, range, true);
|
||||
|
||||
// Value will equal something from the connected node, follow it
|
||||
Node *output = node->GetConnectedRenderOutput(input);
|
||||
@@ -224,7 +224,7 @@ NodeValueTable NodeTraverser::ProcessInput(const Node* node, const QString& inpu
|
||||
} else {
|
||||
|
||||
// Not connected or an array, just pull the immediate
|
||||
TimeRange adjusted_range = node->InputTimeAdjustment(input, -1, range);
|
||||
TimeRange adjusted_range = node->InputTimeAdjustment(input, -1, range, true);
|
||||
|
||||
return_val = node->GetValueAtTime(input, adjusted_range.in());
|
||||
|
||||
@@ -240,7 +240,7 @@ NodeValueTable NodeTraverser::ProcessInput(const Node* node, const QString& inpu
|
||||
void NodeTraverser::ProcessInputElement(NodeValueTableArray &array_tbl, const Node *node, const QString &input, int element, const TimeRange &range)
|
||||
{
|
||||
NodeValueTable& sub_tbl = array_tbl[element];
|
||||
TimeRange adjusted_range = node->InputTimeAdjustment(input, element, range);
|
||||
TimeRange adjusted_range = node->InputTimeAdjustment(input, element, range, true);
|
||||
|
||||
if (node->IsInputConnectedForRender(input, element)) {
|
||||
Node *output = node->GetConnectedRenderOutput(input, element);
|
||||
|
||||
Reference in New Issue
Block a user