summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--HISTORY4
-rw-r--r--remux.c40
-rw-r--r--remux.h7
3 files changed, 42 insertions, 9 deletions
diff --git a/HISTORY b/HISTORY
index 9451433c..ea57a04e 100644
--- a/HISTORY
+++ b/HISTORY
@@ -6557,8 +6557,10 @@ Video Disk Recorder Revision History
- The original display size of subtitles is now used to scale them properly when
displaying them on an HD OSD.
-2011-03-13: Version 1.7.18
+2011-03-20: Version 1.7.18
- Changed -O2 to -O3 in Make.config.template (reported by Matti Lehtimäki).
- Added a missing 'default' case in cPixmapMemory::DrawEllipse().
- Fixed some direct comparisons of double values.
+- Fixed detecting frames on channels that broadcast with separate "fields" instead
+ of complete frames.
diff --git a/remux.c b/remux.c
index afe9180e..f7ef87a9 100644
--- a/remux.c
+++ b/remux.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: remux.c 2.52 2011/03/13 13:57:09 kls Exp $
+ * $Id: remux.c 2.53 2011/03/20 10:21:14 kls Exp $
*/
#include "remux.h"
@@ -783,9 +783,11 @@ cFrameDetector::cFrameDetector(int Pid, int Type)
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::SetPid(int Pid, int Type)
void cFrameDetector::Reset(void)
{
newFrame = independentFrame = false;
+ payloadUnitOfFrame = 0;
scanning = false;
scanner = EMPTY_SCANNER;
}
@@ -844,6 +847,7 @@ int cFrameDetector::Analyze(const uchar *Data, int Length)
dbgframes("#");
numPtsValues = 0;
numIFrames = 0;
+ numFrames = 0;
}
else
numPtsValues++;
@@ -863,10 +867,23 @@ int cFrameDetector::Analyze(const uchar *Data, int Length)
framesPerSecond = 25.0;
else if (Delta % 3003 == 0)
framesPerSecond = 30.0 / 1.001;
- else if (abs(Delta - 1800) <= 1)
- framesPerSecond = 50.0;
+ 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)
- framesPerSecond = 60.0 / 1.001;
+ 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;
dsyslog("unknown frame delta (%d), assuming 25 fps", Delta);
@@ -874,7 +891,7 @@ int cFrameDetector::Analyze(const uchar *Data, int Length)
}
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 @@ int cFrameDetector::Analyze(const uchar *Data, int Length)
framesInPayloadUnit++;
if (independentFrame)
numIFrames++;
+ if (numIFrames == 1)
+ numFrames++;
dbgframes("%d ", (Data[i + 2] >> 3) & 0x07);
}
if (synced)
@@ -923,6 +942,13 @@ int cFrameDetector::Analyze(const uchar *Data, int Length)
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 @@ int cFrameDetector::Analyze(const uchar *Data, int Length)
framesInPayloadUnit++;
if (independentFrame)
numIFrames++;
+ if (numIFrames == 1)
+ numFrames++;
dbgframes("%02X ", Data[i + 1]);
}
if (synced)
@@ -955,7 +983,7 @@ int cFrameDetector::Analyze(const uchar *Data, int Length)
}
if (!synced && framesPerSecond > 0.0 && independentFrame) {
synced = true;
- dbgframes("*");
+ dbgframes("*\n");
Reset();
return Processed + TS_SIZE;
}
diff --git a/remux.h b/remux.h
index 7140aaf0..60a9a578 100644
--- a/remux.h
+++ b/remux.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: remux.h 2.27 2010/11/01 11:24:20 kls Exp $
+ * $Id: remux.h 2.28 2011/03/19 16:52:46 kls Exp $
*/
#ifndef __REMUX_H
@@ -345,12 +345,15 @@ private:
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: