New upstream version 21.0.2+dfsg1

This commit is contained in:
Sebastian Ramacher 2018-02-19 20:54:37 +01:00
parent 1f1bbb3518
commit baafb6325b
706 changed files with 49633 additions and 5044 deletions

View file

@ -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(), &currentFrame);
}
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;
}