mirror of
				https://github.com/vdr-projects/vdr.git
				synced 2025-03-01 10:50:46 +00: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:
		| @@ -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; | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user