diff options
author | Klaus Schmidinger <vdr@tvdr.de> | 2009-05-24 15:11:28 +0200 |
---|---|---|
committer | Klaus Schmidinger <vdr@tvdr.de> | 2009-05-24 15:11:28 +0200 |
commit | e51e38bc3307749b0bcb76a1f72322d56b0c42d6 (patch) | |
tree | 0b11e2641bb754a96bf24bdff3e99bebf3f6e117 | |
parent | 6cdfb489aea9b4e8ea7f3287c76227a573b75161 (diff) | |
download | vdr-e51e38bc3307749b0bcb76a1f72322d56b0c42d6.tar.gz vdr-e51e38bc3307749b0bcb76a1f72322d56b0c42d6.tar.bz2 |
Fixed generating PAT/PMT version numbers in case the PIDs change during recording
-rw-r--r-- | CONTRIBUTORS | 1 | ||||
-rw-r--r-- | HISTORY | 4 | ||||
-rw-r--r-- | recorder.c | 8 | ||||
-rw-r--r-- | recording.c | 54 | ||||
-rw-r--r-- | recording.h | 3 | ||||
-rw-r--r-- | remux.c | 15 | ||||
-rw-r--r-- | remux.h | 14 |
7 files changed, 91 insertions, 8 deletions
diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 99e3cc02..a6055064 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -1216,6 +1216,7 @@ Reinhard Nissl <rnissl@gmx.de> for fixing the 'VideoOnly' condition in the PlayPes() and PlayTs() calls in cDvbPlayer::Action() for reporting a typo in aspect ratio 2.21:1 + for reporting a problem in case the PIDs change during recording Richard Robson <richard_robson@beeb.net> for reporting freezing replay if a timer starts while in Transfer Mode from the @@ -6075,7 +6075,7 @@ Video Disk Recorder Revision History - cFrameDetector::Analyze() now syncs on the TS packet sync bytes (thanks to Oliver Endriss for reporting broken index generation after a buffer overflow). -2009-05-23: Version 1.7.8 +2009-05-24: Version 1.7.8 - Fixed a typo in aspect ratio 2.21:1 (reported by Reinhard Nissl). - The name of the function cDevice::GetVideoSize() wasn't very well chosen @@ -6109,3 +6109,5 @@ Video Disk Recorder Revision History what happens if the Pause key on the remote control is pressed during live tv (thanks to Timo Eskola). - Added a note about cFont::GetFont() not being thread-safe. +- Fixed generating PAT/PMT version numbers in case the PIDs change during + recording (reported by Reinhard Nissl). @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: recorder.c 2.3 2009/03/20 15:49:02 kls Exp $ + * $Id: recorder.c 2.4 2009/05/23 12:18:25 kls Exp $ */ #include "recorder.h" @@ -44,12 +44,14 @@ cRecorder::cRecorder(const char *FileName, tChannelID ChannelID, int Priority, i Type = 0x06; } frameDetector = new cFrameDetector(Pid, Type); - patPmtGenerator.SetChannel(Channel); - fileName = NULL; index = NULL; fileSize = 0; lastDiskSpaceCheck = time(NULL); fileName = new cFileName(FileName, true); + int PatVersion, PmtVersion; + if (fileName->GetLastPatPmtVersions(PatVersion, PmtVersion)) + patPmtGenerator.SetVersions(PatVersion + 1, PmtVersion + 1); + patPmtGenerator.SetChannel(Channel); recordFile = fileName->Open(); if (!recordFile) return; diff --git a/recording.c b/recording.c index c86b1636..e33d20bc 100644 --- a/recording.c +++ b/recording.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: recording.c 2.12 2009/04/13 13:50:39 kls Exp $ + * $Id: recording.c 2.13 2009/05/24 15:11:28 kls Exp $ */ #include "recording.h" @@ -20,6 +20,7 @@ #include "channels.h" #include "i18n.h" #include "interface.h" +#include "remux.h" #include "skins.h" #include "tools.h" #include "videodir.h" @@ -1629,6 +1630,57 @@ cFileName::~cFileName() free(fileName); } +bool cFileName::GetLastPatPmtVersions(int &PatVersion, int &PmtVersion) +{ + if (fileName && !isPesRecording) { + // Find the last recording file: + int Number = 1; + for (; Number <= MAXFILESPERRECORDINGTS + 1; Number++) { // +1 to correctly set Number in case there actually are that many files + sprintf(pFileNumber, RECORDFILESUFFIXTS, Number); + if (access(fileName, F_OK) != 0) { // file doesn't exist + Number--; + break; + } + } + for (; Number > 0; Number--) { + // Search for a PAT packet from the end of the file: + cPatPmtParser PatPmtParser; + sprintf(pFileNumber, RECORDFILESUFFIXTS, Number); + int fd = open(fileName, O_RDONLY | O_LARGEFILE, DEFFILEMODE); + if (fd >= 0) { + off_t pos = lseek(fd, -TS_SIZE, SEEK_END); + while (pos >= 0) { + // Read and parse the PAT/PMT: + uchar buf[TS_SIZE]; + while (read(fd, buf, sizeof(buf)) == sizeof(buf)) { + if (buf[0] == TS_SYNC_BYTE) { + int Pid = TsPid(buf); + if (Pid == 0) + PatPmtParser.ParsePat(buf, sizeof(buf)); + else if (Pid == PatPmtParser.PmtPid()) { + PatPmtParser.ParsePmt(buf, sizeof(buf)); + if (PatPmtParser.GetVersions(PatVersion, PmtVersion)) { + close(fd); + return true; + } + } + else + break; // PAT/PMT is always in one sequence + } + else + return false; + } + pos = lseek(fd, pos - TS_SIZE, SEEK_SET); + } + close(fd); + } + else + break; + } + } + return false; +} + cUnbufferedFile *cFileName::Open(void) { if (!file) { diff --git a/recording.h b/recording.h index d55cfdf0..81c72fd4 100644 --- a/recording.h +++ b/recording.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: recording.h 2.7 2009/04/19 09:00:45 kls Exp $ + * $Id: recording.h 2.8 2009/05/23 12:14:42 kls Exp $ */ #ifndef __RECORDING_H @@ -260,6 +260,7 @@ public: ~cFileName(); const char *Name(void) { return fileName; } int Number(void) { return fileNumber; } + bool GetLastPatPmtVersions(int &PatVersion, int &PmtVersion); cUnbufferedFile *Open(void); void Close(void); cUnbufferedFile *SetOffset(int Number, off_t Offset = 0); @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: remux.c 2.22 2009/05/17 09:46:10 kls Exp $ + * $Id: remux.c 2.23 2009/05/24 11:44:54 kls Exp $ */ #include "remux.h" @@ -357,6 +357,12 @@ void cPatPmtGenerator::GeneratePmt(cChannel *Channel) } } +void cPatPmtGenerator::SetVersions(int PatVersion, int PmtVersion) +{ + patVersion = PatVersion & 0x1F; + pmtVersion = PmtVersion & 0x1F; +} + void cPatPmtGenerator::SetChannel(cChannel *Channel) { if (Channel) { @@ -585,6 +591,13 @@ void cPatPmtParser::ParsePmt(const uchar *Data, int Length) pmtSize = 0; } +bool cPatPmtParser::GetVersions(int &PatVersion, int &PmtVersion) +{ + PatVersion = patVersion; + PmtVersion = pmtVersion; + return patVersion >= 0 && pmtVersion >= 0; +} + // --- cTsToPes -------------------------------------------------------------- cTsToPes::cTsToPes(void) @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: remux.h 2.15 2009/05/23 09:51:45 kls Exp $ + * $Id: remux.h 2.16 2009/05/24 15:07:44 kls Exp $ */ #ifndef __REMUX_H @@ -181,6 +181,15 @@ protected: ///< with GetPmt(). public: cPatPmtGenerator(cChannel *Channel = NULL); + void SetVersions(int PatVersion, int PmtVersion); + ///< Sets the version numbers for the generated PAT and PMT, in case + ///< this generator is used to, e.g., continue a previously interrupted + ///< recording (in which case the numbers given should be derived from + ///< the PAT/PMT versions last used in the existing recording, incremented + ///< by 1. If the given numbers exceed the allowed range of 0..31, the + ///< higher bits will automatically be cleared. + ///< SetVersions() needs to be called before SetChannel() in order to + ///< have an effect from the very start. void SetChannel(cChannel *Channel); ///< Sets the Channel for which the PAT/PMT shall be generated. uchar *GetPat(void); @@ -221,6 +230,9 @@ public: ///< 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. + bool GetVersions(int &PatVersion, int &PmtVersion); + ///< Returns true if a valid PAT/PMT has been parsed and stores + ///< the current version numbers in the given variables. int PmtPid(void) { return pmtPid; } ///< Returns the PMT pid as defined by the current PAT. ///< If no PAT has been received yet, -1 will be returned. |