summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarton Balint <cus@passwd.hu>2018-09-20 23:56:00 +0200
committerMarton Balint <cus@passwd.hu>2018-09-23 18:55:29 +0200
commitdb6b4b56b322969d99f77e087e9e72295738efb4 (patch)
tree54686f7d14308cb4840013010e1d9416907dc22e
parent0f9b298242ca2e1e2e4414967921463566f1dded (diff)
downloadffmpeg-db6b4b56b322969d99f77e087e9e72295738efb4.tar.gz
avdevice/decklink: add support for selecting devices based on their unique ID
Also bump the API version requirement to 10.9.5, because on olders versions there were some reports of crashes using the undocumented, yet available BMDDeckLinkDeviceHandle. Signed-off-by: Marton Balint <cus@passwd.hu>
-rwxr-xr-xconfigure2
-rw-r--r--doc/indevs.texi3
-rw-r--r--doc/outdevs.texi3
-rw-r--r--libavdevice/decklink_common.cpp59
-rw-r--r--libavdevice/decklink_common.h1
-rw-r--r--libavdevice/version.h2
6 files changed, 46 insertions, 24 deletions
diff --git a/configure b/configure
index aeb2fdb13a..1946bcb69c 100755
--- a/configure
+++ b/configure
@@ -6039,7 +6039,7 @@ done
enabled cuda_sdk && require cuda_sdk cuda.h cuCtxCreate -lcuda
enabled chromaprint && require chromaprint chromaprint.h chromaprint_get_version -lchromaprint
enabled decklink && { require_headers DeckLinkAPI.h &&
- { test_cpp_condition DeckLinkAPIVersion.h "BLACKMAGIC_DECKLINK_API_VERSION >= 0x0a060100" || die "ERROR: Decklink API version must be >= 10.6.1."; } }
+ { test_cpp_condition DeckLinkAPIVersion.h "BLACKMAGIC_DECKLINK_API_VERSION >= 0x0a090500" || die "ERROR: Decklink API version must be >= 10.9.5."; } }
enabled libndi_newtek && require_headers Processing.NDI.Lib.h
enabled frei0r && require_headers frei0r.h
enabled gmp && require gmp gmp.h mpz_export -lgmp
diff --git a/doc/indevs.texi b/doc/indevs.texi
index 5d4c02c597..ed2784be9f 100644
--- a/doc/indevs.texi
+++ b/doc/indevs.texi
@@ -267,7 +267,8 @@ audio track.
@item list_devices
If set to @option{true}, print a list of devices and exit.
-Defaults to @option{false}.
+Defaults to @option{false}. Alternatively you can use the @code{-sources}
+option of ffmpeg to list the available input devices.
@item list_formats
If set to @option{true}, print a list of supported formats and exit.
diff --git a/doc/outdevs.texi b/doc/outdevs.texi
index 34c508a970..2518f9b559 100644
--- a/doc/outdevs.texi
+++ b/doc/outdevs.texi
@@ -140,7 +140,8 @@ device with @command{-list_formats 1}. Audio sample rate is always 48 kHz.
@item list_devices
If set to @option{true}, print a list of devices and exit.
-Defaults to @option{false}.
+Defaults to @option{false}. Alternatively you can use the @code{-sinks}
+option of ffmpeg to list the available output devices.
@item list_formats
If set to @option{true}, print a list of supported formats and exit.
diff --git a/libavdevice/decklink_common.cpp b/libavdevice/decklink_common.cpp
index 503417bb35..b88d6c6219 100644
--- a/libavdevice/decklink_common.cpp
+++ b/libavdevice/decklink_common.cpp
@@ -77,15 +77,25 @@ static IDeckLinkIterator *decklink_create_iterator(AVFormatContext *avctx)
return iter;
}
-HRESULT ff_decklink_get_display_name(IDeckLink *This, const char **displayName)
+int decklink_get_attr_string(IDeckLink *dl, BMDDeckLinkAttributeID cfg_id, const char **s)
{
- DECKLINK_STR tmpDisplayName;
- HRESULT hr = This->GetDisplayName(&tmpDisplayName);
- if (hr != S_OK)
- return hr;
- *displayName = DECKLINK_STRDUP(tmpDisplayName);
- DECKLINK_FREE(tmpDisplayName);
- return hr;
+ DECKLINK_STR tmp;
+ HRESULT hr;
+ IDeckLinkAttributes *attr;
+ *s = NULL;
+ if (dl->QueryInterface(IID_IDeckLinkAttributes, (void **)&attr) != S_OK)
+ return AVERROR_EXTERNAL;
+ hr = attr->GetString(cfg_id, &tmp);
+ attr->Release();
+ if (hr == S_OK) {
+ *s = DECKLINK_STRDUP(tmp);
+ DECKLINK_FREE(tmp);
+ if (!*s)
+ return AVERROR(ENOMEM);
+ } else if (hr == E_FAIL) {
+ return AVERROR_EXTERNAL;
+ }
+ return 0;
}
static int decklink_select_input(AVFormatContext *avctx, BMDDeckLinkConfigurationID cfg_id)
@@ -276,11 +286,17 @@ int ff_decklink_list_devices(AVFormatContext *avctx,
while (ret == 0 && iter->Next(&dl) == S_OK) {
IDeckLinkOutput *output_config;
IDeckLinkInput *input_config;
- const char *displayName;
+ const char *display_name = NULL;
+ const char *unique_name = NULL;
AVDeviceInfo *new_device = NULL;
int add = 0;
- ff_decklink_get_display_name(dl, &displayName);
+ ret = decklink_get_attr_string(dl, BMDDeckLinkDisplayName, &display_name);
+ if (ret < 0)
+ goto next;
+ ret = decklink_get_attr_string(dl, BMDDeckLinkDeviceHandle, &unique_name);
+ if (ret < 0)
+ goto next;
if (show_outputs) {
if (dl->QueryInterface(IID_IDeckLinkOutput, (void **)&output_config) == S_OK) {
@@ -303,8 +319,8 @@ int ff_decklink_list_devices(AVFormatContext *avctx,
goto next;
}
- new_device->device_name = av_strdup(displayName);
- new_device->device_description = av_strdup(displayName);
+ new_device->device_name = av_strdup(unique_name ? unique_name : display_name);
+ new_device->device_description = av_strdup(display_name);
if (!new_device->device_name ||
!new_device->device_description ||
@@ -318,7 +334,8 @@ int ff_decklink_list_devices(AVFormatContext *avctx,
}
next:
- av_freep(&displayName);
+ av_freep(&display_name);
+ av_freep(&unique_name);
dl->Release();
}
iter->Release();
@@ -343,7 +360,7 @@ void ff_decklink_list_devices_legacy(AVFormatContext *avctx,
av_log(avctx, AV_LOG_INFO, "Blackmagic DeckLink %s devices:\n",
show_inputs ? "input" : "output");
for (int i = 0; i < device_list->nb_devices; i++) {
- av_log(avctx, AV_LOG_INFO, "\t'%s'\n", device_list->devices[i]->device_name);
+ av_log(avctx, AV_LOG_INFO, "\t'%s'\n", device_list->devices[i]->device_description);
}
}
avdevice_free_list_devices(&device_list);
@@ -427,14 +444,18 @@ int ff_decklink_init_device(AVFormatContext *avctx, const char* name)
return AVERROR_EXTERNAL;
while (iter->Next(&dl) == S_OK) {
- const char *displayName;
- ff_decklink_get_display_name(dl, &displayName);
- if (!strcmp(name, displayName)) {
- av_free((void *)displayName);
+ const char *display_name = NULL;
+ const char *unique_name = NULL;
+ decklink_get_attr_string(dl, BMDDeckLinkDisplayName, &display_name);
+ decklink_get_attr_string(dl, BMDDeckLinkDeviceHandle, &unique_name);
+ if (display_name && !strcmp(name, display_name) || unique_name && !strcmp(name, unique_name)) {
+ av_free((void *)unique_name);
+ av_free((void *)display_name);
ctx->dl = dl;
break;
}
- av_free((void *)displayName);
+ av_free((void *)display_name);
+ av_free((void *)unique_name);
dl->Release();
}
iter->Release();
diff --git a/libavdevice/decklink_common.h b/libavdevice/decklink_common.h
index 128144f50d..d2fc3f79d5 100644
--- a/libavdevice/decklink_common.h
+++ b/libavdevice/decklink_common.h
@@ -191,7 +191,6 @@ static const BMDTimecodeFormat decklink_timecode_format_map[] = {
bmdTimecodeSerial,
};
-HRESULT ff_decklink_get_display_name(IDeckLink *This, const char **displayName);
int ff_decklink_set_configs(AVFormatContext *avctx, decklink_direction_t direction);
int ff_decklink_set_format(AVFormatContext *avctx, int width, int height, int tb_num, int tb_den, enum AVFieldOrder field_order, decklink_direction_t direction = DIRECTION_OUT, int num = 0);
int ff_decklink_set_format(AVFormatContext *avctx, decklink_direction_t direction, int num);
diff --git a/libavdevice/version.h b/libavdevice/version.h
index fb8102eda6..8c96e606c2 100644
--- a/libavdevice/version.h
+++ b/libavdevice/version.h
@@ -29,7 +29,7 @@
#define LIBAVDEVICE_VERSION_MAJOR 58
#define LIBAVDEVICE_VERSION_MINOR 4
-#define LIBAVDEVICE_VERSION_MICRO 103
+#define LIBAVDEVICE_VERSION_MICRO 104
#define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \
LIBAVDEVICE_VERSION_MINOR, \