===================================================================
RCS file: ./RCS/remux.c
retrieving revision 2.52
diff -u -b -r2.52 ./remux.c
--- ./remux.c	2011/03/13 13:57:09	2.52
+++ ./remux.c	2011/03/20 10:05:34
@@ -17,7 +17,7 @@
 
 // Set these to 'true' for debug output:
 static bool DebugPatPmt = false;
-static bool DebugFrames = false;
+static bool DebugFrames = true;//XXX false;
 
 #define dbgpatpmt(a...) if (DebugPatPmt) fprintf(stderr, a)
 #define dbgframes(a...) if (DebugFrames) fprintf(stderr, a)
@@ -783,9 +783,11 @@
   synced = false;
   newFrame = independentFrame = false;
   numPtsValues = 0;
+  numFrames = 0;
   numIFrames = 0;
   framesPerSecond = 0;
   framesInPayloadUnit = framesPerPayloadUnit = 0;
+  payloadUnitOfFrame = 0;
   scanning = false;
   scanner = EMPTY_SCANNER;
 }
@@ -807,6 +809,7 @@
 void cFrameDetector::Reset(void)
 {
   newFrame = independentFrame = false;
+  payloadUnitOfFrame = 0;
   scanning = false;
   scanner = EMPTY_SCANNER;
 }
@@ -844,6 +847,7 @@
                              dbgframes("#");
                              numPtsValues = 0;
                              numIFrames = 0;
+                             numFrames = 0;
                              }
                           else
                              numPtsValues++;
@@ -863,9 +867,22 @@
                              framesPerSecond = 25.0;
                           else if (Delta % 3003 == 0)
                              framesPerSecond = 30.0 / 1.001;
-                          else if (abs(Delta - 1800) <= 1)
+                          else if (abs(Delta - 1800) <= 1) {
+                             if (numFrames > 50) {
+                                // this is a "best guess": if there are more than 50 frames between two I-frames, we assume each "frame" actually contains a "field", so two "fields" make one "frame"
+                                framesPerSecond = 25.0;
+                                framesPerPayloadUnit = -2;
+                                }
+                             else
                              framesPerSecond = 50.0;
+                             }
                           else if (Delta == 1501)
+                             if (numFrames > 50) {
+                                // this is a "best guess": if there are more than 50 frames between two I-frames, we assume each "frame" actually contains a "field", so two "fields" make one "frame"
+                                framesPerSecond = 30.0 / 1.001;
+                                framesPerPayloadUnit = -2;
+                                }
+                             else
                              framesPerSecond = 60.0 / 1.001;
                           else {
                              framesPerSecond = 25.0;
@@ -874,7 +891,7 @@
                           }
                        else // audio
                           framesPerSecond = 90000.0 / Delta; // PTS of audio frames is always increasing
-                       dbgframes("\nDelta = %d  FPS = %5.2f  FPPU = %d\n", Delta, framesPerSecond, framesPerPayloadUnit);
+                       dbgframes("\nDelta = %d  FPS = %5.2f  FPPU = %d NF = %d\n", Delta, framesPerSecond, framesPerPayloadUnit, numFrames);
                        }
                     }
                  scanner = EMPTY_SCANNER;
@@ -909,6 +926,8 @@
                                   framesInPayloadUnit++;
                                   if (independentFrame)
                                      numIFrames++;
+                                  if (numIFrames == 1)
+                                     numFrames++;
                                   dbgframes("%d ", (Data[i + 2] >> 3) & 0x07);
                                   }
                                if (synced)
@@ -923,6 +942,13 @@
                                newFrame = true;
                                independentFrame = Data[i + 1] == 0x10;
                                if (synced) {
+                                  if (framesPerPayloadUnit < 0) {
+                                     payloadUnitOfFrame = (payloadUnitOfFrame + 1) % -framesPerPayloadUnit;
+                                     if (payloadUnitOfFrame != 0 && independentFrame)
+                                        payloadUnitOfFrame = 0;
+                                     if (payloadUnitOfFrame)
+                                        newFrame = false;
+                                     }
                                   if (framesPerPayloadUnit <= 1)
                                      scanning = false;
                                   }
@@ -930,6 +956,8 @@
                                   framesInPayloadUnit++;
                                   if (independentFrame)
                                      numIFrames++;
+                                  if (numIFrames == 1)
+                                     numFrames++;
                                   dbgframes("%02X ", Data[i + 1]);
                                   }
                                if (synced)
@@ -955,7 +983,7 @@
                      }
                  if (!synced && framesPerSecond > 0.0 && independentFrame) {
                     synced = true;
-                    dbgframes("*");
+                    dbgframes("*\n");
                     Reset();
                     return Processed + TS_SIZE;
                     }
===================================================================
RCS file: ./RCS/remux.h
retrieving revision 2.27
diff -u -b -r2.27 ./remux.h
--- ./remux.h	2010/11/01 11:24:20	2.27
+++ ./remux.h	2011/03/19 16:52:46
@@ -345,12 +345,15 @@
   bool independentFrame;
   uint32_t ptsValues[MaxPtsValues]; // 32 bit is enough - we only need the delta
   int numPtsValues;
+  int numFrames;
   int numIFrames;
   bool isVideo;
   double framesPerSecond;
   int framesInPayloadUnit;
   int framesPerPayloadUnit; // Some broadcasters send one frame per payload unit (== 1),
-                            // while others put an entire GOP into one payload unit (> 1).
+                            // some put an entire GOP into one payload unit (> 1), and
+                            // some spread a single frame over several payload units (< 0).
+  int payloadUnitOfFrame;
   bool scanning;
   uint32_t scanner;
 public:
