1
0
mirror of https://github.com/VDR4Arch/vdr.git synced 2023-10-10 13:36:52 +02:00

Fixed generating PAT/PMT version numbers in case the PIDs change during recording

This commit is contained in:
Klaus Schmidinger 2009-05-24 15:11:28 +02:00
parent 6cdfb489ae
commit e51e38bc33
7 changed files with 91 additions and 8 deletions

View File

@ -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

View File

@ -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).

View File

@ -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;

View File

@ -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) {

View File

@ -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);

15
remux.c
View File

@ -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)

14
remux.h
View File

@ -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.