mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
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:
parent
47a6f8fbff
commit
9eda923269
@ -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
|
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 suggesting to eliminate MAXDVBDEVICES
|
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>
|
Reinhard Walter Buchner <rw.buchner@freenet.de>
|
||||||
for adding some satellites to 'sources.conf'
|
for adding some satellites to 'sources.conf'
|
||||||
|
4
HISTORY
4
HISTORY
@ -8175,3 +8175,7 @@ Video Disk Recorder Revision History
|
|||||||
- 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
|
||||||
|
Oliver Endriss).
|
||||||
|
54
remux.c
54
remux.c
@ -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 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"
|
#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
13
remux.h
@ -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 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
|
#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;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user