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 <DeckLinkAPIVersion.h>
29 #include <DeckLinkAPI.h>
30 #if BLACKMAGIC_DECKLINK_API_VERSION >= 0x0e030000
31 #include <DeckLinkAPI_v14_2_1.h>
32 #endif
33 
34 #ifdef _WIN32
35 #include <DeckLinkAPI_i.c>
36 #else
37 /* The file provided by the SDK is known to be missing prototypes, which doesn't
38  cause issues with GCC since the warning doesn't apply to C++ files. However
39  Clang does complain (and warnings are treated as errors), so suppress the
40  warning just for this one file */
41 #ifdef __clang__
42 #pragma clang diagnostic push
43 #pragma clang diagnostic ignored "-Wmissing-prototypes"
44 #endif
45 #include <DeckLinkAPIDispatch.cpp>
46 #ifdef __clang__
47 #pragma clang diagnostic pop
48 #endif
49 #endif
50 
51 extern "C" {
52 #include "libavformat/avformat.h"
53 #include "libavutil/imgutils.h"
54 #include "libavutil/intreadwrite.h"
55 #include "libavutil/bswap.h"
56 #include "avdevice.h"
57 }
58 
59 #include "decklink_common.h"
60 
61 static IDeckLinkIterator *decklink_create_iterator(AVFormatContext *avctx)
62 {
63  IDeckLinkIterator *iter;
64 
65 #ifdef _WIN32
66  if (CoInitialize(NULL) < 0) {
67  av_log(avctx, AV_LOG_ERROR, "COM initialization failed.\n");
68  return NULL;
69  }
70 
71  if (CoCreateInstance(CLSID_CDeckLinkIterator, NULL, CLSCTX_ALL,
72  IID_IDeckLinkIterator, (void**) &iter) != S_OK) {
73  iter = NULL;
74  }
75 #else
76  iter = CreateDeckLinkIteratorInstance();
77 #endif
78  if (!iter) {
79  av_log(avctx, AV_LOG_ERROR, "Could not create DeckLink iterator. "
80  "Make sure you have DeckLink drivers " BLACKMAGIC_DECKLINK_API_VERSION_STRING " or newer installed.\n");
81  } else {
82  IDeckLinkAPIInformation *api;
84 #ifdef _WIN32
85  if (CoCreateInstance(CLSID_CDeckLinkAPIInformation, NULL, CLSCTX_ALL,
86  IID_IDeckLinkAPIInformation, (void**) &api) != S_OK) {
87  api = NULL;
88  }
89 #else
90  api = CreateDeckLinkAPIInformationInstance();
91 #endif
92  if (api && api->GetInt(BMDDeckLinkAPIVersion, &version) == S_OK) {
93  if (version < BLACKMAGIC_DECKLINK_API_VERSION)
94  av_log(avctx, AV_LOG_WARNING, "Installed DeckLink drivers are too old and may be incompatible with the SDK this module was built against. "
95  "Make sure you have DeckLink drivers " BLACKMAGIC_DECKLINK_API_VERSION_STRING " or newer installed.\n");
96  } else {
97  av_log(avctx, AV_LOG_ERROR, "Failed to check installed DeckLink API version.\n");
98  }
99  if (api)
100  api->Release();
101  }
102 
103  return iter;
104 }
105 
106 static int decklink_get_attr_string(IDeckLink *dl, BMDDeckLinkAttributeID cfg_id, const char **s)
107 {
109  HRESULT hr;
111  *s = NULL;
112  if (dl->QueryInterface(IID_IDeckLinkProfileAttributes, (void **)&attr) != S_OK)
113  return AVERROR_EXTERNAL;
114  hr = attr->GetString(cfg_id, &tmp);
115  attr->Release();
116  if (hr == S_OK) {
117  *s = DECKLINK_STRDUP(tmp);
119  if (!*s)
120  return AVERROR(ENOMEM);
121  } else if (hr == E_FAIL) {
122  return AVERROR_EXTERNAL;
123  }
124  return 0;
125 }
126 
127 static int decklink_select_input(AVFormatContext *avctx, BMDDeckLinkConfigurationID cfg_id)
128 {
129  struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data;
130  struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx;
131  BMDDeckLinkAttributeID attr_id = (cfg_id == bmdDeckLinkConfigAudioInputConnection) ? BMDDeckLinkAudioInputConnections : BMDDeckLinkVideoInputConnections;
132  int64_t bmd_input = (cfg_id == bmdDeckLinkConfigAudioInputConnection) ? (int64_t)ctx->audio_input : (int64_t)ctx->video_input;
133  const char *type_name = (cfg_id == bmdDeckLinkConfigAudioInputConnection) ? "audio" : "video";
134  int64_t supported_connections = 0;
135  HRESULT res;
136 
137  if (bmd_input) {
138  res = ctx->attr->GetInt(attr_id, &supported_connections);
139  if (res != S_OK) {
140  av_log(avctx, AV_LOG_ERROR, "Failed to query supported %s inputs.\n", type_name);
141  return AVERROR_EXTERNAL;
142  }
143  if ((supported_connections & bmd_input) != bmd_input) {
144  av_log(avctx, AV_LOG_ERROR, "Device does not support selected %s input.\n", type_name);
145  return AVERROR(ENOSYS);
146  }
147  res = ctx->cfg->SetInt(cfg_id, bmd_input);
148  if (res != S_OK) {
149  av_log(avctx, AV_LOG_ERROR, "Failed to select %s input.\n", type_name);
150  return AVERROR_EXTERNAL;
151  }
152  }
153  return 0;
154 }
155 
156 static DECKLINK_BOOL field_order_eq(enum AVFieldOrder field_order, BMDFieldDominance bmd_field_order)
157 {
158  if (field_order == AV_FIELD_UNKNOWN)
159  return true;
160  if ((field_order == AV_FIELD_TT || field_order == AV_FIELD_TB) && bmd_field_order == bmdUpperFieldFirst)
161  return true;
162  if ((field_order == AV_FIELD_BB || field_order == AV_FIELD_BT) && bmd_field_order == bmdLowerFieldFirst)
163  return true;
164  if (field_order == AV_FIELD_PROGRESSIVE && (bmd_field_order == bmdProgressiveFrame || bmd_field_order == bmdProgressiveSegmentedFrame))
165  return true;
166  return false;
167 }
168 
170  decklink_direction_t direction) {
171  struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data;
172  struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx;
173  HRESULT res;
174 
175  if (ctx->duplex_mode) {
176  DECKLINK_BOOL duplex_supported = false;
177 
178 #if BLACKMAGIC_DECKLINK_API_VERSION >= 0x0b000000
179  IDeckLinkProfileManager *manager = NULL;
180  if (ctx->dl->QueryInterface(IID_IDeckLinkProfileManager, (void **)&manager) == S_OK)
181  duplex_supported = true;
182 #else
183  if (ctx->attr->GetFlag(BMDDeckLinkSupportsDuplexModeConfiguration, &duplex_supported) != S_OK)
184  duplex_supported = false;
185 #endif
186 
187  if (duplex_supported) {
188 #if BLACKMAGIC_DECKLINK_API_VERSION >= 0x0b000000
189  IDeckLinkProfile *profile = NULL;
190  BMDProfileID bmd_profile_id;
191 
192  if (ctx->duplex_mode < 0 || ctx->duplex_mode >= FF_ARRAY_ELEMS(decklink_profile_id_map))
193  return EINVAL;
194  bmd_profile_id = decklink_profile_id_map[ctx->duplex_mode];
195  res = manager->GetProfile(bmd_profile_id, &profile);
196  if (res == S_OK) {
197  res = profile->SetActive();
198  profile->Release();
199  }
200  manager->Release();
201 #else
202  res = ctx->cfg->SetInt(bmdDeckLinkConfigDuplexMode, ctx->duplex_mode == 2 ? bmdDuplexModeFull : bmdDuplexModeHalf);
203 #endif
204  if (res != S_OK)
205  av_log(avctx, AV_LOG_WARNING, "Setting duplex mode failed.\n");
206  else
207  av_log(avctx, AV_LOG_VERBOSE, "Successfully set duplex mode to %s duplex.\n", ctx->duplex_mode == 2 || ctx->duplex_mode == 4 ? "full" : "half");
208  } else {
209  av_log(avctx, AV_LOG_WARNING, "Unable to set duplex mode, because it is not supported.\n");
210  }
211  }
212  if (direction == DIRECTION_IN) {
213  int ret;
214  ret = decklink_select_input(avctx, bmdDeckLinkConfigAudioInputConnection);
215  if (ret < 0)
216  return ret;
217  ret = decklink_select_input(avctx, bmdDeckLinkConfigVideoInputConnection);
218  if (ret < 0)
219  return ret;
220  }
221  if (direction == DIRECTION_OUT && cctx->timing_offset != INT_MIN) {
222  res = ctx->cfg->SetInt(bmdDeckLinkConfigReferenceInputTimingOffset, cctx->timing_offset);
223  if (res != S_OK)
224  av_log(avctx, AV_LOG_WARNING, "Setting timing offset failed.\n");
225  }
226 
227  if (direction == DIRECTION_OUT && ctx->link > 0) {
228  res = ctx->cfg->SetInt(bmdDeckLinkConfigSDIOutputLinkConfiguration, ctx->link);
229  if (res != S_OK)
230  av_log(avctx, AV_LOG_WARNING, "Setting link configuration failed.\n");
231  else
232  av_log(avctx, AV_LOG_VERBOSE, "Successfully set link configuration: 0x%x.\n", ctx->link);
233  if (ctx->link == bmdLinkConfigurationQuadLink && cctx->sqd >= 0) {
234  res = ctx->cfg->SetFlag(bmdDeckLinkConfigQuadLinkSDIVideoOutputSquareDivisionSplit, cctx->sqd);
235  if (res != S_OK)
236  av_log(avctx, AV_LOG_WARNING, "Setting SquareDivisionSplit failed.\n");
237  else
238  av_log(avctx, AV_LOG_VERBOSE, "Successfully set SquareDivisionSplit.\n");
239  }
240  }
241 
242  if (direction == DIRECTION_OUT && cctx->level_a >= 0) {
243  DECKLINK_BOOL level_a_supported = false;
244 
245  if (ctx->attr->GetFlag(BMDDeckLinkSupportsSMPTELevelAOutput, &level_a_supported) != S_OK)
246  level_a_supported = false;
247 
248  if (level_a_supported) {
249  res = ctx->cfg->SetFlag(bmdDeckLinkConfigSMPTELevelAOutput, cctx->level_a);
250  if (res != S_OK)
251  av_log(avctx, AV_LOG_WARNING, "Setting SMPTE levelA failed.\n");
252  else
253  av_log(avctx, AV_LOG_VERBOSE, "Successfully set SMPTE levelA.\n");
254  } else {
255  av_log(avctx, AV_LOG_WARNING, "Unable to set SMPTE levelA mode, because it is not supported.\n");
256  }
257  }
258 
259  return 0;
260 }
261 
263  int width, int height,
264  int tb_num, int tb_den,
265  enum AVFieldOrder field_order,
266  decklink_direction_t direction)
267 {
268  struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data;
269  struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx;
270 #if BLACKMAGIC_DECKLINK_API_VERSION >= 0x0b000000
271  DECKLINK_BOOL support;
272 #else
273  BMDDisplayModeSupport support;
274 #endif
275  IDeckLinkDisplayModeIterator *itermode;
276  IDeckLinkDisplayMode *mode;
277  int i = 1;
278  HRESULT res;
279 
280  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",
281  width, height, tb_num, tb_den, field_order, direction, cctx->format_code ? cctx->format_code : "(unset)");
282 
283  if (direction == DIRECTION_IN) {
284  res = ctx->dli->GetDisplayModeIterator (&itermode);
285  } else {
286  res = ctx->dlo->GetDisplayModeIterator (&itermode);
287  }
288 
289  if (res!= S_OK) {
290  av_log(avctx, AV_LOG_ERROR, "Could not get Display Mode Iterator\n");
291  return AVERROR(EIO);
292  }
293 
294  char format_buf[] = " ";
295  if (cctx->format_code)
296  memcpy(format_buf, cctx->format_code, FFMIN(strlen(cctx->format_code), sizeof(format_buf)));
297  BMDDisplayMode target_mode = (BMDDisplayMode)AV_RB32(format_buf);
298  AVRational target_tb = av_make_q(tb_num, tb_den);
299  ctx->bmd_mode = bmdModeUnknown;
300  while ((ctx->bmd_mode == bmdModeUnknown) && itermode->Next(&mode) == S_OK) {
301  BMDTimeValue bmd_tb_num, bmd_tb_den;
302  int bmd_width = mode->GetWidth();
303  int bmd_height = mode->GetHeight();
304  BMDDisplayMode bmd_mode = mode->GetDisplayMode();
305  BMDFieldDominance bmd_field_dominance = mode->GetFieldDominance();
306 
307  mode->GetFrameRate(&bmd_tb_num, &bmd_tb_den);
308  AVRational mode_tb = av_make_q(bmd_tb_num, bmd_tb_den);
309 
310  if ((bmd_width == width &&
311  bmd_height == height &&
312  !av_cmp_q(mode_tb, target_tb) &&
313  field_order_eq(field_order, bmd_field_dominance))
314  || target_mode == bmd_mode) {
315  ctx->bmd_mode = bmd_mode;
316  ctx->bmd_width = bmd_width;
317  ctx->bmd_height = bmd_height;
318  ctx->bmd_tb_den = bmd_tb_den;
319  ctx->bmd_tb_num = bmd_tb_num;
320  ctx->bmd_field_dominance = bmd_field_dominance;
321  av_log(avctx, AV_LOG_INFO, "Found Decklink mode %d x %d with rate %.2f%s\n",
322  bmd_width, bmd_height, 1/av_q2d(mode_tb),
323  (ctx->bmd_field_dominance==bmdLowerFieldFirst || ctx->bmd_field_dominance==bmdUpperFieldFirst)?"(i)":"");
324  }
325 
326  mode->Release();
327  i++;
328  }
329 
330  itermode->Release();
331 
332  if (ctx->bmd_mode == bmdModeUnknown)
333  return -1;
334 
335 #if BLACKMAGIC_DECKLINK_API_VERSION >= 0x0b050000
336  if (direction == DIRECTION_IN) {
337  BMDDisplayMode actualMode = ctx->bmd_mode;
338  if (ctx->dli->DoesSupportVideoMode(ctx->video_input, ctx->bmd_mode, ctx->raw_format,
339  bmdNoVideoInputConversion, bmdSupportedVideoModeDefault,
340  &actualMode, &support) != S_OK || !support || ctx->bmd_mode != actualMode)
341  return -1;
342  } else {
343  BMDDisplayMode actualMode = ctx->bmd_mode;
344  if (ctx->dlo->DoesSupportVideoMode(bmdVideoConnectionUnspecified, ctx->bmd_mode, ctx->raw_format,
345  bmdNoVideoOutputConversion, bmdSupportedVideoModeDefault,
346  &actualMode, &support) != S_OK || !support || ctx->bmd_mode != actualMode)
347  return -1;
348  }
349  return 0;
350 #elif BLACKMAGIC_DECKLINK_API_VERSION >= 0x0b000000
351  if (direction == DIRECTION_IN) {
352  if (ctx->dli->DoesSupportVideoMode(ctx->video_input, ctx->bmd_mode, ctx->raw_format,
353  bmdSupportedVideoModeDefault,
354  &support) != S_OK)
355  return -1;
356  } else {
357  BMDDisplayMode actualMode = ctx->bmd_mode;
358  if (ctx->dlo->DoesSupportVideoMode(bmdVideoConnectionUnspecified, ctx->bmd_mode, ctx->raw_format,
359  bmdSupportedVideoModeDefault,
360  &actualMode, &support) != S_OK || !support || ctx->bmd_mode != actualMode) {
361  return -1;
362  }
363 
364  }
365  if (support)
366  return 0;
367 #else
368  if (direction == DIRECTION_IN) {
369  if (ctx->dli->DoesSupportVideoMode(ctx->bmd_mode, ctx->raw_format,
370  bmdVideoOutputFlagDefault,
371  &support, NULL) != S_OK)
372  return -1;
373  } else {
374  if (!ctx->supports_vanc || ctx->dlo->DoesSupportVideoMode(ctx->bmd_mode, ctx->raw_format,
375  bmdVideoOutputVANC,
376  &support, NULL) != S_OK || support != bmdDisplayModeSupported) {
377  /* Try without VANC enabled */
378  if (ctx->dlo->DoesSupportVideoMode(ctx->bmd_mode, ctx->raw_format,
379  bmdVideoOutputFlagDefault,
380  &support, NULL) != S_OK) {
381  return -1;
382  }
383  ctx->supports_vanc = 0;
384  }
385 
386  }
387  if (support == bmdDisplayModeSupported)
388  return 0;
389 #endif
390 
391  return -1;
392 }
393 
395  return ff_decklink_set_format(avctx, 0, 0, 0, 0, AV_FIELD_UNKNOWN, direction);
396 }
397 
399 {
400  memset(q, 0, sizeof(DecklinkPacketQueue));
403  q->avctx = avctx;
404  q->max_q_size = queue_size;
405 }
406 
408 {
409  AVPacket pkt;
410 
412  while (avpriv_packet_list_get(&q->pkt_list, &pkt) == 0) {
414  }
415  q->nb_packets = 0;
416  q->size = 0;
418 }
419 
421 {
425 }
426 
428 {
429  unsigned long long size;
431  size = q->size;
433  return size;
434 }
435 
437 {
438  int pkt_size = pkt->size;
439  int ret;
440 
441  // Drop Packet if queue size is > maximum queue size
442  if (ff_decklink_packet_queue_size(q) > (uint64_t)q->max_q_size) {
444  av_log(q->avctx, AV_LOG_WARNING, "Decklink input buffer overrun!\n");
445  return -1;
446  }
447  /* ensure the packet is reference counted */
448  if (av_packet_make_refcounted(pkt) < 0) {
450  return -1;
451  }
452 
454 
456  if (ret == 0) {
457  q->nb_packets++;
458  q->size += pkt_size + sizeof(AVPacket);
460  } else {
462  }
463 
465  return ret;
466 }
467 
469 {
470  int ret;
471 
473 
474  for (;; ) {
476  if (ret == 0) {
477  q->nb_packets--;
478  q->size -= pkt->size + sizeof(AVPacket);
479  ret = 1;
480  break;
481  } else if (!block) {
482  ret = 0;
483  break;
484  } else {
485  pthread_cond_wait(&q->cond, &q->mutex);
486  }
487  }
489  return ret;
490 }
491 
493 {
494  PacketListEntry *pkt1;
495  int64_t pts = -1;
496 
498  pkt1 = q->pkt_list.head;
499  if (pkt1) {
500  pts = pkt1->pkt.pts;
501  }
503 
504  return pts;
505 }
506 
507 
509  struct AVDeviceInfoList *device_list,
510  int show_inputs, int show_outputs)
511 {
512  IDeckLink *dl = NULL;
513  IDeckLinkIterator *iter = decklink_create_iterator(avctx);
514  int ret = 0;
515 
516  if (!iter)
517  return AVERROR(EIO);
518 
519  while (ret == 0 && iter->Next(&dl) == S_OK) {
520  IDeckLinkOutput_v14_2_1 *output_config;
521  IDeckLinkInput_v14_2_1 *input_config;
522  const char *display_name = NULL;
523  const char *unique_name = NULL;
524  AVDeviceInfo *new_device = NULL;
525  int add = 0;
526 
527  ret = decklink_get_attr_string(dl, BMDDeckLinkDisplayName, &display_name);
528  if (ret < 0)
529  goto next;
530  ret = decklink_get_attr_string(dl, BMDDeckLinkDeviceHandle, &unique_name);
531  if (ret < 0)
532  goto next;
533 
534  if (show_outputs) {
535  if (dl->QueryInterface(IID_IDeckLinkOutput_v14_2_1, (void **)&output_config) == S_OK) {
536  output_config->Release();
537  add = 1;
538  }
539  }
540 
541  if (show_inputs) {
542  if (dl->QueryInterface(IID_IDeckLinkInput_v14_2_1, (void **)&input_config) == S_OK) {
543  input_config->Release();
544  add = 1;
545  }
546  }
547 
548  if (add == 1) {
549  new_device = (AVDeviceInfo *) av_mallocz(sizeof(AVDeviceInfo));
550  if (!new_device) {
551  ret = AVERROR(ENOMEM);
552  goto next;
553  }
554 
555  new_device->device_name = av_strdup(unique_name ? unique_name : display_name);
556  new_device->device_description = av_strdup(display_name);
557 
558  if (!new_device->device_name ||
559  !new_device->device_description ||
560  av_dynarray_add_nofree(&device_list->devices, &device_list->nb_devices, new_device) < 0) {
561  ret = AVERROR(ENOMEM);
562  av_freep(&new_device->device_name);
563  av_freep(&new_device->device_description);
564  av_freep(&new_device);
565  goto next;
566  }
567  }
568 
569  next:
570  av_freep(&display_name);
571  av_freep(&unique_name);
572  dl->Release();
573  }
574  iter->Release();
575  return ret;
576 }
577 
578 /* This is a wrapper around the ff_decklink_list_devices() which dumps the
579  output to av_log() and exits (for backward compatibility with the
580  "-list_devices" argument). */
582  int show_inputs, int show_outputs)
583 {
584  struct AVDeviceInfoList *device_list = NULL;
585  int ret;
586 
587  device_list = (struct AVDeviceInfoList *) av_mallocz(sizeof(AVDeviceInfoList));
588  if (!device_list)
589  return;
590 
591  ret = ff_decklink_list_devices(avctx, device_list, show_inputs, show_outputs);
592  if (ret == 0) {
593  av_log(avctx, AV_LOG_INFO, "Blackmagic DeckLink %s devices:\n",
594  show_inputs ? "input" : "output");
595  for (int i = 0; i < device_list->nb_devices; i++) {
596  av_log(avctx, AV_LOG_INFO, "\t'%s'\n", device_list->devices[i]->device_description);
597  }
598  }
599  avdevice_free_list_devices(&device_list);
600 }
601 
603 {
604  struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data;
605  struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx;
606  IDeckLinkDisplayModeIterator *itermode;
607  IDeckLinkDisplayMode *mode;
608  uint32_t format_code;
609  HRESULT res;
610 
611  if (direction == DIRECTION_IN) {
612  int ret;
613  ret = decklink_select_input(avctx, bmdDeckLinkConfigAudioInputConnection);
614  if (ret < 0)
615  return ret;
616  ret = decklink_select_input(avctx, bmdDeckLinkConfigVideoInputConnection);
617  if (ret < 0)
618  return ret;
619  res = ctx->dli->GetDisplayModeIterator (&itermode);
620  } else {
621  res = ctx->dlo->GetDisplayModeIterator (&itermode);
622  }
623 
624  if (res!= S_OK) {
625  av_log(avctx, AV_LOG_ERROR, "Could not get Display Mode Iterator\n");
626  return AVERROR(EIO);
627  }
628 
629  av_log(avctx, AV_LOG_INFO, "Supported formats for '%s':\n\tformat_code\tdescription",
630  avctx->url);
631  while (itermode->Next(&mode) == S_OK) {
632  BMDTimeValue tb_num, tb_den;
633  mode->GetFrameRate(&tb_num, &tb_den);
634  format_code = av_bswap32(mode->GetDisplayMode());
635  av_log(avctx, AV_LOG_INFO, "\n\t%.4s\t\t%ldx%ld at %d/%d fps",
636  (char*) &format_code, mode->GetWidth(), mode->GetHeight(),
637  (int) tb_den, (int) tb_num);
638  switch (mode->GetFieldDominance()) {
639  case bmdLowerFieldFirst:
640  av_log(avctx, AV_LOG_INFO, " (interlaced, lower field first)"); break;
641  case bmdUpperFieldFirst:
642  av_log(avctx, AV_LOG_INFO, " (interlaced, upper field first)"); break;
643  }
644  mode->Release();
645  }
646  av_log(avctx, AV_LOG_INFO, "\n");
647 
648  itermode->Release();
649 
650  return 0;
651 }
652 
654 {
655  struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data;
656  struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx;
657 
658  if (ctx->dli)
659  ctx->dli->Release();
660  if (ctx->dlo)
661  ctx->dlo->Release();
662  if (ctx->attr)
663  ctx->attr->Release();
664  if (ctx->cfg)
665  ctx->cfg->Release();
666  if (ctx->dl)
667  ctx->dl->Release();
668 }
669 
671 {
672  struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data;
673  struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx;
674  IDeckLink *dl = NULL;
675  IDeckLinkIterator *iter = decklink_create_iterator(avctx);
676  if (!iter)
677  return AVERROR_EXTERNAL;
678 
679  while (iter->Next(&dl) == S_OK) {
680  const char *display_name = NULL;
681  const char *unique_name = NULL;
682  decklink_get_attr_string(dl, BMDDeckLinkDisplayName, &display_name);
683  decklink_get_attr_string(dl, BMDDeckLinkDeviceHandle, &unique_name);
684  if (display_name && !strcmp(name, display_name) || unique_name && !strcmp(name, unique_name)) {
685  av_free((void *)unique_name);
686  av_free((void *)display_name);
687  ctx->dl = dl;
688  break;
689  }
690  av_free((void *)display_name);
691  av_free((void *)unique_name);
692  dl->Release();
693  }
694  iter->Release();
695  if (!ctx->dl)
696  return AVERROR(ENXIO);
697 
698  if (ctx->dl->QueryInterface(IID_IDeckLinkConfiguration, (void **)&ctx->cfg) != S_OK) {
699  av_log(avctx, AV_LOG_ERROR, "Could not get configuration interface for '%s'\n", name);
700  ff_decklink_cleanup(avctx);
701  return AVERROR_EXTERNAL;
702  }
703 
704  if (ctx->dl->QueryInterface(IID_IDeckLinkProfileAttributes, (void **)&ctx->attr) != S_OK) {
705  av_log(avctx, AV_LOG_ERROR, "Could not get attributes interface for '%s'\n", name);
706  ff_decklink_cleanup(avctx);
707  return AVERROR_EXTERNAL;
708  }
709 
710  return 0;
711 }
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: packet.c:432
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:216
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
PacketList::head
PacketListEntry * head
Definition: packet_internal.h:34
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
AVFieldOrder
AVFieldOrder
Definition: defs.h:211
AV_FIELD_PROGRESSIVE
@ AV_FIELD_PROGRESSIVE
Definition: defs.h:213
pthread_mutex_init
static av_always_inline int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
Definition: os2threads.h:104
AVDeviceInfo::device_name
char * device_name
device name, format depends on device
Definition: avdevice.h:334
int64_t
long long int64_t
Definition: coverity.c:34
AVDeviceInfoList::nb_devices
int nb_devices
number of autodetected devices
Definition: avdevice.h:345
mode
Definition: swscale.c:56
pthread_mutex_lock
static av_always_inline int pthread_mutex_lock(pthread_mutex_t *mutex)
Definition: os2threads.h:119
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:226
AV_FIELD_BT
@ AV_FIELD_BT
Bottom coded first, top displayed first.
Definition: defs.h:217
AV_FIELD_TT
@ AV_FIELD_TT
Top coded_first, top displayed first.
Definition: defs.h:214
avpriv_packet_list_get
int avpriv_packet_list_get(PacketList *pkt_buffer, AVPacket *pkt)
Remove the oldest AVPacket in the list and return it.
Definition: packet.c:595
pts
static int64_t pts
Definition: transcode_aac.c:644
AV_FIELD_TB
@ AV_FIELD_TB
Top coded first, bottom displayed first.
Definition: defs.h:216
AVDeviceInfoList::devices
AVDeviceInfo ** devices
list of autodetected devices
Definition: avdevice.h:344
pkt
AVPacket * pkt
Definition: movenc.c:60
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
AV_FIELD_UNKNOWN
@ AV_FIELD_UNKNOWN
Definition: defs.h:212
DecklinkPacketQueue::cond
pthread_cond_t cond
Definition: decklink_common.h:115
intreadwrite.h
s
#define s(width, name)
Definition: cbs_vp9.c:198
pthread_mutex_unlock
static av_always_inline int pthread_mutex_unlock(pthread_mutex_t *mutex)
Definition: os2threads.h:126
av_q2d
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition: rational.h:104
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:231
ctx
AVFormatContext * ctx
Definition: movenc.c:49
av_mallocz
#define av_mallocz(s)
Definition: tableprint_vlc.h:31
tmp
static uint8_t tmp[40]
Definition: aes_ctr.c:52
AVFormatContext
Format I/O context.
Definition: avformat.h:1264
DecklinkPacketQueue::nb_packets
int nb_packets
Definition: decklink_common.h:111
internal.h
NULL
#define NULL
Definition: coverity.c:32
avpriv_packet_list_put
int avpriv_packet_list_put(PacketList *packet_buffer, AVPacket *pkt, int(*copy)(AVPacket *dst, const AVPacket *src), int flags)
Append an AVPacket to the list.
Definition: packet.c:546
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
DecklinkPacketQueue::avctx
AVFormatContext * avctx
Definition: decklink_common.h:116
DecklinkPacketQueue::pkt_list
PacketList pkt_list
Definition: decklink_common.h:110
AVPacket::size
int size
Definition: packet.h:589
height
#define height
Definition: dsp.h:89
av_bswap32
#define av_bswap32
Definition: bswap.h:47
DecklinkPacketQueue
Definition: decklink_common.h:109
AVFormatContext::url
char * url
input or output URL.
Definition: avformat.h:1380
DecklinkPacketQueue::size
unsigned long long size
Definition: decklink_common.h:112
size
int size
Definition: twinvq_data.h:10344
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
PacketListEntry::pkt
AVPacket pkt
Definition: packet_internal.h:30
AVDeviceInfo
Structure describes basic parameters of the device.
Definition: avdevice.h:333
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:107
AVERROR_EXTERNAL
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition: error.h:59
av_packet_make_refcounted
int av_packet_make_refcounted(AVPacket *pkt)
Ensure the data described by a given packet is reference counted.
Definition: packet.c:495
version
version
Definition: libkvazaar.c:313
AVDeviceInfo::device_description
char * device_description
human friendly name
Definition: avdevice.h:335
pthread_cond_destroy
static av_always_inline int pthread_cond_destroy(pthread_cond_t *cond)
Definition: os2threads.h:144
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:221
pthread_mutex_destroy
static av_always_inline int pthread_mutex_destroy(pthread_mutex_t *mutex)
Definition: os2threads.h:112
PacketListEntry
Definition: packet_internal.h:28
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:581
AV_FIELD_BB
@ AV_FIELD_BB
Bottom coded first, bottom displayed first.
Definition: defs.h:215
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
profile
int profile
Definition: mxfenc.c:2297
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:343
avformat.h
pthread_cond_signal
static av_always_inline int pthread_cond_signal(pthread_cond_t *cond)
Definition: os2threads.h:152
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:315
mode
mode
Definition: ebur128.h:83
pthread_cond_wait
static av_always_inline int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
Definition: os2threads.h:192
av_strdup
char * av_strdup(const char *s)
Duplicate a string.
Definition: mem.c:272
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
AVPacket
This structure stores compressed data.
Definition: packet.h:565
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
imgutils.h
DecklinkPacketQueue::max_q_size
int64_t max_q_size
Definition: decklink_common.h:117
block
The exact code depends on how similar the blocks are and how related they are to the block
Definition: filter_design.txt:207
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
pthread_cond_init
static av_always_inline int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
Definition: os2threads.h:133
width
#define width
Definition: dsp.h:89
AVFormatContext::priv_data
void * priv_data
Format private data.
Definition: avformat.h:1292
DecklinkPacketQueue::mutex
pthread_mutex_t mutex
Definition: decklink_common.h:114