FFmpeg
Loading...
Searching...
No Matches
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 */
24extern "C" {
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
51extern "C" {
53#include "libavutil/imgutils.h"
55#include "libavutil/bswap.h"
56#include "avdevice.h"
57}
58
59#include "decklink_common.h"
60
61static 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
106static 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) {
119 if (!*s)
120 return AVERROR(ENOMEM);
121 } else if (hr == E_FAIL) {
122 return AVERROR_EXTERNAL;
123 }
124 return 0;
125}
126
127static 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
156static 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);
309
310 if ((bmd_width == width &&
311 bmd_height == height &&
312 !av_cmp_q(mode_tb, target_tb) &&
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{
410
412 while (ff_packet_list_get(&q->pkt_list, &pkt) == 0) {
414 }
415 q->nb_packets = 0;
416 q->size = 0;
418}
419
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 */
450 return -1;
451 }
452
454
455 ret = ff_packet_list_put(&q->pkt_list, pkt, NULL, 0);
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 (;; ) {
475 ret = ff_packet_list_get(&q->pkt_list, pkt);
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}
static AVFormatContext * ctx
Main libavdevice API header.
Main libavformat public API header.
byte swapping routines
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define s(width, name)
Definition cbs_vp9.c:198
#define NULL
Definition coverity.c:32
long long int64_t
Definition coverity.c:34
static int16_t block[64]
Definition dct.c:125
AVFieldOrder
Definition defs.h:211
@ AV_FIELD_TT
Top coded_first, top displayed first.
Definition defs.h:214
@ AV_FIELD_BB
Bottom coded first, bottom displayed first.
Definition defs.h:215
@ AV_FIELD_UNKNOWN
Definition defs.h:212
@ AV_FIELD_PROGRESSIVE
Definition defs.h:213
@ AV_FIELD_BT
Bottom coded first, top displayed first.
Definition defs.h:217
@ AV_FIELD_TB
Top coded first, bottom displayed first.
Definition defs.h:216
static AVPacket * pkt
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition packet.c:434
int av_packet_make_refcounted(AVPacket *pkt)
Ensure the data described by a given packet is reference counted.
Definition packet.c:497
void avdevice_free_list_devices(AVDeviceInfoList **device_list)
Convenient function to free result of avdevice_list_devices().
Definition avdevice.c:107
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition error.h:59
#define AVERROR(e)
Definition error.h:45
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition log.h:231
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition log.h:216
#define AV_LOG_VERBOSE
Detailed information.
Definition log.h:226
#define AV_LOG_INFO
Standard information.
Definition log.h:221
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
static AVRational av_make_q(int num, int den)
Create an AVRational.
Definition rational.h:71
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition rational.h:104
static int av_cmp_q(AVRational a, AVRational b)
Compare two rationals.
Definition rational.h:89
int av_dynarray_add_nofree(void *tab_ptr, int *nb_ptr, void *elem)
Add an element to a dynamic array.
Definition mem.c:313
misc image utilities
#define AV_RB32(p)
int ff_packet_list_get(PacketList *list, AVPacket *pkt)
Remove the oldest AVPacket in the list and return it.
Definition packet_list.c:89
int ff_packet_list_put(PacketList *list, AVPacket *pkt, int(*copy)(AVPacket *dst, const AVPacket *src), int flags)
Append an AVPacket to the list.
Definition packet_list.c:40
version
Definition libkvazaar.c:313
#define FFMIN(a, b)
Definition macros.h:49
int profile
Definition mxfenc.c:2299
#define av_strdup(s)
Definition ops_static.c:55
static av_always_inline int pthread_cond_signal(pthread_cond_t *cond)
Definition os2threads.h:158
static av_always_inline int pthread_mutex_lock(pthread_mutex_t *mutex)
Definition os2threads.h:119
static av_always_inline int pthread_cond_destroy(pthread_cond_t *cond)
Definition os2threads.h:150
static av_always_inline int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
Definition os2threads.h:104
static av_always_inline int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
Definition os2threads.h:139
static av_always_inline int pthread_mutex_unlock(pthread_mutex_t *mutex)
Definition os2threads.h:132
static av_always_inline int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
Definition os2threads.h:198
static av_always_inline int pthread_mutex_destroy(pthread_mutex_t *mutex)
Definition os2threads.h:112
const char * name
Definition qsvenc.c:142
#define av_bswap32
Definition bswap.h:47
#define FF_ARRAY_ELEMS(a)
List of devices.
Definition avdevice.h:343
int nb_devices
number of autodetected devices
Definition avdevice.h:345
AVDeviceInfo ** devices
list of autodetected devices
Definition avdevice.h:344
Structure describes basic parameters of the device.
Definition avdevice.h:333
char * device_description
human friendly name
Definition avdevice.h:335
char * device_name
device name, format depends on device
Definition avdevice.h:334
Format I/O context.
Definition avformat.h:1333
char * url
input or output URL.
Definition avformat.h:1449
void * priv_data
Format private data.
Definition avformat.h:1361
This structure stores compressed data.
Definition packet.h:580
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition packet.h:596
Rational number (pair of numerator and denominator).
Definition rational.h:58
pthread_mutex_t mutex
unsigned long long size
AVFormatContext * avctx
PacketListEntry * head
Definition swscale.c:71
#define av_free(p)
#define av_mallocz(s)
#define av_freep(p)
#define av_log(a,...)
static uint8_t tmp[40]
Definition aes_ctr.c:52
#define height
Definition dsp.h:89
#define width
Definition dsp.h:89
static int64_t pts
int size