\r
namespace caspar { namespace bluefish { \r
\r
-struct bluefish_consumer : public Concurrency::agent, boost::noncopyable\r
+struct bluefish_consumer : boost::noncopyable\r
{\r
- unbounded_buffer<safe_ptr<core::read_frame>> frames_;\r
- overwrite_buffer<std::exception_ptr> exception_;\r
-\r
- safe_ptr<CBlueVelvet4> blue_;\r
+ const safe_ptr<CBlueVelvet4> blue_;\r
const unsigned int device_index_;\r
const core::video_format_desc format_desc_;\r
\r
const std::wstring model_name_;\r
\r
- safe_ptr<diagnostics::graph> graph_;\r
+ const safe_ptr<diagnostics::graph> graph_;\r
boost::timer frame_timer_;\r
boost::timer tick_timer_;\r
boost::timer sync_timer_; \r
\r
const bool embedded_audio_;\r
const bool key_only_;\r
- \r
- governor governor_;\r
- tbb::atomic<bool> is_running_;\r
public:\r
bluefish_consumer(const core::video_format_desc& format_desc, unsigned int device_index, bool embedded_audio, bool key_only) \r
: blue_(create_blue(device_index))\r
, vid_fmt_(get_video_mode(*blue_, format_desc))\r
, embedded_audio_(embedded_audio)\r
, key_only_(key_only)\r
- , governor_(1)\r
{\r
graph_->add_guide("tick-time", 0.5);\r
graph_->set_color("tick-time", diagnostics::color(0.0f, 0.6f, 0.9f)); \r
graph_->add_guide("frame-time", 0.5f); \r
graph_->set_color("frame-time", diagnostics::color(1.0f, 0.0f, 0.0f));\r
- graph_->set_color("sync-time", diagnostics::color(0.5f, 1.0f, 0.2f));\r
- graph_->set_color("input-buffer", diagnostics::color(1.0f, 1.0f, 0.0f));\r
+ graph_->set_color("sync-time", diagnostics::color(1.0f, 0.3f, 0.5f));\r
graph_->set_text(print());\r
diagnostics::register_graph(graph_);\r
\r
{\r
return std::make_shared<blue_dma_buffer>(format_desc_.size, n++);\r
});\r
-\r
- is_running_ = true;\r
- start();\r
- \r
+ \r
CASPAR_LOG(info) << print() << L" Successfully Initialized.";\r
}\r
\r
~bluefish_consumer()\r
{\r
- is_running_ = false;\r
- governor_.cancel();\r
- agent::wait(this);\r
try\r
{ \r
disable_video_output();\r
\r
void send(const safe_ptr<core::read_frame>& frame)\r
{ \r
- if(exception_.has_value())\r
- std::rethrow_exception(exception_.value());\r
-\r
- auto ticket = governor_.acquire();\r
- Concurrency::send(frames_, safe_ptr<core::read_frame>(frame.get(), [frame, ticket](core::read_frame*){}));\r
- }\r
- \r
- virtual void run()\r
- {\r
static std::vector<int16_t> silence(MAX_HANC_BUFFER_SIZE, 0);\r
- \r
- try\r
- {\r
- while(is_running_)\r
- {\r
- auto frame = receive(frames_);\r
\r
- const size_t audio_samples = format_desc_.audio_samples_per_frame;\r
- const size_t audio_nchannels = format_desc_.audio_channels;\r
+ const size_t audio_samples = format_desc_.audio_samples_per_frame;\r
+ const size_t audio_nchannels = format_desc_.audio_channels;\r
\r
- frame_timer_.restart();\r
+ frame_timer_.restart();\r
\r
- // Copy to local buffers\r
-\r
- if(!frame->image_data().empty())\r
- {\r
- if(key_only_) \r
- fast_memshfl(reserved_frames_.front()->image_data(), frame->image_data().begin(), frame->image_data().size(), 0x0F0F0F0F, 0x0B0B0B0B, 0x07070707, 0x03030303);\r
- else\r
- fast_memcpy(reserved_frames_.front()->image_data(), frame->image_data().begin(), frame->image_data().size());\r
- }\r
- else\r
- fast_memclr(reserved_frames_.front()->image_data(), reserved_frames_.front()->image_size());\r
+ // Copy to local buffers\r
+\r
+ if(!frame->image_data().empty())\r
+ {\r
+ if(key_only_) \r
+ fast_memshfl(reserved_frames_.front()->image_data(), frame->image_data().begin(), frame->image_data().size(), 0x0F0F0F0F, 0x0B0B0B0B, 0x07070707, 0x03030303);\r
+ else\r
+ fast_memcpy(reserved_frames_.front()->image_data(), frame->image_data().begin(), frame->image_data().size());\r
+ }\r
+ else\r
+ fast_memclr(reserved_frames_.front()->image_data(), reserved_frames_.front()->image_size());\r
\r
- // Sync\r
+ // Sync\r
\r
- sync_timer_.restart();\r
- unsigned long n_field = 0;\r
- {\r
- scoped_oversubcription_token oversubscribe;\r
- blue_->wait_output_video_synch(UPD_FMT_FRAME, n_field);\r
- }\r
- graph_->update_value("sync-time", static_cast<float>(sync_timer_.elapsed()*format_desc_.fps*0.5));\r
+ sync_timer_.restart();\r
+ unsigned long n_field = 0;\r
+ {\r
+ scoped_oversubcription_token oversubscribe;\r
+ blue_->wait_output_video_synch(UPD_FMT_FRAME, n_field);\r
+ }\r
+ graph_->update_value("sync-time", static_cast<float>(sync_timer_.elapsed()*format_desc_.fps*0.5));\r
\r
- // Send and display\r
+ // Send and display\r
\r
- if(embedded_audio_)\r
- { \r
- auto frame_audio = core::audio_32_to_16_sse(frame->audio_data());\r
- auto frame_audio_data = frame_audio.size() != audio_samples ? silence.data() : frame_audio.data(); \r
+ if(embedded_audio_)\r
+ { \r
+ auto frame_audio = core::audio_32_to_16_sse(frame->audio_data());\r
+ auto frame_audio_data = frame_audio.size() != audio_samples ? silence.data() : frame_audio.data(); \r
\r
- encode_hanc(reinterpret_cast<BLUE_UINT32*>(reserved_frames_.front()->hanc_data()), frame_audio_data, audio_samples, audio_nchannels);\r
+ encode_hanc(reinterpret_cast<BLUE_UINT32*>(reserved_frames_.front()->hanc_data()), frame_audio_data, audio_samples, audio_nchannels);\r
\r
- blue_->system_buffer_write_async(const_cast<uint8_t*>(reserved_frames_.front()->image_data()), \r
- reserved_frames_.front()->image_size(), \r
- nullptr, \r
- BlueImage_HANC_DMABuffer(reserved_frames_.front()->id(), BLUE_DATA_IMAGE));\r
-\r
- blue_->system_buffer_write_async(reserved_frames_.front()->hanc_data(),\r
- reserved_frames_.front()->hanc_size(), \r
- nullptr, \r
- BlueImage_HANC_DMABuffer(reserved_frames_.front()->id(), BLUE_DATA_HANC));\r
-\r
- if(BLUE_FAIL(blue_->render_buffer_update(BlueBuffer_Image_HANC(reserved_frames_.front()->id()))))\r
- CASPAR_LOG(warning) << print() << TEXT(" render_buffer_update failed.");\r
- }\r
- else\r
- {\r
- blue_->system_buffer_write_async(const_cast<uint8_t*>(reserved_frames_.front()->image_data()),\r
- reserved_frames_.front()->image_size(), \r
- nullptr, \r
- BlueImage_DMABuffer(reserved_frames_.front()->id(), BLUE_DATA_IMAGE));\r
- \r
- if(BLUE_FAIL(blue_->render_buffer_update(BlueBuffer_Image(reserved_frames_.front()->id()))))\r
- CASPAR_LOG(warning) << print() << TEXT(" render_buffer_update failed.");\r
- }\r
-\r
- std::rotate(reserved_frames_.begin(), reserved_frames_.begin() + 1, reserved_frames_.end());\r
- \r
- graph_->update_value("frame-time", static_cast<float>(frame_timer_.elapsed()*format_desc_.fps*0.5));\r
-\r
- graph_->update_value("tick-time", static_cast<float>(tick_timer_.elapsed()*format_desc_.fps*0.5));\r
- tick_timer_.restart(); \r
- }\r
+ blue_->system_buffer_write_async(const_cast<uint8_t*>(reserved_frames_.front()->image_data()), \r
+ reserved_frames_.front()->image_size(), \r
+ nullptr, \r
+ BlueImage_HANC_DMABuffer(reserved_frames_.front()->id(), BLUE_DATA_IMAGE));\r
+\r
+ blue_->system_buffer_write_async(reserved_frames_.front()->hanc_data(),\r
+ reserved_frames_.front()->hanc_size(), \r
+ nullptr, \r
+ BlueImage_HANC_DMABuffer(reserved_frames_.front()->id(), BLUE_DATA_HANC));\r
+\r
+ if(BLUE_FAIL(blue_->render_buffer_update(BlueBuffer_Image_HANC(reserved_frames_.front()->id()))))\r
+ CASPAR_LOG(warning) << print() << TEXT(" render_buffer_update failed.");\r
}\r
- catch(...)\r
+ else\r
{\r
- Concurrency::send(exception_, std::current_exception());\r
+ blue_->system_buffer_write_async(const_cast<uint8_t*>(reserved_frames_.front()->image_data()),\r
+ reserved_frames_.front()->image_size(), \r
+ nullptr, \r
+ BlueImage_DMABuffer(reserved_frames_.front()->id(), BLUE_DATA_IMAGE));\r
+ \r
+ if(BLUE_FAIL(blue_->render_buffer_update(BlueBuffer_Image(reserved_frames_.front()->id()))))\r
+ CASPAR_LOG(warning) << print() << TEXT(" render_buffer_update failed.");\r
}\r
\r
- done();\r
- }\r
+ std::rotate(reserved_frames_.begin(), reserved_frames_.begin() + 1, reserved_frames_.end());\r
+ \r
+ graph_->update_value("frame-time", static_cast<float>(frame_timer_.elapsed()*format_desc_.fps*0.5));\r
\r
+ graph_->update_value("tick-time", static_cast<float>(tick_timer_.elapsed()*format_desc_.fps*0.5));\r
+ tick_timer_.restart(); \r
+ }\r
+ \r
void encode_hanc(BLUE_UINT32* hanc_data, void* audio_data, size_t audio_samples, size_t audio_nchannels)\r
{ \r
const auto sample_type = AUDIO_CHANNEL_16BIT | AUDIO_CHANNEL_LITTLEENDIAN;\r