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 {
395  memset(q, 0, sizeof(DecklinkPacketQueue));
398  q->avctx = avctx;
399  q->max_q_size = queue_size;
400 }
401 
403 {
404  AVPacket pkt;
405 
407  while (avpriv_packet_list_get(&q->pkt_list, &pkt) == 0) {
409  }
410  q->nb_packets = 0;
411  q->size = 0;
413 }
414 
416 {
420 }
421 
423 {
424  unsigned long long size;
426  size = q->size;
428  return size;
429 }
430 
432 {
433  int pkt_size = pkt->size;
434  int ret;
435 
436  // Drop Packet if queue size is > maximum queue size
437  if (ff_decklink_packet_queue_size(q) > (uint64_t)q->max_q_size) {
439  av_log(q->avctx, AV_LOG_WARNING, "Decklink input buffer overrun!\n");
440  return -1;
441  }
442  /* ensure the packet is reference counted */
443  if (av_packet_make_refcounted(pkt) < 0) {
445  return -1;
446  }
447 
449 
451  if (ret == 0) {
452  q->nb_packets++;
453  q->size += pkt_size + sizeof(AVPacket);
455  } else {
457  }
458 
460  return ret;
461 }
462 
464 {
465  int ret;
466 
468 
469  for (;; ) {
471  if (ret == 0) {
472  q->nb_packets--;
473  q->size -= pkt->size + sizeof(AVPacket);
474  ret = 1;
475  break;
476  } else if (!block) {
477  ret = 0;
478  break;
479  } else {
480  pthread_cond_wait(&q->cond, &q->mutex);
481  }
482  }
484  return ret;
485 }
486 
488 {
489  PacketListEntry *pkt1;
490  int64_t pts = -1;
491 
493  pkt1 = q->pkt_list.head;
494  if (pkt1) {
495  pts = pkt1->pkt.pts;
496  }
498 
499  return pts;
500 }
501 
502 
504  struct AVDeviceInfoList *device_list,
505  int show_inputs, int show_outputs)
506 {
507  IDeckLink *dl = NULL;
508  IDeckLinkIterator *iter = decklink_create_iterator(avctx);
509  int ret = 0;
510 
511  if (!iter)
512  return AVERROR(EIO);
513 
514  while (ret == 0 && iter->Next(&dl) == S_OK) {
515  IDeckLinkOutput *output_config;
516  IDeckLinkInput *input_config;
517  const char *display_name = NULL;
518  const char *unique_name = NULL;
519  AVDeviceInfo *new_device = NULL;
520  int add = 0;
521 
522  ret = decklink_get_attr_string(dl, BMDDeckLinkDisplayName, &display_name);
523  if (ret < 0)
524  goto next;
525  ret = decklink_get_attr_string(dl, BMDDeckLinkDeviceHandle, &unique_name);
526  if (ret < 0)
527  goto next;
528 
529  if (show_outputs) {
530  if (dl->QueryInterface(IID_IDeckLinkOutput, (void **)&output_config) == S_OK) {
531  output_config->Release();
532  add = 1;
533  }
534  }
535 
536  if (show_inputs) {
537  if (dl->QueryInterface(IID_IDeckLinkInput, (void **)&input_config) == S_OK) {
538  input_config->Release();
539  add = 1;
540  }
541  }
542 
543  if (add == 1) {
544  new_device = (AVDeviceInfo *) av_mallocz(sizeof(AVDeviceInfo));
545  if (!new_device) {
546  ret = AVERROR(ENOMEM);
547  goto next;
548  }
549 
550  new_device->device_name = av_strdup(unique_name ? unique_name : display_name);
551  new_device->device_description = av_strdup(display_name);
552 
553  if (!new_device->device_name ||
554  !new_device->device_description ||
555  av_dynarray_add_nofree(&device_list->devices, &device_list->nb_devices, new_device) < 0) {
556  ret = AVERROR(ENOMEM);
557  av_freep(&new_device->device_name);
558  av_freep(&new_device->device_description);
559  av_freep(&new_device);
560  goto next;
561  }
562  }
563 
564  next:
565  av_freep(&display_name);
566  av_freep(&unique_name);
567  dl->Release();
568  }
569  iter->Release();
570  return ret;
571 }
572 
573 /* This is a wrapper around the ff_decklink_list_devices() which dumps the
574  output to av_log() and exits (for backward compatibility with the
575  "-list_devices" argument). */
577  int show_inputs, int show_outputs)
578 {
579  struct AVDeviceInfoList *device_list = NULL;
580  int ret;
581 
582  device_list = (struct AVDeviceInfoList *) av_mallocz(sizeof(AVDeviceInfoList));
583  if (!device_list)
584  return;
585 
586  ret = ff_decklink_list_devices(avctx, device_list, show_inputs, show_outputs);
587  if (ret == 0) {
588  av_log(avctx, AV_LOG_INFO, "Blackmagic DeckLink %s devices:\n",
589  show_inputs ? "input" : "output");
590  for (int i = 0; i < device_list->nb_devices; i++) {
591  av_log(avctx, AV_LOG_INFO, "\t'%s'\n", device_list->devices[i]->device_description);
592  }
593  }
594  avdevice_free_list_devices(&device_list);
595 }
596 
598 {
599  struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data;
600  struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx;
601  IDeckLinkDisplayModeIterator *itermode;
602  IDeckLinkDisplayMode *mode;
603  uint32_t format_code;
604  HRESULT res;
605 
606  if (direction == DIRECTION_IN) {
607  int ret;
608  ret = decklink_select_input(avctx, bmdDeckLinkConfigAudioInputConnection);
609  if (ret < 0)
610  return ret;
611  ret = decklink_select_input(avctx, bmdDeckLinkConfigVideoInputConnection);
612  if (ret < 0)
613  return ret;
614  res = ctx->dli->GetDisplayModeIterator (&itermode);
615  } else {
616  res = ctx->dlo->GetDisplayModeIterator (&itermode);
617  }
618 
619  if (res!= S_OK) {
620  av_log(avctx, AV_LOG_ERROR, "Could not get Display Mode Iterator\n");
621  return AVERROR(EIO);
622  }
623 
624  av_log(avctx, AV_LOG_INFO, "Supported formats for '%s':\n\tformat_code\tdescription",
625  avctx->url);
626  while (itermode->Next(&mode) == S_OK) {
627  BMDTimeValue tb_num, tb_den;
628  mode->GetFrameRate(&tb_num, &tb_den);
629  format_code = av_bswap32(mode->GetDisplayMode());
630  av_log(avctx, AV_LOG_INFO, "\n\t%.4s\t\t%ldx%ld at %d/%d fps",
631  (char*) &format_code, mode->GetWidth(), mode->GetHeight(),
632  (int) tb_den, (int) tb_num);
633  switch (mode->GetFieldDominance()) {
634  case bmdLowerFieldFirst:
635  av_log(avctx, AV_LOG_INFO, " (interlaced, lower field first)"); break;
636  case bmdUpperFieldFirst:
637  av_log(avctx, AV_LOG_INFO, " (interlaced, upper field first)"); break;
638  }
639  mode->Release();
640  }
641  av_log(avctx, AV_LOG_INFO, "\n");
642 
643  itermode->Release();
644 
645  return 0;
646 }
647 
649 {
650  struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data;
651  struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx;
652 
653  if (ctx->dli)
654  ctx->dli->Release();
655  if (ctx->dlo)
656  ctx->dlo->Release();
657  if (ctx->attr)
658  ctx->attr->Release();
659  if (ctx->cfg)
660  ctx->cfg->Release();
661  if (ctx->dl)
662  ctx->dl->Release();
663 }
664 
666 {
667  struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data;
668  struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx;
669  IDeckLink *dl = NULL;
670  IDeckLinkIterator *iter = decklink_create_iterator(avctx);
671  if (!iter)
672  return AVERROR_EXTERNAL;
673 
674  while (iter->Next(&dl) == S_OK) {
675  const char *display_name = NULL;
676  const char *unique_name = NULL;
677  decklink_get_attr_string(dl, BMDDeckLinkDisplayName, &display_name);
678  decklink_get_attr_string(dl, BMDDeckLinkDeviceHandle, &unique_name);
679  if (display_name && !strcmp(name, display_name) || unique_name && !strcmp(name, unique_name)) {
680  av_free((void *)unique_name);
681  av_free((void *)display_name);
682  ctx->dl = dl;
683  break;
684  }
685  av_free((void *)display_name);
686  av_free((void *)unique_name);
687  dl->Release();
688  }
689  iter->Release();
690  if (!ctx->dl)
691  return AVERROR(ENXIO);
692 
693  if (ctx->dl->QueryInterface(IID_IDeckLinkConfiguration, (void **)&ctx->cfg) != S_OK) {
694  av_log(avctx, AV_LOG_ERROR, "Could not get configuration interface for '%s'\n", name);
695  ff_decklink_cleanup(avctx);
696  return AVERROR_EXTERNAL;
697  }
698 
699  if (ctx->dl->QueryInterface(IID_IDeckLinkProfileAttributes, (void **)&ctx->attr) != S_OK) {
700  av_log(avctx, AV_LOG_ERROR, "Could not get attributes interface for '%s'\n", name);
701  ff_decklink_cleanup(avctx);
702  return AVERROR_EXTERNAL;
703  }
704 
705  return 0;
706 }
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: packet.c:427
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
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:199
AV_FIELD_PROGRESSIVE
@ AV_FIELD_PROGRESSIVE
Definition: defs.h:201
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
AVDeviceInfoList::nb_devices
int nb_devices
number of autodetected devices
Definition: avdevice.h:345
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:28
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:196
AV_FIELD_BT
@ AV_FIELD_BT
Bottom coded first, top displayed first.
Definition: defs.h:205
AV_FIELD_TT
@ AV_FIELD_TT
Top coded_first, top displayed first.
Definition: defs.h:202
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:580
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:204
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:180
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
AV_FIELD_UNKNOWN
@ AV_FIELD_UNKNOWN
Definition: defs.h:200
width
#define width
DecklinkPacketQueue::cond
pthread_cond_t cond
Definition: decklink_common.h:88
intreadwrite.h
s
#define s(width, name)
Definition: cbs_vp9.c:198
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:201
ctx
AVFormatContext * ctx
Definition: movenc.c:49
AVFormatContext
Format I/O context.
Definition: avformat.h:1255
DecklinkPacketQueue::nb_packets
int nb_packets
Definition: decklink_common.h:84
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:541
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
DecklinkPacketQueue::avctx
AVFormatContext * avctx
Definition: decklink_common.h:89
pthread_mutex_unlock
#define pthread_mutex_unlock(a)
Definition: ffprobe.c:82
DecklinkPacketQueue::pkt_list
PacketList pkt_list
Definition: decklink_common.h:83
AVPacket::size
int size
Definition: packet.h:521
av_bswap32
#define av_bswap32
Definition: bswap.h:47
DecklinkPacketQueue
Definition: decklink_common.h:82
AVFormatContext::url
char * url
input or output URL.
Definition: avformat.h:1371
DecklinkPacketQueue::size
unsigned long long size
Definition: decklink_common.h:85
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
height
#define height
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:490
version
version
Definition: libkvazaar.c:321
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:191
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:513
AV_FIELD_BB
@ AV_FIELD_BB
Bottom coded first, bottom displayed first.
Definition: defs.h:203
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:256
profile
int profile
Definition: mxfenc.c:2228
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:33
AVPacket
This structure stores compressed data.
Definition: packet.h:497
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
imgutils.h
DecklinkPacketQueue::max_q_size
int64_t max_q_size
Definition: decklink_common.h:90
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
AVFormatContext::priv_data
void * priv_data
Format private data.
Definition: avformat.h:1283
DecklinkPacketQueue::mutex
pthread_mutex_t mutex
Definition: decklink_common.h:87
pthread_mutex_lock
#define pthread_mutex_lock(a)
Definition: ffprobe.c:78