mirror of
https://github.com/outbackdingo/UltraGrid.git
synced 2026-03-21 02:40:14 +00:00
DeckLink cap./disp.: check profile for 3D
Verify if active profile is compatible with 3D mode - if not, suggest profile change.
This commit is contained in:
@@ -308,13 +308,27 @@ cleanup:
|
||||
HRESULT result = cmd;\
|
||||
if (FAILED(result)) {;\
|
||||
LOG(LOG_LEVEL_ERROR) << MOD_NAME << name << ": " << bmd_hresult_to_string(result) << "\n";\
|
||||
ret = false;\
|
||||
ret = {};\
|
||||
goto cleanup;\
|
||||
}\
|
||||
} while (0)
|
||||
|
||||
#define RELEASE_IF_NOT_NULL(x) if (x != nullptr) { x->Release(); x = nullptr; }
|
||||
|
||||
static BMDProfileID GetDeckLinkProfileID(IDeckLinkProfile* profile)
|
||||
{
|
||||
IDeckLinkProfileAttributes* profileAttributes = nullptr;
|
||||
if (HRESULT result = profile->QueryInterface(IID_IDeckLinkProfileAttributes, (void**)&profileAttributes); FAILED(result)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
int64_t profileIDInt = 0;
|
||||
// Get Profile ID attribute
|
||||
profileAttributes->GetInt(BMDDeckLinkProfileID, &profileIDInt);
|
||||
profileAttributes->Release();
|
||||
return (BMDProfileID) profileIDInt;
|
||||
}
|
||||
|
||||
class ProfileCallback : public IDeckLinkProfileCallback
|
||||
{
|
||||
public:
|
||||
@@ -322,7 +336,7 @@ class ProfileCallback : public IDeckLinkProfileCallback
|
||||
m_requestedProfile->AddRef();
|
||||
}
|
||||
|
||||
HRESULT ProfileChanging (/* in */ [[maybe_unused]] IDeckLinkProfile* profileToBeActivated, /* in */ [[maybe_unused]] BOOL streamsWillBeForcedToStop) override { return S_OK; }
|
||||
HRESULT ProfileChanging (/* in */ [[maybe_unused]] IDeckLinkProfile* profileToBeActivated, /* in */ [[maybe_unused]] BMD_BOOL streamsWillBeForcedToStop) override { return S_OK; }
|
||||
HRESULT ProfileActivated (/* in */ [[maybe_unused]] IDeckLinkProfile* activatedProfile) override {
|
||||
std::lock_guard<std::mutex> lock(m_profileActivatedMutex);
|
||||
{
|
||||
@@ -434,6 +448,50 @@ cleanup:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BMDProfileID decklink_get_active_profile_id(IDeckLink *decklink)
|
||||
{
|
||||
BMDProfileID ret{};
|
||||
IDeckLinkProfileManager *manager = nullptr;
|
||||
|
||||
if (HRESULT result = decklink->QueryInterface(IID_IDeckLinkProfileManager, (void**)&manager); FAILED(result)) {
|
||||
if (result != E_NOINTERFACE) {
|
||||
LOG(LOG_LEVEL_ERROR) << "Cannot get IDeckLinkProfileManager: " << bmd_hresult_to_string(result) << "\n";
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
IDeckLinkProfileIterator *it = nullptr;
|
||||
IDeckLinkProfile *profile = nullptr;
|
||||
EXIT_IF_FAILED(manager->GetProfiles(&it), "Cannot get profiles iterator");
|
||||
while (it->Next(&profile) == S_OK) {
|
||||
BMD_BOOL isActiveProfile = BMD_FALSE;
|
||||
if ((profile->IsActive(&isActiveProfile) == S_OK) && isActiveProfile) {
|
||||
ret = GetDeckLinkProfileID(profile);
|
||||
profile->Release();
|
||||
break;
|
||||
}
|
||||
profile->Release();
|
||||
}
|
||||
|
||||
cleanup:
|
||||
RELEASE_IF_NOT_NULL(it);
|
||||
RELEASE_IF_NOT_NULL(manager);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool bmd_check_stereo_profile(IDeckLink *deckLink) {
|
||||
if (BMDProfileID profile_active = decklink_get_active_profile_id(deckLink)) {
|
||||
if (profile_active != bmdProfileOneSubDeviceHalfDuplex &&
|
||||
profile_active != bmdProfileOneSubDeviceFullDuplex) {
|
||||
uint32_t profile_fcc_host = ntohl(profile_active);
|
||||
log_msg(LOG_LEVEL_ERROR, MOD_NAME "Active profile '%.4s' may not be compatible with stereo mode.\n", (char *) &profile_fcc_host);
|
||||
log_msg(LOG_LEVEL_INFO, MOD_NAME "Use 'profile=' parameter to set 1-subdevice mode in either '1dhd' (half) or '1dfd' (full) duplex.\n");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
string bmd_get_device_name(IDeckLink *decklink) {
|
||||
BMD_STR deviceNameString = NULL;
|
||||
char * deviceNameCString = NULL;
|
||||
|
||||
@@ -104,6 +104,7 @@ void decklink_uninitialize();
|
||||
bool blackmagic_api_version_check();
|
||||
void print_decklink_version(void);
|
||||
|
||||
bool bmd_check_stereo_profile(IDeckLink *deckLink);
|
||||
bool decklink_set_duplex(IDeckLink *decklink, uint32_t profileID);
|
||||
std::string bmd_get_device_name(IDeckLink *decklink);
|
||||
std::string bmd_get_audio_connection_name(BMDAudioOutputAnalogAESSwitch audioConnection);
|
||||
|
||||
@@ -142,6 +142,7 @@ struct device_state {
|
||||
bool audio = false; /* wheather we process audio or not */
|
||||
struct tile *tile = nullptr;
|
||||
bool init(struct vidcap_decklink_state *s, struct tile *tile, BMDAudioConnection audioConnection);
|
||||
void check_attributes(struct vidcap_decklink_state *s);
|
||||
};
|
||||
|
||||
struct vidcap_decklink_state {
|
||||
@@ -1062,6 +1063,13 @@ static bool decklink_cap_configure_audio(struct vidcap_decklink_state *s, unsign
|
||||
return true;
|
||||
}
|
||||
|
||||
void device_state::check_attributes(struct vidcap_decklink_state *s)
|
||||
{
|
||||
if (s->stereo) {
|
||||
bmd_check_stereo_profile(deckLink);
|
||||
}
|
||||
}
|
||||
|
||||
#define INIT_ERR() do { RELEASE_IF_NOT_NULL(displayMode); RELEASE_IF_NOT_NULL(displayModeIterator); return false; } while (0)
|
||||
bool device_state::init(struct vidcap_decklink_state *s, struct tile *t, BMDAudioConnection audioConnection)
|
||||
{
|
||||
@@ -1153,6 +1161,8 @@ bool device_state::init(struct vidcap_decklink_state *s, struct tile *t, BMDAudi
|
||||
BMD_CHECK(deckLinkInput->GetDisplayModeIterator(&displayModeIterator),
|
||||
"Could not obtain the video input display mode iterator:", INIT_ERR());
|
||||
|
||||
check_attributes(s);
|
||||
|
||||
int mnum = 0;
|
||||
#define MODE_SPEC_AUTODETECT -1
|
||||
#define MODE_SPEC_FOURCC -2
|
||||
|
||||
@@ -750,6 +750,7 @@ display_decklink_reconfigure_video(void *state, struct video_desc desc)
|
||||
}
|
||||
|
||||
if (s->stereo) {
|
||||
bmd_check_stereo_profile(s->state.at(0).deckLink);
|
||||
if ((int) desc.tile_count != 2) {
|
||||
log_msg(LOG_LEVEL_ERROR, MOD_NAME "In stereo mode exactly "
|
||||
"2 streams expected, %d received.\n", desc.tile_count);
|
||||
|
||||
Reference in New Issue
Block a user