예제 #1
0
	virtual safe_ptr<basic_frame> receive(int) override
	{
		auto format_desc = consumer_->get_video_format_desc();

		if(frame_buffer_.size() > 0)
		{
			auto frame = frame_buffer_.front();
			frame_buffer_.pop();
			return last_frame_ = frame;
		}
		
		auto read_frame = consumer_->receive();
		if(!read_frame || read_frame->image_data().empty())
			return basic_frame::late();		

		frame_number_++;
		
		core::pixel_format_desc desc;
		bool double_speed	= std::abs(frame_factory_->get_video_format_desc().fps / 2.0 - format_desc.fps) < 0.01;		
		bool half_speed		= std::abs(format_desc.fps / 2.0 - frame_factory_->get_video_format_desc().fps) < 0.01;

		if(half_speed && frame_number_ % 2 == 0) // Skip frame
			return receive(0);

		desc.pix_fmt = core::pixel_format::bgra;
		desc.planes.push_back(core::pixel_format_desc::plane(format_desc.width, format_desc.height, 4));
		auto frame = frame_factory_->create_frame(this, desc, read_frame->multichannel_view().channel_layout());

		bool copy_audio = !double_speed && !half_speed;

		if (copy_audio)
		{
			frame->audio_data().reserve(read_frame->audio_data().size());
			boost::copy(read_frame->audio_data(), std::back_inserter(frame->audio_data()));
		}

		fast_memcpy(frame->image_data().begin(), read_frame->image_data().begin(), read_frame->image_data().size());
		frame->commit();

		frame_buffer_.push(frame);	
		
		if(double_speed)	
			frame_buffer_.push(frame);

		return receive(0);
	}	
예제 #2
0
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;
}
예제 #3
0
파일: layer.cpp 프로젝트: AronVietti/Server
	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();
		}
	}