X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fbluefish%2Fconsumer%2Fbluefish_consumer.cpp;h=c52a0b50ffa606cd80e14b5e15036a89d44e4247;hb=34420e565fdeb9b862d59835c212f44ebdda8d5b;hp=f6b61304674afca304e0c928f8a874d962fd4a24;hpb=9c90e97ee000666a73a0e95f1785aad3d22e41c3;p=casparcg diff --git a/modules/bluefish/consumer/bluefish_consumer.cpp b/modules/bluefish/consumer/bluefish_consumer.cpp index f6b613046..c52a0b50f 100644 --- a/modules/bluefish/consumer/bluefish_consumer.cpp +++ b/modules/bluefish/consumer/bluefish_consumer.cpp @@ -28,10 +28,14 @@ #include #include -#include #include +#include +#include #include +#include +#include + #include #include @@ -53,44 +57,35 @@ struct bluefish_consumer : boost::noncopyable boost::timer frame_timer_; boost::timer tick_timer_; boost::timer sync_timer_; - - const EVideoMode vid_fmt_; - const EMemoryFormat mem_fmt_; - const EUpdateMethod upd_fmt_; - const EResoFormat res_fmt_; - EEngineMode engine_mode_; - - std::array reserved_frames_; - tbb::concurrent_bounded_queue> frame_buffer_; + + unsigned int vid_fmt_; - int preroll_count_; + std::array reserved_frames_; + tbb::concurrent_bounded_queue> frame_buffer_; - const bool embedded_audio_; + int preroll_count_; + + const bool embedded_audio_; + const bool key_only_; - executor executor_; + executor executor_; public: - bluefish_consumer(const core::video_format_desc& format_desc, unsigned int device_index, bool embedded_audio) - : blue_(create_blue()) + bluefish_consumer(const core::video_format_desc& format_desc, unsigned int device_index, bool embedded_audio, bool key_only) + : blue_(create_blue(device_index)) , device_index_(device_index) , format_desc_(format_desc) , model_name_(get_card_desc(*blue_)) - , vid_fmt_(get_video_mode(*blue_, format_desc)) - , mem_fmt_(MEM_FMT_ARGB_PC) - , upd_fmt_(UPD_FMT_FRAME) - , res_fmt_(RES_FMT_NORMAL) - , engine_mode_(VIDEO_ENGINE_FRAMESTORE) + , vid_fmt_(get_video_mode(*blue_, format_desc)) , preroll_count_(0) , embedded_audio_(embedded_audio) + , key_only_(key_only) , executor_(print()) { - if(BLUE_FAIL(blue_->device_attach(device_index, FALSE))) - BOOST_THROW_EXCEPTION(bluefish_exception() << msg_info("Failed to attach device.")); - - executor_.set_capacity(CONSUMER_BUFFER_DEPTH); + executor_.set_capacity(core::consumer_buffer_depth()); graph_ = diagnostics::create_graph(narrow(print())); graph_->add_guide("tick-time", 0.5); - graph_->set_color("tick-time", diagnostics::color(0.1f, 0.7f, 0.8f)); + graph_->set_color("tick-time", diagnostics::color(0.0f, 0.6f, 0.9f)); graph_->add_guide("frame-time", 0.5f); graph_->set_color("frame-time", diagnostics::color(1.0f, 0.0f, 0.0f)); graph_->set_color("sync-time", diagnostics::color(0.5f, 1.0f, 0.2f)); @@ -98,24 +93,24 @@ public: //Setting output Video mode if(BLUE_FAIL(set_card_property(blue_, VIDEO_MODE, vid_fmt_))) - BOOST_THROW_EXCEPTION(bluefish_exception() << msg_info(narrow(print()) + " Failed to set videomode.")); + BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(narrow(print()) + " Failed to set videomode.")); //Select Update Mode for output - if(BLUE_FAIL(set_card_property(blue_, VIDEO_UPDATE_TYPE, upd_fmt_))) - BOOST_THROW_EXCEPTION(bluefish_exception() << msg_info(narrow(print()) + " Failed to set update type.")); + if(BLUE_FAIL(set_card_property(blue_, VIDEO_UPDATE_TYPE, UPD_FMT_FRAME))) + BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(narrow(print()) + " Failed to set update type.")); disable_video_output(); //Enable dual link output if(BLUE_FAIL(set_card_property(blue_, VIDEO_DUAL_LINK_OUTPUT, 1))) - BOOST_THROW_EXCEPTION(bluefish_exception() << msg_info(narrow(print()) + " Failed to enable dual link.")); + BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(narrow(print()) + " Failed to enable dual link.")); if(BLUE_FAIL(set_card_property(blue_, VIDEO_DUAL_LINK_OUTPUT_SIGNAL_FORMAT_TYPE, Signal_FormatType_4224))) - BOOST_THROW_EXCEPTION(bluefish_exception() << msg_info(narrow(print()) + " Failed to set dual link format type to 4:2:2:4.")); + BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(narrow(print()) + " Failed to set dual link format type to 4:2:2:4.")); //Select output memory format - if(BLUE_FAIL(set_card_property(blue_, VIDEO_MEMORY_FORMAT, mem_fmt_))) - BOOST_THROW_EXCEPTION(bluefish_exception() << msg_info(narrow(print()) + " Failed to set memory format.")); + if(BLUE_FAIL(set_card_property(blue_, VIDEO_MEMORY_FORMAT, MEM_FMT_ARGB_PC))) + BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(narrow(print()) + " Failed to set memory format.")); //Select image orientation if(BLUE_FAIL(set_card_property(blue_, VIDEO_IMAGE_ORIENTATION, ImageOrientation_Normal))) @@ -150,8 +145,9 @@ public: if(blue_->GetHDCardType(device_index_) != CRD_HD_INVALID) blue_->Set_DownConverterSignalType(vid_fmt_ == VID_FMT_PAL ? SD_SDI : HD_SDI); - if(BLUE_FAIL(blue_->set_video_engine(*reinterpret_cast(&engine_mode_)))) - BOOST_THROW_EXCEPTION(bluefish_exception() << msg_info(narrow(print()) + " Failed to set video engine.")); + unsigned long engine_mode = VIDEO_ENGINE_FRAMESTORE; + if(BLUE_FAIL(blue_->set_video_engine(engine_mode))) + BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(narrow(print()) + " Failed to set video engine.")); enable_video_output(); @@ -166,11 +162,18 @@ public: ~bluefish_consumer() { - executor_.invoke([&] + try { - disable_video_output(); - blue_->device_detach(); - }); + executor_.invoke([&] + { + disable_video_output(); + blue_->device_detach(); + }); + } + catch(...) + { + CASPAR_LOG_CURRENT_EXCEPTION(); + } CASPAR_LOG(info) << print() << L" Shutting down."; } @@ -192,7 +195,7 @@ public: CASPAR_LOG(error)<< print() << TEXT(" Failed to disable video output."); } - void send(const safe_ptr& frame) + void send(const safe_ptr& frame) { if(preroll_count_ < executor_.capacity()) { @@ -203,9 +206,9 @@ public: schedule_next_video(frame); } - void schedule_next_video(const safe_ptr& frame) + void schedule_next_video(const safe_ptr& frame) { - static std::vector silence(MAX_HANC_BUFFER_SIZE, 0); + static std::vector silence(MAX_HANC_BUFFER_SIZE, 0); executor_.begin_invoke([=] { @@ -219,10 +222,15 @@ public: // Copy to local buffers if(!frame->image_data().empty()) - fast_memcpy(reserved_frames_.front()->image_data(), frame->image_data().begin(), frame->image_data().size()); + { + if(key_only_) + fast_memshfl(reserved_frames_.front()->image_data(), frame->image_data().begin(), frame->image_data().size(), 0x0F0F0F0F, 0x0B0B0B0B, 0x07070707, 0x03030303); + else + fast_memcpy(reserved_frames_.front()->image_data(), frame->image_data().begin(), frame->image_data().size()); + } else fast_memclr(reserved_frames_.front()->image_data(), reserved_frames_.front()->image_size()); - + // Sync sync_timer_.restart(); @@ -234,7 +242,8 @@ public: if(embedded_audio_) { - auto frame_audio_data = frame->audio_data().empty() ? silence.data() : const_cast(frame->audio_data().begin()); + auto frame_audio = core::audio_32_to_24(frame->audio_data()); + auto frame_audio_data = frame_audio.size() != audio_samples ? silence.data() : frame_audio.data(); encode_hanc(reinterpret_cast(reserved_frames_.front()->hanc_data()), frame_audio_data, audio_samples, audio_nchannels); @@ -280,8 +289,8 @@ public: void encode_hanc(BLUE_UINT32* hanc_data, void* audio_data, size_t audio_samples, size_t audio_nchannels) { - static const auto sample_type = AUDIO_CHANNEL_16BIT | AUDIO_CHANNEL_LITTLEENDIAN; - static const auto emb_audio_flag = blue_emb_audio_enable | blue_emb_audio_group1_enable; + const auto sample_type = AUDIO_CHANNEL_24BIT | AUDIO_CHANNEL_LITTLEENDIAN; + const auto emb_audio_flag = blue_emb_audio_enable | blue_emb_audio_group1_enable; hanc_stream_info_struct hanc_stream_info; memset(&hanc_stream_info, 0, sizeof(hanc_stream_info)); @@ -311,21 +320,26 @@ struct bluefish_consumer_proxy : public core::frame_consumer const size_t device_index_; const bool embedded_audio_; const bool key_only_; + core::video_format_desc format_desc_; public: bluefish_consumer_proxy(size_t device_index, bool embedded_audio, bool key_only) : device_index_(device_index) , embedded_audio_(embedded_audio) - , key_only_(key_only){} + , key_only_(key_only) + { + } virtual void initialize(const core::video_format_desc& format_desc) { - consumer_.reset(new bluefish_consumer(format_desc, device_index_, embedded_audio_)); + format_desc_ = format_desc; + consumer_.reset(new bluefish_consumer(format_desc, device_index_, embedded_audio_, key_only_)); } - virtual void send(const safe_ptr& frame) + virtual bool send(const safe_ptr& frame) { consumer_->send(frame); + return true; } virtual const core::video_format_desc& get_video_format_desc() const @@ -335,12 +349,10 @@ public: virtual std::wstring print() const { - return consumer_->print(); - } + if(consumer_) + consumer_->print(); - virtual bool key_only() const - { - return key_only_; + return L"bluefish [" + boost::lexical_cast(device_index_) + L"]"; } };