Mailing List archive

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

[vdr] Re: SPEEDUP: processing audio in transfer thread



Hi,

C.Y.M. wrote:

I tried this second patch but it doesn't appear to have any affect on the
Audio/Video desync issues when playing back recorded shows while using a
Nexus card. As for the first patch, it must have just been a coincidence
that the A/V seemed better. I have tried replaying the recorded shows again
and now I'm seeing the same problems.  After much discussion on this topic
with friends, I am really starting to believe that this A/V desync issue is
a result of variable frame rates in the data stream and VDR not being able
to self adjust to the changes.
I'm sorry that the patch didn't help.

I've finally created a third release of the patch, where filling the padding frame with the padding byte is turned of by default to save the memset() calls.

If somebody needs a stream which adheres to the specification, the memset() calls can be enabled by defining

FILL_PADDING_PACKET_WITH_PADDING_BYTE

in transfer.c and dvbplayer.c.

Bye.
--
Dipl.-Inform. (FH) Reinhard Nissl
mailto:rnissl@gmx.de
diff -Nurp vdr-1.3.11-orig/dvbplayer.c vdr-1.3.11-patched/dvbplayer.c
--- vdr-1.3.11-orig/dvbplayer.c	2004-06-19 10:55:49.000000000 +0200
+++ vdr-1.3.11-patched/dvbplayer.c	2004-06-27 21:39:27.242089000 +0200
@@ -15,6 +15,8 @@
 #include "thread.h"
 #include "tools.h"
 
+//#define FILL_PADDING_PACKET_WITH_PADDING_BYTE 1 // adhere to specification (needs more CPU power)
+
 // --- cBackTrace ----------------------------------------------------------
 
 #define AVG_FRAME_SIZE 15000         // an assumption about the average frame size
@@ -202,7 +204,7 @@ private:
   cFrame *playFrame;
   void TrickSpeed(int Increment);
   void Empty(void);
-  void StripAudioPackets(uchar *b, int Length, uchar Except = 0x00);
+  bool StripAudioPackets(uchar *b, int Length, uchar Except = 0x00);
   bool NextFile(uchar FileNumber = 0, int FileOffset = -1);
   int Resume(void);
   bool Save(void);
@@ -314,7 +316,7 @@ void cDvbPlayer::Empty(void)
   firstPacket = true;
 }
 
