New upstream version 21.0.2+dfsg1
This commit is contained in:
parent
1f1bbb3518
commit
baafb6325b
706 changed files with 49633 additions and 5044 deletions
|
|
@ -9,7 +9,11 @@
|
|||
#define LOG(level, message, ...) blog(level, "%s: " message, \
|
||||
obs_source_get_name(this->decklink->GetSource()), ##__VA_ARGS__)
|
||||
|
||||
#define ISSTEREO(flag) ((flag) == SPEAKERS_STEREO)
|
||||
#ifdef _WIN32
|
||||
#define IS_WIN 1
|
||||
#else
|
||||
#define IS_WIN 0
|
||||
#endif
|
||||
|
||||
static inline enum video_format ConvertPixelFormat(BMDPixelFormat format)
|
||||
{
|
||||
|
|
@ -26,8 +30,10 @@ static inline enum video_format ConvertPixelFormat(BMDPixelFormat format)
|
|||
static inline int ConvertChannelFormat(speaker_layout format)
|
||||
{
|
||||
switch (format) {
|
||||
case SPEAKERS_2POINT1:
|
||||
case SPEAKERS_4POINT0:
|
||||
case SPEAKERS_4POINT1:
|
||||
case SPEAKERS_5POINT1:
|
||||
case SPEAKERS_5POINT1_SURROUND:
|
||||
case SPEAKERS_7POINT1:
|
||||
return 8;
|
||||
|
||||
|
|
@ -40,13 +46,16 @@ static inline int ConvertChannelFormat(speaker_layout format)
|
|||
static inline audio_repack_mode_t ConvertRepackFormat(speaker_layout format)
|
||||
{
|
||||
switch (format) {
|
||||
case SPEAKERS_2POINT1:
|
||||
return repack_mode_8to3ch_swap23;
|
||||
case SPEAKERS_4POINT0:
|
||||
return repack_mode_8to4ch_swap23;
|
||||
case SPEAKERS_4POINT1:
|
||||
return repack_mode_8to5ch_swap23;
|
||||
case SPEAKERS_5POINT1:
|
||||
case SPEAKERS_5POINT1_SURROUND:
|
||||
return repack_mode_8to6ch_swap23;
|
||||
|
||||
case SPEAKERS_7POINT1:
|
||||
return repack_mode_8ch_swap23;
|
||||
|
||||
return repack_mode_8ch_swap23_swap46_swap57;
|
||||
default:
|
||||
assert(false && "No repack requested");
|
||||
return (audio_repack_mode_t)-1;
|
||||
|
|
@ -83,15 +92,29 @@ void DeckLinkDeviceInstance::HandleAudioPacket(
|
|||
currentPacket.frames = frameCount;
|
||||
currentPacket.timestamp = timestamp;
|
||||
|
||||
if (!ISSTEREO(channelFormat)) {
|
||||
if (decklink && !decklink->buffering) {
|
||||
currentPacket.timestamp = os_gettime_ns();
|
||||
currentPacket.timestamp -=
|
||||
(uint64_t)frameCount * 1000000000ULL /
|
||||
(uint64_t)currentPacket.samples_per_sec;
|
||||
}
|
||||
|
||||
int maxdevicechannel = device->GetMaxChannel();
|
||||
bool isWin = IS_WIN;
|
||||
|
||||
if (channelFormat != SPEAKERS_UNKNOWN &&
|
||||
channelFormat != SPEAKERS_MONO &&
|
||||
channelFormat != SPEAKERS_STEREO &&
|
||||
maxdevicechannel >= 8 &&
|
||||
isWin) {
|
||||
|
||||
if (audioRepacker->repack((uint8_t *)bytes, frameCount) < 0) {
|
||||
LOG(LOG_ERROR, "Failed to convert audio packet data");
|
||||
return;
|
||||
}
|
||||
|
||||
currentPacket.data[0] = (*audioRepacker)->packet_buffer;
|
||||
currentPacket.data[0] = (*audioRepacker)->packet_buffer;
|
||||
} else {
|
||||
currentPacket.data[0] = (uint8_t *)bytes;
|
||||
currentPacket.data[0] = (uint8_t *)bytes;
|
||||
}
|
||||
|
||||
nextAudioTS = timestamp +
|
||||
|
|
@ -118,16 +141,15 @@ void DeckLinkDeviceInstance::HandleVideoFrame(
|
|||
currentFrame.height = (uint32_t)videoFrame->GetHeight();
|
||||
currentFrame.timestamp = timestamp;
|
||||
|
||||
video_format_get_parameters(VIDEO_CS_601, VIDEO_RANGE_PARTIAL,
|
||||
currentFrame.color_matrix, currentFrame.color_range_min,
|
||||
currentFrame.color_range_max);
|
||||
|
||||
obs_source_output_video(decklink->GetSource(), ¤tFrame);
|
||||
}
|
||||
|
||||
void DeckLinkDeviceInstance::FinalizeStream()
|
||||
{
|
||||
input->SetCallback(nullptr);
|
||||
input->DisableVideoInput();
|
||||
if (channelFormat != SPEAKERS_UNKNOWN)
|
||||
input->DisableAudioInput();
|
||||
|
||||
if (audioRepacker != nullptr)
|
||||
{
|
||||
|
|
@ -138,6 +160,43 @@ void DeckLinkDeviceInstance::FinalizeStream()
|
|||
mode = nullptr;
|
||||
}
|
||||
|
||||
//#define LOG_SETUP_VIDEO_FORMAT 1
|
||||
|
||||
void DeckLinkDeviceInstance::SetupVideoFormat(DeckLinkDeviceMode *mode_)
|
||||
{
|
||||
if (mode_ == nullptr)
|
||||
return;
|
||||
|
||||
currentFrame.format = ConvertPixelFormat(pixelFormat);
|
||||
|
||||
colorSpace = decklink->GetColorSpace();
|
||||
if (colorSpace == VIDEO_CS_DEFAULT) {
|
||||
const BMDDisplayModeFlags flags = mode_->GetDisplayModeFlags();
|
||||
if (flags & bmdDisplayModeColorspaceRec709)
|
||||
activeColorSpace = VIDEO_CS_709;
|
||||
else if (flags & bmdDisplayModeColorspaceRec601)
|
||||
activeColorSpace = VIDEO_CS_601;
|
||||
else
|
||||
activeColorSpace = VIDEO_CS_DEFAULT;
|
||||
} else {
|
||||
activeColorSpace = colorSpace;
|
||||
}
|
||||
|
||||
colorRange = decklink->GetColorRange();
|
||||
currentFrame.full_range = colorRange == VIDEO_RANGE_FULL;
|
||||
|
||||
video_format_get_parameters(activeColorSpace, colorRange,
|
||||
currentFrame.color_matrix, currentFrame.color_range_min,
|
||||
currentFrame.color_range_max);
|
||||
|
||||
#ifdef LOG_SETUP_VIDEO_FORMAT
|
||||
LOG(LOG_INFO, "Setup video format: %s, %s, %s",
|
||||
pixelFormat == bmdFormat8BitYUV ? "YUV" : "RGB",
|
||||
activeColorSpace == VIDEO_CS_709 ? "BT.709" : "BT.601",
|
||||
colorRange == VIDEO_RANGE_FULL ? "full" : "limited");
|
||||
#endif
|
||||
}
|
||||
|
||||
bool DeckLinkDeviceInstance::StartCapture(DeckLinkDeviceMode *mode_)
|
||||
{
|
||||
if (mode != nullptr)
|
||||
|
|
@ -150,33 +209,50 @@ bool DeckLinkDeviceInstance::StartCapture(DeckLinkDeviceMode *mode_)
|
|||
if (!device->GetInput(&input))
|
||||
return false;
|
||||
|
||||
pixelFormat = decklink->GetPixelFormat();
|
||||
currentFrame.format = ConvertPixelFormat(pixelFormat);
|
||||
BMDVideoInputFlags flags;
|
||||
|
||||
const BMDDisplayMode displayMode = mode_->GetDisplayMode();
|
||||
bool isauto = mode_->GetName() == "Auto";
|
||||
if (isauto) {
|
||||
displayMode = bmdModeNTSC;
|
||||
pixelFormat = bmdFormat8BitYUV;
|
||||
flags = bmdVideoInputEnableFormatDetection;
|
||||
} else {
|
||||
displayMode = mode_->GetDisplayMode();
|
||||
pixelFormat = decklink->GetPixelFormat();
|
||||
flags = bmdVideoInputFlagDefault;
|
||||
}
|
||||
|
||||
const HRESULT videoResult = input->EnableVideoInput(displayMode,
|
||||
pixelFormat, bmdVideoInputFlagDefault);
|
||||
|
||||
pixelFormat, flags);
|
||||
if (videoResult != S_OK) {
|
||||
LOG(LOG_ERROR, "Failed to enable video input");
|
||||
return false;
|
||||
}
|
||||
|
||||
SetupVideoFormat(mode_);
|
||||
|
||||
channelFormat = decklink->GetChannelFormat();
|
||||
currentPacket.speakers = channelFormat;
|
||||
|
||||
int maxdevicechannel = device->GetMaxChannel();
|
||||
bool isWin = IS_WIN;
|
||||
|
||||
if (channelFormat != SPEAKERS_UNKNOWN) {
|
||||
const int channel = ConvertChannelFormat(channelFormat);
|
||||
const HRESULT audioResult = input->EnableAudioInput(
|
||||
bmdAudioSampleRate48kHz, bmdAudioSampleType16bitInteger,
|
||||
channel);
|
||||
|
||||
if (audioResult != S_OK)
|
||||
LOG(LOG_WARNING, "Failed to enable audio input; continuing...");
|
||||
|
||||
if (!ISSTEREO(channelFormat)) {
|
||||
const audio_repack_mode_t repack_mode = ConvertRepackFormat(channelFormat);
|
||||
if (channelFormat != SPEAKERS_UNKNOWN &&
|
||||
channelFormat != SPEAKERS_MONO &&
|
||||
channelFormat != SPEAKERS_STEREO &&
|
||||
maxdevicechannel >= 8 &&
|
||||
isWin) {
|
||||
|
||||
const audio_repack_mode_t repack_mode = ConvertRepackFormat
|
||||
(channelFormat);
|
||||
audioRepacker = new AudioRepacker(repack_mode);
|
||||
}
|
||||
}
|
||||
|
|
@ -257,12 +333,41 @@ HRESULT STDMETHODCALLTYPE DeckLinkDeviceInstance::VideoInputFormatChanged(
|
|||
IDeckLinkDisplayMode *newMode,
|
||||
BMDDetectedVideoInputFormatFlags detectedSignalFlags)
|
||||
{
|
||||
UNUSED_PARAMETER(events);
|
||||
UNUSED_PARAMETER(newMode);
|
||||
UNUSED_PARAMETER(detectedSignalFlags);
|
||||
input->PauseStreams();
|
||||
|
||||
// There is no implementation for automatic format detection, so this
|
||||
// method goes unused.
|
||||
mode->SetMode(newMode);
|
||||
|
||||
if (events & bmdVideoInputDisplayModeChanged) {
|
||||
displayMode = mode->GetDisplayMode();
|
||||
}
|
||||
|
||||
if (events & bmdVideoInputColorspaceChanged) {
|
||||
switch (detectedSignalFlags) {
|
||||
case bmdDetectedVideoInputRGB444:
|
||||
pixelFormat = bmdFormat8BitBGRA;
|
||||
break;
|
||||
|
||||
default:
|
||||
case bmdDetectedVideoInputYCbCr422:
|
||||
pixelFormat = bmdFormat8BitYUV;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const HRESULT videoResult = input->EnableVideoInput(displayMode,
|
||||
pixelFormat, bmdVideoInputEnableFormatDetection);
|
||||
if (videoResult != S_OK) {
|
||||
LOG(LOG_ERROR, "Failed to enable video input");
|
||||
input->StopStreams();
|
||||
FinalizeStream();
|
||||
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
SetupVideoFormat(mode);
|
||||
|
||||
input->FlushStreams();
|
||||
input->StartStreams();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue