X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=core%2Fproducer%2Ftransition%2Ftransition_producer.cpp;h=66c79b9ee3bfbc03d054b3ad951c5d39e034686e;hb=bb79328678a8758ed9227e6b436aae5f875fee57;hp=f1a03db4fd0865ff2c9964c3eceda33d7725d7ec;hpb=61453874a6d82db915d911a09ae60da2e3694edf;p=casparcg diff --git a/core/producer/transition/transition_producer.cpp b/core/producer/transition/transition_producer.cpp index f1a03db4f..66c79b9ee 100644 --- a/core/producer/transition/transition_producer.cpp +++ b/core/producer/transition/transition_producer.cpp @@ -27,19 +27,21 @@ #include #include +#include + namespace caspar { namespace core { struct transition_producer : public frame_producer { const video_mode::type mode_; - uint32_t current_frame_; + unsigned int current_frame_; const transition_info info_; safe_ptr dest_producer_; safe_ptr source_producer_; - safe_ptr last_dest_; - safe_ptr last_source_; + + safe_ptr last_frame_; explicit transition_producer(const video_mode::type& mode, const safe_ptr& dest, const transition_info& info) : mode_(mode) @@ -47,8 +49,7 @@ struct transition_producer : public frame_producer , info_(info) , dest_producer_(dest) , source_producer_(frame_producer::empty()) - , last_dest_(core::basic_frame::empty()) - , last_source_(core::basic_frame::empty()){} + , last_frame_(basic_frame::empty()){} // frame_producer @@ -62,36 +63,46 @@ struct transition_producer : public frame_producer source_producer_ = producer; } - virtual safe_ptr receive() + virtual safe_ptr receive(int hints) { if(current_frame_++ >= info_.duration) return basic_frame::eof(); - tbb::parallel_invoke - ( - [&]{last_dest_ = receive_and_follow_w_last(dest_producer_, last_dest_);}, - [&]{last_source_ = receive_and_follow_w_last(source_producer_, last_source_);} - ); + auto dest = basic_frame::empty(); + auto source = basic_frame::empty(); - return compose(last_dest_, last_source_); + tbb::parallel_invoke( + [&] + { + dest = receive_and_follow(dest_producer_, hints); + if(dest == core::basic_frame::late()) + dest = dest_producer_->last_frame(); + }, + [&] + { + source = receive_and_follow(source_producer_, hints); + if(source == core::basic_frame::late()) + source = source_producer_->last_frame(); + }); + + return last_frame_ = compose(dest, source); } - virtual std::wstring print() const + virtual safe_ptr last_frame() const { - return L"transition"; + return disable_audio(last_frame_); } - safe_ptr receive_and_follow_w_last(safe_ptr& producer, safe_ptr last_frame) + virtual int64_t nb_frames() const { - auto frame = core::receive_and_follow(producer); - if(frame == basic_frame::late()) - { - last_frame->get_audio_transform().set_has_audio(false); - frame = last_frame; - } - return frame; + return get_following_producer()->nb_frames(); } + virtual std::wstring print() const + { + return L"transition[" + source_producer_->print() + L"|" + dest_producer_->print() + L"]"; + } + // transition_producer safe_ptr compose(const safe_ptr& dest_frame, const safe_ptr& src_frame) @@ -99,10 +110,10 @@ struct transition_producer : public frame_producer if(info_.type == transition::cut) return src_frame; - double delta1 = info_.tweener(current_frame_*2-1, 0.0, 1.0, info_.duration*2); - double delta2 = info_.tweener(current_frame_*2, 0.0, 1.0, info_.duration*2); + const double delta1 = info_.tweener(current_frame_*2-1, 0.0, 1.0, info_.duration*2); + const double delta2 = info_.tweener(current_frame_*2, 0.0, 1.0, info_.duration*2); - double dir = info_.direction == transition_direction::from_left ? 1.0 : -1.0; + const double dir = info_.direction == transition_direction::from_left ? 1.0 : -1.0; // For interlaced transitions. Seperate fields into seperate frames which are transitioned accordingly. @@ -121,7 +132,10 @@ struct transition_producer : public frame_producer if(info_.type == transition::mix) { d_frame1->get_image_transform().set_opacity(delta1); - d_frame2->get_image_transform().set_opacity(delta2); + d_frame2->get_image_transform().set_opacity(delta2); + + //s_frame1->get_image_transform().set_opacity(1.0-delta1); + //s_frame2->get_image_transform().set_opacity(1.0-delta2); } else if(info_.type == transition::slide) { @@ -138,12 +152,12 @@ struct transition_producer : public frame_producer } else if(info_.type == transition::wipe) { - d_frame1->get_image_transform().set_key_scale(delta1, 1.0); - d_frame2->get_image_transform().set_key_scale(delta2, 1.0); + d_frame1->get_image_transform().set_clip_scale(delta1, 1.0); + d_frame2->get_image_transform().set_clip_scale(delta2, 1.0); } - auto s_frame = s_frame1->get_image_transform() == s_frame2->get_image_transform() ? s_frame2 : basic_frame::interlace(s_frame1, s_frame2, mode_); - auto d_frame = d_frame1->get_image_transform() == d_frame2->get_image_transform() ? d_frame2 : basic_frame::interlace(d_frame1, d_frame2, mode_); + const auto s_frame = s_frame1->get_image_transform() == s_frame2->get_image_transform() ? s_frame2 : basic_frame::interlace(s_frame1, s_frame2, mode_); + const auto d_frame = d_frame1->get_image_transform() == d_frame2->get_image_transform() ? d_frame2 : basic_frame::interlace(d_frame1, d_frame2, mode_); return basic_frame::combine(s_frame, d_frame); }