VDR-1.3.44: speedup patch for cRemux::ScanVideoPacket()

Message ID 441D8E26.6070208@gmx.de
State New
Headers

Commit Message

Reinhard Nissl March 19, 2006, 5 p.m. UTC
  Hi,

the attached patch speeds up ScanVideoPacket() in two ways:

- finding the start code is done by memchr(), which was the major change 
for the cVideoRepacker speedup patches some VDR versions ago.

- ScanVideoPacket() may skip scanning the packets most of the time when 
cVideoRepacker is enabled (see source comments for details).

As a result, the CPU load of my EPIA system with a 600 MHz CPU drops 
from 27 % to 17 % for receiving the 'ASTRA HD' HDTV demo channel.

Besides the mentioned improvements, I've declared ScanVideoPacket() and 
GetPacketLength() static and pubic, as I'd like to use their 
functionality in future versions of vdr-xine.

Bye.
  

Patch

--- ../vdr-1.3.44-orig/remux.h	2005-08-26 15:22:19.000000000 +0200
+++ remux.h	2006-03-19 17:42:40.000000000 +0100
@@ -46,8 +48,6 @@  private:
   cRingBufferLinear *resultBuffer;
   int resultSkipped;
   int GetPid(const uchar *Data);
-  int GetPacketLength(const uchar *Data, int Count, int Offset);
-  int ScanVideoPacket(const uchar *Data, int Count, int Offset, uchar &PictureType);
 public:
   cRemux(int VPid, const int *APids, const int *DPids, const int *SPids, bool ExitOnFailure = false);
        ///< Creates a new remuxer for the given PIDs. VPid is the video PID, while
@@ -79,6 +80,8 @@  public:
        ///< Clears the remuxer of all data it might still contain, keeping the PID
        ///< settings as they are.
   static void SetBrokenLink(uchar *Data, int Length);
+  static int GetPacketLength(const uchar *Data, int Count, int Offset);
+  static int ScanVideoPacket(const uchar *Data, int Count, int Offset, uchar &PictureType);
   };
 
 #endif // __REMUX_H
--- ../vdr-1.3.44-orig/remux.c	2006-02-03 17:19:02.000000000 +0100
+++ remux.c	2006-03-19 13:33:29.000000000 +0100
@@ -1429,7 +1821,9 @@  int cDolbyRepacker::BreakAt(const uchar 
 #define IPACKS 2048
 
 // Start codes:
-#define SC_PICTURE 0x00  // "picture header"
+#define SC_SEQUENCE 0xB3  // "sequence header code"
+#define SC_GROUP    0xB8  // "group start code"
+#define SC_PICTURE  0x00  // "picture start code"
 
 #define MAXNONUSEFULDATA (10*1024*1024)
 #define MAXNUMUPTERRORS  10
@@ -1925,14 +2327,38 @@  int cRemux::ScanVideoPacket(const uchar 
   if (Length > 0) {
      int PesPayloadOffset = 0;
      if (AnalyzePesHeader(Data + Offset, Length, PesPayloadOffset) >= phMPEG1) {
-        for (int i = Offset + PesPayloadOffset; i < Offset + Length - 5; i++) {
-            if (Data[i] == 0 && Data[i + 1] == 0 && Data[i + 2] == 1) {
-               switch (Data[i + 3]) {
-                 case SC_PICTURE: PictureType = (Data[i + 5] >> 3) & 0x07;
-                                  return Length;
+        const uchar *p = Data + Offset + PesPayloadOffset + 2;
+        const uchar *pLimit = Data + Offset + Length - 3;
+#ifdef TEST_cVideoRepacker
+        // cVideoRepacker ensures that a new PES packet is started for a new sequence,
+        // group or picture which allows us to easily skip scanning through a huge
+        // amount of video data.
+        if (p < pLimit) {
+           if (p[-2] || p[-1] || p[0] != 0x01)
+              pLimit = 0; // skip scanning: packet doesn't start with 0x000001
+           else {
+              switch (p[1]) {
+                case SC_SEQUENCE:
+                case SC_GROUP:
+                case SC_PICTURE:
+                     break;
+                default: // skip scanning: packet doesn't start a new sequence, group or picture
+                     pLimit = 0;
+                }
+              }
+           }
+#endif
+        while (p < pLimit && (p = (const uchar *)memchr(p, 0x01, pLimit - p))) {
+              if (!p[-2] && !p[-1]) { // found 0x000001
+                 switch (p[1]) {
+                   case SC_PICTURE: PictureType = (p[3] >> 3) & 0x07;
+                                    return Length;
+                   }
+                 p += 4; // continue scanning after 0x01ssxxyy
                  }
-               }
-            }
+              else
+                 p += 3; // continue scanning after 0x01xxyy
+              }
         }
      PictureType = NO_PICTURE;
      return Length;