+ if(current_frame_ >= info_.duration)\r
+ return dest_producer_->receive(flags);\r
+ \r
+ ++current_frame_;\r
+\r
+ event_subject_ << monitor::event("transition/frame") % current_frame_ % info_.duration\r
+ << monitor::event("transition/type") % [&]() -> std::string\r
+ {\r
+ switch(info_.type.value())\r
+ {\r
+ case transition_type::mix: return "mix";\r
+ case transition_type::wipe: return "wipe";\r
+ case transition_type::slide: return "slide";\r
+ case transition_type::push: return "push";\r
+ case transition_type::cut: return "cut";\r
+ default: return "n/a";\r
+ }\r
+ }();\r
+\r
+ auto dest = draw_frame::empty();\r
+ auto source = draw_frame::empty();\r
+\r
+ tbb::parallel_invoke(\r
+ [&]\r
+ {\r
+ dest = dest_producer_->receive(flags);\r
+ if(dest == core::draw_frame::late())\r
+ dest = dest_producer_->last_frame();\r
+ },\r
+ [&]\r
+ {\r
+ source = source_producer_->receive(flags);\r
+ if(source == core::draw_frame::late())\r
+ source = source_producer_->last_frame();\r
+ }); \r
+\r
+ return compose(dest, source);\r