\r
struct configuration\r
{\r
- size_t device_index;\r
- bool embedded_audio;\r
- bool internal_key;\r
- bool low_latency;\r
- bool key_only;\r
- size_t base_buffer_depth;\r
+ enum keyer_t\r
+ {\r
+ internal_keyer,\r
+ external_keyer,\r
+ default_keyer\r
+ };\r
+\r
+ enum latency_t\r
+ {\r
+ low_latency,\r
+ normal_latency,\r
+ default_latency\r
+ };\r
+\r
+ size_t device_index;\r
+ bool embedded_audio;\r
+ keyer_t keyer;\r
+ latency_t latency;\r
+ bool key_only;\r
+ size_t base_buffer_depth;\r
\r
configuration()\r
: device_index(1)\r
, embedded_audio(false)\r
- , internal_key(false)\r
- , low_latency(true)\r
+ , keyer(default_keyer)\r
+ , latency(default_latency)\r
, key_only(false)\r
, base_buffer_depth(3)\r
{\r
\r
size_t buffer_depth() const\r
{\r
- return base_buffer_depth + (low_latency ? 0 : 1) + (embedded_audio ? 1 : 0);\r
+ return base_buffer_depth + (latency == low_latency ? 0 : 1) + (embedded_audio ? 1 : 0);\r
}\r
};\r
\r
CComQIPtr<IDeckLinkOutput> output_;\r
CComQIPtr<IDeckLinkConfiguration> configuration_;\r
CComQIPtr<IDeckLinkKeyer> keyer_;\r
+ CComQIPtr<IDeckLinkAttributes> attributes_;\r
\r
tbb::spin_mutex exception_mutex_;\r
std::exception_ptr exception_;\r
, output_(decklink_)\r
, configuration_(decklink_)\r
, keyer_(decklink_)\r
+ , attributes_(decklink_)\r
, model_name_(get_model_name(decklink_))\r
, format_desc_(format_desc)\r
, buffer_size_(config.buffer_depth()) // Minimum buffer-size 3.\r
if(config.embedded_audio)\r
enable_audio();\r
\r
- set_latency(config.low_latency); \r
- set_keyer(config.internal_key);\r
+ set_latency(config.latency); \r
+ set_keyer(config.keyer);\r
\r
if(config.embedded_audio) \r
output_->BeginAudioPreroll(); \r
}\r
}\r
\r
- void set_latency(bool low_latency)\r
+ void set_latency(configuration::latency_t latency)\r
{ \r
- if(!low_latency)\r
+ if(latency == configuration::low_latency)\r
{\r
- configuration_->SetFlag(bmdDeckLinkConfigLowLatencyVideoOutput, false);\r
- CASPAR_LOG(info) << print() << L" Enabled normal-latency mode";\r
+ configuration_->SetFlag(bmdDeckLinkConfigLowLatencyVideoOutput, true);\r
+ CASPAR_LOG(info) << print() << L" Enabled low-latency mode.";\r
}\r
- else\r
+ else if(latency == configuration::normal_latency)\r
{ \r
- configuration_->SetFlag(bmdDeckLinkConfigLowLatencyVideoOutput, true);\r
- CASPAR_LOG(info) << print() << L" Enabled low-latency mode";\r
+ configuration_->SetFlag(bmdDeckLinkConfigLowLatencyVideoOutput, false);\r
+ CASPAR_LOG(info) << print() << L" Disabled low-latency mode.";\r
}\r
}\r
\r
- void set_keyer(bool internal_key)\r
+ void set_keyer(configuration::keyer_t keyer)\r
{\r
- if(internal_key) \r
+ if(keyer == configuration::internal_keyer) \r
{\r
- if(FAILED(keyer_->Enable(FALSE))) \r
+ BOOL value = true;\r
+ if(SUCCEEDED(attributes_->GetFlag(BMDDeckLinkSupportsInternalKeying, &value)) && !value)\r
+ CASPAR_LOG(error) << print() << L" Failed to enable internal keyer."; \r
+ else if(FAILED(keyer_->Enable(FALSE))) \r
CASPAR_LOG(error) << print() << L" Failed to enable internal keyer."; \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" Enabled internal keyer."; \r
}\r
- else\r
+ else if(keyer == configuration::external_keyer)\r
{\r
- if(FAILED(keyer_->Enable(TRUE))) \r
+ BOOL value = true;\r
+ if(SUCCEEDED(attributes_->GetFlag(BMDDeckLinkSupportsExternalKeying, &value)) && !value)\r
+ CASPAR_LOG(error) << print() << L" Failed to enable external keyer."; \r
+ else if(FAILED(keyer_->Enable(TRUE))) \r
CASPAR_LOG(error) << print() << L" Failed to enable external keyer."; \r
else if(FAILED(keyer_->SetLevel(255))) \r
CASPAR_LOG(error) << print() << L" Failed to set key-level to max.";\r
info.add(L"low-latency", config_.low_latency);\r
info.add(L"embedded-audio", config_.embedded_audio);\r
info.add(L"low-latency", config_.low_latency);\r
- info.add(L"internal-key", config_.internal_key);\r
+ //info.add(L"internal-key", config_.internal_key);\r
return info;\r
}\r
\r
if(params.size() > 1)\r
config.device_index = lexical_cast_or_default<int>(params[1], config.device_index);\r
\r
- config.internal_key = std::find(params.begin(), params.end(), L"INTERNAL_KEY") != params.end();\r
- config.low_latency = std::find(params.begin(), params.end(), L"LOW_LATENCY") != params.end();\r
+ if(std::find(params.begin(), params.end(), L"INTERNAL_KEY") != params.end())\r
+ config.keyer = configuration::internal_keyer;\r
+ else if(std::find(params.begin(), params.end(), L"EXTERNAL_KEY") != params.end())\r
+ config.keyer = configuration::external_keyer;\r
+ else\r
+ config.keyer = configuration::default_keyer;\r
+\r
+ if(std::find(params.begin(), params.end(), L"LOW_LATENCY") != params.end())\r
+ config.latency = configuration::low_latency;\r
+\r
config.embedded_audio = std::find(params.begin(), params.end(), L"EMBEDDED_AUDIO") != params.end();\r
config.key_only = std::find(params.begin(), params.end(), L"KEY_ONLY") != params.end();\r
\r
{\r
configuration config;\r
\r
- config.internal_key = ptree.get(L"internal-key", config.internal_key);\r
- config.low_latency = ptree.get(L"low-latency", config.low_latency);\r
+ auto keyer = ptree.get(L"keyer", L"external");\r
+ if(keyer == L"external")\r
+ config.keyer = configuration::external_keyer;\r
+ else if(keyer == L"internal")\r
+ config.keyer = configuration::internal_keyer;\r
+\r
+ auto latency = ptree.get(L"latency", L"normal");\r
+ if(latency == L"low")\r
+ config.latency = configuration::low_latency;\r
+ else if(latency == L"normal")\r
+ config.latency = configuration::normal_latency;\r
+\r
config.key_only = ptree.get(L"key-only", config.key_only);\r
config.device_index = ptree.get(L"device", config.device_index);\r
config.embedded_audio = ptree.get(L"embedded-audio", config.embedded_audio);\r