Increased MIN_TS_PACKETS_FOR_FRAME_DETECTOR to 100 and introduced counting the number of actual video TS packets in cTsPayload

This commit is contained in:
Klaus Schmidinger 2014-01-28 12:40:04 +01:00
parent 538a4f7674
commit 9e9219d8fb
4 changed files with 60 additions and 18 deletions

View File

@ -706,6 +706,8 @@ Oliver Endriss <o.endriss@gmx.de>
for reporting a problem with resuming replay of PES recordings for reporting a problem with resuming replay of PES recordings
for suggesting to make all bonded devices (except for the master) turn off their LNB for suggesting to make all bonded devices (except for the master) turn off their LNB
power completely to avoid problems when receiving vertically polarized transponders power completely to avoid problems when receiving vertically polarized transponders
for reporting that there are channels that need even more than 10 TS packets in order
to detect the frame type
Reinhard Walter Buchner <rw.buchner@freenet.de> Reinhard Walter Buchner <rw.buchner@freenet.de>
for adding some satellites to 'sources.conf' for adding some satellites to 'sources.conf'

View File

@ -7870,17 +7870,18 @@ Video Disk Recorder Revision History
and also to use the correct directory with --edit (the latter reported by Marko and also to use the correct directory with --edit (the latter reported by Marko
Mäkelä). Mäkelä).
2014-01-26: Version 2.0.6 2014-01-28: Version 2.0.6
- Updated 'sources.conf' (thanks to Antti Hartikainen). - Updated 'sources.conf' (thanks to Antti Hartikainen).
- cFont::CreateFont() now returns a dummy font in case there are no fonts installed. - cFont::CreateFont() now returns a dummy font in case there are no fonts installed.
This prevents a crash with the LCARS skin on a system that has no fonts. This prevents a crash with the LCARS skin on a system that has no fonts.
- 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 - 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). GOP structures (reported by Christian Paulick, with help from Helmut Auer).
- Fixed a wrong alignment in cCiDateTime::SendDateTime(). - Fixed a wrong alignment in cCiDateTime::SendDateTime().
- Now checking whether the primary device actually has a decoder before retuning the - Now checking whether the primary device actually has a decoder before retuning the
current channel after a change in its parameters. This fixes broken recordings on current channel after a change in its parameters. This fixes broken recordings on
the primary device on "headless" systems. the primary device on "headless" systems.
- Increased MIN_TS_PACKETS_FOR_FRAME_DETECTOR to 100 and introduced counting the number
of actual video TS packets in cTsPayload in order to be able to record channels that
sometimes need even more than 10 TS packets for detecting frame borders (reported by
Eike Sauer and Oliver Endriss).

