FF card AV sync problems, possible fix to VDR

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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;


[Index of Archives]     [Linux Media]     [Asterisk]     [DCCP]     [Netdev]     [Xorg]     [Util Linux NG]     [Xfree86]     [Big List of Linux Books]     [Fedora Users]     [Fedora Women]     [ALSA Devel]     [Linux USB]

  Powered by Linux