diff options
Diffstat (limited to 'libavdevice/decklink_common.cpp')
-rw-r--r-- | libavdevice/decklink_common.cpp | 89 |
1 files changed, 83 insertions, 6 deletions
diff --git a/libavdevice/decklink_common.cpp b/libavdevice/decklink_common.cpp index c782171f2c..2bd63ac820 100644 --- a/libavdevice/decklink_common.cpp +++ b/libavdevice/decklink_common.cpp @@ -37,6 +37,7 @@ extern "C" { #include "libavutil/imgutils.h" #include "libavutil/intreadwrite.h" #include "libavutil/bswap.h" +#include "avdevice.h" } #include "decklink_common.h" @@ -261,24 +262,100 @@ int ff_decklink_set_format(AVFormatContext *avctx, decklink_direction_t directio return ff_decklink_set_format(avctx, 0, 0, 0, 0, AV_FIELD_UNKNOWN, direction, num); } -int ff_decklink_list_devices(AVFormatContext *avctx) +int ff_decklink_list_devices(AVFormatContext *avctx, + struct AVDeviceInfoList *device_list, + int show_inputs, int show_outputs) { IDeckLink *dl = NULL; IDeckLinkIterator *iter = CreateDeckLinkIteratorInstance(); + int ret = 0; + if (!iter) { av_log(avctx, AV_LOG_ERROR, "Could not create DeckLink iterator\n"); return AVERROR(EIO); } - av_log(avctx, AV_LOG_INFO, "Blackmagic DeckLink devices:\n"); - while (iter->Next(&dl) == S_OK) { + + while (ret == 0 && iter->Next(&dl) == S_OK) { + IDeckLinkOutput *output_config; + IDeckLinkInput *input_config; const char *displayName; + AVDeviceInfo *new_device = NULL; + int add = 0; + ff_decklink_get_display_name(dl, &displayName); - av_log(avctx, AV_LOG_INFO, "\t'%s'\n", displayName); - av_free((void *) displayName); + + if (show_outputs) { + if (dl->QueryInterface(IID_IDeckLinkOutput, (void **)&output_config) == S_OK) { + output_config->Release(); + add = 1; + } + } + + if (show_inputs) { + if (dl->QueryInterface(IID_IDeckLinkInput, (void **)&input_config) == S_OK) { + input_config->Release(); + add = 1; + } + } + + if (add == 1) { + new_device = (AVDeviceInfo *) av_mallocz(sizeof(AVDeviceInfo)); + if (!new_device) { + ret = AVERROR(ENOMEM); + goto next; + } + new_device->device_name = av_strdup(displayName); + if (!new_device->device_name) { + ret = AVERROR(ENOMEM); + goto next; + } + + new_device->device_description = av_strdup(displayName); + if (!new_device->device_description) { + av_freep(&new_device->device_name); + ret = AVERROR(ENOMEM); + goto next; + } + + if ((ret = av_dynarray_add_nofree(&device_list->devices, + &device_list->nb_devices, new_device)) < 0) { + av_freep(&new_device->device_name); + av_freep(&new_device->device_description); + av_freep(&new_device); + goto next; + } + } + + next: + av_freep(&displayName); dl->Release(); } iter->Release(); - return 0; + return ret; +} + +/* This is a wrapper around the ff_decklink_list_devices() which dumps the + output to av_log() and exits (for backward compatibility with the + "-list_devices" argument). */ +void ff_decklink_list_devices_legacy(AVFormatContext *avctx, + int show_inputs, int show_outputs) +{ + struct AVDeviceInfoList *device_list = NULL; + int ret; + + device_list = (struct AVDeviceInfoList *) av_mallocz(sizeof(AVDeviceInfoList)); + if (!device_list) + return; + + ret = ff_decklink_list_devices(avctx, device_list, show_inputs, show_outputs); + if (ret == 0) { + 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); + } + } + avdevice_free_list_devices(&device_list); } int ff_decklink_list_formats(AVFormatContext *avctx, decklink_direction_t direction) |