diff options
author | Rainer Hochecker <fernetmenta@online.de> | 2015-04-10 21:04:00 +0200 |
---|---|---|
committer | Rainer Hochecker <fernetmenta@online.de> | 2015-04-12 15:58:08 +0200 |
commit | db7b0521135084331aee2e486d6dc372683a10e1 (patch) | |
tree | 5c66be22d39fddd316140b939dcf2014229276ee | |
parent | 1549e4e19ab23f9801ce847a868ce2ad447df67e (diff) |
dvdplayer: improve audio sync for large packet durations
-rw-r--r-- | xbmc/cores/dvdplayer/DVDPlayerAudio.cpp | 28 |
1 files 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) { |