virtual safe_ptr<basic_frame> receive(int hints) override { tbb::parallel_invoke( [&] { if(fill_ == core::basic_frame::late()) fill_ = receive_and_follow(fill_producer_, hints); }, [&] { if(key_ == core::basic_frame::late()) key_ = receive_and_follow(key_producer_, hints | ALPHA_HINT); }); if(fill_ == basic_frame::eof() || key_ == basic_frame::eof()) return basic_frame::eof(); if(fill_ == core::basic_frame::late() || key_ == core::basic_frame::late()) // One of the producers is lagging, keep them in sync. return core::basic_frame::late(); auto frame = basic_frame::fill_and_key(fill_, key_); fill_ = basic_frame::late(); key_ = basic_frame::late(); return last_frame_ = frame; }
safe_ptr<basic_frame> receive(int hints) { try { if(is_paused_) return disable_audio(foreground_->last_frame()); auto frame = receive_and_follow(foreground_, hints); if(frame == core::basic_frame::late()) return foreground_->last_frame(); auto frames_left = static_cast<int64_t>(foreground_->nb_frames()) - static_cast<int64_t>(++frame_number_) - static_cast<int64_t>(auto_play_delta_); if(auto_play_delta_ > -1 && frames_left < 1) { play(); return receive(hints); } return frame; } catch(...) { CASPAR_LOG_CURRENT_EXCEPTION(); stop(); return core::basic_frame::empty(); } }
safe_ptr<basic_frame> receive() { try { if(is_paused_) return disable_audio(foreground_->last_frame()); 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(); } }
virtual safe_ptr<basic_frame> receive(int hints) override { if(++current_frame_ >= info_.duration) return basic_frame::eof(); auto dest = basic_frame::empty(); auto source = basic_frame::empty(); 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(); }); monitor_subject_ << monitor::message("/transition/frame") % static_cast<std::int32_t>(current_frame_) % static_cast<std::int32_t>(info_.duration) << monitor::message("/transition/type") % [&]() -> std::string { switch(info_.type) { case transition::mix: return "mix"; case transition::wipe: return "wipe"; case transition::slide: return "slide"; case transition::push: return "push"; case transition::cut: return "cut"; default: return "n/a"; } }(); return compose(dest, source); }
virtual safe_ptr<basic_frame> receive(int hints) { if(++current_frame_ >= info_.duration) return basic_frame::eof(); auto dest = basic_frame::empty(); auto source = basic_frame::empty(); 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 compose(dest, source); }
safe_ptr<basic_frame> receive_and_follow(safe_ptr<frame_producer>& producer, int hints) { auto frame = producer->receive(hints); if(frame == basic_frame::eof()) { CASPAR_LOG(info) << producer->print() << " End Of File."; auto following = producer->get_following_producer(); if(following != frame_producer::empty()) { following->set_leading_producer(producer); producer = std::move(following); } else producer = make_safe<last_frame_producer>(producer); return receive_and_follow(producer, hints); } return frame; }
safe_ptr<basic_frame> receive(int hints) { try { monitor_subject_ << monitor::message("/paused") % is_paused_; if(is_paused_) { if(foreground_->last_frame() == basic_frame::empty()) foreground_->receive(frame_producer::NO_HINT); return disable_audio(foreground_->last_frame()); } auto foreground = foreground_; auto frame = receive_and_follow(foreground, hints); if(foreground != foreground_) set_foreground(foreground); if(frame == core::basic_frame::late()) return foreground_->last_frame(); auto frames_left = static_cast<int64_t>(foreground_->nb_frames()) - static_cast<int64_t>(++frame_number_) - static_cast<int64_t>(auto_play_delta_); if(auto_play_delta_ > -1 && frames_left < 1) { play(); return receive(hints); } return frame; } catch(...) { CASPAR_LOG_CURRENT_EXCEPTION(); stop(); return core::basic_frame::empty(); } }