From 5bad7c1c1348fe338b748cff8dbc448155d3ae85 Mon Sep 17 00:00:00 2001 From: ronag Date: Wed, 24 Aug 2011 14:18:44 +0000 Subject: [PATCH] 2.0. core: Simplified layer and frame_producer logic. git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches/2.0.0.2@1274 362d55ac-95cf-4e76-9f9a-cbaa9c17b72d --- core/producer/frame_producer.cpp | 48 ++++++++++++----- core/producer/layer.cpp | 58 +++++++++------------ modules/ffmpeg/producer/ffmpeg_producer.cpp | 9 +--- 3 files changed, 61 insertions(+), 54 deletions(-) diff --git a/core/producer/frame_producer.cpp b/core/producer/frame_producer.cpp index da08185ac..f881d2adb 100644 --- a/core/producer/frame_producer.cpp +++ b/core/producer/frame_producer.cpp @@ -34,16 +34,36 @@ namespace caspar { namespace core { std::vector g_factories; -const safe_ptr& frame_producer::empty() // nothrow +class last_frame_producer : public frame_producer { - struct empty_frame_producer : public frame_producer + const std::wstring print_; + const safe_ptr frame_; + const int64_t nb_frames_; +public: + last_frame_producer(const safe_ptr& producer) + : print_(producer->print()) + , frame_(producer->last_frame() != basic_frame::eof() ? producer->last_frame() : basic_frame::empty()) + , nb_frames_(producer->nb_frames()) { - virtual safe_ptr receive(int){return basic_frame::empty();} - virtual safe_ptr last_frame() const{return basic_frame::empty();} - virtual void set_frame_factory(const safe_ptr&){} - virtual int64_t nb_frames() const {return 0;} - virtual std::wstring print() const { return L"empty";} - }; + } + + virtual safe_ptr receive(int){return frame_;} + virtual safe_ptr last_frame() const{return frame_;} + virtual std::wstring print() const{return L"dummy[" + print_ + L"]";} + virtual int64_t nb_frames() const {return nb_frames_;} +}; + +struct empty_frame_producer : public frame_producer +{ + virtual safe_ptr receive(int){return basic_frame::empty();} + virtual safe_ptr last_frame() const{return basic_frame::empty();} + virtual void set_frame_factory(const safe_ptr&){} + virtual int64_t nb_frames() const {return 0;} + virtual std::wstring print() const { return L"empty";} +}; + +const safe_ptr& frame_producer::empty() // nothrow +{ static safe_ptr producer = make_safe(); return producer; } @@ -55,11 +75,13 @@ safe_ptr receive_and_follow(safe_ptr& producer, int { CASPAR_LOG(info) << producer->print() << " End Of File."; auto following = producer->get_following_producer(); - following->set_leading_producer(producer); - producer = std::move(following); - - if(producer == frame_producer::empty()) - return basic_frame::eof(); + if(following != frame_producer::empty()) + { + following->set_leading_producer(producer); + producer = std::move(following); + } + else + producer = make_safe(producer); return receive_and_follow(producer, hints); } diff --git a/core/producer/layer.cpp b/core/producer/layer.cpp index c267c611e..7ef42e9fe 100644 --- a/core/producer/layer.cpp +++ b/core/producer/layer.cpp @@ -31,19 +31,19 @@ struct layer::implementation { safe_ptr foreground_; safe_ptr background_; - bool is_paused_; - int auto_play_delta_; int64_t frame_number_; - safe_ptr last_frame_; + int auto_play_delta_; + bool is_paused_; public: implementation() : foreground_(frame_producer::empty()) , background_(frame_producer::empty()) - , is_paused_(false) - , auto_play_delta_(-1) , frame_number_(0) - , last_frame_(core::basic_frame::empty()){} + , auto_play_delta_(std::numeric_limits::min()) + , is_paused_(false) + { + } void pause() { @@ -73,19 +73,24 @@ public: if(background_ != frame_producer::empty()) { background_->set_leading_producer(foreground_); - foreground_ = background_; - frame_number_ = 0; - auto_play_delta_ = -1; - background_ = frame_producer::empty(); + + foreground_ = background_; + background_ = frame_producer::empty(); + frame_number_ = 0; + auto_play_delta_ = std::numeric_limits::min(); } - resume(); + + is_paused_ = false; } void stop() { - foreground_ = frame_producer::empty(); - frame_number_ = 0; - last_frame_ = core::basic_frame::empty(); + foreground_ = frame_producer::empty(); + background_ = background_; + frame_number_ = 0; + auto_play_delta_ = std::numeric_limits::min(); + + is_paused_ = true; } safe_ptr receive() @@ -93,35 +98,20 @@ public: try { if(is_paused_) - return disable_audio(last_frame_); + return disable_audio(foreground_->last_frame()); - const auto frames_left = foreground_->nb_frames() - (++frame_number_) - auto_play_delta_; - auto frame = receive_and_follow(foreground_, frame_producer::NO_HINT); if(frame == core::basic_frame::late()) return foreground_->last_frame(); - - if(auto_play_delta_ >= 0) - { - CASPAR_ASSERT(background_ != core::frame_producer::empty()); - if(frames_left <= 0 || frame == core::basic_frame::eof()) - { - //CASPAR_ASSERT(frame != core::basic_frame::eof() && "Received early EOF. Media duration metadata incorrect."); - - CASPAR_LOG(info) << L"Automatically playing next clip with " << auto_play_delta_ << " frames offset. Frames left: " << frames_left; - - play(); - frame = receive(); - } - } - if(frame == core::basic_frame::eof()) + auto frames_left = foreground_->nb_frames() - (++frame_number_) - auto_play_delta_; + if(frames_left < 1) { - pause(); + play(); return receive(); } - return last_frame_ = frame; + return frame; } catch(...) { diff --git a/modules/ffmpeg/producer/ffmpeg_producer.cpp b/modules/ffmpeg/producer/ffmpeg_producer.cpp index 3b62cf403..3db902f5f 100644 --- a/modules/ffmpeg/producer/ffmpeg_producer.cpp +++ b/modules/ffmpeg/producer/ffmpeg_producer.cpp @@ -65,7 +65,6 @@ struct ffmpeg_producer : public core::frame_producer double fps_; frame_muxer muxer_; - int late_frames_; const int start_; const bool loop_; const size_t length_; @@ -87,7 +86,6 @@ public: , audio_decoder_(input_.context(), frame_factory->get_video_format_desc()) , fps_(video_decoder_.fps()) , muxer_(fps_, frame_factory) - , late_frames_(0) , start_(start) , loop_(loop) , length_(length) @@ -121,11 +119,8 @@ public: { if(input_.eof()) return core::basic_frame::eof(); - else - { + else graph_->add_tag("underflow"); - ++late_frames_; - } } return frame; @@ -194,7 +189,7 @@ public: // TODO: Might need to scale nb_frames av frame_muxer transformations. - return nb_frames + late_frames_ - start_; + return nb_frames - start_; } virtual std::wstring print() const -- 2.39.2