X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fdecklink%2Fproducer%2Fdecklink_producer.cpp;h=178b0042c1dd6a3bce18989fca03fef82d34e3b4;hb=11e9ee9363a33cee4f3433c83b1f5fd76b95b57e;hp=54c84152be7b6dd9da1cb8c9d036b2c19f53d17d;hpb=0b0991ee9118226b405a2529ebb4456691d18cb8;p=casparcg diff --git a/modules/decklink/producer/decklink_producer.cpp b/modules/decklink/producer/decklink_producer.cpp index 54c84152b..178b0042c 100644 --- a/modules/decklink/producer/decklink_producer.cpp +++ b/modules/decklink/producer/decklink_producer.cpp @@ -36,7 +36,7 @@ #include #include -#include +#include #include #include @@ -71,7 +71,7 @@ extern "C" #include -namespace caspar { +namespace caspar { namespace decklink { class decklink_producer : boost::noncopyable, public IDeckLinkInputCallback { @@ -91,9 +91,9 @@ class decklink_producer : boost::noncopyable, public IDeckLinkInputCallback tbb::concurrent_bounded_queue> frame_buffer_; std::exception_ptr exception_; - filter filter_; + ffmpeg::filter filter_; - frame_muxer muxer_; + ffmpeg::frame_muxer muxer_; public: decklink_producer(const core::video_format_desc& format_desc, size_t device_index, const safe_ptr& frame_factory, const std::wstring& filter) @@ -104,11 +104,11 @@ public: , device_index_(device_index) , frame_factory_(frame_factory) , filter_(filter) - , muxer_(double_rate(filter) ? format_desc.fps * 2.0 : format_desc.fps, frame_factory) + , muxer_(ffmpeg::double_rate(filter) ? format_desc.fps * 2.0 : format_desc.fps, frame_factory) { frame_buffer_.set_capacity(2); - graph_ = diagnostics::create_graph(boost::bind(&decklink_producer::print, this)); + graph_ = diagnostics::create_graph(narrow(print())); graph_->add_guide("tick-time", 0.5); graph_->set_color("tick-time", diagnostics::color(0.0f, 0.6f, 0.9f)); graph_->set_color("late-frame", diagnostics::color(0.6f, 0.3f, 0.3f)); @@ -124,7 +124,7 @@ public: << msg_info(narrow(print()) + " Could not enable video input.") << boost::errinfo_api_function("EnableVideoInput")); - if(FAILED(input_->EnableAudioInput(bmdAudioSampleRate48kHz, bmdAudioSampleType16bitInteger, 2))) + if(FAILED(input_->EnableAudioInput(bmdAudioSampleRate48kHz, bmdAudioSampleType32bitInteger, format_desc_.audio_channels))) BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(narrow(print()) + " Could not enable audio input.") << boost::errinfo_api_function("EnableAudioInput")); @@ -184,8 +184,8 @@ public: av_frame->format = PIX_FMT_UYVY422; av_frame->width = video->GetWidth(); av_frame->height = video->GetHeight(); - av_frame->interlaced_frame = format_desc_.mode != core::video_mode::progressive; - av_frame->top_field_first = format_desc_.mode == core::video_mode::upper ? 1 : 0; + av_frame->interlaced_frame = format_desc_.field_mode != core::field_mode::progressive; + av_frame->top_field_first = format_desc_.field_mode == core::field_mode::upper ? 1 : 0; BOOST_FOREACH(auto& av_frame2, filter_.execute(av_frame)) muxer_.push(av_frame2); @@ -194,11 +194,11 @@ public: if(audio && SUCCEEDED(audio->GetBytes(&bytes))) { auto sample_frame_count = audio->GetSampleFrameCount(); - auto audio_data = reinterpret_cast(bytes); - muxer_.push(std::make_shared>(audio_data, audio_data + sample_frame_count*2)); + auto audio_data = reinterpret_cast(bytes); + muxer_.push(std::make_shared(audio_data, audio_data + sample_frame_count*format_desc_.audio_channels)); } else - muxer_.push(std::make_shared>(frame_factory_->get_video_format_desc().audio_samples_per_frame, 0)); + muxer_.push(std::make_shared(frame_factory_->get_video_format_desc().audio_samples_per_frame, 0)); muxer_.commit(); @@ -241,16 +241,25 @@ public: class decklink_producer_proxy : public core::frame_producer { - safe_ptr last_frame_; - com_context context_; + safe_ptr last_frame_; + com_context context_; + const int64_t length_; public: - explicit decklink_producer_proxy(const safe_ptr& frame_factory, const core::video_format_desc& format_desc, size_t device_index, const std::wstring& filter_str = L"") + explicit decklink_producer_proxy(const safe_ptr& frame_factory, const core::video_format_desc& format_desc, size_t device_index, const std::wstring& filter_str, int64_t length) : context_(L"decklink_producer[" + boost::lexical_cast(device_index) + L"]") , last_frame_(core::basic_frame::empty()) + , length_(length) { context_.reset([&]{return new decklink_producer(format_desc, device_index, frame_factory, filter_str);}); } + + ~decklink_producer_proxy() + { + auto str = print(); + context_.reset(); + CASPAR_LOG(info) << str << L" Successfully Uninitialized."; + } virtual safe_ptr receive(int) { @@ -265,39 +274,35 @@ public: return disable_audio(last_frame_); } + virtual int64_t nb_frames() const + { + return length_; + } + std::wstring print() const { return context_->print(); } }; -safe_ptr create_decklink_producer(const safe_ptr& frame_factory, const std::vector& params) +safe_ptr create_producer(const safe_ptr& frame_factory, const std::vector& params) { if(params.empty() || !boost::iequals(params[0], "decklink")) return core::frame_producer::empty(); - size_t device_index = 1; - if(params.size() > 1) - device_index = lexical_cast_or_default(params[1], 1); - - core::video_format_desc format_desc = core::video_format_desc::get(L"PAL"); - if(params.size() > 2) - { - auto desc = core::video_format_desc::get(params[2]); - if(desc.format != core::video_format::invalid) - format_desc = desc; - } + auto device_index = core::get_param(L"DEVICE", params, 1); + auto filter_str = core::get_param(L"FILTER", params, L""); + auto length = core::get_param(L"LENGTH", params, std::numeric_limits::max()); - std::wstring filter_str = L""; + boost::replace_all(filter_str, L"DEINTERLACE", L"YADIF=0:-1"); + boost::replace_all(filter_str, L"DEINTERLACE_BOB", L"YADIF=1:-1"); - auto filter_it = std::find(params.begin(), params.end(), L"FILTER"); - if(filter_it != params.end()) - { - if(++filter_it != params.end()) - filter_str = *filter_it; - } + auto format_desc = core::video_format_desc::get(core::get_param(L"FORMAT", params, L"INVALID")); - return make_safe(frame_factory, format_desc, device_index, filter_str); + if(format_desc.format == core::video_format::invalid) + format_desc = frame_factory->get_video_format_desc(); + + return make_safe(frame_factory, format_desc, device_index, filter_str, length); } -} \ No newline at end of file +}} \ No newline at end of file