|
|
@@ -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) |
|
|
|