54
remux.c
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: remux.c 2.75.1.1 2014/01/25 14:37:05 kls Exp $ * $Id: remux.c 2.75.1.2 2014/01/28 12:36:57 kls Exp $
*/ */
#include "remux.h" #include "remux.h"
@ -23,6 +23,10 @@ static bool DebugFrames = false;
#define dbgpatpmt(a...) if (DebugPatPmt) fprintf(stderr, a) #define dbgpatpmt(a...) if (DebugPatPmt) fprintf(stderr, a)
#define dbgframes(a...) if (DebugFrames) fprintf(stderr, a) #define dbgframes(a...) if (DebugFrames) fprintf(stderr, a)
#define MAX_TS_PACKETS_FOR_VIDEO_FRAME_DETECTION 6
#define WRN_TS_PACKETS_FOR_VIDEO_FRAME_DETECTION (MAX_TS_PACKETS_FOR_VIDEO_FRAME_DETECTION / 2)
#define WRN_TS_PACKETS_FOR_FRAME_DETECTOR (MIN_TS_PACKETS_FOR_FRAME_DETECTOR / 2)
#define EMPTY_SCANNER (0xFFFFFFFF) #define EMPTY_SCANNER (0xFFFFFFFF)
ePesHeader AnalyzePesHeader(const uchar *Data, int Count, int &PesPayloadOffset, bool *ContinuationHeader) ePesHeader AnalyzePesHeader(const uchar *Data, int Count, int &PesPayloadOffset, bool *ContinuationHeader)
@ -231,7 +235,7 @@ cTsPayload::cTsPayload(void)
data = NULL; data = NULL;
length = 0; length = 0;
pid = -1; pid = -1;
index = 0; Reset();
} }
cTsPayload::cTsPayload(uchar *Data, int Length, int Pid) cTsPayload::cTsPayload(uchar *Data, int Length, int Pid)
@ -239,12 +243,25 @@ cTsPayload::cTsPayload(uchar *Data, int Length, int Pid)
Setup(Data, Length, Pid); Setup(Data, Length, Pid);
} }
uchar cTsPayload::SetEof(void)
{
length = index; // triggers EOF
return 0x00;
}
void cTsPayload::Reset(void)
{
index = 0;
numPacketsPid = 0;
numPacketsOther = 0;
}
void cTsPayload::Setup(uchar *Data, int Length, int Pid) void cTsPayload::Setup(uchar *Data, int Length, int Pid)
{ {
data = Data; data = Data;
length = Length; length = Length;
pid = Pid >= 0 ? Pid : TsPid(Data); pid = Pid >= 0 ? Pid : TsPid(Data);
index = 0; Reset();
} }
uchar cTsPayload::GetByte(void) uchar cTsPayload::GetByte(void)
@ -255,20 +272,20 @@ uchar cTsPayload::GetByte(void)
if (data[index] == TS_SYNC_BYTE && index + TS_SIZE <= length) { // to make sure we are at a TS header start and drop incomplete TS packets at the end if (data[index] == TS_SYNC_BYTE && index + TS_SIZE <= length) { // to make sure we are at a TS header start and drop incomplete TS packets at the end
uchar *p = data + index; uchar *p = data + index;
if (TsPid(p) == pid) { // only handle TS packets for the initial PID if (TsPid(p) == pid) { // only handle TS packets for the initial PID
if (numPacketsPid++ > MAX_TS_PACKETS_FOR_VIDEO_FRAME_DETECTION)
return SetEof();
if (TsHasPayload(p)) { if (TsHasPayload(p)) {
if (index > 0 && TsPayloadStart(p)) { // checking index to not skip the very first TS packet if (index > 0 && TsPayloadStart(p)) // checking index to not skip the very first TS packet
length = index; // triggers EOF return SetEof();
return 0x00;
}
index += TsPayloadOffset(p); index += TsPayloadOffset(p);
break; break;
} }
} }
else
numPacketsOther++;
} }
else { else
length = index; // triggers EOF return SetEof();
return 0x00;
}
} }
} }
return data[index++]; return data[index++];
@ -302,6 +319,8 @@ void cTsPayload::SetByte(uchar Byte, int Index)
bool cTsPayload::Find(uint32_t Code) bool cTsPayload::Find(uint32_t Code)
{ {
int OldIndex = index; int OldIndex = index;
int OldNumPacketsPid = numPacketsPid;
int OldNumPacketsOther = numPacketsOther;
uint32_t Scanner = EMPTY_SCANNER; uint32_t Scanner = EMPTY_SCANNER;
while (!Eof()) { while (!Eof()) {
Scanner = (Scanner << 8) | GetByte(); Scanner = (Scanner << 8) | GetByte();
@ -309,9 +328,19 @@ bool cTsPayload::Find(uint32_t Code)
return true; return true;
} }
index = OldIndex; index = OldIndex;
numPacketsPid = OldNumPacketsPid;
numPacketsOther = OldNumPacketsOther;
return false; return false;
} }
void cTsPayload::Statistics(void) const
{
if (numPacketsPid + numPacketsOther > WRN_TS_PACKETS_FOR_FRAME_DETECTOR)
dsyslog("WARNING: required (%d+%d) TS packets to determine frame type", numPacketsOther, numPacketsPid);
if (numPacketsPid > WRN_TS_PACKETS_FOR_VIDEO_FRAME_DETECTION)
dsyslog("WARNING: required %d video TS packets to determine frame type", numPacketsPid);
}
// --- cPatPmtGenerator ------------------------------------------------------ // --- cPatPmtGenerator ------------------------------------------------------
cPatPmtGenerator::cPatPmtGenerator(const cChannel *Channel) cPatPmtGenerator::cPatPmtGenerator(const cChannel *Channel)
@ -1120,6 +1149,7 @@ int cMpeg2Parser::Parse(const uchar *Data, int Length, int Pid)
dbgframes("%c", FrameTypes[FrameType]); dbgframes("%c", FrameTypes[FrameType]);
} }
} }
tsPayload.Statistics();
break; break;
} }
if (tsPayload.AtPayloadStart() // stop at any new payload start to have the buffer refilled if necessary if (tsPayload.AtPayloadStart() // stop at any new payload start to have the buffer refilled if necessary
@ -1266,6 +1296,8 @@ int cH264Parser::Parse(const uchar *Data, int Length, int Pid)
case nutCodedSliceIdr: if (gotAccessUnitDelimiter && gotSequenceParameterSet) { case nutCodedSliceIdr: if (gotAccessUnitDelimiter && gotSequenceParameterSet) {
ParseSliceHeader(); ParseSliceHeader();
gotAccessUnitDelimiter = false; gotAccessUnitDelimiter = false;
if (newFrame)
tsPayload.Statistics();
return tsPayload.Used(); return tsPayload.Used();
} }
break; break;

13
remux.h
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: remux.h 2.37.1.1 2014/01/16 10:33:35 kls Exp $ * $Id: remux.h 2.37.1.2 2014/01/28 12:36:26 kls Exp $
*/ */
#ifndef __REMUX_H #ifndef __REMUX_H
@ -217,8 +217,11 @@ private:
int length; int length;
int pid; int pid;
int index; // points to the next byte to process int index; // points to the next byte to process
int numPacketsPid; // the number of TS packets with the given PID (for statistical purposes)
int numPacketsOther; // the number of TS packets with other PIDs (for statistical purposes)
uchar SetEof(void);
protected: protected:
void Reset(void) { index = 0; } void Reset(void);
public: public:
cTsPayload(void); cTsPayload(void);
cTsPayload(uchar *Data, int Length, int Pid = -1); cTsPayload(uchar *Data, int Length, int Pid = -1);
@ -246,6 +249,10 @@ public:
///< is counted with its full size. ///< is counted with its full size.
bool Eof(void) const { return index >= length; } bool Eof(void) const { return index >= length; }
///< Returns true if all available bytes of the TS payload have been processed. ///< Returns true if all available bytes of the TS payload have been processed.
void Statistics(void) const;
///< May be called after a new frame has been detected, and will log a warning
///< if the number of TS packets required to determine the frame type exceeded
///< some safety limits.
uchar GetByte(void); uchar GetByte(void);
///< Gets the next byte of the TS payload, skipping any intermediate TS header data. ///< Gets the next byte of the TS payload, skipping any intermediate TS header data.
bool SkipBytes(int Bytes); bool SkipBytes(int Bytes);
@ -462,7 +469,7 @@ void PesDump(const char *Name, const u_char *Data, int Length);
// Frame detector: // Frame detector:
#define MIN_TS_PACKETS_FOR_FRAME_DETECTOR 10 #define MIN_TS_PACKETS_FOR_FRAME_DETECTOR 100
class cFrameParser; class cFrameParser;