From db7b0521135084331aee2e486d6dc372683a10e1 Mon Sep 17 00:00:00 2001 From: Rainer Hochecker Date: Fri, 10 Apr 2015 21:04:00 +0200 Subject: dvdplayer: improve audio sync for large packet durations --- xbmc/cores/dvdplayer/DVDPlayerAudio.cpp | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp b/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp index 2f83d655b5..8b96e05139 100644 --- a/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp +++ b/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp @@ -757,8 +757,24 @@ bool CDVDPlayerAudio::OutputPacket(DVDAudioFrame &audioframe) double clock = m_pClock->GetClock(absolute); double error = m_dvdAudio.GetPlayingPts() - clock; m_dvdAudio.SetResampleRatio(1.0); - if (error > 0) + + // sync audio by skipping or dropping frames if we are above or + // below a given threshold. the constants are aligned with known + // durations: DTS = 11ms, AC3 = 32ms + // during this stage audio is muted + if (error > DVD_MSEC_TO_TIME(10)) { + unsigned int nb_frames = audioframe.nb_frames; + double duration = audioframe.duration; + + // reduce large packets for better sync, i.e. FLAC can have 96ms packets + // 32ms because I know this works good for AC3 + if (audioframe.duration > DVD_MSEC_TO_TIME(32) && audioframe.sample_rate) + { + audioframe.nb_frames = 0.032 * audioframe.sample_rate; + audioframe.duration = ((double)audioframe.nb_frames * DVD_TIME_BASE) / audioframe.sample_rate; + } + int dups = std::min(DVD_MSEC_TO_TIME(100), error) / audioframe.duration; if (dups > 0) CLog::Log(LOGNOTICE,"CDVDPlayerAudio::OutputPacket duplicate %d packets of duration %d", @@ -767,14 +783,22 @@ bool CDVDPlayerAudio::OutputPacket(DVDAudioFrame &audioframe) { m_dvdAudio.AddPackets(audioframe); } + + audioframe.nb_frames = nb_frames; + audioframe.duration = duration; + m_dvdAudio.AddPackets(audioframe); } - else + else if (error < -DVD_MSEC_TO_TIME(32)) { m_dvdAudio.SetPlayingPts(audioframe.pts); CLog::Log(LOGNOTICE,"CDVDPlayerAudio::OutputPacket skipping a packets of duration %d", DVD_TIME_TO_MSEC(audioframe.duration)); } + else + { + m_dvdAudio.AddPackets(audioframe); + } } else if (m_synctype == SYNC_DISCON) { -- cgit v1.2.3 From 0ebd21ba547568d761cd3e9b2e5fefe2154fff47 Mon Sep 17 00:00:00 2001 From: Rainer Hochecker Date: Sun, 12 Apr 2015 15:54:49 +0200 Subject: AE: flush resampler when flushing buffers --- xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEBuffer.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEBuffer.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEBuffer.cpp index daa242a912..b8b1485f58 100644 --- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEBuffer.cpp +++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEBuffer.cpp @@ -415,4 +415,6 @@ void CActiveAEBufferPoolResample::Flush() m_outputSamples.front()->Return(); m_outputSamples.pop_front(); } + if (m_resampler) + ChangeResampler(); } -- cgit v1.2.3 From bfa955a5eac113e5ca0fbb59f37dcc387e045691 Mon Sep 17 00:00:00 2001 From: Rainer Hochecker Date: Sun, 12 Apr 2015 15:56:57 +0200 Subject: dvdplayer audio: proper handle resume if playspeed is already normal --- xbmc/cores/dvdplayer/DVDPlayerAudio.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp b/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp index 8b96e05139..74df969217 100644 --- a/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp +++ b/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp @@ -435,8 +435,11 @@ int CDVDPlayerAudio::DecodeFrame(DVDAudioFrame &audioframe) if (speed == DVD_PLAYSPEED_NORMAL) { - m_dvdAudio.Resume(); - m_syncclock = true; + if (speed != m_speed) + { + m_dvdAudio.Resume(); + m_syncclock = true; + } } else { -- cgit v1.2.3