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:
parent
6cdfb489ae
commit
e51e38bc33
@ -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
|
||||
|
4
HISTORY
4
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).
|
||||
|
@ -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;
|
||||
|
54
recording.c
54
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) {
|
||||
|
@ -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
15
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)
|
||||
|
14
remux.h
14
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.
|
||||
|
Loading…
Reference in New Issue
Block a user