From b63e4b055e68a504da6379fbd4477be7da985a94 Mon Sep 17 00:00:00 2001 From: jp9000 Date: Fri, 7 Apr 2017 00:31:16 -0700 Subject: [PATCH] decklink: Add workaround for audio timestamp jump issue --- plugins/decklink/decklink-device-instance.cpp | 26 ++++++++++++++++--- plugins/decklink/decklink-device-instance.hpp | 4 ++- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/plugins/decklink/decklink-device-instance.cpp b/plugins/decklink/decklink-device-instance.cpp index f4f7acfe1..557713aaa 100644 --- a/plugins/decklink/decklink-device-instance.cpp +++ b/plugins/decklink/decklink-device-instance.cpp @@ -94,6 +94,9 @@ void DeckLinkDeviceInstance::HandleAudioPacket( currentPacket.data[0] = (uint8_t *)bytes; } + nextAudioTS = timestamp + + ((uint64_t)frameCount * 1000000000ULL / 48000ULL) + 1; + obs_source_output_audio(decklink->GetSource(), ¤tPacket); } @@ -219,10 +222,27 @@ HRESULT STDMETHODCALLTYPE DeckLinkDeviceInstance::VideoInputFrameArrived( BMDTimeValue videoDur = 0; BMDTimeValue audioTS = 0; - if (videoFrame) + if (videoFrame) { videoFrame->GetStreamTime(&videoTS, &videoDur, TIME_BASE); - if (audioPacket) - audioPacket->GetPacketTime(&audioTS, TIME_BASE); + lastVideoTS = (uint64_t)videoTS; + } + if (audioPacket) { + BMDTimeValue newAudioTS = 0; + int64_t diff; + + audioPacket->GetPacketTime(&newAudioTS, TIME_BASE); + audioTS = newAudioTS + audioOffset; + + diff = (int64_t)audioTS - (int64_t)nextAudioTS; + if (diff > 10000000LL) { + audioOffset -= diff; + audioTS = newAudioTS + audioOffset; + + } else if (diff < -1000000) { + audioOffset = 0; + audioTS = newAudioTS; + } + } if (videoFrame && videoTS >= 0) HandleVideoFrame(videoFrame, (uint64_t)videoTS); diff --git a/plugins/decklink/decklink-device-instance.hpp b/plugins/decklink/decklink-device-instance.hpp index 854e983e0..c0af8f5b0 100644 --- a/plugins/decklink/decklink-device-instance.hpp +++ b/plugins/decklink/decklink-device-instance.hpp @@ -14,7 +14,9 @@ protected: BMDPixelFormat pixelFormat = bmdFormat8BitYUV; ComPtr input; volatile long refCount = 1; - + int64_t audioOffset = 0; + uint64_t nextAudioTS = 0; + uint64_t lastVideoTS = 0; AudioRepacker *audioRepacker = nullptr; speaker_layout channelFormat = SPEAKERS_STEREO;