Mailing List archive

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

[vdr] [PATCH] replay MPEG1 video with vdr 1.3.19



Hi,
as Stefan Hagendorn wrote in another thread, vdr 1.3.18 & 1.3.19
are no longer capable of playing MPEG1 videos.

This is mainly because vdr assumes that a PES packet allways has
the size 6+data[4]*256+data[5], but this is not true for some
MPEG1 packets.

The attached patch brings back MPEG1 capability.

Regards.

-- 
Stefan Huelswitt
s.huelswitt@gmx.de  | http://www.muempf.de/
--- vdr-1.3.19-orig/device.c	2005-01-23 16:41:05.000000000 +0100
+++ vdr-1.3.19/device.c	2005-02-06 14:45:04.000000000 +0100
@@ -31,7 +31,8 @@
 public:
   cPesAssembler(void);
   ~cPesAssembler();
-  int ExpectedLength(void) { return data[4] * 256 + data[5] + 6; }
+  int ExpectedLength(void) { return PacketSize(data); }
+  static int PacketSize(const uchar *data);
   int Length(void) { return length; }
   const uchar *Data(void) { return data; }
   void Reset(void);
@@ -100,6 +101,48 @@
      }
 }
 
+int cPesAssembler::PacketSize(const uchar *data)
+{
+  // we need atleast 6 bytes of data here !!!
+  switch(data[3]) {
+    default:
+    // video stream start codes
+    case 0x00 ... 0xB8:
+    // Program end
+    case 0xB9:
+    // Programm stream map
+    case 0xBC:
+    // reserved
+    case 0xF0 ... 0xFF:
+      return 6;
+
+    // Pack header
+    case 0xBA:
+      if((data[4]&0xC0)==0x40) // MPEG2
+        return 14;
+        // to be absolutely correct we would have to add the stuffing bytes
+        // as well, but at this point we only may have 6 bytes of data avail-
+        // able. So it's up to the higher level to resync...
+        //return 14+(data[13]&0x07); // add stuffing bytes
+      else // MPEG1
+        return 12;
+
+    // System header
+    case 0xBB:
+    // Private stream1
+    case 0xBD:
+    // Padding stream
+    case 0xBE:
+    // Private stream2 (navigation data)
+    case 0xBF:
+    // all the rest (the real packets)
+    case 0xC0 ... 0xCF:
+    case 0xD0 ... 0xDF:
+    case 0xE0 ... 0xEF:
+      return 6+data[4]*256+data[5];
+    }
+}
+
 // --- cDevice ---------------------------------------------------------------
 
 // The default priority for non-primary devices:
@@ -832,6 +877,7 @@
         int w = d;
         switch (c) {
           case 0xE0 ... 0xEF: // video
+          case 0xBE:          // padding stream, needed for MPEG1
                w = PlayVideo(Start, d);
                break;
           case 0xC0 ... 0xDF: // audio
@@ -924,7 +970,7 @@
   int i = 0;
   while (i <= Length - 6) {
         if (Data[i] == 0x00 && Data[i + 1] == 0x00 && Data[i + 2] == 0x01) {
-           int l = Data[i + 4] * 256 + Data[i + 5] + 6;
+           int l = cPesAssembler::PacketSize(&Data[i]);
            if (i + l > Length) {
               // Store incomplete PES packet for later completion:
               pesAssembler->Put(Data + i, Length - i);

Home | Main Index | Thread Index