summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKlaus Schmidinger <vdr@tvdr.de>2009-05-24 15:11:28 +0200
committerKlaus Schmidinger <vdr@tvdr.de>2009-05-24 15:11:28 +0200
commite51e38bc3307749b0bcb76a1f72322d56b0c42d6 (patch)
tree0b11e2641bb754a96bf24bdff3e99bebf3f6e117
parent6cdfb489aea9b4e8ea7f3287c76227a573b75161 (diff)
downloadvdr-e51e38bc3307749b0bcb76a1f72322d56b0c42d6.tar.gz
vdr-e51e38bc3307749b0bcb76a1f72322d56b0c42d6.tar.bz2
Fixed generating PAT/PMT version numbers in case the PIDs change during recording
-rw-r--r--CONTRIBUTORS1
-rw-r--r--HISTORY4
-rw-r--r--recorder.c8
-rw-r--r--recording.c54
-rw-r--r--recording.h3
-rw-r--r--remux.c15
-rw-r--r--remux.h14
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
diff --git a/HISTORY b/HISTORY
index f7775a8f..ca880768 100644
--- a/HISTORY
+++ b/HISTORY
@@ -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).
diff --git a/recorder.c b/recorder.c
index d8f22ce1..4e48a51e 100644
--- a/recorder.c
+++ b/recorder.c
@@ -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);
diff --git a/remux.c b/remux.c
index 043b8bbc..f3d0f262 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.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)
diff --git a/remux.h b/remux.h
index 5e2ba566..44ac9cbc 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.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.