FFmpeg
decklink_common.cpp
Go to the documentation of this file.
1 /*
2  * Blackmagic DeckLink output
3  * Copyright (c) 2013-2014 Ramiro Polla, Luca Barbato, Deti Fliegl
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 /* Include internal.h first to avoid conflict between winsock.h (used by
23  * DeckLink headers) and winsock2.h (used by libavformat) in MSVC++ builds */
24 extern "C" {
25 #include "libavformat/internal.h"
26 }
27 
28 #include <DeckLinkAPI.h>
29 #ifdef _WIN32
30 #include <DeckLinkAPI_i.c>
31 #else
32 /* The file provided by the SDK is known to be missing prototypes, which doesn't
33  cause issues with GCC since the warning doesn't apply to C++ files. However
34  Clang does complain (and warnings are treated as errors), so suppress the
35  warning just for this one file */
36 #ifdef __clang__
37 #pragma clang diagnostic push
38 #pragma clang diagnostic ignored "-Wmissing-prototypes"
39 #endif
40 #include <DeckLinkAPIDispatch.cpp>
41 #ifdef __clang__
42 #pragma clang diagnostic pop
43 #endif
44 #endif
45 
46 extern "C" {
47 #include "libavformat/avformat.h"
48 #include "libavutil/imgutils.h"
49 #include "libavutil/intreadwrite.h"
50 #include "libavutil/bswap.h"
51 #include "avdevice.h"
52 }
53 
54 #include "decklink_common.h"
55 
56 static IDeckLinkIterator *decklink_create_iterator(AVFormatContext *avctx)
57 {
58  IDeckLinkIterator *iter;
59 
60 #ifdef _WIN32
61  if (CoInitialize(NULL) < 0) {
62  av_log(avctx, AV_LOG_ERROR, "COM initialization failed.\n");
63  return NULL;
64  }
65 
66  if (CoCreateInstance(CLSID_CDeckLinkIterator, NULL, CLSCTX_ALL,
67  IID_IDeckLinkIterator, (void**) &iter) != S_OK) {
68  iter = NULL;
69  }
70 #else
71  iter = CreateDeckLinkIteratorInstance();
72 #endif
73  if (!iter) {
74  av_log(avctx, AV_LOG_ERROR, "Could not create DeckLink iterator. "
75  "Make sure you have DeckLink drivers " BLACKMAGIC_DECKLINK_API_VERSION_STRING " or newer installed.\n");
76  } else {
77  IDeckLinkAPIInformation *api;
78  int64_t version;
79 #ifdef _WIN32
80  if (CoCreateInstance(CLSID_CDeckLinkAPIInformation, NULL, CLSCTX_ALL,
81  IID_IDeckLinkAPIInformation, (void**) &api) != S_OK) {
82  api = NULL;
83  }
84 #else
85  api = CreateDeckLinkAPIInformationInstance();
86 #endif
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");
91  } else {
92  av_log(avctx, AV_LOG_ERROR, "Failed to check installed DeckLink API version.\n");
93  }
94  if (api)
95  api->Release();
96  }
97 
98  return iter;
99 }
100 
101 static int decklink_get_attr_string(IDeckLink *dl, BMDDeckLinkAttributeID cfg_id, const char **s)
102 {
104  HRESULT hr;
106  *s = NULL;
107  if (dl->QueryInterface(IID_IDeckLinkProfileAttributes, (void **)&attr) != S_OK)
108  return AVERROR_EXTERNAL;
109  hr = attr->GetString(cfg_id, &tmp);
110  attr->Release();
111  if (hr == S_OK) {
112  *s = DECKLINK_STRDUP(tmp);
114  if (!*s)
115  return AVERROR(ENOMEM);
116  } else if (hr == E_FAIL) {
117  return AVERROR_EXTERNAL;
118  }
119  return 0;
120 }
121 
122 static int decklink_select_input(AVFormatContext *avctx, BMDDeckLinkConfigurationID cfg_id)
123 {
124  struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data;
125  struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx;
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;
130  HRESULT res;
131 
132  if (bmd_input) {
133  res = ctx->attr->GetInt(attr_id, &supported_connections);
134  if (res != S_OK) {
135  av_log(avctx, AV_LOG_ERROR, "Failed to query supported %s inputs.\n", type_name);
136  return AVERROR_EXTERNAL;
137  }
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);
140  return AVERROR(ENOSYS);
141  }
142  res = ctx->cfg->SetInt(cfg_id, bmd_input);
143  if (res != S_OK) {
144  av_log(avctx, AV_LOG_ERROR, "Failed to select %s input.\n", type_name);
145  return AVERROR_EXTERNAL;
146  }
147  }
148  return 0;
149 }
150 
151 static DECKLINK_BOOL field_order_eq(enum AVFieldOrder field_order, BMDFieldDominance bmd_field_order)
152 {
153  if (field_order == AV_FIELD_UNKNOWN)
154  return true;
155  if ((field_order == AV_FIELD_TT || field_order == AV_FIELD_TB) && bmd_field_order == bmdUpperFieldFirst)
156  return true;
157  if ((field_order == AV_FIELD_BB || field_order == AV_FIELD_BT) && bmd_field_order == bmdLowerFieldFirst)
158  return true;
159  if (field_order == AV_FIELD_PROGRESSIVE && (bmd_field_order == bmdProgressiveFrame || bmd_field_order == bmdProgressiveSegmentedFrame))
160  return true;
161  return false;
162 }
163 
165  decklink_direction_t direction) {
166  struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data;
167  struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx;
168  HRESULT res;
169 
170  if (ctx->duplex_mode) {
171  DECKLINK_BOOL duplex_supported = false;
172 
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;
177 #else
178  if (ctx->attr->GetFlag(BMDDeckLinkSupportsDuplexModeConfiguration, &duplex_supported) != S_OK)
179  duplex_supported = false;
180 #endif
181 
182  if (duplex_supported) {
183 #if BLACKMAGIC_DECKLINK_API_VERSION >= 0x0b000000
184  IDeckLinkProfile *profile = NULL;
185  BMDProfileID bmd_profile_id;
186 
187  if (ctx->duplex_mode < 0 || ctx->duplex_mode >= FF_ARRAY_ELEMS(decklink_profile_id_map))
188  return EINVAL;
189  bmd_profile_id = decklink_profile_id_map[ctx->duplex_mode];
190  res = manager->GetProfile(bmd_profile_id, &profile);
191  if (res == S_OK) {
192  res = profile->SetActive();
193  profile->Release();
194  }
195  manager->Release();
196 #else
197  res = ctx->cfg->SetInt(bmdDeckLinkConfigDuplexMode, ctx->duplex_mode == 2 ? bmdDuplexModeFull : bmdDuplexModeHalf);
198 #endif
199  if (res != S_OK)
200  av_log(avctx, AV_LOG_WARNING, "Setting duplex mode failed.\n");
201  else
202  av_log(avctx, AV_LOG_VERBOSE, "Successfully set duplex mode to %s duplex.\n", ctx->duplex_mode == 2 || ctx->duplex_mode == 4 ? "full" : "half");
203  } else {
204  av_log(avctx, AV_LOG_WARNING, "Unable to set duplex mode, because it is not supported.\n");
205  }
206  }
207  if (direction == DIRECTION_IN) {
208  int ret;
209  ret = decklink_select_input(avctx, bmdDeckLinkConfigAudioInputConnection);
210  if (ret < 0)
211  return ret;
212  ret = decklink_select_input(avctx, bmdDeckLinkConfigVideoInputConnection);
213  if (ret < 0)
214  return ret;
215  }
216  if (direction == DIRECTION_OUT && cctx->timing_offset != INT_MIN) {
217  res = ctx->cfg->SetInt(bmdDeckLinkConfigReferenceInputTimingOffset, cctx->timing_offset);
218  if (res != S_OK)
219  av_log(avctx, AV_LOG_WARNING, "Setting timing offset failed.\n");
220  }
221 
222  if (direction == DIRECTION_OUT && ctx->link > 0) {
223  res = ctx->cfg->SetInt(bmdDeckLinkConfigSDIOutputLinkConfiguration, ctx->link);
224  if (res != S_OK)
225  av_log(avctx, AV_LOG_WARNING, "Setting link configuration failed.\n");
226  else
227  av_log(avctx, AV_LOG_VERBOSE, "Successfully set link configuration: 0x%x.\n", ctx->link);
228  if (ctx->link == bmdLinkConfigurationQuadLink && cctx->sqd >= 0) {
229  res = ctx->cfg->SetFlag(bmdDeckLinkConfigQuadLinkSDIVideoOutputSquareDivisionSplit, cctx->sqd);
230  if (res != S_OK)
231  av_log(avctx, AV_LOG_WARNING, "Setting SquareDivisionSplit failed.\n");
232  else
233  av_log(avctx, AV_LOG_VERBOSE, "Successfully set SquareDivisionSplit.\n");
234  }
235  }
236 
237  if (direction == DIRECTION_OUT && cctx->level_a >= 0) {
238  DECKLINK_BOOL level_a_supported = false;
239 
240  if (ctx->attr->GetFlag(BMDDeckLinkSupportsSMPTELevelAOutput, &level_a_supported) != S_OK)
241  level_a_supported = false;
242 
243  if (level_a_supported) {
244  res = ctx->cfg->SetFlag(bmdDeckLinkConfigSMPTELevelAOutput, cctx->level_a);
245  if (res != S_OK)
246  av_log(avctx, AV_LOG_WARNING, "Setting SMPTE levelA failed.\n");
247  else
248  av_log(avctx, AV_LOG_VERBOSE, "Successfully set SMPTE levelA.\n");
249  } else {
250  av_log(avctx, AV_LOG_WARNING, "Unable to set SMPTE levelA mode, because it is not supported.\n");
251  }
252  }
253 
254  return 0;
255 }
256 
258  int width, int height,
259  int tb_num, int tb_den,
260  enum AVFieldOrder field_order,
261  decklink_direction_t direction)
262 {
263  struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data;
264  struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx;
265 #if BLACKMAGIC_DECKLINK_API_VERSION >= 0x0b000000
266  DECKLINK_BOOL support;
267 #else
268  BMDDisplayModeSupport support;
269 #endif
270  IDeckLinkDisplayModeIterator *itermode;
271  IDeckLinkDisplayMode *mode;
272  int i = 1;
273  HRESULT res;
274 
275  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",
276  width, height, tb_num, tb_den, field_order, direction, cctx->format_code ? cctx->format_code : "(unset)");
277 
278  if (direction == DIRECTION_IN) {
279  res = ctx->dli->GetDisplayModeIterator (&itermode);
280  } else {
281  res = ctx->dlo->GetDisplayModeIterator (&itermode);
282  }
283 
284  if (res!= S_OK) {
285  av_log(avctx, AV_LOG_ERROR, "Could not get Display Mode Iterator\n");
286  return AVERROR(EIO);
287  }
288 
289  char format_buf[] = " ";
290  if (cctx->format_code)
291  memcpy(format_buf, cctx->format_code, FFMIN(strlen(cctx->format_code), sizeof(format_buf)));
292  BMDDisplayMode target_mode = (BMDDisplayMode)AV_RB32(format_buf);
293  AVRational target_tb = av_make_q(tb_num, tb_den);
294  ctx->bmd_mode = bmdModeUnknown;
295  while ((ctx->bmd_mode == bmdModeUnknown) && itermode->Next(&mode) == S_OK) {
296  BMDTimeValue bmd_tb_num, bmd_tb_den;
297  int bmd_width = mode->GetWidth();
298  int bmd_height = mode->GetHeight();
299  BMDDisplayMode bmd_mode = mode->GetDisplayMode();
300  BMDFieldDominance bmd_field_dominance = mode->GetFieldDominance();
301 
302  mode->GetFrameRate(&bmd_tb_num, &bmd_tb_den);
303  AVRational mode_tb = av_make_q(bmd_tb_num, bmd_tb_den);
304 
305  if ((bmd_width == width &&
306  bmd_height == height &&
307  !av_cmp_q(mode_tb, target_tb) &&
308  field_order_eq(field_order, bmd_field_dominance))
309  || target_mode == bmd_mode) {
310  ctx->bmd_mode = bmd_mode;
311  ctx->bmd_width = bmd_width;
312  ctx->bmd_height = bmd_height;
313  ctx->bmd_tb_den = bmd_tb_den;
314  ctx->bmd_tb_num = bmd_tb_num;
315  ctx->bmd_field_dominance = bmd_field_dominance;
316  av_log(avctx, AV_LOG_INFO, "Found Decklink mode %d x %d with rate %.2f%s\n",
317  bmd_width, bmd_height, 1/av_q2d(mode_tb),
318  (ctx->bmd_field_dominance==bmdLowerFieldFirst || ctx->bmd_field_dominance==bmdUpperFieldFirst)?"(i)":"");
319  }
320 
321  mode->Release();
322  i++;
323  }
324 
325  itermode->Release();
326 
327  if (ctx->bmd_mode == bmdModeUnknown)
328  return -1;
329 
330 #if BLACKMAGIC_DECKLINK_API_VERSION >= 0x0b050000
331  if (direction == DIRECTION_IN) {
332  BMDDisplayMode actualMode = ctx->bmd_mode;
333  if (ctx->dli->DoesSupportVideoMode(ctx->video_input, ctx->bmd_mode, ctx->raw_format,
334  bmdNoVideoInputConversion, bmdSupportedVideoModeDefault,
335  &actualMode, &support) != S_OK || !support || ctx->bmd_mode != actualMode)
336  return -1;
337  } else {
338  BMDDisplayMode actualMode = ctx->bmd_mode;
339  if (ctx->dlo->DoesSupportVideoMode(bmdVideoConnectionUnspecified, ctx->bmd_mode, ctx->raw_format,
340  bmdNoVideoOutputConversion, bmdSupportedVideoModeDefault,
341  &actualMode, &support) != S_OK || !support || ctx->bmd_mode != actualMode)
342  return -1;
343  }
344  return 0;
345 #elif BLACKMAGIC_DECKLINK_API_VERSION >= 0x0b000000
346  if (direction == DIRECTION_IN) {
347  if (ctx->dli->DoesSupportVideoMode(ctx->video_input, ctx->bmd_mode, ctx->raw_format,
348  bmdSupportedVideoModeDefault,
349  &support) != S_OK)
350  return -1;
351  } else {
352  BMDDisplayMode actualMode = ctx->bmd_mode;
353  if (ctx->dlo->DoesSupportVideoMode(bmdVideoConnectionUnspecified, ctx->bmd_mode, ctx->raw_format,
354  bmdSupportedVideoModeDefault,
355  &actualMode, &support) != S_OK || !support || ctx->bmd_mode != actualMode) {
356  return -1;
357  }
358 
359  }
360  if (support)
361  return 0;
362 #else
363  if (direction == DIRECTION_IN) {
364  if (ctx->dli->DoesSupportVideoMode(ctx->bmd_mode, ctx->raw_format,
365  bmdVideoOutputFlagDefault,
366  &support, NULL) != S_OK)
367  return -1;
368  } else {
369  if (!ctx->supports_vanc || ctx->dlo->DoesSupportVideoMode(ctx->bmd_mode, ctx->raw_format,
370  bmdVideoOutputVANC,
371  &support, NULL) != S_OK || support != bmdDisplayModeSupported) {
372  /* Try without VANC enabled */
373  if (ctx->dlo->DoesSupportVideoMode(ctx->bmd_mode, ctx->raw_format,
374  bmdVideoOutputFlagDefault,
375  &support, NULL) != S_OK) {
376  return -1;
377  }
378  ctx->supports_vanc = 0;
379  }
380 
381  }
382  if (support == bmdDisplayModeSupported)
383  return 0;
384 #endif
385 
386  return -1;
387 }
388 
390  return ff_decklink_set_format(avctx, 0, 0, 0, 0, AV_FIELD_UNKNOWN, direction);
391 }
392 
394  struct AVDeviceInfoList *device_list,
395  int show_inputs, int show_outputs)
396 {
397  IDeckLink *dl = NULL;
398  IDeckLinkIterator *iter = decklink_create_iterator(avctx);
399  int ret = 0;
400 
401  if (!iter)
402  return AVERROR(EIO);
403 
404  while (ret == 0 && iter->Next(&dl) == S_OK) {
405  IDeckLinkOutput *output_config;
406  IDeckLinkInput *input_config;
407  const char *display_name = NULL;
408  const char *unique_name = NULL;
409  AVDeviceInfo *new_device = NULL;
410  int add = 0;
411 
412  ret = decklink_get_attr_string(dl, BMDDeckLinkDisplayName, &display_name);
413  if (ret < 0)
414  goto next;
415  ret = decklink_get_attr_string(dl, BMDDeckLinkDeviceHandle, &unique_name);
416  if (ret < 0)
417  goto next;
418 
419  if (show_outputs) {
420  if (dl->QueryInterface(IID_IDeckLinkOutput, (void **)&output_config) == S_OK) {
421  output_config->Release();
422  add = 1;
423  }
424  }
425 
426  if (show_inputs) {
427  if (dl->QueryInterface(IID_IDeckLinkInput, (void **)&input_config) == S_OK) {
428  input_config->Release();
429  add = 1;
430  }
431  }
432 
433  if (add == 1) {
434  new_device = (AVDeviceInfo *) av_mallocz(sizeof(AVDeviceInfo));
435  if (!new_device) {
436  ret = AVERROR(ENOMEM);
437  goto next;
438  }
439 
440  new_device->device_name = av_strdup(unique_name ? unique_name : display_name);
441  new_device->device_description = av_strdup(display_name);
442 
443  if (!new_device->device_name ||
444  !new_device->device_description ||
445  av_dynarray_add_nofree(&device_list->devices, &device_list->nb_devices, new_device) < 0) {
446  ret = AVERROR(ENOMEM);
447  av_freep(&new_device->device_name);
448  av_freep(&new_device->device_description);
449  av_freep(&new_device);
450  goto next;
451  }
452  }
453 
454  next:
455  av_freep(&display_name);
456  av_freep(&unique_name);
457  dl->Release();
458  }
459  iter->Release();
460  return ret;
461 }
462 
463 /* This is a wrapper around the ff_decklink_list_devices() which dumps the
464  output to av_log() and exits (for backward compatibility with the
465  "-list_devices" argument). */
467  int show_inputs, int show_outputs)
468 {
469  struct AVDeviceInfoList *device_list = NULL;
470  int ret;
471 
472  device_list = (struct AVDeviceInfoList *) av_mallocz(sizeof(AVDeviceInfoList));
473  if (!device_list)
474  return;
475 
476  ret = ff_decklink_list_devices(avctx, device_list, show_inputs, show_outputs);
477  if (ret == 0) {
478  av_log(avctx, AV_LOG_INFO, "Blackmagic DeckLink %s devices:\n",
479  show_inputs ? "input" : "output");
480  for (int i = 0; i < device_list->nb_devices; i++) {
481  av_log(avctx, AV_LOG_INFO, "\t'%s'\n", device_list->devices[i]->device_description);
482  }
483  }
484  avdevice_free_list_devices(&device_list);
485 }
486 
488 {
489  struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data;
490  struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx;
491  IDeckLinkDisplayModeIterator *itermode;
492  IDeckLinkDisplayMode *mode;
493  uint32_t format_code;
494  HRESULT res;
495 
496  if (direction == DIRECTION_IN) {
497  int ret;
498  ret = decklink_select_input(avctx, bmdDeckLinkConfigAudioInputConnection);
499  if (ret < 0)
500  return ret;
501  ret = decklink_select_input(avctx, bmdDeckLinkConfigVideoInputConnection);
502  if (ret < 0)
503  return ret;
504  res = ctx->dli->GetDisplayModeIterator (&itermode);
505  } else {
506  res = ctx->dlo->GetDisplayModeIterator (&itermode);
507  }
508 
509  if (res!= S_OK) {
510  av_log(avctx, AV_LOG_ERROR, "Could not get Display Mode Iterator\n");
511  return AVERROR(EIO);
512  }
513 
514  av_log(avctx, AV_LOG_INFO, "Supported formats for '%s':\n\tformat_code\tdescription",
515  avctx->url);
516  while (itermode->Next(&mode) == S_OK) {
517  BMDTimeValue tb_num, tb_den;
518  mode->GetFrameRate(&tb_num, &tb_den);
519  format_code = av_bswap32(mode->GetDisplayMode());
520  av_log(avctx, AV_LOG_INFO, "\n\t%.4s\t\t%ldx%ld at %d/%d fps",
521  (char*) &format_code, mode->GetWidth(), mode->GetHeight(),
522  (int) tb_den, (int) tb_num);
523  switch (mode->GetFieldDominance()) {
524  case bmdLowerFieldFirst:
525  av_log(avctx, AV_LOG_INFO, " (interlaced, lower field first)"); break;
526  case bmdUpperFieldFirst:
527  av_log(avctx, AV_LOG_INFO, " (interlaced, upper field first)"); break;
528  }
529  mode->Release();
530  }
531  av_log(avctx, AV_LOG_INFO, "\n");
532 
533  itermode->Release();
534 
535  return 0;
536 }
537 
539 {
540  struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data;
541  struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx;
542 
543  if (ctx->dli)
544  ctx->dli->Release();
545  if (ctx->dlo)
546  ctx->dlo->Release();
547  if (ctx->attr)
548  ctx->attr->Release();
549  if (ctx->cfg)
550  ctx->cfg->Release();
551  if (ctx->dl)
552  ctx->dl->Release();
553 }
554 
556 {
557  struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data;
558  struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx;
559  IDeckLink *dl = NULL;
560  IDeckLinkIterator *iter = decklink_create_iterator(avctx);
561  if (!iter)
562  return AVERROR_EXTERNAL;
563 
564  while (iter->Next(&dl) == S_OK) {
565  const char *display_name = NULL;
566  const char *unique_name = NULL;
567  decklink_get_attr_string(dl, BMDDeckLinkDisplayName, &display_name);
568  decklink_get_attr_string(dl, BMDDeckLinkDeviceHandle, &unique_name);
569  if (display_name && !strcmp(name, display_name) || unique_name && !strcmp(name, unique_name)) {
570  av_free((void *)unique_name);
571  av_free((void *)display_name);
572  ctx->dl = dl;
573  break;
574  }
575  av_free((void *)display_name);
576  av_free((void *)unique_name);
577  dl->Release();
578  }
579  iter->Release();
580  if (!ctx->dl)
581  return AVERROR(ENXIO);
582 
583  if (ctx->dl->QueryInterface(IID_IDeckLinkConfiguration, (void **)&ctx->cfg) != S_OK) {
584  av_log(avctx, AV_LOG_ERROR, "Could not get configuration interface for '%s'\n", name);
585  ff_decklink_cleanup(avctx);
586  return AVERROR_EXTERNAL;
587  }
588 
589  if (ctx->dl->QueryInterface(IID_IDeckLinkProfileAttributes, (void **)&ctx->attr) != S_OK) {
590  av_log(avctx, AV_LOG_ERROR, "Could not get attributes interface for '%s'\n", name);
591  ff_decklink_cleanup(avctx);
592  return AVERROR_EXTERNAL;
593  }
594 
595  return 0;
596 }
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
name
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default minimum maximum flags name is the option name
Definition: writing_filters.txt:88
AVERROR
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
AVDeviceInfo::device_name
char * device_name
device name, format depends on device
Definition: avdevice.h:458
AVDeviceInfoList::nb_devices
int nb_devices
number of autodetected devices
Definition: avdevice.h:467
profile
mfxU16 profile
Definition: qsvenc.c:45
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:26
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:196
AV_FIELD_TT
@ AV_FIELD_TT
Definition: codec_par.h:39
AV_FIELD_TB
@ AV_FIELD_TB
Definition: codec_par.h:41
av_bswap32
#define av_bswap32
Definition: bswap.h:33
AVDeviceInfoList::devices
AVDeviceInfo ** devices
list of autodetected devices
Definition: avdevice.h:466
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
width
#define width
intreadwrite.h
s
#define s(width, name)
Definition: cbs_vp9.c:257
av_q2d
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition: rational.h:104
AV_FIELD_UNKNOWN
@ AV_FIELD_UNKNOWN
Definition: codec_par.h:37
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
ctx
AVFormatContext * ctx
Definition: movenc.c:48
AV_FIELD_BT
@ AV_FIELD_BT
Definition: codec_par.h:42
AVFormatContext
Format I/O context.
Definition: avformat.h:1097
internal.h
NULL
#define NULL
Definition: coverity.c:32
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
AVFormatContext::url
char * url
input or output URL.
Definition: avformat.h:1180
av_make_q
static AVRational av_make_q(int num, int den)
Create an AVRational.
Definition: rational.h:71
AV_RB32
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
Definition: bytestream.h:96
AVDeviceInfo
Structure describes basic parameters of the device.
Definition: avdevice.h:457
avdevice.h
avdevice_free_list_devices
void avdevice_free_list_devices(AVDeviceInfoList **device_list)
Convenient function to free result of avdevice_list_devices().
Definition: avdevice.c:144
height
#define height
AVERROR_EXTERNAL
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition: error.h:59
version
version
Definition: libkvazaar.c:307
AVDeviceInfo::device_description
char * device_description
human friendly name
Definition: avdevice.h:459
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:191
AV_FIELD_BB
@ AV_FIELD_BB
Definition: codec_par.h:40
i
int i
Definition: input.c:406
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:263
av_cmp_q
static int av_cmp_q(AVRational a, AVRational b)
Compare two rationals.
Definition: rational.h:89
ret
ret
Definition: filter_design.txt:187
bswap.h
AVDeviceInfoList
List of devices.
Definition: avdevice.h:465
avformat.h
av_dynarray_add_nofree
int av_dynarray_add_nofree(void *tab_ptr, int *nb_ptr, void *elem)
Add an element to a dynamic array.
Definition: mem.c:322
mode
mode
Definition: ebur128.h:83
av_strdup
char * av_strdup(const char *s)
Duplicate a string.
Definition: mem.c:279
add
static float add(float src0, float src1)
Definition: dnn_backend_native_layer_mathbinary.c:35
AV_FIELD_PROGRESSIVE
@ AV_FIELD_PROGRESSIVE
Definition: codec_par.h:38
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
AVFieldOrder
AVFieldOrder
Definition: codec_par.h:36
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
imgutils.h
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
AVFormatContext::priv_data
void * priv_data
Format private data.
Definition: avformat.h:1125