aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRainer Hochecker <fernetmenta@online.de>2015-04-10 21:04:00 +0200
committerRainer Hochecker <fernetmenta@online.de>2015-04-12 15:58:08 +0200
commitdb7b0521135084331aee2e486d6dc372683a10e1 (patch)
tree5c66be22d39fddd316140b939dcf2014229276ee
parent1549e4e19ab23f9801ce847a868ce2ad447df67e (diff)
dvdplayer: improve audio sync for large packet durations
-rw-r--r--xbmc/cores/dvdplayer/DVDPlayerAudio.cpp28
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)
{