summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CONTRIBUTORS2
-rw-r--r--HISTORY4
-rw-r--r--remux.c54
-rw-r--r--remux.h13
4 files changed, 59 insertions, 14 deletions
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index 2fec0012..865c7a32 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -707,6 +707,8 @@ Oliver Endriss <o.endriss@gmx.de>
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
for suggesting to eliminate MAXDVBDEVICES
+ 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>
for adding some satellites to 'sources.conf'
diff --git a/HISTORY b/HISTORY
index 5e9da0bd..f5e74534 100644
--- a/HISTORY
+++ b/HISTORY
@@ -8175,3 +8175,7 @@ Video Disk Recorder Revision History
- 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
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
+ Oliver Endriss).
diff --git a/remux.c b/remux.c
index fd726017..d0b8e8e2 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 3.1 2014/01/18 11:27:30 kls Exp $
+ * $Id: remux.c 3.2 2014/01/28 11:07:59 kls Exp $
*/
#include "remux.h"
@@ -23,6 +23,10 @@ static bool DebugFrames = false;
#define dbgpatpmt(a...) if (DebugPatPmt) 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)
ePesHeader AnalyzePesHeader(const uchar *Data, int Count, int &PesPayloadOffset, bool *ContinuationHeader)
@@ -231,7 +235,7 @@ cTsPayload::cTsPayload(void)
data = NULL;
length = 0;
pid = -1;
- index = 0;
+ Reset();
}
cTsPayload::cTsPayload(uchar *Data, int Length, int Pid)
@@ -239,12 +243,25 @@ cTsPayload::cTsPayload(uchar *Data, int Length, int 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)
{
data = Data;
length = Length;
pid = Pid >= 0 ? Pid : TsPid(Data);
- index = 0;
+ Reset();
}
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
uchar *p = data + index;
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 (index > 0 && TsPayloadStart(p)) { // checking index to not skip the very first TS packet
- length = index; // triggers EOF
- return 0x00;
- }
+ if (index > 0 && TsPayloadStart(p)) // checking index to not skip the very first TS packet
+ return SetEof();
index += TsPayloadOffset(p);
break;
}
}
+ else
+ numPacketsOther++;
}
- else {
- length = index; // triggers EOF
- return 0x00;
- }
+ else
+ return SetEof();
}
}
return data[index++];
@@ -302,6 +319,8 @@ void cTsPayload::SetByte(uchar Byte, int Index)
bool cTsPayload::Find(uint32_t Code)
{
int OldIndex = index;
+ int OldNumPacketsPid = numPacketsPid;
+ int OldNumPacketsOther = numPacketsOther;
uint32_t Scanner = EMPTY_SCANNER;
while (!Eof()) {
Scanner = (Scanner << 8) | GetByte();
@@ -309,9 +328,19 @@ bool cTsPayload::Find(uint32_t Code)
return true;
}
index = OldIndex;
+ numPacketsPid = OldNumPacketsPid;
+ numPacketsOther = OldNumPacketsOther;
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(const cChannel *Channel)
@@ -1120,6 +1149,7 @@ int cMpeg2Parser::Parse(const uchar *Data, int Length, int Pid)
dbgframes("%c", FrameTypes[FrameType]);
}
}
+ tsPayload.Statistics();
break;
}
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) {
ParseSliceHeader();
gotAccessUnitDelimiter = false;
+ if (newFrame)
+ tsPayload.Statistics();
return tsPayload.Used();
}
break;
diff --git a/remux.h b/remux.h
index 5dd24ebd..ac627371 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 3.1 2014/01/16 10:15:50 kls Exp $
+ * $Id: remux.h 3.2 2014/01/28 11:06:37 kls Exp $
*/
#ifndef __REMUX_H
@@ -217,8 +217,11 @@ private:
int length;
int pid;
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:
- void Reset(void) { index = 0; }
+ void Reset(void);
public:
cTsPayload(void);
cTsPayload(uchar *Data, int Length, int Pid = -1);
@@ -246,6 +249,10 @@ public:
///< is counted with its full size.
bool Eof(void) const { return index >= length; }
///< 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);
///< Gets the next byte of the TS payload, skipping any intermediate TS header data.
bool SkipBytes(int Bytes);
@@ -462,7 +469,7 @@ void PesDump(const char *Name, const u_char *Data, int Length);
// Frame detector:
-#define MIN_TS_PACKETS_FOR_FRAME_DETECTOR 10
+#define MIN_TS_PACKETS_FOR_FRAME_DETECTOR 100
class cFrameParser;