Переглянути джерело

decklink: Add workaround for audio timestamp jump issue

jp9000 8 роки тому
батько
коміт
b63e4b055e

+ 23 - 3
plugins/decklink/decklink-device-instance.cpp

@@ -94,6 +94,9 @@ void DeckLinkDeviceInstance::HandleAudioPacket(
 		currentPacket.data[0]   = (uint8_t *)bytes;
 		currentPacket.data[0]   = (uint8_t *)bytes;
 	}
 	}
 
 
+	nextAudioTS = timestamp +
+		((uint64_t)frameCount * 1000000000ULL / 48000ULL) + 1;
+
 	obs_source_output_audio(decklink->GetSource(), &currentPacket);
 	obs_source_output_audio(decklink->GetSource(), &currentPacket);
 }
 }
 
 
@@ -219,10 +222,27 @@ HRESULT STDMETHODCALLTYPE DeckLinkDeviceInstance::VideoInputFrameArrived(
 	BMDTimeValue videoDur = 0;
 	BMDTimeValue videoDur = 0;
 	BMDTimeValue audioTS = 0;
 	BMDTimeValue audioTS = 0;
 
 
-	if (videoFrame)
+	if (videoFrame) {
 		videoFrame->GetStreamTime(&videoTS, &videoDur, TIME_BASE);
 		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)
 	if (videoFrame && videoTS >= 0)
 		HandleVideoFrame(videoFrame, (uint64_t)videoTS);
 		HandleVideoFrame(videoFrame, (uint64_t)videoTS);

+ 3 - 1
plugins/decklink/decklink-device-instance.hpp

@@ -14,7 +14,9 @@ protected:
 	BMDPixelFormat          pixelFormat = bmdFormat8BitYUV;
 	BMDPixelFormat          pixelFormat = bmdFormat8BitYUV;
 	ComPtr<IDeckLinkInput>  input;
 	ComPtr<IDeckLinkInput>  input;
 	volatile long           refCount = 1;
 	volatile long           refCount = 1;
-
+	int64_t                 audioOffset = 0;
+	uint64_t                nextAudioTS = 0;
+	uint64_t                lastVideoTS = 0;
 	AudioRepacker           *audioRepacker = nullptr;
 	AudioRepacker           *audioRepacker = nullptr;
 	speaker_layout          channelFormat = SPEAKERS_STEREO;
 	speaker_layout          channelFormat = SPEAKERS_STEREO;