[vdr] FF card AV sync problems, possible fix to VDR

Ville Rannikko mac at cc.hut.fi
Wed Jan 31 18:04:47 CET 2007


Hi!

The newest firmware for FF cards did not completely fix the AV desync problems 
for me. According to information from Werner the problem happens when small 
video frames fill the decoder buffer with over 2 seconds of data. So I made 
this patch for dvbplayer.c to stop it from uploading more PES frames to decoder 
when STC/PTS difference is more than 2 seconds. This seems to fix the remaining 
problems for me, but I have not tested it much. The PTS/STC-code has been 
mostly taken from the dvb-subtitles plugin. Comments, please

Ville

--- dvbplayer.c.orig	2007-01-31 18:21:42.000000000 +0200
+++ dvbplayer.c	2007-01-31 18:35:36.000000000 +0200
@@ -495,6 +495,51 @@
                       }
                    }
                if (p) {
+                 if(playMode == pmPlay && pc > 13)
+                   {
+                     int64_t stc = -1;
+                     int64_t pts = -1;
+
+                     if ( p[0] == 0x00 && p[1] == 0x00 && p[2] == 0x01)
+                       {
+                         if(p[7] & 0x80)
+                           {
+                             switch( p[3] )
+                               {
+                               case 0xE0 ... 0xEF: // video
+                               case 0xC0 ... 0xDF: // audio
+                                 pts  = (int64_t) (p[ 9] & 0x0E) << 29 ;
+                                 pts |= (int64_t)  p[ 10]         << 22 ;
+                                 pts |= (int64_t) (p[ 11] & 0xFE) << 14 ;
+                                 pts |= (int64_t)  p[ 12]         <<  7 ;
+                                 pts |= (int64_t) (p[ 13] & 0xFE) >>  1 ;
+                               }
+                           }
+                       }
+                     if(pts != -1)
+                       {
+                         cDevice *pd = cDevice::PrimaryDevice();
+                         if(pd)
+                           {
+                             stc = pd->GetSTC();
+                             if(stc != 0)
+                               {
+                                 if(pts & (int64_t)1<<32)
+                                   {
+                                     stc |= (int64_t)1<<32;
+                                   }
+                                 int64_t timeDiff = (pts-stc);
+                                 if (pts<stc)
+                                   {
+                                     timeDiff += (int64_t)1<<33;
+                                   }
+                                 timeDiff /= 90;
+                                 if(timeDiff > 2000)
+				   cCondWait::SleepMs(timeDiff - 2000);
+                               }
+			   }
+		       }
+		   }
                    int w = PlayPes(p, pc, playMode != pmPlay);
                    if (w > 0) {
                       p += w;



More information about the vdr mailing list