summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKlaus Schmidinger <vdr@tvdr.de>2014-01-25 14:37:05 +0100
committerKlaus Schmidinger <vdr@tvdr.de>2014-01-25 14:37:05 +0100
commitdd95f4ed61db236b5135129ca70e1315a89b71ca (patch)
tree0553a3bfc649881c27a2b0b7c318d7ba0652d3ec
parent6bd94489deb08ab5eed2e83cbb1f818295fd9a26 (diff)
downloadvdr-dd95f4ed61db236b5135129ca70e1315a89b71ca.tar.gz
vdr-dd95f4ed61db236b5135129ca70e1315a89b71ca.tar.bz2
Fixed detecting frame borders in MPEG-2 streams that have "bottom fields" or varying GOP structures
-rw-r--r--CONTRIBUTORS6
-rw-r--r--HISTORY2
-rw-r--r--remux.c30
3 files changed, 33 insertions, 5 deletions
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index 48ec1409..e6dce486 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -620,6 +620,8 @@ Helmut Auer <vdr@helmutauer.de>
command line option to be left empty to use the default values if only ENC shall be set
for reporting an inconsistent behavior between opening the Recordings menu manually
via the main menu and by pressing the Recordings key
+ for helping to debug a problem with frame detection in MPEG-2 streams that have "bottom fields"
+ or varying GOP structures
Jeremy Hall <jhall@UU.NET>
for fixing an incomplete initialization of the filter parameters in eit.c
@@ -3192,3 +3194,7 @@ Eike Edener <eike@edener.de>
Eike Sauer <EikeSauer@t-online.de>
for reporting a problem with channels that need more than 5 TS packets for detecting
frame borders
+
+Christian Paulick <cpaulick@xeatre.tv>
+ for reporting a problem with frame detection in MPEG-2 streams that have "bottom fields"
+ or varying GOP structures
diff --git a/HISTORY b/HISTORY
index aab6a0f3..73c35003 100644
--- a/HISTORY
+++ b/HISTORY
@@ -7878,4 +7878,6 @@ Video Disk Recorder Revision History
- Increased MIN_TS_PACKETS_FOR_FRAME_DETECTOR to 10 in order to be able to record
channels that need more than 5 TS packets for detecting frame borders (reported by
Eike Sauer).
+- Fixed detecting frame borders in MPEG-2 streams that have "bottom fields" or varying
+ GOP structures (reported by Christian Paulick, with help from Helmut Auer).
- Fixed a wrong alignment in cCiDateTime::SendDateTime().
diff --git a/remux.c b/remux.c
index 587d7e5c..15a5e44b 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.75 2013/03/03 10:37:58 kls Exp $
+ * $Id: remux.c 2.75.1.1 2014/01/25 14:37:05 kls Exp $
*/
#include "remux.h"
@@ -1004,6 +1004,7 @@ protected:
bool debug;
bool newFrame;
bool independentFrame;
+ int iFrameTemporalReferenceOffset;
public:
cFrameParser(void);
virtual ~cFrameParser() {};
@@ -1017,6 +1018,7 @@ public:
void SetDebug(bool Debug) { debug = Debug; }
bool NewFrame(void) { return newFrame; }
bool IndependentFrame(void) { return independentFrame; }
+ int IFrameTemporalReferenceOffset(void) { return iFrameTemporalReferenceOffset; }
};
cFrameParser::cFrameParser(void)
@@ -1024,6 +1026,7 @@ cFrameParser::cFrameParser(void)
debug = true;
newFrame = false;
independentFrame = false;
+ iFrameTemporalReferenceOffset = 0;
}
// --- cAudioParser ----------------------------------------------------------
@@ -1056,6 +1059,7 @@ class cMpeg2Parser : public cFrameParser {
private:
uint32_t scanner;
bool seenIndependentFrame;
+ int lastIFrameTemporalReference;
public:
cMpeg2Parser(void);
virtual int Parse(const uchar *Data, int Length, int Pid);
@@ -1065,6 +1069,7 @@ cMpeg2Parser::cMpeg2Parser(void)
{
scanner = EMPTY_SCANNER;
seenIndependentFrame = false;
+ lastIFrameTemporalReference = -1; // invalid
}
int cMpeg2Parser::Parse(const uchar *Data, int Length, int Pid)
@@ -1089,10 +1094,25 @@ int cMpeg2Parser::Parse(const uchar *Data, int Length, int Pid)
scanner = OldScanner;
return tsPayload.Used() - TS_SIZE;
}
+ uchar b1 = tsPayload.GetByte();
+ uchar b2 = tsPayload.GetByte();
+ int TemporalReference = (b1 << 2 ) + ((b2 & 0xC0) >> 6);
+ uchar FrameType = (b2 >> 3) & 0x07;
+ if (tsPayload.Find(0x000001B5)) { // Extension start code
+ if (((tsPayload.GetByte() & 0xF0) >> 4) == 0x08) { // Picture coding extension
+ tsPayload.GetByte();
+ uchar PictureStructure = tsPayload.GetByte() & 0x03;
+ if (PictureStructure == 0x02) // bottom field
+ break;
+ }
+ }
newFrame = true;
- tsPayload.GetByte();
- uchar FrameType = (tsPayload.GetByte() >> 3) & 0x07;
independentFrame = FrameType == 1; // I-Frame
+ if (independentFrame) {
+ if (lastIFrameTemporalReference >= 0)
+ iFrameTemporalReferenceOffset = TemporalReference - lastIFrameTemporalReference;
+ lastIFrameTemporalReference = TemporalReference;
+ }
if (debug) {
seenIndependentFrame |= independentFrame;
if (seenIndependentFrame) {
@@ -1457,7 +1477,7 @@ int cFrameDetector::Analyze(const uchar *Data, int Length)
for (int i = 0; i < numPtsValues; i++)
ptsValues[i] = ptsValues[i + 1] - ptsValues[i];
qsort(ptsValues, numPtsValues, sizeof(uint32_t), CmpUint32);
- uint32_t Delta = ptsValues[0] / framesPerPayloadUnit;
+ uint32_t Delta = ptsValues[0] / (framesPerPayloadUnit + parser->IFrameTemporalReferenceOffset());
// determine frame info:
if (isVideo) {
if (abs(Delta - 3600) <= 1)
@@ -1475,7 +1495,7 @@ int cFrameDetector::Analyze(const uchar *Data, int Length)
}
else // audio
framesPerSecond = double(PTSTICKS) / Delta; // PTS of audio frames is always increasing
- dbgframes("\nDelta = %d FPS = %5.2f FPPU = %d NF = %d\n", Delta, framesPerSecond, framesPerPayloadUnit, numPtsValues + 1);
+ dbgframes("\nDelta = %d FPS = %5.2f FPPU = %d NF = %d TRO = %d\n", Delta, framesPerSecond, framesPerPayloadUnit, numPtsValues + 1, parser->IFrameTemporalReferenceOffset());
synced = true;
parser->SetDebug(false);
}