예제 #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<core::frame_producer> create_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::vector<std::wstring>& params)
{
	if(params.empty() || !boost::iequals(params[0], "decklink"))
		return core::frame_producer::empty();

	auto device_index	= get_param(L"DEVICE", params, -1);
	if(device_index == -1)
		device_index = boost::lexical_cast<int>(params.at(1));
	auto filter_str		= get_param(L"FILTER", params); 	
	auto length			= get_param(L"LENGTH", params, std::numeric_limits<uint32_t>::max()); 	
	auto format_desc	= core::video_format_desc::get(get_param(L"FORMAT", params, L"INVALID"));
	
	boost::replace_all(filter_str, L"DEINTERLACE", L"YADIF=0:-1");
	boost::replace_all(filter_str, L"DEINTERLACE_BOB", L"YADIF=1:-1");
	
	if(format_desc.format == core::video_format::invalid)
		format_desc = frame_factory->get_video_format_desc();
			
	return create_producer_print_proxy(
		   create_producer_destroy_proxy(
			make_safe<decklink_producer_proxy>(frame_factory, format_desc, device_index, filter_str, length)));
}