Framerates

Message ID 4D19B6D0.9090303@tvdr.de
State New
Headers

Commit Message

Klaus Schmidinger Dec. 28, 2010, 10:07 a.m. UTC
  On 28.12.2010 00:30, Tobias Grimm wrote:
> Am Dienstag, den 28.12.2010, 00:01 +0100 schrieb Christopher Reimer:
> 
>> That's a Bug in VDR. Klaus already posted a quick'n'dirty bugfix here
>> -> http://vdr-portal.de/board/thread.php?postid=951626#post951626
> 
> Ah, ok - Thx!

Actually the complete fix is in the attached patch.

Klaus
  

Patch

--- remux.h	2010/06/05 13:27:55	2.26
+++ remux.h	2010/11/01 11:24:20	2.27
@@ -347,12 +347,10 @@ 
   int numPtsValues;
   int numIFrames;
   bool isVideo;
-  int frameDuration;
+  double framesPerSecond;
   int framesInPayloadUnit;
   int framesPerPayloadUnit; // Some broadcasters send one frame per 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;
+                            // while others put an entire GOP into one payload unit (> 1).
   bool scanning;
   uint32_t scanner;
 public:
@@ -380,7 +378,7 @@ 
       ///< Returns true if a new frame was detected and this is an independent frame
       ///< (i.e. one that can be displayed by itself, without using data from any
       ///< other frames).
-  double FramesPerSecond(void) { return frameDuration ? 90000.0 / frameDuration : 0; }
+  double FramesPerSecond(void) { return framesPerSecond; }
       ///< Returns the number of frames per second, or 0 if this information is not
       ///< available.
   };
--- remux.c	2010/06/05 13:32:15	2.47
+++ remux.c	2010/11/01 12:29:17	2.48
@@ -780,9 +780,8 @@ 
   newFrame = independentFrame = false;
   numPtsValues = 0;
   numIFrames = 0;
-  frameDuration = 0;
+  framesPerSecond = 0;
   framesInPayloadUnit = framesPerPayloadUnit = 0;
-  payloadUnitOfFrame = 0;
   scanning = false;
   scanner = EMPTY_SCANNER;
 }
@@ -804,7 +803,6 @@ 
 void cFrameDetector::Reset(void)
 {
   newFrame = independentFrame = false;
-  payloadUnitOfFrame = 0;
   scanning = false;
   scanner = EMPTY_SCANNER;
 }
@@ -831,8 +829,8 @@ 
                     return Processed;
                  if (Length < MIN_TS_PACKETS_FOR_FRAME_DETECTOR * TS_SIZE)
                     return Processed; // need more data, in case the frame type is not stored in the first TS packet
-                 if (!frameDuration) {
-                    // frame duration unknown, so collect a sequence of PTS values:
+                 if (!framesPerSecond) {
+                    // frame rate unknown, so collect a sequence of PTS values:
                     if (numPtsValues < MaxPtsValues && numIFrames < 2) { // collect a sequence containing at least two I-frames
                        const uchar *Pes = Data + TsPayloadOffset(Data);
                        if (PesHasPts(Pes)) {
@@ -857,28 +855,22 @@ 
                        uint32_t Delta = ptsValues[0];
                        // determine frame info:
                        if (isVideo) {
-                          if (Delta % 3600 == 0)
-                             frameDuration = 3600; // PAL, 25 fps, exact timing
-                          else if (abs(Delta % 3600) == 3599 || abs(Delta % 3600) == 1)
-                             frameDuration = 3600; // PAL, 25 fps, timing with jitter
+                          if (abs(Delta - 3600) <= 1)
+                             framesPerSecond = 25.0;
                           else if (Delta % 3003 == 0)
-                             frameDuration = 3003; // NTSC, 29.97 fps
-                          else if (abs(Delta - 1800) <= 1) {
-                             frameDuration = 3600; // PAL, 25 fps
-                             framesPerPayloadUnit = -2;
-                             }
-                          else if (Delta == 1501) {
-                             frameDuration = 3003; // NTSC, 29.97 fps
-                             framesPerPayloadUnit = -2;
-                             }
+                             framesPerSecond = 30.0 / 1.001;
+                          else if (abs(Delta - 1800) <= 1)
+                             framesPerSecond = 50.0;
+                          else if (Delta == 1501)
+                             framesPerSecond = 60.0 / 1.001;
                           else {
-                             frameDuration = 3600; // unknown, assuming 25 fps
-                             dsyslog("unknown frame duration (%d), assuming 25 fps", Delta);
+                             framesPerSecond = 25.0;
+                             dsyslog("unknown frame delta (%d), assuming 25 fps", Delta);
                              }
                           }
                        else // audio
-                          frameDuration = Delta; // PTS of audio frames is always increasing
-                       dbgframes("\nframe duration = %d  FPS = %5.2f  FPPU = %d\n", frameDuration, 90000.0 / frameDuration, framesPerPayloadUnit);
+                          framesPerSecond = 90000.0 / Delta; // PTS of audio frames is always increasing
+                       dbgframes("\nDelta = %d  FPS = %5.2f  FPPU = %d\n", Delta, framesPerSecond, framesPerPayloadUnit);
                        }
                     }
                  scanner = EMPTY_SCANNER;
@@ -927,13 +919,6 @@ 
                                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;
                                   }
@@ -964,7 +949,7 @@ 
                                 pid = 0; // let's just ignore any further data
                        }
                      }
-                 if (!synced && frameDuration && independentFrame) {
+                 if (!synced && framesPerSecond && independentFrame) {
                     synced = true;
                     dbgframes("*");
                     Reset();