~co_init(){CoUninitialize();}\r
} co_;\r
\r
- std::wstring model_name_;\r
const size_t device_index_;\r
+ const bool embed_audio_;\r
+ const decklink_consumer::key key_;\r
+\r
+ std::wstring model_name_;\r
tbb::atomic<bool> is_running_;\r
\r
std::shared_ptr<diagnostics::graph> graph_;\r
std::array<std::pair<void*, CComPtr<IDeckLinkMutableVideoFrame>>, 3> reserved_frames_;\r
boost::circular_buffer<std::vector<short>> audio_container_;\r
\r
- const bool embed_audio_;\r
- const bool internal_key;\r
-\r
CComPtr<IDeckLink> decklink_;\r
CComQIPtr<IDeckLinkOutput> output_;\r
- CComQIPtr<IDeckLinkKeyer> keyer_;\r
\r
core::video_format_desc format_desc_;\r
\r
tbb::concurrent_bounded_queue<std::shared_ptr<const core::read_frame>> audio_frame_buffer_;\r
\r
public:\r
- decklink_output(const core::video_format_desc& format_desc,size_t device_index, bool embed_audio, bool internalKey) \r
+ decklink_output(const core::video_format_desc& format_desc,size_t device_index, bool embed_audio, decklink_consumer::key key) \r
: model_name_(L"DECKLINK")\r
, device_index_(device_index)\r
, audio_container_(5)\r
, embed_audio_(embed_audio)\r
- , internal_key(internalKey)\r
+ , key_(key)\r
, frames_scheduled_(0)\r
, audio_scheduled_(0)\r
, format_desc_(format_desc)\r
\r
if(n != device_index_ || !decklink_)\r
BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(narrow(print()) + " Decklink card not found.") << arg_name_info("device_index") << arg_value_info(boost::lexical_cast<std::string>(device_index_)));\r
-\r
- output_ = decklink_;\r
- keyer_ = decklink_;\r
-\r
+ \r
BSTR pModelName;\r
decklink_->GetModelName(&pModelName);\r
model_name_ = std::wstring(pModelName);\r
graph_->add_guide("tick-time", 0.5);\r
graph_->set_color("tick-time", diagnostics::color(0.1f, 0.7f, 0.8f));\r
\r
+ output_ = decklink_;\r
+\r
auto display_mode = get_display_mode(output_.p, format_desc_.format);\r
if(display_mode == nullptr) \r
BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(narrow(print()) + " Card does not support requested videoformat."));\r
if(FAILED(output_->SetScheduledFrameCompletionCallback(this)))\r
BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(narrow(print()) + " Failed to set playback completion callback."));\r
\r
- if(internal_key) \r
+ CComQIPtr<IDeckLinkKeyer> keyer = decklink_;\r
+ if(key_ == decklink_consumer::internal_key) \r
{\r
- if(FAILED(keyer_->Enable(FALSE))) \r
+ if(FAILED(keyer->Enable(FALSE))) \r
CASPAR_LOG(error) << print() << L" Failed to enable internal keyer."; \r
- else if(FAILED(keyer_->SetLevel(255))) \r
+ else if(FAILED(keyer->SetLevel(255))) \r
CASPAR_LOG(error) << print() << L" Failed to set key-level to max.";\r
else\r
CASPAR_LOG(info) << print() << L" Successfully configured internal keyer."; \r
}\r
- else\r
+ else if(key_ == decklink_consumer::external_key)\r
{\r
- if(FAILED(keyer_->Enable(TRUE))) \r
+ if(FAILED(keyer->Enable(TRUE))) \r
CASPAR_LOG(error) << print() << L" Failed to enable external keyer."; \r
- else if(FAILED(keyer_->SetLevel(255))) \r
+ else if(FAILED(keyer->SetLevel(255))) \r
CASPAR_LOG(error) << print() << L" Failed to set key-level to max.";\r
else\r
CASPAR_LOG(info) << print() << L" Successfully configured external keyer."; \r
}\r
+ else\r
+ CASPAR_LOG(info) << print() << L" Uses default keyer settings."; \r
+\r
\r
for(size_t n = 0; n < reserved_frames_.size(); ++n)\r
{\r
std::unique_ptr<decklink_output> input_;\r
size_t device_index_;\r
bool embed_audio_;\r
- bool internal_key_;\r
+ decklink_consumer::key key_;\r
\r
executor executor_;\r
public:\r
\r
- implementation(size_t device_index, bool embed_audio, bool internal_key)\r
+ implementation(size_t device_index, bool embed_audio, decklink_consumer::key key)\r
: device_index_(device_index)\r
, embed_audio_(embed_audio)\r
- , internal_key_(internal_key)\r
+ , key_(key)\r
, executor_(L"DECKLINK[" + boost::lexical_cast<std::wstring>(device_index) + L"]")\r
{\r
executor_.start();\r
{\r
executor_.invoke([&]\r
{\r
- input_.reset(new decklink_output(format_desc, device_index_, embed_audio_, internal_key_));\r
+ input_.reset(new decklink_output(format_desc, device_index_, embed_audio_, key_));\r
});\r
}\r
\r
}\r
};\r
\r
-decklink_consumer::decklink_consumer(size_t device_index, bool embed_audio, bool internalKey) : impl_(new implementation(device_index, embed_audio, internalKey)){}\r
+decklink_consumer::decklink_consumer(size_t device_index, bool embed_audio, key key) : impl_(new implementation(device_index, embed_audio, key)){}\r
decklink_consumer::decklink_consumer(decklink_consumer&& other) : impl_(std::move(other.impl_)){}\r
void decklink_consumer::initialize(const core::video_format_desc& format_desc){impl_->initialize(format_desc);}\r
void decklink_consumer::send(const safe_ptr<const core::read_frame>& frame){impl_->send(frame);}\r
\r
int device_index = 1;\r
bool embed_audio = false;\r
- bool internal_key = false;\r
+ auto key = decklink_consumer::default_key;\r
\r
if(params.size() > 1) \r
device_index = lexical_cast_or_default<int>(params[2], device_index);\r
if(params.size() > 2)\r
embed_audio = lexical_cast_or_default<bool>(params[3], embed_audio);\r
\r
+\r
if(params.size() > 3) \r
- internal_key = lexical_cast_or_default<bool>(params[4], internal_key);\r
+ {\r
+ if(params[4] == L"INTERNAL_KEY")\r
+ key = decklink_consumer::internal_key;\r
+ else if(params[4] == L"EXTERNAL_KEY")\r
+ key = decklink_consumer::external_key;\r
+ }\r
\r
- return make_safe<decklink_consumer>(device_index, embed_audio, internal_key);\r
+ return make_safe<decklink_consumer>(device_index, embed_audio, key);\r
}\r
\r
}
\ No newline at end of file