[PATCH] fix: pullup pattern correction fails with certain OGM files

  Thread Rating:
  • 0 Votes - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Post Reply
Shine Offline
Member
Posts: 51
Joined: Apr 2012
Reputation: 1
Post: #1
Issue: With some OGM files - for example containing XviD with packed bitstream - pullup pattern corrections fails, causing heavily choppy playback. Detailed description and debug log see here.

Cause: Some frames are returned with an incorrect pts (ie. earlier than the preceding frame), resulting in negative frame duration which confuses CPullupCorrection. I assume that the broken pts is returned by the decoder or demuxer.

Fix: When encountering an obviously broken pts, replace it with a proper/better one calculated from the stream's frame rate.

Please review and comment.

Patch:
Code:
---
xbmc/cores/dvdplayer/DVDPlayerVideo.cpp  |    4 ++++
xbmc/cores/dvdplayer/DVDTSCorrection.cpp |    6 ++++++
xbmc/cores/dvdplayer/DVDTSCorrection.h   |    2 +-
3 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
index 64f08df..5590044 100644
--- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
@@ -1141,6 +1141,10 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts)
   if(m_fFrameRate * abs(m_speed) / DVD_PLAYSPEED_NORMAL > maxfps*0.9)
     limited = true;

+  // decoder/demuxer might return an incorrect timestamp that will
+  // cause pattern detection to fail, so we ignore an obviously broken pts
+  // and use the given frame rate to calculate a better one instead
+  pts = m_pullupCorrection.GetPlausiblePTS(pts,m_fFrameRate);
   //correct any pattern in the timestamps
   m_pullupCorrection.Add(pts);
   pts += m_pullupCorrection.GetCorrection();
diff --git a/xbmc/cores/dvdplayer/DVDTSCorrection.cpp b/xbmc/cores/dvdplayer/DVDTSCorrection.cpp
index 20d40e6..08d85b5 100644
--- a/xbmc/cores/dvdplayer/DVDTSCorrection.cpp
+++ b/xbmc/cores/dvdplayer/DVDTSCorrection.cpp
@@ -48,6 +48,12 @@ void CPullupCorrection::Flush()
   m_trackingpts   = DVD_NOPTS_VALUE;
}

+double CPullupCorrection::GetPlausiblePTS(double pts, double framerate)
+{
+    if (m_prevpts != DVD_NOPTS_VALUE && pts < m_prevpts) return  m_prevpts + 1000000 / framerate;
+    else return pts;
+}
+
void CPullupCorrection::Add(double pts)
{
   //can't get a diff with just one pts
diff --git a/xbmc/cores/dvdplayer/DVDTSCorrection.h b/xbmc/cores/dvdplayer/DVDTSCorrection.h
index ded74b2..f975aba 100644
--- a/xbmc/cores/dvdplayer/DVDTSCorrection.h
+++ b/xbmc/cores/dvdplayer/DVDTSCorrection.h
@@ -31,7 +31,7 @@ class CPullupCorrection
     CPullupCorrection();
     void   Add(double pts);
     void   Flush(); //flush the saved pattern and the ringbuffer
-
+    double GetPlausiblePTS(double pts, double framerate);
     double GetCorrection()    { return m_ptscorrection;            }
     int    GetPatternLength() { return m_patternlength;            }
     double GetFrameDuration() { return m_frameduration;            }
--
Patched against 2fdc4dfac3 (2012-04-22)
find quote
bobo1on1 Offline
cheapass Team-XBMC Developer
Posts: 2,758
Joined: Dec 2008
Reputation: 22
Post: #2
I'll look into it.
find quote
Robotica Offline
Banned
Posts: 1,202
Joined: Aug 2010
Post: #3
it seems to be lost...
find quote