\r
struct decklink_consumer : public IDeckLinkVideoOutputCallback, public IDeckLinkAudioOutputCallback, boost::noncopyable\r
{ \r
- static const size_t BUFFER_SIZE = 4;\r
- \r
const configuration config_;\r
\r
CComPtr<IDeckLink> decklink_;\r
unsigned long frames_scheduled_;\r
unsigned long audio_scheduled_;\r
\r
- std::array<std::pair<void*, CComPtr<IDeckLinkMutableVideoFrame>>, BUFFER_SIZE+1> reserved_frames_;\r
+ std::vector<std::pair<void*, CComPtr<IDeckLinkMutableVideoFrame>>> reserved_frames_;\r
boost::circular_buffer<std::vector<short>> audio_container_;\r
\r
tbb::concurrent_bounded_queue<std::shared_ptr<const core::read_frame>> video_frame_buffer_;\r
std::shared_ptr<diagnostics::graph> graph_;\r
boost::timer tick_timer_;\r
\r
+ size_t buffer_size_;\r
+\r
public:\r
decklink_consumer(const configuration& config, const core::video_format_desc& format_desc) \r
: config_(config)\r
, audio_container_(5)\r
, frames_scheduled_(0)\r
, audio_scheduled_(0)\r
+ , buffer_size_(5) // Minimum buffer-size (4 + 1 tolerance).\r
{\r
is_running_ = true;\r
\r
BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(narrow(print()) + " Could not set audio callback."));\r
\r
CASPAR_LOG(info) << print() << L" Enabled embedded-audio.";\r
+\r
+ buffer_size_ = 6; // Minimum buffer-size with embedded-audio (5 + 1 tolerance).\r
}\r
\r
if(config.latency == normal_latency)\r
}\r
else\r
CASPAR_LOG(info) << print() << L" Uses driver latency settings."; \r
- \r
+ \r
if(config.keyer == internal_key) \r
{\r
if(FAILED(keyer_->Enable(FALSE))) \r
if(FAILED(output_->SetScheduledFrameCompletionCallback(this)))\r
BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(narrow(print()) + " Failed to set playback completion callback."));\r
\r
- BOOST_FOREACH(auto& frame, reserved_frames_)\r
+ for(size_t n = 0; n < buffer_size_+1; ++n)\r
{\r
- if(FAILED(output_->CreateVideoFrame(format_desc_.width, format_desc_.height, format_desc_.size/format_desc_.height, bmdFormat8BitBGRA, bmdFrameFlagDefault, &frame.second)))\r
+ CComPtr<IDeckLinkMutableVideoFrame> frame;\r
+\r
+ if(FAILED(output_->CreateVideoFrame(format_desc_.width, format_desc_.height, format_desc_.size/format_desc_.height, bmdFormat8BitBGRA, bmdFrameFlagDefault, &frame)))\r
BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(narrow(print()) + " Failed to create frame."));\r
\r
- if(FAILED(frame.second->GetBytes(&frame.first)))\r
+ void* bytes = nullptr;\r
+\r
+ if(FAILED(frame->GetBytes(&bytes)) || bytes == nullptr)\r
BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(narrow(print()) + " Failed to get frame bytes."));\r
- }\r
\r
- CASPAR_LOG(info) << print() << L" Buffer-depth: " << BUFFER_SIZE;\r
+ reserved_frames_.push_back(std::make_pair(bytes, frame));\r
+ }\r
\r
- for(size_t n = 0; n < BUFFER_SIZE; ++n)\r
+ CASPAR_LOG(info) << print() << L" Buffer-depth: " << buffer_size_;\r
+ \r
+ for(size_t n = 0; n < buffer_size_; ++n)\r
schedule_next_video(core::read_frame::empty());\r
\r
video_frame_buffer_.set_capacity(2);\r
video_frame_buffer_.push(frame);\r
if(config_.embedded_audio)\r
audio_frame_buffer_.push(frame);\r
+ \r
}\r
\r
+ size_t buffer_depth() const {return 1;}\r
+\r
std::wstring print() const\r
{\r
return model_name_ + L" [" + boost::lexical_cast<std::wstring>(config_.device_index) + L"]";\r
: config_(config)\r
, context_(L"decklink_consumer[" + boost::lexical_cast<std::wstring>(config.device_index) + L"]"){}\r
\r
- void initialize(const core::video_format_desc& format_desc)\r
+ virtual void initialize(const core::video_format_desc& format_desc)\r
{\r
context_.reset([&]{return new decklink_consumer(config_, format_desc);});\r
}\r
\r
- void send(const safe_ptr<const core::read_frame>& frame)\r
+ virtual void send(const safe_ptr<const core::read_frame>& frame)\r
{\r
context_->send(frame);\r
}\r
\r
- std::wstring print() const\r
+ virtual std::wstring print() const\r
{\r
return context_->print();\r
}\r
+\r
+ virtual size_t buffer_depth() const \r
+ {\r
+ return context_->buffer_depth();\r
+ }\r
}; \r
\r
safe_ptr<core::frame_consumer> create_decklink_consumer(const std::vector<std::wstring>& params) \r