git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches/2.0.0.2@1044
362d55ac-95cf-4e76-9f9a-
cbaa9c17b72d
15 files changed:
// frame_producer\r
\r
virtual safe_ptr<basic_frame> receive() { return frame_; } \r
// frame_producer\r
\r
virtual safe_ptr<basic_frame> receive() { return frame_; } \r
+ virtual safe_ptr<basic_frame> last_frame() const { return frame_; } \r
virtual std::wstring print() const { return L"color[" + color_str_ + L"]"; }\r
};\r
\r
virtual std::wstring print() const { return L"color[" + color_str_ + L"]"; }\r
};\r
\r
frames.push_back(fill);\r
return basic_frame(std::move(frames));\r
}\r
frames.push_back(fill);\r
return basic_frame(std::move(frames));\r
}\r
+\r
+safe_ptr<basic_frame> disable_audio(const safe_ptr<basic_frame>& frame)\r
+{\r
+ basic_frame frame2 = frame;\r
+ frame2.get_audio_transform().set_has_audio(false);\r
+ return std::move(frame2);\r
+}\r
\r
}}
\ No newline at end of file
\r
}}
\ No newline at end of file
safe_ptr<implementation> impl_;\r
};\r
\r
safe_ptr<implementation> impl_;\r
};\r
\r
+safe_ptr<basic_frame> disable_audio(const safe_ptr<basic_frame>& frame);\r
+\r
inline bool is_concrete_frame(const safe_ptr<basic_frame>& frame)\r
{\r
return frame != basic_frame::empty() && frame != basic_frame::eof() && frame != basic_frame::late();\r
inline bool is_concrete_frame(const safe_ptr<basic_frame>& frame)\r
{\r
return frame != basic_frame::empty() && frame != basic_frame::eof() && frame != basic_frame::late();\r
\r
std::vector<const producer_factory_t> g_factories;\r
\r
\r
std::vector<const producer_factory_t> g_factories;\r
\r
-frame_producer::frame_producer() : last_frame_(core::basic_frame::empty()){}\r
-\r
const safe_ptr<frame_producer>& frame_producer::empty() // nothrow\r
{\r
struct empty_frame_producer : public frame_producer\r
{\r
virtual safe_ptr<basic_frame> receive(){return basic_frame::empty();}\r
const safe_ptr<frame_producer>& frame_producer::empty() // nothrow\r
{\r
struct empty_frame_producer : public frame_producer\r
{\r
virtual safe_ptr<basic_frame> receive(){return basic_frame::empty();}\r
+ virtual safe_ptr<basic_frame> last_frame() const{return basic_frame::empty();}\r
virtual void set_frame_factory(const safe_ptr<frame_factory>&){}\r
virtual std::wstring print() const { return L"empty";}\r
};\r
virtual void set_frame_factory(const safe_ptr<frame_factory>&){}\r
virtual std::wstring print() const { return L"empty";}\r
};\r
return producer;\r
} \r
\r
return producer;\r
} \r
\r
-safe_ptr<basic_frame> frame_producer::receive_save_last()\r
-{\r
- auto frame = receive();\r
- if(frame != core::basic_frame::late())\r
- {\r
- last_frame_ = make_safe<basic_frame>(frame);\r
- last_frame_->get_audio_transform().set_has_audio(false);\r
- } \r
- return frame;\r
-}\r
-\r
-safe_ptr<basic_frame> receive(const safe_ptr<frame_producer>& producer)\r
-{\r
- return producer->receive_save_last();\r
-}\r
-\r
safe_ptr<basic_frame> receive_and_follow(safe_ptr<frame_producer>& producer)\r
{ \r
if(producer == frame_producer::empty())\r
safe_ptr<basic_frame> receive_and_follow(safe_ptr<frame_producer>& producer)\r
{ \r
if(producer == frame_producer::empty())\r
auto frame = basic_frame::eof();\r
try\r
{\r
auto frame = basic_frame::eof();\r
try\r
{\r
- frame = receive(producer);\r
+ frame = producer->receive();\r
class frame_producer : boost::noncopyable\r
{\r
public:\r
class frame_producer : boost::noncopyable\r
{\r
public:\r
virtual ~frame_producer(){} \r
\r
virtual std::wstring print() const = 0; // nothrow\r
virtual ~frame_producer(){} \r
\r
virtual std::wstring print() const = 0; // nothrow\r
virtual void set_leading_producer(const safe_ptr<frame_producer>&) {} // nothrow\r
\r
virtual int64_t nb_frames() const {return 0;}\r
virtual void set_leading_producer(const safe_ptr<frame_producer>&) {} // nothrow\r
\r
virtual int64_t nb_frames() const {return 0;}\r
-\r
- virtual safe_ptr<core::basic_frame> last_frame() const {return last_frame_;}\r
-\r
- static const safe_ptr<frame_producer>& empty(); // nothrow\r
-private:\r
- friend safe_ptr<basic_frame> receive(const safe_ptr<frame_producer>& producer);\r
-\r
virtual safe_ptr<basic_frame> receive() = 0;\r
virtual safe_ptr<basic_frame> receive() = 0;\r
+ virtual safe_ptr<core::basic_frame> last_frame() const = 0;\r
- safe_ptr<basic_frame> receive_save_last();\r
-\r
- safe_ptr<core::basic_frame> last_frame_;\r
+ static const safe_ptr<frame_producer>& empty(); // nothrow\r
-safe_ptr<basic_frame> receive(const safe_ptr<frame_producer>& producer);\r
safe_ptr<basic_frame> receive_and_follow(safe_ptr<frame_producer>& producer);\r
\r
typedef std::function<safe_ptr<core::frame_producer>(const safe_ptr<frame_factory>&, const std::vector<std::wstring>&)> producer_factory_t;\r
safe_ptr<basic_frame> receive_and_follow(safe_ptr<frame_producer>& producer);\r
\r
typedef std::function<safe_ptr<core::frame_producer>(const safe_ptr<frame_factory>&, const std::vector<std::wstring>&)> producer_factory_t;\r
safe_ptr<frame_producer> key_producer_;\r
safe_ptr<basic_frame> fill_;\r
safe_ptr<basic_frame> key_;\r
safe_ptr<frame_producer> key_producer_;\r
safe_ptr<basic_frame> fill_;\r
safe_ptr<basic_frame> key_;\r
+ safe_ptr<basic_frame> last_frame_;\r
\r
explicit separated_producer(const safe_ptr<frame_producer>& fill, const safe_ptr<frame_producer>& key) \r
: fill_producer_(fill)\r
, key_producer_(key)\r
, fill_(core::basic_frame::late())\r
\r
explicit separated_producer(const safe_ptr<frame_producer>& fill, const safe_ptr<frame_producer>& key) \r
: fill_producer_(fill)\r
, key_producer_(key)\r
, fill_(core::basic_frame::late())\r
- , key_(core::basic_frame::late()){}\r
+ , key_(core::basic_frame::late())\r
+ , last_frame_(core::basic_frame::empty()){}\r
\r
// frame_producer\r
\r
\r
// frame_producer\r
\r
fill_ = basic_frame::late();\r
key_ = basic_frame::late();\r
\r
fill_ = basic_frame::late();\r
key_ = basic_frame::late();\r
\r
+ return last_frame_ = frame;\r
+ }\r
+\r
+ virtual safe_ptr<core::basic_frame> last_frame() const\r
+ {\r
+ return last_frame_;\r
}\r
\r
virtual std::wstring print() const\r
}\r
\r
virtual std::wstring print() const\r
destroy_context_.begin_invoke(std::bind(&destroy_producer, std::move(producer_)));\r
}\r
\r
destroy_context_.begin_invoke(std::bind(&destroy_producer, std::move(producer_)));\r
}\r
\r
- virtual safe_ptr<basic_frame> receive() {return core::receive(producer_);}\r
+ virtual safe_ptr<basic_frame> receive() {return producer_->receive();}\r
+ virtual safe_ptr<basic_frame> last_frame() const {return producer_->last_frame();}\r
virtual std::wstring print() const {return producer_->print();}\r
virtual void param(const std::wstring& str) {producer_->param(str);}\r
virtual safe_ptr<frame_producer> get_following_producer() const {return producer_->get_following_producer();}\r
virtual std::wstring print() const {return producer_->print();}\r
virtual void param(const std::wstring& str) {producer_->param(str);}\r
virtual safe_ptr<frame_producer> get_following_producer() const {return producer_->get_following_producer();}\r
\r
safe_ptr<frame_producer> dest_producer_;\r
safe_ptr<frame_producer> source_producer_;\r
\r
safe_ptr<frame_producer> dest_producer_;\r
safe_ptr<frame_producer> source_producer_;\r
+ safe_ptr<frame_producer> org_dest_producer_;\r
+ safe_ptr<frame_producer> org_source_producer_;\r
+\r
+ safe_ptr<basic_frame> last_frame_;\r
\r
explicit transition_producer(const video_mode::type& mode, const safe_ptr<frame_producer>& dest, const transition_info& info) \r
: mode_(mode)\r
, current_frame_(0)\r
, info_(info)\r
, dest_producer_(dest)\r
\r
explicit transition_producer(const video_mode::type& mode, const safe_ptr<frame_producer>& dest, const transition_info& info) \r
: mode_(mode)\r
, current_frame_(0)\r
, info_(info)\r
, dest_producer_(dest)\r
- , source_producer_(frame_producer::empty()){}\r
+ , org_dest_producer_(dest)\r
+ , source_producer_(frame_producer::empty())\r
+ , org_source_producer_(frame_producer::empty())\r
+ , last_frame_(basic_frame::empty()){}\r
\r
// frame_producer\r
\r
\r
// frame_producer\r
\r
\r
virtual void set_leading_producer(const safe_ptr<frame_producer>& producer)\r
{\r
\r
virtual void set_leading_producer(const safe_ptr<frame_producer>& producer)\r
{\r
- source_producer_ = producer;\r
+ source_producer_ = producer;\r
+ org_source_producer_ = producer;\r
}\r
\r
virtual safe_ptr<basic_frame> receive()\r
}\r
\r
virtual safe_ptr<basic_frame> receive()\r
- return compose(dest, source);\r
+ return last_frame_ = compose(dest, source);\r
+ }\r
+\r
+ virtual safe_ptr<core::basic_frame> last_frame() const\r
+ {\r
+ return last_frame_;\r
}\r
\r
virtual int64_t nb_frames() const \r
}\r
\r
virtual int64_t nb_frames() const \r
\r
virtual std::wstring print() const\r
{\r
\r
virtual std::wstring print() const\r
{\r
- return L"transition";\r
+ return L"transition[" + org_source_producer_->print() + L"|" + org_dest_producer_->print() + L"]";\r
}\r
\r
// transition_producer\r
}\r
\r
// transition_producer\r
\r
class decklink_producer_proxy : public core::frame_producer\r
{ \r
\r
class decklink_producer_proxy : public core::frame_producer\r
{ \r
+ safe_ptr<core::basic_frame> last_frame_;\r
com_context<decklink_producer> context_;\r
public:\r
\r
explicit decklink_producer_proxy(const safe_ptr<core::frame_factory>& frame_factory, const core::video_format_desc& format_desc, size_t device_index, const std::wstring& filter_str = L"")\r
: context_(L"decklink_producer[" + boost::lexical_cast<std::wstring>(device_index) + L"]")\r
com_context<decklink_producer> context_;\r
public:\r
\r
explicit decklink_producer_proxy(const safe_ptr<core::frame_factory>& frame_factory, const core::video_format_desc& format_desc, size_t device_index, const std::wstring& filter_str = L"")\r
: context_(L"decklink_producer[" + boost::lexical_cast<std::wstring>(device_index) + L"]")\r
+ , last_frame_(core::basic_frame::empty())\r
{\r
context_.reset([&]{return new decklink_producer(format_desc, device_index, frame_factory, filter_str);}); \r
}\r
\r
virtual safe_ptr<core::basic_frame> receive()\r
{\r
{\r
context_.reset([&]{return new decklink_producer(format_desc, device_index, frame_factory, filter_str);}); \r
}\r
\r
virtual safe_ptr<core::basic_frame> receive()\r
{\r
- return context_->get_frame();\r
+ return last_frame_ = context_->get_frame();\r
+ }\r
+\r
+ virtual safe_ptr<core::basic_frame> last_frame() const\r
+ {\r
+ return disable_audio(last_frame_);\r
}\r
\r
std::wstring print() const\r
}\r
\r
std::wstring print() const\r
int64_t nb_frames_;\r
bool loop_;\r
\r
int64_t nb_frames_;\r
bool loop_;\r
\r
+ safe_ptr<core::basic_frame> last_frame_;\r
+\r
public:\r
explicit ffmpeg_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::wstring& filename, const std::wstring& filter, bool loop, int start, int length) \r
: filename_(filename)\r
public:\r
explicit ffmpeg_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::wstring& filename, const std::wstring& filter, bool loop, int start, int length) \r
: filename_(filename)\r
, start_(start)\r
, nb_frames_(video_decoder_.nb_frames() - start)\r
, loop_(loop)\r
, start_(start)\r
, nb_frames_(video_decoder_.nb_frames() - start)\r
, loop_(loop)\r
+ , last_frame_(core::basic_frame::empty())\r
{\r
graph_->add_guide("frame-time", 0.5);\r
graph_->set_color("frame-time", diagnostics::color(1.0f, 0.0f, 0.0f));\r
{\r
graph_->add_guide("frame-time", 0.5);\r
graph_->set_color("frame-time", diagnostics::color(1.0f, 0.0f, 0.0f));\r
else \r
frame = muxer_.pop(); \r
\r
else \r
frame = muxer_.pop(); \r
\r
+ return last_frame_ = frame;\r
+ }\r
+\r
+ virtual safe_ptr<core::basic_frame> last_frame() const\r
+ {\r
+ return disable_audio(last_frame_);\r
}\r
\r
void decode_frame()\r
}\r
\r
void decode_frame()\r
flash_producer_->param(str);\r
}\r
\r
flash_producer_->param(str);\r
}\r
\r
- safe_ptr<core::basic_frame> receive()\r
+ virtual safe_ptr<core::basic_frame> receive()\r
- return core::receive(flash_producer_);\r
+ return flash_producer_->receive();\r
+\r
+ virtual safe_ptr<core::basic_frame> last_frame() const\r
+ {\r
+ return flash_producer_->last_frame();\r
+ } \r
\r
std::wstring print() const\r
{\r
\r
std::wstring print() const\r
{\r
cg_producer::cg_producer(const safe_ptr<core::frame_producer>& frame_producer) : impl_(new implementation(frame_producer)){}\r
cg_producer::cg_producer(cg_producer&& other) : impl_(std::move(other.impl_)){}\r
safe_ptr<core::basic_frame> cg_producer::receive(){return impl_->receive();}\r
cg_producer::cg_producer(const safe_ptr<core::frame_producer>& frame_producer) : impl_(new implementation(frame_producer)){}\r
cg_producer::cg_producer(cg_producer&& other) : impl_(std::move(other.impl_)){}\r
safe_ptr<core::basic_frame> cg_producer::receive(){return impl_->receive();}\r
+safe_ptr<core::basic_frame> cg_producer::last_frame() const{return impl_->last_frame();}\r
void cg_producer::add(int layer, const std::wstring& template_name, bool play_on_load, const std::wstring& startFromLabel, const std::wstring& data){impl_->add(layer, template_name, play_on_load, startFromLabel, data);}\r
void cg_producer::remove(int layer){impl_->remove(layer);}\r
void cg_producer::play(int layer){impl_->play(layer);}\r
void cg_producer::add(int layer, const std::wstring& template_name, bool play_on_load, const std::wstring& startFromLabel, const std::wstring& data){impl_->add(layer, template_name, play_on_load, startFromLabel, data);}\r
void cg_producer::remove(int layer){impl_->remove(layer);}\r
void cg_producer::play(int layer){impl_->play(layer);}\r
\r
// frame_producer\r
virtual safe_ptr<core::basic_frame> receive();\r
\r
// frame_producer\r
virtual safe_ptr<core::basic_frame> receive();\r
+ virtual safe_ptr<core::basic_frame> last_frame() const;\r
virtual std::wstring print() const;\r
\r
//cg_producer\r
virtual std::wstring print() const;\r
\r
//cg_producer\r
std::shared_ptr<diagnostics::graph> graph_;\r
\r
tbb::concurrent_bounded_queue<safe_ptr<core::basic_frame>> frame_buffer_;\r
std::shared_ptr<diagnostics::graph> graph_;\r
\r
tbb::concurrent_bounded_queue<safe_ptr<core::basic_frame>> frame_buffer_;\r
+\r
+ safe_ptr<core::basic_frame> last_frame_;\r
\r
com_context<flash_renderer> context_; \r
public:\r
\r
com_context<flash_renderer> context_; \r
public:\r
: filename_(filename) \r
, frame_factory_(frame_factory)\r
, context_(L"flash_producer")\r
: filename_(filename) \r
, frame_factory_(frame_factory)\r
, context_(L"flash_producer")\r
+ , last_frame_(core::basic_frame::empty())\r
{ \r
if(!boost::filesystem::exists(filename))\r
BOOST_THROW_EXCEPTION(file_not_found() << boost::errinfo_file_name(narrow(filename))); \r
{ \r
if(!boost::filesystem::exists(filename))\r
BOOST_THROW_EXCEPTION(file_not_found() << boost::errinfo_file_name(narrow(filename))); \r
\r
auto frame = core::basic_frame::late();\r
frame_buffer_.try_pop(frame); \r
\r
auto frame = core::basic_frame::late();\r
frame_buffer_.try_pop(frame); \r
+ return last_frame_ = frame;\r
+\r
+ virtual safe_ptr<core::basic_frame> last_frame() const\r
+ {\r
+ return last_frame_;\r
+ } \r
\r
virtual void param(const std::wstring& param) \r
{ \r
\r
virtual void param(const std::wstring& param) \r
{ \r
\r
virtual safe_ptr<core::basic_frame> receive(){return frame_;}\r
\r
\r
virtual safe_ptr<core::basic_frame> receive(){return frame_;}\r
\r
+ virtual safe_ptr<core::basic_frame> last_frame() const\r
+ {\r
+ return frame_;\r
+ }\r
+\r
virtual std::wstring print() const\r
{\r
return L"image_producer[" + filename_ + L"]";\r
virtual std::wstring print() const\r
{\r
return L"image_producer[" + filename_ + L"]";\r
int speed_;\r
\r
std::array<double, 2> start_offset_;\r
int speed_;\r
\r
std::array<double, 2> start_offset_;\r
+\r
+ safe_ptr<core::basic_frame> last_frame_;\r
\r
explicit image_scroll_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::wstring& filename, int speed) \r
: filename_(filename)\r
, delta_(0)\r
, format_desc_(frame_factory->get_video_format_desc())\r
, speed_(speed)\r
\r
explicit image_scroll_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::wstring& filename, int speed) \r
: filename_(filename)\r
, delta_(0)\r
, format_desc_(frame_factory->get_video_format_desc())\r
, speed_(speed)\r
+ , last_frame_(core::basic_frame::empty())\r
{\r
start_offset_.assign(0.0);\r
\r
{\r
start_offset_.assign(0.0);\r
\r
\r
virtual safe_ptr<core::basic_frame> receive()\r
{ \r
\r
virtual safe_ptr<core::basic_frame> receive()\r
{ \r
- delta_ = 1;//+= speed_;\r
\r
if(frames_.empty())\r
return core::basic_frame::eof();\r
\r
if(frames_.empty())\r
return core::basic_frame::eof();\r
frames_[n]->get_image_transform().set_fill_translation(start_offset_[0] -0.5*(n+1) + delta_ * 0.5/static_cast<double>(format_desc_.height), start_offset_[1]);\r
}\r
\r
frames_[n]->get_image_transform().set_fill_translation(start_offset_[0] -0.5*(n+1) + delta_ * 0.5/static_cast<double>(format_desc_.height), start_offset_[1]);\r
}\r
\r
- return core::basic_frame(frames_);\r
+ return last_frame_ = core::basic_frame(frames_);\r
+ }\r
+\r
+ virtual safe_ptr<core::basic_frame> last_frame() const\r
+ {\r
+ return last_frame_;\r
}\r
\r
virtual std::wstring print() const\r
}\r
\r
virtual std::wstring print() const\r