mirror of
				https://github.com/vdr-projects/vdr.git
				synced 2025-03-01 10:50:46 +00:00 
			
		
		
		
	Fixed frame detection when regenerating the index
This commit is contained in:
		
							
								
								
									
										94
									
								
								remux.c
									
									
									
									
									
								
							
							
						
						
									
										94
									
								
								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.68 2012/11/02 14:35:57 kls Exp $ | ||||
|  * $Id: remux.c 2.69 2012/11/06 10:59:39 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #include "remux.h" | ||||
| @@ -991,8 +991,6 @@ cMpeg2Parser::cMpeg2Parser(void) | ||||
| int cMpeg2Parser::Parse(const uchar *Data, int Length, int Pid) | ||||
| { | ||||
|   newFrame = independentFrame = false; | ||||
|   if (Length < MIN_TS_PACKETS_FOR_FRAME_DETECTOR * TS_SIZE) | ||||
|      return 0; // need more data | ||||
|   cTsPayload tsPayload(const_cast<uchar *>(Data), Length, Pid); | ||||
|   if (TsPayloadStart(Data)) { | ||||
|      tsPayload.SkipPesHeader(); | ||||
| @@ -1000,23 +998,27 @@ int cMpeg2Parser::Parse(const uchar *Data, int Length, int Pid) | ||||
|      if (debug && seenIndependentFrame) | ||||
|         dbgframes("/"); | ||||
|      } | ||||
|   do { | ||||
|      scanner = (scanner << 8) | tsPayload.GetByte(); | ||||
|      if (scanner == 0x00000100) { // Picture Start Code | ||||
|         newFrame = true; | ||||
|         tsPayload.GetByte(); | ||||
|         uchar FrameType = (tsPayload.GetByte() >> 3) & 0x07; | ||||
|         independentFrame = FrameType == 1; // I-Frame | ||||
|         if (debug) { | ||||
|            seenIndependentFrame |= independentFrame; | ||||
|            if (seenIndependentFrame) { | ||||
|               static const char FrameTypes[] = "?IPBD???"; | ||||
|               dbgframes("%c", FrameTypes[FrameType]); | ||||
|               } | ||||
|            } | ||||
|         break; | ||||
|         } | ||||
|      } while (tsPayload.Available() > (MIN_TS_PACKETS_FOR_FRAME_DETECTOR - 1) * TS_SIZE); | ||||
|   for (;;) { | ||||
|       scanner = (scanner << 8) | tsPayload.GetByte(); | ||||
|       if (scanner == 0x00000100) { // Picture Start Code | ||||
|          newFrame = true; | ||||
|          tsPayload.GetByte(); | ||||
|          uchar FrameType = (tsPayload.GetByte() >> 3) & 0x07; | ||||
|          independentFrame = FrameType == 1; // I-Frame | ||||
|          if (debug) { | ||||
|             seenIndependentFrame |= independentFrame; | ||||
|             if (seenIndependentFrame) { | ||||
|                static const char FrameTypes[] = "?IPBD???"; | ||||
|                dbgframes("%c", FrameTypes[FrameType]); | ||||
|                } | ||||
|             } | ||||
|          break; | ||||
|          } | ||||
|       if (tsPayload.AtPayloadStart() // stop at any new payload start to have the buffer refilled if necessary | ||||
|          || (tsPayload.Available() < MIN_TS_PACKETS_FOR_FRAME_DETECTOR * TS_SIZE // stop if the available data is below the limit... | ||||
|             && (tsPayload.Available() <= 0 || tsPayload.AtTsStart()))) // ...but only if there is no more data at all, or if we are at a TS boundary | ||||
|          break; | ||||
|       } | ||||
|   return tsPayload.Used(); | ||||
| } | ||||
|  | ||||
| @@ -1133,8 +1135,6 @@ int32_t cMpeg4Parser::GetGolombSe(void) | ||||
| int cMpeg4Parser::Parse(const uchar *Data, int Length, int Pid) | ||||
| { | ||||
|   newFrame = independentFrame = false; | ||||
|   if (Length < MIN_TS_PACKETS_FOR_FRAME_DETECTOR * TS_SIZE) | ||||
|      return 0; // need more data | ||||
|   tsPayload.Setup(const_cast<uchar *>(Data), Length, Pid); | ||||
|   if (TsPayloadStart(Data)) { | ||||
|      tsPayload.SkipPesHeader(); | ||||
| @@ -1143,28 +1143,32 @@ int cMpeg4Parser::Parse(const uchar *Data, int Length, int Pid) | ||||
|         dbgframes("/"); | ||||
|         } | ||||
|      } | ||||
|   do { | ||||
|      scanner = (scanner << 8) | GetByte(true); | ||||
|      if ((scanner & 0xFFFFFF00) == 0x00000100) { // NAL unit start | ||||
|         uchar NalUnitType = scanner & 0x1F; | ||||
|         switch (NalUnitType) { | ||||
|           case nutAccessUnitDelimiter:  ParseAccessUnitDelimiter(); | ||||
|                                         gotAccessUnitDelimiter = true; | ||||
|                                         break; | ||||
|           case nutSequenceParameterSet: ParseSequenceParameterSet(); | ||||
|                                         gotSequenceParameterSet = true; | ||||
|                                         break; | ||||
|           case nutCodedSliceNonIdr: | ||||
|           case nutCodedSliceIdr:        if (gotAccessUnitDelimiter && gotSequenceParameterSet) { | ||||
|                                            ParseSliceHeader();  | ||||
|                                            gotAccessUnitDelimiter = false; | ||||
|                                            return tsPayload.Used(); | ||||
|                                            } | ||||
|                                         break; | ||||
|           default: ; | ||||
|           } | ||||
|         } | ||||
|      } while (tsPayload.Available() > (MIN_TS_PACKETS_FOR_FRAME_DETECTOR - 1) * TS_SIZE); | ||||
|   for (;;) { | ||||
|       scanner = (scanner << 8) | GetByte(true); | ||||
|       if ((scanner & 0xFFFFFF00) == 0x00000100) { // NAL unit start | ||||
|          uchar NalUnitType = scanner & 0x1F; | ||||
|          switch (NalUnitType) { | ||||
|            case nutAccessUnitDelimiter:  ParseAccessUnitDelimiter(); | ||||
|                                          gotAccessUnitDelimiter = true; | ||||
|                                          break; | ||||
|            case nutSequenceParameterSet: ParseSequenceParameterSet(); | ||||
|                                          gotSequenceParameterSet = true; | ||||
|                                          break; | ||||
|            case nutCodedSliceNonIdr: | ||||
|            case nutCodedSliceIdr:        if (gotAccessUnitDelimiter && gotSequenceParameterSet) { | ||||
|                                             ParseSliceHeader();  | ||||
|                                             gotAccessUnitDelimiter = false; | ||||
|                                             return tsPayload.Used(); | ||||
|                                             } | ||||
|                                          break; | ||||
|            default: ; | ||||
|            } | ||||
|          } | ||||
|       if (tsPayload.AtPayloadStart() // stop at any new payload start to have the buffer refilled if necessary | ||||
|          || (tsPayload.Available() < MIN_TS_PACKETS_FOR_FRAME_DETECTOR * TS_SIZE // stop if the available data is below the limit... | ||||
|             && (tsPayload.Available() <= 0 || tsPayload.AtTsStart()))) // ...but only if there is no more data at all, or if we are at a TS boundary | ||||
|          break; | ||||
|       } | ||||
|   return tsPayload.Used(); | ||||
| } | ||||
|  | ||||
| @@ -1324,8 +1328,6 @@ int cFrameDetector::Analyze(const uchar *Data, int Length) | ||||
|                  int n = parser->Parse(Data, Length, pid); | ||||
|                  if (n > 0) { | ||||
|                     if (parser->NewFrame()) { | ||||
|                        if (Processed) | ||||
|                           return Processed; // flush everything before this new frame | ||||
|                        newFrame = true; | ||||
|                        independentFrame = parser->IndependentFrame(); | ||||
|                        if (synced) { | ||||
|   | ||||
							
								
								
									
										10
									
								
								remux.h
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								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 2.33 2012/11/02 14:33:11 kls Exp $ | ||||
|  * $Id: remux.h 2.34 2012/11/06 11:03:06 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #ifndef __REMUX_H | ||||
| @@ -158,7 +158,7 @@ private: | ||||
|   uchar *data; | ||||
|   int length; | ||||
|   int pid; | ||||
|   int index;  // points to the next byte to process | ||||
|   int index; // points to the next byte to process | ||||
| public: | ||||
|   cTsPayload(void); | ||||
|   cTsPayload(uchar *Data, int Length, int Pid = -1); | ||||
| @@ -171,6 +171,12 @@ public: | ||||
|        ///< Otherwise the PID of the first TS packet defines which payload will be | ||||
|        ///< delivered. | ||||
|        ///< Any intermediate TS packets with different PIDs will be skipped. | ||||
|   bool AtTsStart(void) { return index < length && (index % TS_SIZE) == 0; } | ||||
|        ///< Returns true if this payload handler is currently pointing to first byte | ||||
|        ///< of a TS packet. | ||||
|   bool AtPayloadStart(void) { return AtTsStart() && TsPayloadStart(data + index); } | ||||
|        ///< Returns true if this payload handler is currently pointing to the first byte | ||||
|        ///< of a TS packet that starts a new payload. | ||||
|   int Available(void) { return length - index; } | ||||
|        ///< Returns the number of raw bytes (including any TS headers) still available | ||||
|        ///< in the TS payload handler. | ||||
|   | ||||
		Reference in New Issue
	
	Block a user