28 #include <DeckLinkAPI.h> 30 #include <DeckLinkAPI_i.c> 37 #pragma clang diagnostic push 38 #pragma clang diagnostic ignored "-Wmissing-prototypes" 40 #include <DeckLinkAPIDispatch.cpp> 42 #pragma clang diagnostic pop 58 IDeckLinkIterator *iter;
61 if (CoInitialize(
NULL) < 0) {
66 if (CoCreateInstance(CLSID_CDeckLinkIterator,
NULL, CLSCTX_ALL,
67 IID_IDeckLinkIterator, (
void**) &iter) != S_OK) {
71 iter = CreateDeckLinkIteratorInstance();
75 "Make sure you have DeckLink drivers " BLACKMAGIC_DECKLINK_API_VERSION_STRING
" or newer installed.\n");
77 IDeckLinkAPIInformation *api;
80 if (CoCreateInstance(CLSID_CDeckLinkAPIInformation,
NULL, CLSCTX_ALL,
81 IID_IDeckLinkAPIInformation, (
void**) &api) != S_OK) {
85 api = CreateDeckLinkAPIInformationInstance();
87 if (api && api->GetInt(BMDDeckLinkAPIVersion, &version) == S_OK) {
88 if (version < BLACKMAGIC_DECKLINK_API_VERSION)
89 av_log(avctx,
AV_LOG_WARNING,
"Installed DeckLink drivers are too old and may be incompatible with the SDK this module was built against. " 90 "Make sure you have DeckLink drivers " BLACKMAGIC_DECKLINK_API_VERSION_STRING
" or newer installed.\n");
109 hr = attr->GetString(cfg_id, &tmp);
116 }
else if (hr == E_FAIL) {
126 BMDDeckLinkAttributeID attr_id = (cfg_id == bmdDeckLinkConfigAudioInputConnection) ? BMDDeckLinkAudioInputConnections : BMDDeckLinkVideoInputConnections;
127 int64_t bmd_input = (cfg_id == bmdDeckLinkConfigAudioInputConnection) ? (int64_t)
ctx->audio_input : (int64_t)
ctx->video_input;
128 const char *type_name = (cfg_id == bmdDeckLinkConfigAudioInputConnection) ?
"audio" :
"video";
129 int64_t supported_connections = 0;
133 res =
ctx->attr->GetInt(attr_id, &supported_connections);
138 if ((supported_connections & bmd_input) != bmd_input) {
139 av_log(avctx,
AV_LOG_ERROR,
"Device does not support selected %s input.\n", type_name);
142 res =
ctx->cfg->SetInt(cfg_id, bmd_input);
159 if (field_order ==
AV_FIELD_PROGRESSIVE && (bmd_field_order == bmdProgressiveFrame || bmd_field_order == bmdProgressiveSegmentedFrame))
170 if (
ctx->duplex_mode) {
173 #if BLACKMAGIC_DECKLINK_API_VERSION >= 0x0b000000 174 IDeckLinkProfileManager *manager =
NULL;
175 if (
ctx->dl->QueryInterface(IID_IDeckLinkProfileManager, (
void **)&manager) == S_OK)
176 duplex_supported =
true;
178 if (
ctx->attr->GetFlag(BMDDeckLinkSupportsDuplexModeConfiguration, &duplex_supported) != S_OK)
179 duplex_supported =
false;
182 if (duplex_supported) {
183 #if BLACKMAGIC_DECKLINK_API_VERSION >= 0x0b000000 185 BMDProfileID bmd_profile_id =
ctx->duplex_mode == 2 ? bmdProfileOneSubDeviceFullDuplex : bmdProfileTwoSubDevicesHalfDuplex;
186 res = manager->GetProfile(bmd_profile_id, &profile);
188 res = profile->SetActive();
193 res =
ctx->cfg->SetInt(bmdDeckLinkConfigDuplexMode,
ctx->duplex_mode == 2 ? bmdDuplexModeFull : bmdDuplexModeHalf);
198 av_log(avctx,
AV_LOG_VERBOSE,
"Successfully set duplex mode to %s duplex.\n",
ctx->duplex_mode == 2 ?
"full" :
"half");
213 res =
ctx->cfg->SetInt(bmdDeckLinkConfigReferenceInputTimingOffset, cctx->
timing_offset);
222 int tb_num,
int tb_den,
228 #if BLACKMAGIC_DECKLINK_API_VERSION >= 0x0b000000 231 BMDDisplayModeSupport support;
233 IDeckLinkDisplayModeIterator *itermode;
234 IDeckLinkDisplayMode *
mode;
238 av_log(avctx,
AV_LOG_DEBUG,
"Trying to find mode for frame size %dx%d, frame timing %d/%d, field order %d, direction %d, format code %s\n",
239 width, height, tb_num, tb_den, field_order, direction, cctx->
format_code ? cctx->
format_code :
"(unset)");
242 res =
ctx->dli->GetDisplayModeIterator (&itermode);
244 res =
ctx->dlo->GetDisplayModeIterator (&itermode);
252 char format_buf[] =
" ";
255 BMDDisplayMode target_mode = (BMDDisplayMode)
AV_RB32(format_buf);
257 ctx->bmd_mode = bmdModeUnknown;
258 while ((
ctx->bmd_mode == bmdModeUnknown) && itermode->Next(&mode) == S_OK) {
259 BMDTimeValue bmd_tb_num, bmd_tb_den;
260 int bmd_width = mode->GetWidth();
261 int bmd_height = mode->GetHeight();
262 BMDDisplayMode bmd_mode = mode->GetDisplayMode();
263 BMDFieldDominance bmd_field_dominance = mode->GetFieldDominance();
265 mode->GetFrameRate(&bmd_tb_num, &bmd_tb_den);
268 if ((bmd_width == width &&
269 bmd_height == height &&
272 || target_mode == bmd_mode) {
273 ctx->bmd_mode = bmd_mode;
274 ctx->bmd_width = bmd_width;
275 ctx->bmd_height = bmd_height;
276 ctx->bmd_tb_den = bmd_tb_den;
277 ctx->bmd_tb_num = bmd_tb_num;
278 ctx->bmd_field_dominance = bmd_field_dominance;
280 bmd_width, bmd_height, 1/
av_q2d(mode_tb),
281 (
ctx->bmd_field_dominance==bmdLowerFieldFirst ||
ctx->bmd_field_dominance==bmdUpperFieldFirst)?
"(i)":
"");
290 if (
ctx->bmd_mode == bmdModeUnknown)
293 #if BLACKMAGIC_DECKLINK_API_VERSION >= 0x0b050000 295 BMDDisplayMode actualMode =
ctx->bmd_mode;
296 if (
ctx->dli->DoesSupportVideoMode(
ctx->video_input,
ctx->bmd_mode,
ctx->raw_format,
297 bmdNoVideoInputConversion, bmdSupportedVideoModeDefault,
298 &actualMode, &support) != S_OK || !support ||
ctx->bmd_mode != actualMode)
301 BMDDisplayMode actualMode =
ctx->bmd_mode;
302 if (
ctx->dlo->DoesSupportVideoMode(bmdVideoConnectionUnspecified,
ctx->bmd_mode,
ctx->raw_format,
303 bmdNoVideoOutputConversion, bmdSupportedVideoModeDefault,
304 &actualMode, &support) != S_OK || !support ||
ctx->bmd_mode != actualMode)
308 #elif BLACKMAGIC_DECKLINK_API_VERSION >= 0x0b000000 310 if (
ctx->dli->DoesSupportVideoMode(
ctx->video_input,
ctx->bmd_mode,
ctx->raw_format,
311 bmdSupportedVideoModeDefault,
315 BMDDisplayMode actualMode =
ctx->bmd_mode;
316 if (
ctx->dlo->DoesSupportVideoMode(bmdVideoConnectionUnspecified,
ctx->bmd_mode,
ctx->raw_format,
317 bmdSupportedVideoModeDefault,
318 &actualMode, &support) != S_OK || !support ||
ctx->bmd_mode != actualMode) {
327 if (
ctx->dli->DoesSupportVideoMode(
ctx->bmd_mode,
ctx->raw_format,
328 bmdVideoOutputFlagDefault,
329 &support,
NULL) != S_OK)
332 if (!
ctx->supports_vanc ||
ctx->dlo->DoesSupportVideoMode(
ctx->bmd_mode,
ctx->raw_format,
334 &support,
NULL) != S_OK || support != bmdDisplayModeSupported) {
336 if (
ctx->dlo->DoesSupportVideoMode(
ctx->bmd_mode,
ctx->raw_format,
337 bmdVideoOutputFlagDefault,
338 &support,
NULL) != S_OK) {
341 ctx->supports_vanc = 0;
345 if (support == bmdDisplayModeSupported)
358 int show_inputs,
int show_outputs)
360 IDeckLink *dl =
NULL;
367 while (ret == 0 && iter->Next(&dl) == S_OK) {
368 IDeckLinkOutput *output_config;
369 IDeckLinkInput *input_config;
370 const char *display_name =
NULL;
371 const char *unique_name =
NULL;
383 if (dl->QueryInterface(IID_IDeckLinkOutput, (
void **)&output_config) == S_OK) {
384 output_config->Release();
390 if (dl->QueryInterface(IID_IDeckLinkInput, (
void **)&input_config) == S_OK) {
391 input_config->Release();
430 int show_inputs,
int show_outputs)
442 show_inputs ?
"input" :
"output");
454 IDeckLinkDisplayModeIterator *itermode;
455 IDeckLinkDisplayMode *
mode;
467 res =
ctx->dli->GetDisplayModeIterator (&itermode);
469 res =
ctx->dlo->GetDisplayModeIterator (&itermode);
477 av_log(avctx,
AV_LOG_INFO,
"Supported formats for '%s':\n\tformat_code\tdescription",
479 while (itermode->Next(&mode) == S_OK) {
480 BMDTimeValue tb_num, tb_den;
481 mode->GetFrameRate(&tb_num, &tb_den);
482 format_code =
av_bswap32(mode->GetDisplayMode());
484 (
char*) &format_code, mode->GetWidth(), mode->GetHeight(),
485 (
int) tb_den, (
int) tb_num);
486 switch (mode->GetFieldDominance()) {
487 case bmdLowerFieldFirst:
489 case bmdUpperFieldFirst:
511 ctx->attr->Release();
522 IDeckLink *dl =
NULL;
527 while (iter->Next(&dl) == S_OK) {
528 const char *display_name =
NULL;
529 const char *unique_name =
NULL;
532 if (display_name && !strcmp(name, display_name) || unique_name && !strcmp(name, unique_name)) {
546 if (
ctx->dl->QueryInterface(IID_IDeckLinkConfiguration, (
void **)&
ctx->cfg) != S_OK) {
547 av_log(avctx,
AV_LOG_ERROR,
"Could not get configuration interface for '%s'\n", name);
Structure describes basic parameters of the device.
char * device_description
human friendly name
#define AV_LOG_WARNING
Something somehow does not look correct.
char * device_name
device name, format depends on device
int ff_decklink_init_device(AVFormatContext *avctx, const char *name)
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
static DECKLINK_BOOL field_order_eq(enum AVFieldOrder field_order, BMDFieldDominance bmd_field_order)
void avdevice_free_list_devices(AVDeviceInfoList **device_list)
Convenient function to free result of avdevice_list_devices().
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_RB32
void ff_decklink_list_devices_legacy(AVFormatContext *avctx, int show_inputs, int show_outputs)
static double av_q2d(AVRational a)
Convert an AVRational to a double.
#define AV_LOG_VERBOSE
Detailed information.
int av_dynarray_add_nofree(void *tab_ptr, int *nb_ptr, void *elem)
Add an element to a dynamic array.
int ff_decklink_list_devices(AVFormatContext *avctx, struct AVDeviceInfoList *device_list, int show_inputs, int show_outputs)
static IDeckLinkIterator * decklink_create_iterator(AVFormatContext *avctx)
Main libavdevice API header.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
char * url
input or output URL.
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
static int decklink_get_attr_string(IDeckLink *dl, BMDDeckLinkAttributeID cfg_id, const char **s)
AVDeviceInfo ** devices
list of autodetected devices
int ff_decklink_set_configs(AVFormatContext *avctx, decklink_direction_t direction)
int ff_decklink_list_formats(AVFormatContext *avctx, decklink_direction_t direction)
int ff_decklink_set_format(AVFormatContext *avctx, int width, int height, int tb_num, int tb_den, enum AVFieldOrder field_order, decklink_direction_t direction)
#define AV_LOG_INFO
Standard information.
char * av_strdup(const char *s)
Duplicate a string.
static AVRational av_make_q(int num, int den)
Create an AVRational.
#define IID_IDeckLinkProfileAttributes
static int decklink_select_input(AVFormatContext *avctx, BMDDeckLinkConfigurationID cfg_id)
Rational number (pair of numerator and denominator).
void ff_decklink_cleanup(AVFormatContext *avctx)
static int av_cmp_q(AVRational a, AVRational b)
Compare two rationals.
void * priv_data
Format private data.
static float add(float src0, float src1)
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Frame references ownership and permissions
int nb_devices
number of autodetected devices
#define AVERROR_EXTERNAL
Generic error in an external library.
mode
Use these values in ebur128_init (or'ed).
#define IDeckLinkProfileAttributes