DeckLink: Allow names as an identifier

This commit is contained in:
Martin Pulec
2016-05-04 11:58:37 +02:00
parent 177e16253b
commit 3467751248
2 changed files with 67 additions and 26 deletions

View File

@@ -96,7 +96,7 @@ struct device_state {
IDeckLinkInput* deckLinkInput;
VideoDelegate* delegate;
IDeckLinkConfiguration* deckLinkConfiguration;
int index;
string device_id; // either numeric value or device name
};
struct vidcap_decklink_state {
@@ -390,7 +390,7 @@ decklink_help()
const char * deviceNameCString = NULL;
// *** Print the model name of the DeckLink card
result = deckLink->GetModelName((BMD_STR *) &deviceNameString);
result = deckLink->GetDisplayName((BMD_STR *) &deviceNameString);
deviceNameCString = get_cstr_from_bmd_api_str(deviceNameString);
if (result == S_OK)
{
@@ -447,8 +447,8 @@ decklink_help()
printf("\t%s -t decklink # captures autodetected video from first DeckLink in system\n", uv_argv[0]);
printf("\t%s -t decklink:0:Hi50:UYVY # captures 1080i50, 8-bit yuv\n", uv_argv[0]);
printf("\t%s -t decklink:0:10:v210:connection=HDMI # captures 10th format from a card (alternative syntax), 10-bit YUV, from HDMI\n", uv_argv[0]);
printf("\t%s -t decklink:mode=23ps # captures 1080p24, 8-bit yuv from frist device\n", uv_argv[0]);
printf("\t%s -t decklink:mode=Hp30:codec=v210:device=2 # captures 1080p30, 10-bit yuv from 3rd BMD device\n", uv_argv[0]);
printf("\t%s -t decklink:mode=23ps # captures 1080p24, 8-bit yuv from first device\n", uv_argv[0]);
printf("\t%s -t \"decklink:mode=Hp30:codec=v210:device=DeckLink 4K Extreme\" # captures 1080p30, 10-bit yuv from DeckLink 4K Extreme\n", uv_argv[0]);
printf("\n");
@@ -471,7 +471,7 @@ static void parse_devices(struct vidcap_decklink_state *s, const char *devs)
do {
s->devices_cnt += 1;
s->state.resize(s->devices_cnt);
s->state[s->devices_cnt - 1].index = atoi(ptr);
s->state[s->devices_cnt - 1].device_id = ptr;
} while ((ptr = strtok_r(NULL, ",", &save_ptr_dev)));
free (devices);
}
@@ -557,7 +557,7 @@ static int settings_init(struct vidcap_decklink_state *s, char *fmt)
s->codec = UYVY;
s->devices_cnt = 1;
s->state.resize(s->devices_cnt);
s->state[0].index = 0;
s->state[0].device_id = "0";
char *tmp;
char *save_ptr = NULL;
@@ -575,6 +575,7 @@ static int settings_init(struct vidcap_decklink_state *s, char *fmt)
// options are in format <device>:<mode>:<codec>[:other_opts]
if (isdigit(tmp[0])) {
LOG(LOG_LEVEL_WARNING) << MODULE_NAME "Deprecated syntax used, please use options in format \"key=value\"\n";
// choose device
parse_devices(s, tmp);
@@ -868,7 +869,29 @@ vidcap_decklink_init(const struct vidcap_params *params, void **state)
}
while (deckLinkIterator->Next(&deckLink) == S_OK)
{
if (s->state[i].index != dnum) {
bool found = false;
BMD_STR deviceNameString = NULL;
const char* deviceNameCString = NULL;
result = deckLink->GetDisplayName(&deviceNameString);
if (result == S_OK)
{
deviceNameCString = get_cstr_from_bmd_api_str(deviceNameString);
if (strcmp(deviceNameCString, s->state[i].device_id.c_str()) == 0) {
found = true;
}
release_bmd_api_str(deviceNameString);
free((void *) deviceNameCString);
}
if (isdigit(s->state[i].device_id.c_str()[0]) && atoi(s->state[i].device_id.c_str()) == dnum) {
found = true;
}
if (!found) {
dnum++;
// Release the IDeckLink instance when we've finished with it to prevent leaks
@@ -882,11 +905,8 @@ vidcap_decklink_init(const struct vidcap_params *params, void **state)
s->state[i].deckLink = deckLink;
BMD_STR deviceNameString = NULL;
const char* deviceNameCString = NULL;
// Print the model name of the DeckLink card
result = deckLink->GetModelName(&deviceNameString);
result = deckLink->GetDisplayName(&deviceNameString);
if (result == S_OK)
{
deviceNameCString = get_cstr_from_bmd_api_str(deviceNameString);
@@ -1129,7 +1149,7 @@ vidcap_decklink_init(const struct vidcap_params *params, void **state)
{
if (device_found[i] == false)
{
printf("Device %d wasn't found.\n", s->state[i].index);
LOG(LOG_LEVEL_ERROR) << "Device " << s->state[i].device_id << " was not found.\n";
goto error;
}
}
@@ -1466,7 +1486,7 @@ static void print_input_modes (IDeckLink* deckLink)
modeHeight = displayMode->GetHeight();
displayMode->GetFrameRate(&frameRateDuration, &frameRateScale);
uint32_t mode = ntohl(displayMode->GetDisplayMode());
printf("%d (%.4s)) %-20s \t %d x %d \t %2.2f FPS%s\n", displayModeNumber, (char *) &mode, displayModeCString,
printf("%2d (%.4s)) %-20s \t %d x %d \t %2.2f FPS%s\n", displayModeNumber, (char *) &mode, displayModeCString,
modeWidth, modeHeight, (float) ((double)frameRateScale / (double)frameRateDuration),
(flags & bmdDisplayModeSupports3D ? "\t (supports 3D)" : ""));
release_bmd_api_str(displayModeString);

View File

@@ -63,6 +63,7 @@
#include <iomanip>
#include <mutex>
#include <queue>
#include <string>
#include <vector>
#include "DeckLinkAPIVersion.h"
@@ -255,8 +256,8 @@ static void show_help(void)
HRESULT result;
printf("Decklink (output) options:\n");
printf("\t-d decklink[:device=<device_number(s)>][:timecode][:single-link|:dual-link|:quad-link][:3D[:HDMI3DPacking=<packing>]][:audioConsumerLevels={true|false}][:conversion=<fourcc>][:Use1080pNotPsF={true|false}][:low-latency]\n");
printf("\t\t<device_number(s)> is coma-separated indices of output devices\n");
printf("\t-d decklink[:device=<device(s)>][:timecode][:single-link|:dual-link|:quad-link][:3D[:HDMI3DPacking=<packing>]][:audioConsumerLevels={true|false}][:conversion=<fourcc>][:Use1080pNotPsF={true|false}][:low-latency]\n");
printf("\t\t<device(s)> is coma-separated indices or names of output devices\n");
printf("\t\tsingle-link/dual-link specifies if the video output will be in a single-link (HD/3G/6G/12G) or in dual-link HD-SDI mode\n");
// Create an IDeckLinkIterator object to enumerate all DeckLink cards in the system
deckLinkIterator = create_decklink_iterator(true);
@@ -270,7 +271,7 @@ static void show_help(void)
BMD_STR deviceNameString = NULL;
// *** Print the model name of the DeckLink card
result = deckLink->GetModelName(&deviceNameString);
result = deckLink->GetDisplayName(&deviceNameString);
if (result == S_OK)
{
const char *deviceNameCString = get_cstr_from_bmd_api_str(deviceNameString);
@@ -665,7 +666,7 @@ static void display_decklink_probe(struct device_info **available_cards, int *co
BMD_STR deviceNameString = NULL;
// *** Print the model name of the DeckLink card
HRESULT result = deckLink->GetModelName(&deviceNameString);
HRESULT result = deckLink->GetDisplayName(&deviceNameString);
*count += 1;
*available_cards = (struct device_info *)
@@ -691,7 +692,7 @@ static void display_decklink_probe(struct device_info **available_cards, int *co
decklink_uninitialize();
}
static bool parse_devices(const char *devices_str, int *cardIdx, int *devices_cnt) {
static bool parse_devices(const char *devices_str, string *cardId, int *devices_cnt) {
if (strlen(devices_str) == 0) {
log_msg(LOG_LEVEL_ERROR, MOD_NAME "Empty device string!\n");
return false;
@@ -702,7 +703,7 @@ static bool parse_devices(const char *devices_str, int *cardIdx, int *devices_cn
*devices_cnt = 0;
char *item;
while ((item = strtok_r(ptr, ",", &save_ptr))) {
cardIdx[*devices_cnt] = atoi(item);
cardId[*devices_cnt] = item;
++*devices_cnt;
ptr = NULL;
}
@@ -717,7 +718,7 @@ static void *display_decklink_init(struct module *parent, const char *fmt, unsig
struct state_decklink *s;
IDeckLinkIterator* deckLinkIterator;
HRESULT result;
int cardIdx[MAX_DEVICES];
string cardId[MAX_DEVICES];
int dnum = 0;
IDeckLinkConfiguration* deckLinkConfiguration = NULL;
// for Decklink Studio which has switchable XLR - analog 3 and 4 or AES/EBU 3,4 and 5,6
@@ -736,7 +737,7 @@ static void *display_decklink_init(struct module *parent, const char *fmt, unsig
s->stereo = FALSE;
s->emit_timecode = false;
s->link = 0;
cardIdx[0] = 0;
cardId[0] = "0";
s->devices_cnt = 1;
if(fmt == NULL || strlen(fmt) == 0) {
@@ -764,7 +765,7 @@ static void *display_decklink_init(struct module *parent, const char *fmt, unsig
if (first_option_is_device) {
log_msg(LOG_LEVEL_WARNING, MOD_NAME "Unnamed device index "
"deprecated. Use \"device=%s\" instead.\n", ptr);
if (!parse_devices(ptr, cardIdx, &s->devices_cnt)) {
if (!parse_devices(ptr, cardId, &s->devices_cnt)) {
delete s;
return NULL;
}
@@ -773,7 +774,7 @@ static void *display_decklink_init(struct module *parent, const char *fmt, unsig
while (ptr) {
if (strncasecmp(ptr, "device=", strlen("device=")) == 0) {
if (!parse_devices(ptr + strlen("device="), cardIdx, &s->devices_cnt)) {
if (!parse_devices(ptr + strlen("device="), cardId, &s->devices_cnt)) {
delete s;
return NULL;
}
@@ -874,10 +875,30 @@ static void *display_decklink_init(struct module *parent, const char *fmt, unsig
{
bool found = false;
for(int i = 0; i < s->devices_cnt; ++i) {
if (dnum == cardIdx[i]){
s->state[i].deckLink = deckLink;
BMD_STR deviceNameString = NULL;
const char* deviceNameCString = NULL;
result = deckLink->GetDisplayName(&deviceNameString);
if (result == S_OK)
{
deviceNameCString = get_cstr_from_bmd_api_str(deviceNameString);
if (strcmp(deviceNameCString, cardId[i].c_str()) == 0) {
found = true;
}
release_bmd_api_str(deviceNameString);
free((void *) deviceNameCString);
}
if (isdigit(cardId[i].c_str()[0]) && dnum == atoi(cardId[i].c_str())){
found = true;
}
if (found) {
s->state[i].deckLink = deckLink;
}
}
if(!found && deckLink != NULL)
deckLink->Release();
@@ -885,7 +906,7 @@ static void *display_decklink_init(struct module *parent, const char *fmt, unsig
}
for(int i = 0; i < s->devices_cnt; ++i) {
if(s->state[i].deckLink == NULL) {
log_msg(LOG_LEVEL_ERROR, "No DeckLink PCI card #%d found\n", cardIdx[i]);
LOG(LOG_LEVEL_ERROR) << "No DeckLink PCI card " << cardId[i] <<" found\n";
goto error;
}
}