From a2d8913569bc4f3834fd03daf2fcc06ebc2732fe Mon Sep 17 00:00:00 2001 From: Martin Pulec Date: Wed, 19 Jul 2023 08:45:07 +0200 Subject: [PATCH] DeckLink disp.: when resync the stream, reset all audio vals Keep own copy of original and working (with wraparounds) audio TS in order not to fight with the video over the shared variable - reconfigure only if there is a change. --- src/video_display/decklink.cpp | 49 +++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/src/video_display/decklink.cpp b/src/video_display/decklink.cpp index 19a907ce3..da1658463 100644 --- a/src/video_display/decklink.cpp +++ b/src/video_display/decklink.cpp @@ -122,6 +122,13 @@ using namespace std; namespace { class DeckLinkFrame; +struct audio_vals { + int64_t saved_sync_ts = INT64_MIN; + int64_t last_sync_ts = INT64_MIN; + int64_t last_sched_time = -1; + int64_t avg_diff = 0; +}; + /// Used for scheduled playback only class PlaybackDelegate : public IDeckLinkVideoOutputCallback // , public IDeckLinkAudioOutputCallback { @@ -138,8 +145,7 @@ class PlaybackDelegate : public IDeckLinkVideoOutputCallback // , public IDeckLi DeckLinkFrame *lastSchedFrame{}; long schedSeq{}; atomic m_audio_sync_ts = INT64_MIN; - int64_t m_last_sched_audio_time = -1; - int64_t m_avg_diff = 0; + struct audio_vals m_adata; public: int m_preroll = DEFAULT_SCHED_PREROLL_FRMS; @@ -376,8 +382,6 @@ void PlaybackDelegate::Reset() } schedSeq = 0; m_audio_sync_ts = INT64_MIN; - m_last_sched_audio_time = -1; - m_avg_diff = 0; } bool PlaybackDelegate::EnqueueFrame(DeckLinkFrame *deckLinkFrame) @@ -1572,34 +1576,43 @@ static bool display_decklink_get_property(void *state, int property, void *val, */ void PlaybackDelegate::ScheduleAudio(const struct audio_frame *frame, uint32_t *const samples) { - if (m_audio_sync_ts == INT64_MIN) { - return; + if (m_adata.saved_sync_ts == INT64_MIN && + m_audio_sync_ts == INT64_MIN) { + return; + } + if (m_adata.saved_sync_ts != m_audio_sync_ts && + m_audio_sync_ts != INT64_MIN) { + m_adata = audio_vals{}; + m_adata.last_sync_ts = + m_adata.saved_sync_ts = m_audio_sync_ts; } - int64_t audio_sync_ts = m_audio_sync_ts; - if (frame->timestamp < audio_sync_ts) { // wrap-around - audio_sync_ts -= (1LLU << 32); - m_audio_sync_ts = audio_sync_ts; + + if (frame->timestamp < m_adata.last_sync_ts) { // wrap-around + m_adata.last_sync_ts -= (1LLU << 32); } - BMDTimeValue streamTime = ((int64_t) frame->timestamp - audio_sync_ts) * - bmdAudioSampleRate48kHz / 90000; + BMDTimeValue streamTime = + ((int64_t) frame->timestamp - m_adata.last_sync_ts) * + bmdAudioSampleRate48kHz / 90000; // normalize audio start if the input is not properly timestamped // (everything except vidcap testcard and decklink). - const int64_t diff = llabs(streamTime - m_last_sched_audio_time); - const int64_t avg_diff = (m_avg_diff * 39 + diff) / 40; - if (avg_diff >= 50 && m_last_sched_audio_time >= 0) { + const int64_t diff = m_adata.last_sched_time != -1 + ? llabs(streamTime - m_adata.last_sched_time) + : 0; + const int64_t avg_diff = (m_adata.avg_diff * 39 + diff) / 40; + if (avg_diff >= 50 && m_adata.last_sched_time >= 0) { log_msg_once(LOG_LEVEL_WARNING, 0x61c30d43, "Stream discontinuity, auto-" "adjusting audio time. If this is " "an unsynchronized stream, do not " "use synchronized output.\n"); - streamTime = m_last_sched_audio_time; + streamTime = m_adata.last_sched_time; } if (diff < 2000) { // do not store Martians - m_avg_diff = avg_diff; + m_adata.avg_diff = avg_diff; } - m_last_sched_audio_time = streamTime + *samples; + m_adata.last_sched_time = streamTime + *samples; LOG(LOG_LEVEL_DEBUG) << MOD_NAME << "streamTime: " << streamTime << "; timestamp: " << frame->timestamp << "; sync TS: " << m_audio_sync_ts << "\n";