How to programmatically configure DeckLink Duo 2 and DeckLink Quad 2 in half or full duplex mode
In order to use the DeckLink Duo 2 as four independent channels (input or output), the connector mapping for the first and second sub-devices needs to be changed from e.g. "SDI 1 & SDI 2" (Full-duplex) to "SDI 1" (Half-duplex).
In order to use the DeckLink Duo 2 as two input and output channels, the connector mapping for the first sub-device needs to be changed from e.g. "SDI 1" (Half-duplex) to "SDI 1 & SDI 2" (Full-duplex).
This configuration change can be made in the Desktop Video Setup under Video Tab, by opening the configuration for each sub-device, and changing the 'Connector Mapping" from both connectors to a single connector.
The same process applies for the DeckLink Quad 2 as well.
This same configuration can be performed directly using the DeckLink API, please see SDK Manual section "2.4.11 Configurable duplex mode" for a high-level overview of the duplex mode configuration and connector mapping for the DeckLink Duo 2, and section "2.4.11.1 Configuring duplex mode" for the steps to set the duplex mode for individual sub-devices.
e.g.
It is possible to configure the duplex mode by using the IDeckLinkConfiguration [1] interface, e.g. (where deckLink is an IDeckLink*):
DeckLinkConfiguration *deckLinkConfiguration = NULL; if (deckLink->QueryInterface(IID_IDeckLinkConfiguration, (void **)&deckLinkConfiguration) != S_OK) { printf("Could not get the IDeckLinkConfiguration interface\n"); deckLinkConfiguration = NULL; goto bail; }
Then set the video input connection to the desired BMDVideoConnector[2]:
result = deckLinkConfiguration->SetInt(bmdDeckLinkConfigDuplexMode, bmdDuplexModeFull); if (FAILED(result)) goto bail;
Be sure to check the result to ensure the operation was successful.
Note that configuration changes made are global and will be reverted when the IDeckLinkConfiguration reference is released unless the settings are saved with IDeckLinkConfiguration::WriteConfigurationToPreferences() [3].
[1] 2.5.15 IDeckLinkConfiguration Interface
[2] 2.7.60 Duplex Mode
[3] 2.5.15.9 IDeckLinkConfiguration::WriteConfigurationToPreferences method
How to select SDI/HDMI/Component/Composite/etc. as the capture source
The active video input connector can be set using the IDeckLinkConfiguration [1] interface, for example (where decklink is an IDeckLink* [2]):
IDeckLinkConfiguration *deckLinkConfiguration = NULL; if (deckLink->QueryInterface(IID_IDeckLinkConfiguration, (void **)&deckLinkConfiguration) != S_OK) { printf("Could not get the IDeckLinkConfiguration interface\n"); deckLinkConfiguration = NULL; goto bail; }
Then set the video input connection to the desired BMDVideoConnection [3]:
result = deckLinkConfiguration->SetInt(bmdDeckLinkConfigVideoInputConnection, bmdVideoConnectionHDMI); if (FAILED(result)) goto bail;
Note that configuration changes made are global, and will be reverted when the IDeckLinkConfiguration reference is released, unless the settings are saved with IDeckLinkConfiguration::WriteConfigurationToPreferences() [4].
In order to determine the available inputs for a particular device (e.g. whether a particular device has a HDMI input), use the IDeckLinkAttributes [5] interface to query the value of the BMDDeckLinkVideoInputConnections attribute[6]. The returned value is a bitset of the supported video input connections (BMDVideoConnection).
[1] DeckLink SDK Manual, 2.5.15 IDeckLinkConfiguration Interface
[2] 2.5.2 IDeckLink Interface
[3] 2.7.12 Video Connection Modes
[4] 2.5.15.9 IDeckLinkConfiguration::WriteConfigurationToPreferences method
[5] 2.5.17 IDeckLinkAttributes Interface
[6] 2.7.17 DeckLink Attribute ID
How to uniquely identify a DeckLink device
The strength with which a DeckLink device can be uniquely identified varies based on the specific identifiers supported by the device in use.
BMDDeckLinkPersistentID [1] is a device specific, 32-bit unique identifier. It is stable even when the device is plugged in a different connector, across reboots, and when plugged into different computers.
BMDDeckLinkPersistentID is supported by the newer Thunderbolt and PCIe DesktopVideo products.
BMDDeckLinkTopologicalID [1] is a 32-bit identifier for the device based on how the OS enumerates the devices. It will remain stable only so long as no devices are added/removed from the system, it is not stable in other machines nor if the OS changes the order in which devices are enumerated. This is a weaker identifier than BMDDeckLinkPersistentID.
Desktop Video SDK 10.6.6+ added the BMDDeckLinkDeviceHandle [1] attribute. This attribute returns a string value that conceptually combines the topological and persistent identifiers into an opaque handle which represents the best available identifier for a particular device.
If none of the above identifiers are supported by a particular device, the only remaining identifier is the order that the devices are enumerated in (via IDeckLinkIterator [2]).
[1] DeckLink SDK Manual, 2.7.17 DeckLink Attribute ID
[2] 2.5.1 IDeckLinkIterator Interface
Available DeckLink device identifiers
The DeckLink API provides a number of unique identifiers for DeckLink devices.
BMDDeckLinkPersistentID [1] is a device specific, 32-bit unique identifier. It is stable even when the device is plugged in a different connector, across reboots, and when plugged into different computers.
BMDDeckLinkPersistentID is supported by the newer Thunderbolt and PCIe DesktopVideo products.
BMDDeckLinkTopologicalID [1] is a 32-bit identifier for the device based on how the OS enumerates the devices. It will remain stable only so long as no devices are added/removed from the system, it is not stable in other machines nor if the OS changes the order in which devices are enumerated. This is a weaker identifier than BMDDeckLinkPersistentID.
The DeckLink Duo 2 / Quad 2 additionally support the BMDDeckLinkPairedDevicePersistentID [1] and BMDDeckLinkDeviceGroupID [1] attributes.
BMDDeckLinkPairedDevicePersistentID provides the persistent ID of the paired sub-device in a configurable duplex mode pair[2], used to identify the sub-device which will be affected by a change to the duplex mode configuration common to both sub-devices.
Similarly, BMDDeckLinkDeviceGroupID provides an identifier common to all sub-devices of a single DeckLink Duo 2 / Quad 2 device. See "2.4.11 Configurable duplex mode" for more information on these attributes.
[1] DeckLink SDK Manual, 2.7.17 DeckLink Attribute ID
[2] 2.4.11 Configurable duplex mode
How to output HDR metadata
Before attempting to capture or output HDR Metadata, a DeckLink API application should verify support for this feature, by querying the BMDDeckLinkSupportsHDRMetadata [1] attribute via the IDeckLinkAttributes [2] interface:
IDeckLinkAttributes *deckLinkAttributes = NULL; if (deckLink->QueryInterface(IID_IDeckLinkAttributes, (void **)&deckLinkAttributes) != S_OK) { printf("Could not get the IDeckLinkAttributes interface\n"); deckLinkAttributes = NULL; goto bail; } bool supportsHDR = false; if (deckLinkAttributes->GetFlag(BMDDeckLinkSupportsHDRMetadata, &supportsHDR) == S_OK && supportsHDR) { // HDR is supported. }
The IDeckLinkVideoFrameMetadataExtensions [3] interface provides methods to query metadata associated with a video frame, the presence of HDR metadata may be determined by checking the frame flags[4] for the presence of the bmdFrameContainsHDRMetadata [5] flag.
"2.7.63 Frame Metadata ID" enumerates the metadata items which may be queried via the IDeckLinkVideoFrameMetadataExtensions interface. The available HDR metadata includes the RGB primaries, whitepoint, EOTF, etc.
In order to output HDR metadata, the application will need to provide a class that implements both IDeckLinkVideoFrame [6] and IDeckLinkVideoFrameMetadataExtensions (in a similar way as 3D support requires an application to implement IDeckLinkVideoFrame3DExtensions, as demonstrated in the SignalGenerator SDK sample).
The custom video frame type should indicate the presence of HDR metadata by ensuring the IDeckLinkVideoFrame::GetFlags() [7] implementation returns bmdFrameContainsHDRMetadata, and implement IUnknown::QueryInterface() [8] for IDeckLinkVideoFrameMetadataExtensions.
This video frame class which implements the IDeckLinkVideoFrameMetadataExtensions interface may implement additional methods to set the HDR metadata fields as needed by the upper layers of the application.
When scheduling instances of the custom IDeckLinkVideoFrame for playback, the DeckLink API will query the frame flags to determine if the bmdFrameContainsHDRMetadata flag is set, and if so, retrieve the IDeckLinkVideoFrameMetadataExtensions implementation (via IUnknown::QueryInterface()). Assuming IUnknown::QueryInterface() is successful, IDeckLinkVideoFrameMetadataExtensions::Get*() will be called by the DeckLink API to retrieve the HDR metadata for output.
[1] DeckLink SDK Manual, 2.7.17 DeckLink Attribute ID
[2] 2.5.17 IDeckLinkAttributes Interface
[3] 2.5.40 IDeckLinkVideoFrameMetadataExtensions Interface
[4] 2.5.5.5 IDeckLinkVideoFrame::GetFlags method
[5] 2.7.6 Frame Flags
[6] 2.5.5 IDeckLinkVideoFrame Interface
[7] 2.5.5.5 IDeckLinkVideoFrame::GetFlags method
[8] 1.4.1.1 IUnknown::QueryInterface method
How to programmatically enable / disable "1080PsF On” option
Whether 1080p HD and 2K modes are output as progressive video or progressive segmented video can be controlled via the IDeckLinkConfiguration [1] interface, using the bmdDeckLinkConfigOutput1080pAsPsF and bmdDeckLinkConfigCapture1080pAsPsF [2] configuration items.
For example (where deckLink is an IDeckLink* [3]):
IDeckLinkConfiguration *deckLinkConfiguration = NULL; if (deckLink->QueryInterface(IID_IDeckLinkConfiguration, (void **)&deckLinkConfiguration) != S_OK) { printf("Could not get the IDeckLinkConfiguration interface\n"); deckLinkConfiguration = NULL; goto bail; } result = deckLinkConfiguration->SetFlag(bmdDeckLinkConfigOutput1080pAsPsF, false); // For progressive if (FAILED(result)) goto bail;
Note that configuration changes made are global, and will be reverted when the IDeckLinkConfiguration reference is released, unless the settings are saved with IDeckLinkConfiguration::WriteConfigurationToPreferences() [4].
Note: Desktop Video SDK versions prior to 10.9.5 exposed capture and playback PsF configuration in a single flag: bmdDeckLinkConfigUse1080pNotPsF. Setting bmdDeckLinkConfigUse1080pNotPsF to false will cause progressive modes to be captured and output as their PsF equivalent.
[1] DeckLink SDK Manual, 2.5.15 IDeckLinkConfiguration Interface
[2] 2.7.18 DeckLink Configuration ID
[3] 2.5.2 IDeckLink Interface
[4] 2.5.15.9 IDeckLinkConfiguration::WriteConfigurationToPreferences method
[Windows] Using the DeckLink SDK in a C# project
1. The DeckLink API requires a multithreaded COM apartment (Windows) [1]
2. VideoFrames should be released as soon as possible
System.Runtime.InteropServices.Marshal.ReleaseComObject(deckLinkVideoFrame);
3. Using HRESULT values directly in COM bindings
... .method public hidebysig newslot abstract virtual instance int32 Next([out] class DeckLinkAPI.IDeckLink& marshal( interface ) deckLinkInstance) runtime managed internalcall preservesig { } // end of method IDeckLinkIterator::Next
[1] https://msdn.microsoft.com/en-us/library/ms693421(VS.85).aspx
[2] https://msdn.microsoft.com/en-us/library/system.mtathreadattribute(v=vs.110).aspx
[3] DeckLink SDK Manual, 2.5.10.1 IDeckLinkInputCallback::VideoInputFrameArrived method
[4] 2.5.6.1 IDeckLinkVideoOutputCallback::ScheduledFrameCompleted method
[5] 2.5.18 IDeckLinkMemoryAllocator Interface
[Windows] DeckLink SDK missing DeckLinkAPI_i.c
On Windows platforms, the DeckLink API is provided as a set of COM interfaces [1][2]. Language bindings for the COM interfaces are generated from the provided .idl files shipped with the DeckLink API, either within VisualStudio or manually by invoking MIDL directly.
To use the DeckLink API in VisualStudio, add the DeckLinkAPI.idl file to the project, right-click and select 'Compile', and add the generated DeckLinkAPI_i.c & DeckLinkAPI_h.h files to the project.
Please see the documentation for the MIDL compiler [3] for details of manually generating COM bindings.
After adding the generated bindings to the project, clean and Build the project.
[1] DeckLink SDK Manual, 2.1 Using the DeckLink API in a project
[2] https://msdn.microsoft.com/en-us/library/windows/desktop/aa367091(v=vs.85).aspx
[3] 2.5.15.9 IDeckLinkConfiguration::WriteConfigurationToPreferences method
Will my application built with the DeckLink SDK version X work with Desktop Video version Y installed?
It is always possible to reliably use an application built against an older SDK with a newer Desktop Video driver version.
It is not however possible to reliably use a newer SDK with an older driver, as the newer SDK against which the application is built will require the presence of newer interfaces which may not be present in the older driver.
For example, if the application is built against SDK version 10.7 it will be possible to deploy the application with any Desktop Video version from 10.7 onwards.
Configuration changes made with IDeckLinkConfiguration are reset
Configuration changes made via IDeckLinkConfiguration::Set*() [1] are globally visible (not limited to the current process), and will be reverted when the IDeckLinkConfiguration [1] reference is released.
In order to maintain the modified configuration, the application can hold a reference to the IDeckLinkConfiguration object for as long as the updated configuration is required, or persist the settings by calling IDeckLinkConfiguration::WriteConfigurationToPreferences() [2], after which the IDeckLinkConfiguration reference may be released.
[1] DeckLink SDK Manual, 2.5.15 IDeckLinkConfiguration Interface
[2] 2.5.15.9 IDeckLinkConfiguration::WriteConfigurationToPreferences method
Single field output when performing playback with IDeckLinkOutput::DisplayVideoFrameSync()
An application using IDeckLinkOutput::DisplayVideoFrameSync() [1] to playback video frames (as distinct from scheduled playback) will need to ensure that the bmdDeckLinkConfigFieldFlickerRemoval [2] configuration item is disabled in order to output both fields.
In the default configuration, flicker removal will ensure that a single field of interlaced modes will be output with IDeckLinkOutput::DisplayVideoFrameSync().
IDeckLinkConfiguration *deckLinkConfiguration = NULL; if (deckLink->QueryInterface(IID_IDeckLinkConfiguration, (void **)&deckLinkConfiguration) != S_OK) { printf("Could not get the IDeckLinkConfiguration interface\n"); deckLinkConfiguration = NULL; goto bail; } result = deckLinkConfiguration->SetFlag(bmdDeckLinkConfigFieldFlickerRemoval, false); if (FAILED(result)) goto bail;
Note that configuration changes made are global, and will be reverted when the IDeckLinkConfiguration [3] reference is released, unless the settings are saved with IDeckLinkConfiguration::WriteConfigurationToPreferences() [4].
[1] DeckLink SDK Manual, 2.5.3.10 IDeckLinkOutput::DisplayVideoFrameSync method
[2] 2.7.18 DeckLink Configuration ID
[3] 2.5.15 IDeckLinkConfiguration Interface
[4] 2.5.15.9 IDeckLinkConfiguration::WriteConfigurationToPreferences method
Full screen preview with DeckLink screen preview helpers
The SDK provided screen preview helpers (e.g. IDeckLinkGLScreenPreviewHelper) are intended for small window preview operations with the lowest possible performance impact - so that they are usable in the greatest variety of scenarios.
By design, these preview helpers render the preview at 1/2 height (1/4 height for 4K) by skipping lines in order to simultaneously perform a simple drop de-interlace.
Applications requiring high-fidelity rendering of the captured video input are recommended to either implement IDeckLinkScreenPreviewCallback [1], or use the captured video frames from IDeckLinkInputCallback::VideoInputFrameArrived() [3] directly.
The built-in screen preview helpers use the IDeckLinkVideoConversion [2] interface to convert from the input pixel format to RGB for the preview, if using OpenGL it may also be possible to perform this conversion in the GPU using a shader - see the LoopThroughWithOpenGLCompositing SDK sample for an example.
[1] DeckLink SDK Manual, 2.5.22 IDeckLinkScreenPreviewCallback Interface
[2] 2.5.41 IDeckLinkVideoConversion Interface
[3] 2.5.10.1 IDeckLinkInputCallback::VideoInputFrameArrived method
Audio / Video stream time offset when capturing with DeckLink Duo 2 / Quad 2 in Half Duplex
When starting a capture operation with the DeckLink Duo 2 / Quad 2 configured as half-duplex [1], it may take a short time before input locks, as in this configuration the sub-devices which default to playback may take a short amount of time to switch from playback to capture.
During this interval, there is an observable offset in the video and audio stream times as determined via IDeckLinkVideoInputFrame::GetStreamTime() [2] / IDeckLinkAudioInputPacket::GetPacketTime() [3].
The recommendation is that applications should restart the streams at the no signal -> signal transition point, which will ensure synchronisation between the stream times, e.g. (in IDeckLinkInputCallback::VideoInputFrameArrived() [4]):
if(hasValidInputSource && !hadValidInputSource) { deckLinkInput->StopStreams(); deckLinkInput->FlushStreams(); deckLinkInput->StartStreams(); } hadValidInputSource = hasValidInputSource;
This will then result in the capture continuing as expected with synchronised stream times.
[1] DeckLink SDK Manual, 2.4.11 Configurable duplex mode
[2] 2.5.11.1 IDeckLinkVideoInputFrame::GetStreamTime method
[3] 2.5.12.3 IDeckLinkAudioInputPacket::GetPacketTime method
[4] 2.5.10.1 IDeckLinkInputCallback::VideoInputFrameArrived method