mirror of
https://github.com/outbackdingo/UltraGrid.git
synced 2026-03-21 16:40:18 +00:00
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.
This commit is contained in:
@@ -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<int64_t> 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;
|
||||
}
|
||||
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 (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;
|
||||
}
|
||||
BMDTimeValue streamTime = ((int64_t) frame->timestamp - audio_sync_ts) *
|
||||
bmdAudioSampleRate48kHz / 90000;
|
||||
|
||||
if (frame->timestamp < m_adata.last_sync_ts) { // wrap-around
|
||||
m_adata.last_sync_ts -= (1LLU << 32);
|
||||
}
|
||||
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";
|
||||
|
||||
Reference in New Issue
Block a user