X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=core%2Fproducer%2Flayer.cpp;h=f940d2a9eb6bda491fa0253bc9b376dcbc47fa50;hb=a8e71e9b2452413398ac10f0b6e2dea41cecdec5;hp=0f4ec257467ef326584a227a6aa3f08448d7dea2;hpb=f3e73dd3a59c37f2bde3905b865f0103970aa651;p=casparcg diff --git a/core/producer/layer.cpp b/core/producer/layer.cpp index 0f4ec2574..f940d2a9e 100644 --- a/core/producer/layer.cpp +++ b/core/producer/layer.cpp @@ -23,6 +23,7 @@ #include "layer.h" #include "frame_producer.h" +#include "frame/basic_frame.h" namespace caspar { namespace core { @@ -30,19 +31,34 @@ struct layer::implementation { safe_ptr foreground_; safe_ptr background_; + int64_t frame_number_; + int auto_play_delta_; bool is_paused_; + public: implementation() : foreground_(frame_producer::empty()) , background_(frame_producer::empty()) - , is_paused_(false){} + , frame_number_(0) + , auto_play_delta_(-1) + , is_paused_(false) + { + } - void pause(){is_paused_ = true;} - void resume(){is_paused_ = false;} + void pause() + { + is_paused_ = true; + } - void load(const safe_ptr& producer, bool preview) + void resume() + { + is_paused_ = false; + } + + void load(const safe_ptr& producer, bool preview, int auto_play_delta) { - background_ = producer; + background_ = producer; + auto_play_delta_ = auto_play_delta; if(preview) // Play the first frame and pause. { @@ -57,23 +73,69 @@ public: if(background_ != frame_producer::empty()) { background_->set_leading_producer(foreground_); - foreground_ = background_; - background_ = frame_producer::empty(); + + foreground_ = background_; + background_ = frame_producer::empty(); + frame_number_ = 0; + auto_play_delta_ = -1; } - resume(); + + is_paused_ = false; } void stop() { - foreground_ = frame_producer::empty(); + foreground_ = frame_producer::empty(); + background_ = background_; + frame_number_ = 0; + auto_play_delta_ = -1; + + is_paused_ = true; } safe_ptr receive() { - if(is_paused_) - return foreground_->last_frame(); + try + { + if(is_paused_) + return disable_audio(foreground_->last_frame()); - return receive_and_follow_w_last(foreground_); + auto frame = receive_and_follow(foreground_, frame_producer::NO_HINT); + if(frame == core::basic_frame::late()) + return foreground_->last_frame(); + + auto frames_left = foreground_->nb_frames() - (++frame_number_) - auto_play_delta_; + if(auto_play_delta_ > -1 && frames_left < 1) + { + play(); + return receive(); + } + + return frame; + } + catch(...) + { + CASPAR_LOG_CURRENT_EXCEPTION(); + stop(); + return core::basic_frame::empty(); + } + } + + layer_status status() const + { + layer_status status; + status.foreground = foreground_->print(); + status.background = background_->print(); + status.is_paused = is_paused_; + status.total_frames = foreground_->nb_frames(); + status.current_frame = frame_number_; + + return status; + } + + bool empty() const + { + return background_ == core::frame_producer::empty() && foreground_ == core::frame_producer::empty(); } }; @@ -95,11 +157,15 @@ void layer::swap(layer& other) { impl_.swap(other.impl_); } -void layer::load(const safe_ptr& frame_producer, bool preview){return impl_->load(frame_producer, preview);} +void layer::load(const safe_ptr& frame_producer, bool preview, int auto_play_delta){return impl_->load(frame_producer, preview, auto_play_delta);} void layer::play(){impl_->play();} void layer::pause(){impl_->pause();} void layer::stop(){impl_->stop();} +bool layer::is_paused() const{return impl_->is_paused_;} +int64_t layer::frame_number() const{return impl_->frame_number_;} +layer_status layer::status() const {return impl_->status();} safe_ptr layer::receive() {return impl_->receive();} safe_ptr layer::foreground() const { return impl_->foreground_;} safe_ptr layer::background() const { return impl_->background_;} +bool layer::empty() const {return impl_->empty();} }} \ No newline at end of file