-void cDvbPlayer::StripAudioPackets(uchar *b, int Length, uchar Except)
+bool cDvbPlayer::StripAudioPackets(uchar *b, int Length, uchar Except)
 {
   if (index) {
      for (int i = 0; i < Length - 6; i++) {
@@ -329,8 +331,14 @@ void cDvbPlayer::StripAudioPackets(uchar
               case 0xC0 ... 0xC1: // audio
                    if (c == 0xC1)
                       canToggleAudioTrack = true;
-                   if (!Except || c != Except)
-                      memset(&b[i], 0x00, min(l, Length-i));
+                   if (!Except || c != Except) {
+                      if (i == 0 && l == Length) 
+                         return true; // drop complete frame
+                      b[ i + 3 ] = 0xBE; // padding stream
+#ifdef FILL_PADDING_PACKET_WITH_PADDING_BYTE
+                      memset(&b[i + 6], 0xFF, min(l, Length-i)-6);
+#endif
+                      }
                    break;
               case 0xE0 ... 0xEF: // video
                    break;
@@ -347,6 +355,7 @@ void cDvbPlayer::StripAudioPackets(uchar
             XXX*/
          }
      }
+  return false;
 }
 
 bool cDvbPlayer::NextFile(uchar FileNumber, int FileOffset)
@@ -481,9 +496,14 @@ void cDvbPlayer::Action(void)
                  int r = nonBlockingFileReader->Read(replayFile, b, Length);
                  if (r > 0) {
                     if (AudioTrack == 0)
-                       StripAudioPackets(b, r);
-                    readFrame = new cFrame(b, -r, ftUnknown, readIndex); // hands over b to the ringBuffer
-                    b = NULL;
+                       if (StripAudioPackets(b, r)) {
+                          free(b); //drop complete frame
+                          b = NULL;
+                          }
+                    if (b) {
+                       readFrame = new cFrame(b, -r, ftUnknown, readIndex); // hands over b to the ringBuffer
+                       b = NULL;
+                       }
                     }
                  else if (r == 0)
                     eof = true;
@@ -523,7 +543,10 @@ void cDvbPlayer::Action(void)
                        firstPacket = false;
                        }
                     if (AudioTrack > 0)
-                       StripAudioPackets(p, pc, AudioTrack);
+                       if (StripAudioPackets(p, pc, AudioTrack)) {
+                          p = NULL; // drop complete frame
+                          pc = 0;
+                          }
                     }
                  }
               if (p) {
@@ -719,8 +742,8 @@ void cDvbPlayer::Goto(int Index, bool St
         if (r > 0) {
            if (playMode == pmPause)
               DevicePlay();
-           StripAudioPackets(b, r);
-           DeviceStillPicture(b, r);
+           if (!StripAudioPackets(b, r))
+              DeviceStillPicture(b, r);
            }
         playMode = pmStill;
         }
diff -Nurp vdr-1.3.11-orig/transfer.c vdr-1.3.11-patched/transfer.c
--- vdr-1.3.11-orig/transfer.c	2004-03-07 15:40:15.000000000 +0100
+++ vdr-1.3.11-patched/transfer.c	2004-06-27 12:52:46.000000000 +0200
@@ -12,6 +12,7 @@
 // (must be larger than MINVIDEODATA - see remux.h)
 #define VIDEOBUFSIZE  MEGABYTE(1)
 #define POLLTIMEOUTS_BEFORE_DEVICECLEAR 3
+//#define FILL_PADDING_PACKET_WITH_PADDING_BYTE 1 // adhere to specification (needs more CPU power)
 
 // --- cTransfer -------------------------------------------------------------
 
@@ -96,7 +99,8 @@ void cTransfer::Action(void)
            uchar *p = remux->Process(b, Count, Result);
            ringBuffer->Del(Count);
            if (p) {
-              StripAudioPackets(p, Result, audioTrack);
+              if (StripAudioPackets(p, Result, audioTrack))
+                 continue; // drop complete frame
               while (Result > 0 && active) {
                     cPoller Poller;
                     if (DevicePoll(Poller, 100)) {
@@ -126,7 +130,7 @@ void cTransfer::Action(void)
         }
 }
 
-void cTransfer::StripAudioPackets(uchar *b, int Length, uchar Except)
+bool cTransfer::StripAudioPackets(uchar *b, int Length, uchar Except)
 {
   for (int i = 0; i < Length - 6; i++) {
       if (b[i] == 0x00 && b[i + 1] == 0x00 && b[i + 2] == 0x01) {
@@ -140,8 +144,14 @@ void cTransfer::StripAudioPackets(uchar 
            case 0xC0 ... 0xC1: // audio
                 if (c == 0xC1)
                    canToggleAudioTrack = true;
-                if (!Except || c != Except)
-                   memset(&b[i], 0x00, min(l, Length-i));
+                if (!Except || c != Except) {
+                   if (i == 0 && l == Length)
+                      return true; // drop complete frame
+                   b[ i + 3 ] = 0xBE; // padding stream
+#ifdef FILL_PADDING_PACKET_WITH_PADDING_BYTE
+                   memset(&b[i + 6], 0xFF, min(l, Length-i)-6);
+#endif
+                   }
                 break;
            case 0xE0 ... 0xEF: // video
                 break;
@@ -157,6 +167,7 @@ void cTransfer::StripAudioPackets(uchar 
          esyslog("ERROR: broken packet header");
          XXX*/
       }
+  return false;
 }
 
 int cTransfer::NumAudioTracks(void) const
diff -Nurp vdr-1.3.11-orig/transfer.h vdr-1.3.11-patched/transfer.h
--- vdr-1.3.11-orig/transfer.h	2003-05-11 10:48:36.000000000 +0200
+++ vdr-1.3.11-patched/transfer.h	2004-06-23 21:43:56.000000000 +0200
@@ -24,7 +24,7 @@ private:
   uchar audioTrack;
   bool gotBufferReserve;
   bool active;
-  void StripAudioPackets(uchar *b, int Length, uchar Except = 0x00);
+  bool StripAudioPackets(uchar *b, int Length, uchar Except = 0x00);
 protected:
   virtual void Activate(bool On);
   virtual void Receive(uchar *Data, int Length);

Home | Main Index | Thread Index