From 1ca753003b97ea3df52460165118e040ae73a080 Mon Sep 17 00:00:00 2001 From: Klaus Schmidinger Date: Fri, 23 Jan 2009 16:43:23 +0100 Subject: Checking the pointer field in cPatPmtParser::ParsePmt() only in 'payload start' packets --- HISTORY | 2 ++ device.c | 11 +++++------ remux.c | 26 +++++++++++++++++++------- remux.h | 13 +++++++------ 4 files changed, 33 insertions(+), 19 deletions(-) diff --git a/HISTORY b/HISTORY index 4e30d8de..ba080b3c 100644 --- a/HISTORY +++ b/HISTORY @@ -5950,3 +5950,5 @@ Video Disk Recorder Revision History - Checking the remaining packet length after processing the pointer field in cPatPmtParser::ParsePat() and cPatPmtParser::ParsePmt() (suggested by Frank Schmirler). +- Checking the pointer field in cPatPmtParser::ParsePmt() only in 'payload start' + packets (suggested by Frank Schmirler). diff --git a/device.c b/device.c index d4576b03..3679651e 100644 --- a/device.c +++ b/device.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: device.c 2.7 2009/01/18 11:42:22 kls Exp $ + * $Id: device.c 2.8 2009/01/23 16:02:21 kls Exp $ */ #include "device.h" @@ -1020,12 +1020,11 @@ void cDevice::StillPicture(const uchar *Data, int Length) uchar *buf = NULL; int Size = 0; while (Length >= TS_SIZE) { - int PayloadOffset = TsPayloadOffset(Data); int Pid = TsPid(Data); if (Pid == 0) - patPmtParser.ParsePat(Data + PayloadOffset, TS_SIZE - PayloadOffset); + patPmtParser.ParsePat(Data, TS_SIZE); else if (Pid == patPmtParser.PmtPid()) - patPmtParser.ParsePmt(Data + PayloadOffset, TS_SIZE - PayloadOffset); + patPmtParser.ParsePmt(Data, TS_SIZE); else if (Pid == patPmtParser.Vpid()) { if (TsPayloadStart(Data)) { int l; @@ -1325,9 +1324,9 @@ int cDevice::PlayTs(const uchar *Data, int Length, bool VideoOnly) cMutexLock MutexLock(&mutexCurrentAudioTrack); int Pid = TsPid(Data); if (Pid == 0) - patPmtParser.ParsePat(Data + PayloadOffset, Length - PayloadOffset); + patPmtParser.ParsePat(Data, Length); else if (Pid == patPmtParser.PmtPid()) - patPmtParser.ParsePmt(Data + PayloadOffset, Length - PayloadOffset); + patPmtParser.ParsePmt(Data, Length); else if (Pid == patPmtParser.Vpid()) return PlayTsVideo(Data, Length); else if (Pid == availableTracks[currentAudioTrack].id) { diff --git a/remux.c b/remux.c index ed5da26a..54ba8723 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 2.9 2009/01/23 14:31:43 kls Exp $ + * $Id: remux.c 2.10 2009/01/23 16:43:23 kls Exp $ */ #include "remux.h" @@ -214,8 +214,8 @@ void cPatPmtGenerator::GeneratePat(void) memset(pat, 0xFF, sizeof(pat)); uchar *p = pat; int i = 0; - p[i++] = 0x47; // TS indicator - p[i++] = 0x40; // flags (3), pid hi (5) + p[i++] = TS_SYNC_BYTE; // TS indicator + p[i++] = TS_PAYLOAD_START; // flags (3), pid hi (5) p[i++] = 0x00; // pid lo p[i++] = 0x10; // flags (4), continuity counter (4) p[i++] = 0x00; // pointer field (payload unit start indicator is set) @@ -292,8 +292,8 @@ void cPatPmtGenerator::GeneratePmt(tChannelID ChannelID) while (i > 0) { uchar *p = pmt[numPmtPackets++]; int j = 0; - p[j++] = 0x47; // TS indicator - p[j++] = (pusi ? 0x40 : 0x00) | (P_PNR >> 8); // flags (3), pid hi (5) + p[j++] = TS_SYNC_BYTE; // TS indicator + p[j++] = (pusi ? TS_PAYLOAD_START : 0x00) | (P_PNR >> 8); // flags (3), pid hi (5) p[j++] = P_PNR & 0xFF; // pid lo p[j++] = 0x10; // flags (4), continuity counter (4) if (pusi) { @@ -337,6 +337,10 @@ cPatPmtParser::cPatPmtParser(void) void cPatPmtParser::ParsePat(const uchar *Data, int Length) { + // Unpack the TS packet: + int PayloadOffset = TsPayloadOffset(Data); + Data += PayloadOffset; + Length -= PayloadOffset; // The PAT is always assumed to fit into a single TS packet if ((Length -= Data[0] + 1) <= 0) return; @@ -359,8 +363,14 @@ void cPatPmtParser::ParsePat(const uchar *Data, int Length) void cPatPmtParser::ParsePmt(const uchar *Data, int Length) { + // Unpack the TS packet: + bool PayloadStart = TsPayloadStart(Data); + int PayloadOffset = TsPayloadOffset(Data); + Data += PayloadOffset; + Length -= PayloadOffset; // The PMT may extend over several TS packets, so we need to assemble them - if (pmtSize == 0) { + if (PayloadStart) { + pmtSize = 0; if ((Length -= Data[0] + 1) <= 0) return; Data += Data[0] + 1; // this is the first packet @@ -375,7 +385,7 @@ void cPatPmtParser::ParsePmt(const uchar *Data, int Length) } // the packet contains the entire PMT section, so we run into the actual parsing } - else { + else if (pmtSize > 0) { // this is a following packet, so we add it to the pmt storage if (Length <= int(sizeof(pmt)) - pmtSize) { memcpy(pmt + pmtSize, Data, Length); @@ -390,6 +400,8 @@ void cPatPmtParser::ParsePmt(const uchar *Data, int Length) // the PMT section is now complete, so we run into the actual parsing Data = pmt; } + else + return; // fragment of broken packet - ignore SI::PMT Pmt(Data, false); if (Pmt.CheckCRCAndParse()) { dbgpatpmt("PMT: sid = %d, c/n = %d, v = %d, s = %d, ls = %d\n", Pmt.getServiceId(), Pmt.getCurrentNextIndicator(), Pmt.getVersionNumber(), Pmt.getSectionNumber(), Pmt.getLastSectionNumber()); diff --git a/remux.h b/remux.h index 9a0921d1..6b09b713 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 2.4 2009/01/06 12:40:43 kls Exp $ + * $Id: remux.h 2.5 2009/01/23 16:40:27 kls Exp $ */ #ifndef __REMUX_H @@ -172,7 +172,7 @@ public: ///< Generates a PMT section for the given ChannelId, for later use ///< with GetPmt(). uchar *GetPat(void); - ///< Returns a pointer to the PAT section, which consist of exactly + ///< Returns a pointer to the PAT section, which consists of exactly ///< one TS packet. uchar *GetPmt(int &Index); ///< Returns a pointer to the Index'th TS packet of the PMT section. @@ -195,11 +195,12 @@ protected: public: cPatPmtParser(void); void ParsePat(const uchar *Data, int Length); - ///< Parses the given PAT Data, which is the payload of a single TS packet - ///< from the PAT stream. The PAT may consist only of a single TS packet. + ///< Parses the PAT data from the single TS packet in Data. + ///< Length is always TS_SIZE. void ParsePmt(const uchar *Data, int Length); - ///< Parses the given PMT Data, which is the payload of a single TS packet - ///< from the PMT stream. The PMT may consist of several TS packets, which + ///< Parses the PMT data from the single TS packet in Data. + ///< Length is always TS_SIZE. + ///< The PMT may consist of several TS packets, which ///< are delivered to the parser through several subsequent calls to ///< ParsePmt(). The whole PMT data will be processed once the last packet ///< has been received. -- cgit v1.2.3