Decklink: Keyer support

master
Colin Edwards 2018-06-23 17:21:07 -05:00
parent f1b9f6b3ce
commit 19bc92d267
7 changed files with 94 additions and 9 deletions

View File

@ -117,7 +117,7 @@ static inline void render_main_texture(struct obs_core_video *video,
profile_start(render_main_texture_name);
struct vec4 clear_color;
vec4_set(&clear_color, 0.0f, 0.0f, 0.0f, 1.0f);
vec4_set(&clear_color, 0.0f, 0.0f, 0.0f, 0.0f);
gs_set_render_target(video->render_textures[cur_texture], NULL);
gs_clear(GS_CLEAR_COLOR, &clear_color, 1.0f, 0);
@ -207,7 +207,14 @@ static inline void render_output_texture(struct obs_core_video *video,
1.0f / (float)video->base_height);
gs_effect_t *effect = get_scale_effect(video, width, height);
gs_technique_t *tech = gs_effect_get_technique(effect, "DrawMatrix");
gs_technique_t *tech;
if (video->ovi.output_format == VIDEO_FORMAT_RGBA) {
tech = gs_effect_get_technique(effect, "Draw");
} else {
tech = gs_effect_get_technique(effect, "DrawMatrix");
}
gs_eparam_t *image = gs_effect_get_param_by_name(effect, "image");
gs_eparam_t *matrix = gs_effect_get_param_by_name(effect,
"color_matrix");

View File

@ -19,6 +19,7 @@ public:
uint32_t audio_samplerate;
size_t audio_planes;
size_t audio_size;
int keyerMode;
DeckLinkOutput(obs_output_t *output, DeckLinkDeviceDiscovery *discovery);
virtual ~DeckLinkOutput(void);

View File

@ -9,6 +9,7 @@
#define BUFFERING "buffering"
#define DEACTIVATE_WNS "deactivate_when_not_showing"
#define AUTO_START "auto_start"
#define KEYER "keyer"
#define TEXT_DEVICE obs_module_text("Device")
#define TEXT_MODE obs_module_text("Mode")
@ -30,3 +31,4 @@
#define TEXT_BUFFERING obs_module_text("Buffering")
#define TEXT_DWNS obs_module_text("DeactivateWhenNotShowing")
#define TEXT_AUTO_START obs_module_text("AutoStart")
#define TEXT_ENABLE_KEYER obs_module_text("Keyer")

View File

@ -1,4 +1,4 @@
#include "decklink-device-instance.hpp"
#include "decklink-device-instance.hpp"
#include "audio-repack.hpp"
#include "DecklinkInput.hpp"
@ -312,6 +312,18 @@ bool DeckLinkDeviceInstance::StartOutput(DeckLinkDeviceMode *mode_)
mode = mode_;
IDeckLinkKeyer *deckLinkKeyer = nullptr;
if (device->GetKeyer(&deckLinkKeyer)) {
int keyerMode = device->GetKeyerMode();
if (keyerMode) {
deckLinkKeyer->Enable(keyerMode == 1);
deckLinkKeyer->SetLevel(255);
} else {
deckLinkKeyer->Disable();
}
}
auto decklinkOutput = dynamic_cast<DeckLinkOutput*>(decklink);
if (decklinkOutput == nullptr)
return false;
@ -319,8 +331,8 @@ bool DeckLinkDeviceInstance::StartOutput(DeckLinkDeviceMode *mode_)
HRESULT result;
result = output->CreateVideoFrame(decklinkOutput->GetWidth(),
decklinkOutput->GetHeight(),
decklinkOutput->GetWidth() * 2,
bmdFormat8BitYUV,
decklinkOutput->GetWidth() * 4,
bmdFormat8BitBGRA,
bmdFrameFlagDefault,
&decklinkOutputFrame);
if (result != S_OK) {
@ -362,7 +374,7 @@ void DeckLinkDeviceInstance::DisplayVideoFrame(video_data *frame)
uint8_t *outData = frame->data[0];
std::copy(outData, outData + (decklinkOutput->GetWidth() *
decklinkOutput->GetHeight() * 2), destData);
decklinkOutput->GetHeight() * 4), destData);
output->DisplayVideoFrameSync(decklinkOutputFrame);
}

View File

