mirror of
https://github.com/outbackdingo/UltraGrid.git
synced 2026-03-21 15:40:21 +00:00
deck: return back original numeric indices
The numeric indices now use the "natural" index as devices given by
IDeckLinkIterator. The idea is to keep the index consistent with previous
versions.
For the devices ordered newly by topological ID, use character indices
instead ('a', 'b' etc.).
Do not advertise numeric indices for now, anyways, even though now left -
it can now be considered as a legacy feature, it can be later added to
the output if considered useful.
This commit is contained in:
@@ -1097,12 +1097,12 @@ print_bmd_attribute(IDeckLinkProfileAttributes *deckLinkAttributes,
|
||||
* take care about the returned object lifetime (particularly not to
|
||||
* be destroyed after decklink_uninitialize()).
|
||||
*/
|
||||
std::map<unsigned, std::unique_ptr<IDeckLink, void (*)(IDeckLink *)>>
|
||||
std::vector<bmd_dev>
|
||||
bmd_get_sorted_devices(IDeckLinkIterator *deckLinkIterator)
|
||||
{
|
||||
IDeckLink *deckLink = nullptr;
|
||||
std::map<unsigned, std::unique_ptr<IDeckLink, void (*)(IDeckLink *)>> out;
|
||||
unsigned tid_substitute = UINT_MAX;
|
||||
std::vector<bmd_dev> out;
|
||||
int idx = 0;
|
||||
while (deckLinkIterator->Next(&deckLink) == S_OK) {
|
||||
IDeckLinkProfileAttributes *deckLinkAttributes = nullptr;
|
||||
HRESULT result = E_FAIL;
|
||||
@@ -1114,15 +1114,26 @@ bmd_get_sorted_devices(IDeckLinkIterator *deckLinkIterator)
|
||||
result =
|
||||
deckLinkAttributes->GetInt(BMDDeckLinkTopologicalID, &id);
|
||||
if (result != S_OK) {
|
||||
id = tid_substitute--;
|
||||
id = UINT_MAX - idx;
|
||||
}
|
||||
assert(id >= 0 && id <= UINT_MAX);
|
||||
deckLinkAttributes->Release();
|
||||
|
||||
auto release = [](IDeckLink *d) { d->Release(); };
|
||||
out.emplace(id,
|
||||
std::unique_ptr<IDeckLink, void (*)(IDeckLink *)>{
|
||||
deckLink, release });
|
||||
auto &it = out.emplace_back(
|
||||
std::unique_ptr<IDeckLink, void (*)(IDeckLink *)>{
|
||||
deckLink, release },
|
||||
0, 0, 0);
|
||||
std::get<unsigned>(it) = id;
|
||||
std::get<int>(it) = idx++;
|
||||
}
|
||||
std::sort(out.begin(), out.end(), [](bmd_dev &a, bmd_dev &b) {
|
||||
return std::get<unsigned>(a) < std::get<unsigned>(b);
|
||||
});
|
||||
// assign new indices
|
||||
char new_idx = 'a';
|
||||
for (auto &d : out) {
|
||||
std::get<char>(d) = new_idx++;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
@@ -175,7 +176,16 @@ bool bmd_parse_audio_levels(const char *opt) noexcept(false);
|
||||
void print_bmd_attribute(IDeckLinkProfileAttributes *deckLinkAttributes,
|
||||
const char *query_prop_fcc);
|
||||
|
||||
std::map<unsigned, std::unique_ptr<IDeckLink, void (*)(IDeckLink *)>>
|
||||
/**
|
||||
* @details parameters:
|
||||
* - first - IDeckLinkInstance
|
||||
* - unsigned - topological ID
|
||||
* - int - natural idx (the old, order as given by IDeckLinkIterator)
|
||||
* - char - new index ('a', 'b', 'c'...); sorted by topological ID
|
||||
*/
|
||||
using bmd_dev = std::tuple<std::unique_ptr<IDeckLink, void (*)(IDeckLink *)>,
|
||||
unsigned, int, char>;
|
||||
std::vector<bmd_dev>
|
||||
bmd_get_sorted_devices(IDeckLinkIterator *deckLinkIterator);
|
||||
|
||||
#endif // defined BLACKMAGIC_COMMON_HPP
|
||||
|
||||
@@ -614,16 +614,16 @@ decklink_help(bool full, const char *query_prop_fcc = nullptr)
|
||||
// Enumerate all cards in this system
|
||||
int numDevices = 0;
|
||||
for (auto &d : bmd_get_sorted_devices(deckLinkIterator)) {
|
||||
IDeckLink *deckLink = d.second.get();
|
||||
IDeckLink *deckLink = get<0>(d).get();
|
||||
string deviceName = bmd_get_device_name(deckLink);
|
||||
if (deviceName.empty()) {
|
||||
deviceName = "(unable to get name)";
|
||||
}
|
||||
|
||||
// *** Print the model name of the DeckLink card
|
||||
color_printf("\t" TBOLD("%d") ") " TBOLD("%6x") ") " TBOLD(
|
||||
TGREEN("%s")) "\n",
|
||||
numDevices, d.first, deviceName.c_str());
|
||||
color_printf("\t" TBOLD("%c") ") " TBOLD("%6x") ") " TBOLD(
|
||||
TGREEN("%s")) "\n",
|
||||
get<char>(d), get<unsigned>(d), deviceName.c_str());
|
||||
|
||||
// Increment the total number of DeckLink cards found
|
||||
numDevices++;
|
||||
@@ -638,8 +638,6 @@ decklink_help(bool full, const char *query_prop_fcc = nullptr)
|
||||
"fullhelp") "\" to see full list of device modes "
|
||||
"and available connections)\n\n";
|
||||
}
|
||||
|
||||
deckLinkIterator->Release();
|
||||
|
||||
decklink_uninitialize(&com_initialized);
|
||||
|
||||
@@ -653,9 +651,9 @@ decklink_help(bool full, const char *query_prop_fcc = nullptr)
|
||||
col() << "\t" << SBOLD(uv_argv[0] << " -t decklink")
|
||||
<< " # captures autodetected video from first DeckLink (index 0) "
|
||||
"in system\n";
|
||||
col()
|
||||
<< "\t" << SBOLD(uv_argv[0] << " -t decklink:d=1:m=Hp30:c=v210")
|
||||
<< " # specify mode for device which doesn't have autodetection\n";
|
||||
col() << "\t" << SBOLD(uv_argv[0] << " -t decklink:d=b:m=Hp30:c=v210")
|
||||
<< " # specify mode for 2nd device which doesn't have "
|
||||
"autodetection\n";
|
||||
col() << "\t"
|
||||
<< SBOLD(uv_argv[0]
|
||||
<< " -t decklink:d=\"DeckLink 8K Pro (1)\":profile=1dfd")
|
||||
@@ -832,7 +830,6 @@ static void vidcap_decklink_probe(device_info **available_cards, int *card_count
|
||||
*deleter = free;
|
||||
|
||||
IDeckLinkIterator* deckLinkIterator;
|
||||
int numDevices = 0;
|
||||
|
||||
// Create an IDeckLinkIterator object to enumerate all DeckLink cards in the system
|
||||
bool com_initialized = false;
|
||||
@@ -843,7 +840,7 @@ static void vidcap_decklink_probe(device_info **available_cards, int *card_count
|
||||
|
||||
// Enumerate all cards in this system
|
||||
for (auto &d : bmd_get_sorted_devices(deckLinkIterator)) {
|
||||
IDeckLink *deckLink = d.second.get();
|
||||
IDeckLink *deckLink = get<0>(d).get();
|
||||
HRESULT result;
|
||||
IDeckLinkProfileAttributes *deckLinkAttributes;
|
||||
|
||||
@@ -867,7 +864,7 @@ static void vidcap_decklink_probe(device_info **available_cards, int *card_count
|
||||
realloc(cards, *card_count * sizeof(struct device_info));
|
||||
memset(&cards[*card_count - 1], 0, sizeof(struct device_info));
|
||||
snprintf(cards[*card_count - 1].dev, sizeof cards[*card_count - 1].dev,
|
||||
":device=%d", numDevices);
|
||||
":device=%u", get<unsigned>(d));
|
||||
snprintf(cards[*card_count - 1].name, sizeof cards[*card_count - 1].name,
|
||||
"%s", deviceName.c_str());
|
||||
snprintf(cards[*card_count - 1].extra, sizeof cards[*card_count - 1].extra,
|
||||
@@ -930,9 +927,6 @@ static void vidcap_decklink_probe(device_info **available_cards, int *card_count
|
||||
dev_add_option(&cards[*card_count - 1], "3D", "3D", "3D", ":3D", true);
|
||||
dev_add_option(&cards[*card_count - 1], "Profile", "Duplex profile can be one of: 1dhd, 2dhd, 2dfd, 4dhd, keep", "profile", ":profile=", false);
|
||||
|
||||
// Increment the total number of DeckLink cards found
|
||||
numDevices++;
|
||||
|
||||
RELEASE_IF_NOT_NULL(deckLinkAttributes);
|
||||
}
|
||||
|
||||
@@ -1113,7 +1107,6 @@ bool device_state::init(struct vidcap_decklink_state *s, struct tile *t, BMDAudi
|
||||
|
||||
tile = t;
|
||||
|
||||
int dnum = 0;
|
||||
bool com_initialized = false;
|
||||
// Create an IDeckLinkIterator object to enumerate all DeckLink cards in the system
|
||||
IDeckLinkIterator *deckLinkIterator = create_decklink_iterator(&com_initialized, true, false);
|
||||
@@ -1121,7 +1114,7 @@ bool device_state::init(struct vidcap_decklink_state *s, struct tile *t, BMDAudi
|
||||
return false;
|
||||
}
|
||||
for (auto &d : bmd_get_sorted_devices(deckLinkIterator)) {
|
||||
deckLink = d.second.release(); // we must release manually!
|
||||
deckLink = get<0>(d).release(); // we must release manually!
|
||||
string deviceName = bmd_get_device_name(deckLink);
|
||||
if (!deviceName.empty() && deviceName == device_id.c_str()) {
|
||||
break;
|
||||
@@ -1130,15 +1123,22 @@ bool device_state::init(struct vidcap_decklink_state *s, struct tile *t, BMDAudi
|
||||
// topological ID
|
||||
const unsigned long tid =
|
||||
strtoul(device_id.c_str(), nullptr, 16);
|
||||
if (d.first == tid) {
|
||||
if (get<unsigned>(d) == tid) {
|
||||
break;
|
||||
}
|
||||
// idx
|
||||
if (isdigit(device_id.c_str()[0]) && atoi(device_id.c_str()) == dnum) {
|
||||
break;
|
||||
// natural (old) index
|
||||
if (isdigit(device_id.c_str()[0])) {
|
||||
if (atoi(device_id.c_str()) == get<int>(d)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// new (character) index
|
||||
if (device_id.length() == 1 && device_id[0] >= 'a') {
|
||||
if (device_id[0] == get<char>(d)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
dnum++;
|
||||
// Release the IDeckLink instance when we've finished with it to prevent leaks
|
||||
deckLink->Release();
|
||||
deckLink = NULL;
|
||||
|
||||
@@ -130,6 +130,7 @@ using std::atomic_bool;
|
||||
using std::cout;
|
||||
using std::copy;
|
||||
using std::exception;
|
||||
using std::get;
|
||||
using std::invalid_argument;
|
||||
using std::lock_guard;
|
||||
using std::map;
|
||||
@@ -637,16 +638,17 @@ show_help(bool full, const char *query_prop_fcc = nullptr)
|
||||
|
||||
// Enumerate all cards in this system
|
||||
for (auto &d : bmd_get_sorted_devices(deckLinkIterator)) {
|
||||
IDeckLink *deckLink = d.second.get();
|
||||
IDeckLink *deckLink = get<0>(d).get();
|
||||
string deviceName = bmd_get_device_name(deckLink);
|
||||
if (deviceName.empty()) {
|
||||
deviceName = "(unable to get name)";
|
||||
}
|
||||
|
||||
// *** Print the model name of the DeckLink card
|
||||
color_printf("\t" TBOLD("%d") ") " TBOLD("%6x") ") " TBOLD(
|
||||
color_printf("\t" TBOLD("%c") ") " TBOLD("%6x") ") " TBOLD(
|
||||
TGREEN("%s")) "\n",
|
||||
numDevices, d.first, deviceName.c_str());
|
||||
get<char>(d), get<unsigned>(d),
|
||||
deviceName.c_str());
|
||||
if (full) {
|
||||
print_output_modes(deckLink, query_prop_fcc);
|
||||
}
|
||||
@@ -1134,7 +1136,7 @@ static void display_decklink_probe(struct device_info **available_cards, int *co
|
||||
|
||||
// Enumerate all cards in this system
|
||||
for (auto &d : bmd_get_sorted_devices(deckLinkIterator)) {
|
||||
IDeckLink *deckLink = d.second.get();
|
||||
IDeckLink *deckLink = get<0>(d).get();
|
||||
string deviceName = bmd_get_device_name(deckLink);
|
||||
if (deviceName.empty()) {
|
||||
deviceName = "(unknown)";
|
||||
@@ -1144,7 +1146,9 @@ static void display_decklink_probe(struct device_info **available_cards, int *co
|
||||
*available_cards = (struct device_info *)
|
||||
realloc(*available_cards, *count * sizeof(struct device_info));
|
||||
memset(*available_cards + *count - 1, 0, sizeof(struct device_info));
|
||||
snprintf((*available_cards)[*count - 1].dev, sizeof (*available_cards)[*count - 1].dev, ":device=%d", *count - 1);
|
||||
snprintf((*available_cards)[*count - 1].dev,
|
||||
sizeof(*available_cards)[*count - 1].dev, ":device=%u",
|
||||
get<unsigned>(d));
|
||||
snprintf((*available_cards)[*count - 1].extra, sizeof (*available_cards)[*count - 1].extra, "\"embeddedAudioAvailable\":\"t\"");
|
||||
(*available_cards)[*count - 1].repeatable = false;
|
||||
|
||||
@@ -1387,7 +1391,6 @@ static void *display_decklink_init(struct module *parent, const char *fmt, unsig
|
||||
IDeckLinkIterator* deckLinkIterator;
|
||||
HRESULT result;
|
||||
string cardId("0");
|
||||
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
|
||||
|
||||
@@ -1433,7 +1436,7 @@ static void *display_decklink_init(struct module *parent, const char *fmt, unsig
|
||||
|
||||
// Connect to the first DeckLink instance
|
||||
for (auto &d : bmd_get_sorted_devices(deckLinkIterator)) {
|
||||
s->deckLink = d.second.release(); // unmanage
|
||||
s->deckLink = get<0>(d).release(); // unmanage
|
||||
string deviceName = bmd_get_device_name(s->deckLink);
|
||||
|
||||
if (!deviceName.empty() && deviceName == cardId) {
|
||||
@@ -1441,17 +1444,24 @@ static void *display_decklink_init(struct module *parent, const char *fmt, unsig
|
||||
}
|
||||
// topological ID
|
||||
const unsigned long tid = strtoul(cardId.c_str(), nullptr, 16);
|
||||
if (d.first == tid) {
|
||||
if (get<unsigned>(d) == tid) {
|
||||
break;
|
||||
}
|
||||
// idx
|
||||
if (isdigit(cardId.c_str()[0]) && dnum == atoi(cardId.c_str())) {
|
||||
break;
|
||||
// natural (old) index
|
||||
if (isdigit(cardId.c_str()[0])) {
|
||||
if (atoi(cardId.c_str()) == get<int>(d)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// new (character) index
|
||||
if (cardId.length() == 1 && cardId[0] >= 'a') {
|
||||
if (cardId[0] == get<char>(d)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
s->deckLink->Release();
|
||||
s->deckLink = nullptr;
|
||||
dnum++;
|
||||
}
|
||||
deckLinkIterator->Release();
|
||||
if (s->deckLink == nullptr) {
|
||||
|
||||
Reference in New Issue
Block a user