Skip to content

Commit 4d218f4

Browse files
committed
implement layer level LENGTH override to support AUTO for all producers
1 parent c04143d commit 4d218f4

File tree

5 files changed

+61
-4
lines changed

5 files changed

+61
-4
lines changed

src/core/producer/layer.cpp

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ struct layer::impl
4040

4141
bool auto_play_ = false;
4242
bool paused_ = false;
43+
std::optional<uint32_t> foreground_length_override_;
44+
std::optional<uint32_t> background_length_override_;
4345

4446
public:
4547
impl(const core::video_format_desc format_desc)
@@ -55,6 +57,20 @@ struct layer::impl
5557
{
5658
background_ = std::move(producer);
5759
auto_play_ = auto_play;
60+
background_length_override_.reset(); // Clear any previous length override
61+
62+
if (auto_play_ && foreground_ == frame_producer::empty()) {
63+
play();
64+
} else if (preview_producer) {
65+
preview(true);
66+
}
67+
}
68+
69+
void load(spl::shared_ptr<frame_producer> producer, bool preview_producer, bool auto_play, std::optional<uint32_t> length)
70+
{
71+
background_ = std::move(producer);
72+
auto_play_ = auto_play;
73+
background_length_override_ = length;
5874

5975
if (auto_play_ && foreground_ == frame_producer::empty()) {
6076
play();
@@ -90,6 +106,8 @@ struct layer::impl
90106

91107
foreground_ = std::move(background_);
92108
background_ = frame_producer::empty();
109+
foreground_length_override_ = background_length_override_;
110+
background_length_override_.reset();
93111

94112
auto_play_ = false;
95113
}
@@ -115,7 +133,8 @@ struct layer::impl
115133
auto auto_play_delta = background_->auto_play_delta();
116134
if (auto_play_delta) {
117135
auto time = static_cast<std::int64_t>(foreground_->frame_number());
118-
auto duration = static_cast<std::int64_t>(foreground_->nb_frames());
136+
auto duration = foreground_length_override_ ? static_cast<std::int64_t>(*foreground_length_override_)
137+
: static_cast<std::int64_t>(foreground_->nb_frames());
119138
frames_left = duration - time - *auto_play_delta;
120139
if (frames_left < 1 && field != video_field::b) {
121140
play();
@@ -179,6 +198,10 @@ void layer::load(spl::shared_ptr<frame_producer> frame_producer, bool preview, b
179198
{
180199
return impl_->load(std::move(frame_producer), preview, auto_play);
181200
}
201+
void layer::load(spl::shared_ptr<frame_producer> frame_producer, bool preview, bool auto_play, std::optional<uint32_t> length)
202+
{
203+
return impl_->load(std::move(frame_producer), preview, auto_play, length);
204+
}
182205
void layer::play() { impl_->play(); }
183206
void layer::preview() { impl_->preview(false); }
184207
void layer::pause() { impl_->pause(); }

src/core/producer/layer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ class layer final
4444
void swap(layer& other);
4545

4646
void load(spl::shared_ptr<frame_producer> producer, bool preview, bool auto_play = false);
47+
void load(spl::shared_ptr<frame_producer> producer, bool preview, bool auto_play, std::optional<uint32_t> length);
4748
void play();
4849
void preview();
4950
void pause();

src/core/producer/stage.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,11 @@ struct stage::impl : public std::enable_shared_from_this<impl>
286286
return executor_.begin_invoke([=] { get_layer(index).load(producer, preview, auto_play); });
287287
}
288288

289+
std::future<void> load(int index, const spl::shared_ptr<frame_producer>& producer, bool preview, bool auto_play, std::optional<uint32_t> length)
290+
{
291+
return executor_.begin_invoke([=] { get_layer(index).load(producer, preview, auto_play, length); });
292+
}
293+
289294
std::future<void> preview(int index)
290295
{
291296
return executor_.begin_invoke([=] { get_layer(index).preview(); });
@@ -457,6 +462,10 @@ std::future<void> stage::load(int index, const spl::shared_ptr<frame_producer>&
457462
{
458463
return impl_->load(index, producer, preview, auto_play);
459464
}
465+
std::future<void> stage::load(int index, const spl::shared_ptr<frame_producer>& producer, bool preview, bool auto_play, std::optional<uint32_t> length)
466+
{
467+
return impl_->load(index, producer, preview, auto_play, length);
468+
}
460469
std::future<void> stage::preview(int index) { return impl_->preview(index); }
461470
std::future<void> stage::pause(int index) { return impl_->pause(index); }
462471
std::future<void> stage::resume(int index) { return impl_->resume(index); }
@@ -545,7 +554,12 @@ std::future<frame_transform> stage_delayed::get_current_transform(int index)
545554
std::future<void>
546555
stage_delayed::load(int index, const spl::shared_ptr<frame_producer>& producer, bool preview, bool auto_play)
547556
{
548-
return executor_.begin_invoke([=]() { return stage_->load(index, producer, preview, auto_play).get(); });
557+
return executor_.begin_invoke([=] { return stage_->load(index, producer, preview, auto_play); });
558+
}
559+
std::future<void>
560+
stage_delayed::load(int index, const spl::shared_ptr<frame_producer>& producer, bool preview, bool auto_play, std::optional<uint32_t> length)
561+
{
562+
return executor_.begin_invoke([=] { return stage_->load(index, producer, preview, auto_play, length); });
549563
}
550564
std::future<void> stage_delayed::preview(int index)
551565
{

src/core/producer/stage.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include <mutex>
3838
#include <tuple>
3939
#include <vector>
40+
#include <optional>
4041

4142
namespace caspar::diagnostics {
4243
class graph;
@@ -82,6 +83,8 @@ class stage_base
8283
virtual std::future<frame_transform> get_current_transform(int index) = 0;
8384
virtual std::future<void>
8485
load(int index, const spl::shared_ptr<frame_producer>& producer, bool preview = false, bool auto_play = false) = 0;
86+
virtual std::future<void>
87+
load(int index, const spl::shared_ptr<frame_producer>& producer, bool preview, bool auto_play, std::optional<uint32_t> length) = 0;
8588
virtual std::future<void> preview(int index) = 0;
8689
virtual std::future<void> pause(int index) = 0;
8790
virtual std::future<void> resume(int index) = 0;
@@ -132,6 +135,7 @@ class stage final : public stage_base
132135
const spl::shared_ptr<frame_producer>& producer,
133136
bool preview = false,
134137
bool auto_play = false) override;
138+
std::future<void> load(int index, const spl::shared_ptr<frame_producer>& producer, bool preview, bool auto_play, std::optional<uint32_t> length) override;
135139
std::future<void> preview(int index) override;
136140
std::future<void> pause(int index) override;
137141
std::future<void> resume(int index) override;
@@ -188,6 +192,7 @@ class stage_delayed final : public stage_base
188192
const spl::shared_ptr<frame_producer>& producer,
189193
bool preview = false,
190194
bool auto_play = false) override;
195+
std::future<void> load(int index, const spl::shared_ptr<frame_producer>& producer, bool preview, bool auto_play, std::optional<uint32_t> length) override;
191196
std::future<void> preview(int index) override;
192197
std::future<void> pause(int index) override;
193198
std::future<void> resume(int index) override;

src/protocol/amcp/AMCPCommandsImpl.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -308,9 +308,16 @@ std::wstring loadbg_command(command_context& ctx)
308308
transition_producer = create_transition_producer(new_producer, transitionInfo);
309309
}
310310

311+
// Check for LENGTH parameter for infinite time producers
312+
auto length_param = get_param(L"LENGTH", ctx.parameters, std::optional<uint32_t>{});
313+
311314
// TODO - we should pass the format into load(), so that we can catch it having changed since the producer was
312315
// initialised
313-
ctx.channel.stage->load(ctx.layer_index(), transition_producer, false, auto_play); // TODO: LOOP
316+
if (length_param) {
317+
ctx.channel.stage->load(ctx.layer_index(), transition_producer, false, auto_play, length_param);
318+
} else {
319+
ctx.channel.stage->load(ctx.layer_index(), transition_producer, false, auto_play); // TODO: LOOP
320+
}
314321
} catch (file_not_found&) {
315322
if (contains_param(L"CLEAR_ON_404", ctx.parameters)) {
316323
ctx.channel.stage->load(
@@ -337,7 +344,14 @@ std::wstring load_command(command_context& ctx)
337344
get_producer_dependencies(ctx.channel.raw_channel, ctx), ctx.parameters);
338345
auto transition_producer = create_transition_producer(new_producer, transition_info{});
339346

340-
ctx.channel.stage->load(ctx.layer_index(), transition_producer, true);
347+
// Check for LENGTH parameter for infinite time producers
348+
auto length_param = get_param(L"LENGTH", ctx.parameters, std::optional<uint32_t>{});
349+
350+
if (length_param) {
351+
ctx.channel.stage->load(ctx.layer_index(), transition_producer, true, false, length_param);
352+
} else {
353+
ctx.channel.stage->load(ctx.layer_index(), transition_producer, true);
354+
}
341355
} catch (file_not_found&) {
342356
if (contains_param(L"CLEAR_ON_404", ctx.parameters)) {
343357
ctx.channel.stage->load(

0 commit comments

Comments
 (0)