libavdevice/decklink: add support for -sources and -sinks arguments

Add support for enumerating the sources/sinks via the ffmpeg
command line options, as opposed to having to create a real pipeline
and use the "-list_devices" option which does exit() after dumping
out the options.

Note that this patch preserves the existing "-list_devices" option,
but now shares common code for the actual enumeration.

Updated to reflect feedback from Marton Balint <cus@passwd.hu>.

Signed-off-by: Devin Heitmueller <dheitmueller@ltnglobal.com>
Signed-off-by: Marton Balint <cus@passwd.hu>
This commit is contained in:
Devin Heitmueller
2017-10-06 08:55:43 -04:00
committed by Marton Balint
parent ff6de6b180
commit 278588cd0b
8 changed files with 104 additions and 10 deletions

View File

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