@ -1,4 +1,4 @@
#include <sstream>
#include <sstream>
#include "decklink-device.hpp"
@ -97,6 +97,10 @@ bool DeckLinkDevice::Init()
}
}
// get keyer support
attributes->GetFlag(BMDDeckLinkSupportsExternalKeying, &supportsExternalKeyer);
attributes->GetFlag(BMDDeckLinkSupportsInternalKeying, &supportsInternalKeyer);
decklink_string_t decklinkModelName;
decklink_string_t decklinkDisplayName;
@ -152,6 +156,27 @@ bool DeckLinkDevice::GetOutput(IDeckLinkOutput **output)
return true;
}
bool DeckLinkDevice::GetKeyer(IDeckLinkKeyer **deckLinkKeyer)
{
if (device->QueryInterface(IID_IDeckLinkKeyer, (void**)deckLinkKeyer) != S_OK)
{
fprintf(stderr, "Could not obtain the IDeckLinkKeyer interface\n");
return false;
}
return true;
}
void DeckLinkDevice::SetKeyerMode(int newKeyerMode)
{
keyerMode = newKeyerMode;
}
int DeckLinkDevice::GetKeyerMode(void)
{
return keyerMode;
}
DeckLinkDeviceMode *DeckLinkDevice::FindInputMode(long long id)
{
return inputModeIdMap[id];
@ -182,6 +207,16 @@ const std::vector<DeckLinkDeviceMode *>& DeckLinkDevice::GetOutputModes(void) co
return outputModes;
}
const bool DeckLinkDevice::GetSupportsExternalKeyer(void) const
{
return supportsExternalKeyer;
}
const bool DeckLinkDevice::GetSupportsInternalKeyer(void) const
{
return supportsInternalKeyer;
}
const std::string& DeckLinkDevice::GetName(void) const
{
return name;

View File

@ -1,4 +1,4 @@
#pragma once
#pragma once
#include "decklink-device-mode.hpp"
@ -7,6 +7,8 @@
#include <vector>
#include <stdint.h>
class DeckLinkDevice {
ComPtr<IDeckLink> device;
std::map<long long, DeckLinkDeviceMode *> inputModeIdMap;
@ -17,6 +19,9 @@ class DeckLinkDevice {
std::string displayName;
std::string hash;
int32_t maxChannel;
decklink_bool_t supportsExternalKeyer;
decklink_bool_t supportsInternalKeyer;
int keyerMode;
volatile long refCount = 1;
public:
@ -34,11 +39,16 @@ public:
const std::string& GetHash(void) const;
const std::vector<DeckLinkDeviceMode *>& GetInputModes(void) const;
const std::vector<DeckLinkDeviceMode *>& GetOutputModes(void) const;
const bool GetSupportsExternalKeyer(void) const;
const bool GetSupportsInternalKeyer(void) const;
int GetKeyerMode(void);
void SetKeyerMode(int newKeyerMode);
const std::string& GetName(void) const;
int32_t GetMaxChannel(void) const;
bool GetInput(IDeckLinkInput **input);
bool GetOutput(IDeckLinkOutput **output);
bool GetKeyer(IDeckLinkKeyer **keyer);
inline bool IsDevice(IDeckLink *device_)
{

View File

@ -22,6 +22,7 @@ static void *decklink_output_create(obs_data_t *settings, obs_output_t *output)
decklinkOutput->deviceHash = obs_data_get_string(settings, DEVICE_HASH);
decklinkOutput->modeID = obs_data_get_int(settings, MODE_ID);
decklinkOutput->keyerMode = obs_data_get_int(settings, KEYER);
return decklinkOutput;
}
@ -32,6 +33,7 @@ static void decklink_output_update(void *data, obs_data_t *settings)
decklink->deviceHash = obs_data_get_string(settings, DEVICE_HASH);
decklink->modeID = obs_data_get_int(settings, MODE_ID);
decklink->keyerMode = obs_data_get_int(settings, KEYER);
}
static bool decklink_output_start(void *data)
@ -59,12 +61,13 @@ static bool decklink_output_start(void *data)
decklink->SetSize(mode->GetWidth(), mode->GetHeight());
struct video_scale_info to = {};
to.format = VIDEO_FORMAT_UYVY;
to.format = VIDEO_FORMAT_BGRA;
to.width = mode->GetWidth();
to.height = mode->GetHeight();
obs_output_set_video_conversion(decklink->GetOutput(), &to);
device->SetKeyerMode(decklink->keyerMode);
decklink->Activate(device, decklink->modeID);
struct audio_convert_info conversion = {};
@ -172,8 +175,10 @@ static bool decklink_output_device_changed(obs_properties_t *props,
}
obs_property_t *modeList = obs_properties_get(props, MODE_ID);
obs_property_t *keyerList = obs_properties_get(props, KEYER);
obs_property_list_clear(modeList);
obs_property_list_clear(keyerList);
ComPtr<DeckLinkDevice> device;
device.Set(deviceEnum->FindByHash(hash));
@ -181,6 +186,7 @@ static bool decklink_output_device_changed(obs_properties_t *props,
if (!device) {
obs_property_list_add_int(modeList, mode, modeId);
obs_property_list_item_disable(modeList, 0, true);
obs_property_list_item_disable(keyerList, 0, true);
} else {
const std::vector<DeckLinkDeviceMode*> &modes =
device->GetOutputModes();
@ -190,6 +196,16 @@ static bool decklink_output_device_changed(obs_properties_t *props,
mode->GetName().c_str(),
mode->GetId());
}
obs_property_list_add_int(keyerList, "Disabled", 0);
if (device->GetSupportsExternalKeyer()) {
obs_property_list_add_int(keyerList, "External", 1);
}
if (device->GetSupportsInternalKeyer()) {
obs_property_list_add_int(keyerList, "Internal", 2);
}
}
return true;
@ -211,6 +227,8 @@ static obs_properties_t *decklink_output_properties(void *unused)
obs_properties_add_bool(props, AUTO_START, TEXT_AUTO_START);
obs_properties_add_list(props, KEYER, TEXT_ENABLE_KEYER, OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
return props;
}