0
0
mirror of https://github.com/obsproject/obs-studio.git synced 2024-09-20 04:42:18 +02:00

decklink: Use unbuffered by default, and decouple

Use unbuffered async mode by default, and when in unbuffered mode,
decouple audio/video so that audio plays as soon as it's received.

This is a workaround for decklink device drivers having unreliable
video/audio timestamps (audio/video sync drifting over time).  From
testing, it seems that the handling of video and audio is completely
separate in the driver; along with the timestamp calculations.  For
example, when the thread of the decklink audio callback is stalled, it
would cause the timestamps of the audio alone to go out of sync, which
indicates timestamps are calculated more or less on the spot independent
of what video is doing (which is how we replicated the issue fixed by
b63e4b055e).  Because decklink drivers treats the audio and video as
essentially decoupled, we must also treat it as decoupled.  This is what
was causing video/audio to drift out of sync over time.
This commit is contained in:
jp9000 2017-09-29 00:40:03 -07:00
parent b54f70ef8d
commit 4330021617
3 changed files with 12 additions and 1 deletions

View File

@ -83,6 +83,13 @@ void DeckLinkDeviceInstance::HandleAudioPacket(
currentPacket.frames = frameCount;
currentPacket.timestamp = timestamp;
if (decklink && !decklink->buffering) {
currentPacket.timestamp = os_gettime_ns();
currentPacket.timestamp -=
(uint64_t)frameCount * 1000000000ULL /
(uint64_t)currentPacket.samples_per_sec;
}
if (!ISSTEREO(channelFormat)) {
if (audioRepacker->repack((uint8_t *)bytes, frameCount) < 0) {
LOG(LOG_ERROR, "Failed to convert audio packet data");

View File

@ -62,4 +62,6 @@ public:
bool Activate(DeckLinkDevice *device, long long modeId);
void Deactivate();
bool buffering = false;
};

View File

@ -40,12 +40,14 @@ static void decklink_enable_buffering(DeckLink *decklink, bool enabled)
{
obs_source_t *source = decklink->GetSource();
obs_source_set_async_unbuffered(source, !enabled);
decklink->buffering = enabled;
}
static void *decklink_create(obs_data_t *settings, obs_source_t *source)
{
DeckLink *decklink = new DeckLink(source, deviceEnum);
obs_source_set_async_decoupled(source, true);
decklink_enable_buffering(decklink,
obs_data_get_bool(settings, BUFFERING));
@ -88,7 +90,7 @@ static void decklink_update(void *data, obs_data_t *settings)
static void decklink_get_defaults(obs_data_t *settings)
{
obs_data_set_default_bool(settings, BUFFERING, true);
obs_data_set_default_bool(settings, BUFFERING, false);
obs_data_set_default_int(settings, PIXEL_FORMAT, bmdFormat8BitYUV);
obs_data_set_default_int(settings, COLOR_SPACE, VIDEO_CS_DEFAULT);
obs_data_set_default_int(settings, COLOR_RANGE, VIDEO_RANGE_DEFAULT);