Version 1.7.9

- Fixed storing the current OSD size in case the device has
  changed it in its setup menu (reported by Reinhard Nissl).
- Fixed cDevice::PlayTsVideo() and cDevice::PlayTsAudio() in case only part of the
  buffer has been accepted by the device (reported by Udo Richter).
- Changed the EIT filter setup to save a few handles on devices that do hardware
  filtering.
- Fixed deleting expired timers if they have the VPS flag set, but the event they
  are assigned to doesn't have a VPS tag.
- Fixed handling file name length on VFAT systems in case they
  contain UTF-8 characters (thanks to Rolf Ahrenberg).
- Fixed generating CaPmts in case audio and video are encrypted using different
  ECM pids.
- Updated vdr.1 to use the new file names in recording directories.
- Fixed cRecordings::DelByName() to avoid compilation errors with gcc 4.4
  (thanks to Matthias Schwarzott).
- Increased the value of MAXFRAMESIZE to better suit HD recordings (thanks to
  Reinhard Nissl).
- Implemented full handling of subtitling descriptors (thanks to Mikko Tuumanen).
This commit is contained in:
Klaus Schmidinger 2009-08-23 16:04:00 +02:00
parent ab6f2ccf42
commit 06bf4c453e
17 changed files with 228 additions and 110 deletions

View File

@ -1079,6 +1079,8 @@ Rolf Ahrenberg <rahrenbe@cc.hut.fi>
for adding cThread::SetIOPriority() and using it in cRemoveDeletedRecordingsThread for adding cThread::SetIOPriority() and using it in cRemoveDeletedRecordingsThread
for suggesting to introduce cDevice::GetOsdSize() for suggesting to introduce cDevice::GetOsdSize()
for adding a note about the meaning of PERCENTAGEDELTA in cRingBuffer::UpdatePercentage() for adding a note about the meaning of PERCENTAGEDELTA in cRingBuffer::UpdatePercentage()
for fixing handling file name length on VFAT systems in case they
contain UTF-8 characters
Ralf Klueber <ralf.klueber@vodafone.com> Ralf Klueber <ralf.klueber@vodafone.com>
for reporting a bug in cutting a recording if there is only a single editing mark for reporting a bug in cutting a recording if there is only a single editing mark
@ -1229,6 +1231,9 @@ Reinhard Nissl <rnissl@gmx.de>
and GetOsdSize() and GetOsdSize()
for reporting a problem with calculating menu colum widths in case the font has a for reporting a problem with calculating menu colum widths in case the font has a
size other than the default size size other than the default size
for reporting a bug in storing the current OSD size in case the
device has changed it in its setup menu
for increasing the value of MAXFRAMESIZE to better suit HD recordings
Richard Robson <richard_robson@beeb.net> Richard Robson <richard_robson@beeb.net>
for reporting freezing replay if a timer starts while in Transfer Mode from the for reporting freezing replay if a timer starts while in Transfer Mode from the
@ -1641,6 +1646,8 @@ Udo Richter <udo_richter@gmx.de>
for suggesting to add a note to the INSTALL file about using subdirectories to for suggesting to add a note to the INSTALL file about using subdirectories to
split a large disk into separate areas for VDR's video data and other stuff split a large disk into separate areas for VDR's video data and other stuff
for reporting wrong variable types in cIndexFile for reporting wrong variable types in cIndexFile
for reporting a problem with cDevice::PlayTsVideo() and cDevice::PlayTsAudio() in
case only part of the buffer has been accepted by the device
Sven Kreiensen <svenk@kammer.uni-hannover.de> Sven Kreiensen <svenk@kammer.uni-hannover.de>
for his help in keeping 'channels.conf.terr' up to date for his help in keeping 'channels.conf.terr' up to date
@ -2281,6 +2288,7 @@ Matthias Schwarzott <zzam@gentoo.org>
for adding DESTDIR and PREFIX handling to the Makefile for adding DESTDIR and PREFIX handling to the Makefile
for fixing some compiler warnings with gcc-4.2.0 for fixing some compiler warnings with gcc-4.2.0
for fixing setting the locale file name in i18n-to-gettext.pl for fixing setting the locale file name in i18n-to-gettext.pl
for fixing cRecordings::DelByName() to avoid compilation errors with gcc 4.4
Martin Ostermann <martin@familie-ostermann.de> Martin Ostermann <martin@familie-ostermann.de>
for fixing processing the PDCDescriptor in 'libsi' on big endian systems for fixing processing the PDCDescriptor in 'libsi' on big endian systems
@ -2478,3 +2486,6 @@ G
Martin Neuditschko <yosuke.tomoe@gmx.net> Martin Neuditschko <yosuke.tomoe@gmx.net>
for reporting a problem with error messages from cDvbDevice::GetVideoSize() for reporting a problem with error messages from cDvbDevice::GetVideoSize()
on systems with no real primary replay device on systems with no real primary replay device
Mikko Tuumanen <mikko.tuumanen@utu.fi>
for implementing full handling of subtitling descriptors

21
HISTORY
View File

@ -6135,3 +6135,24 @@ Video Disk Recorder Revision History
to avoid problems in case the values are stored in the setup.conf to avoid problems in case the values are stored in the setup.conf
file in a wrong way. file in a wrong way.
- Fixed variable types in cIndexFile (reported by Udo Richter). - Fixed variable types in cIndexFile (reported by Udo Richter).
2009-08-23: Version 1.7.9
- Fixed storing the current OSD size in case the device has
changed it in its setup menu (reported by Reinhard Nissl).
- Fixed cDevice::PlayTsVideo() and cDevice::PlayTsAudio() in case only part of the
buffer has been accepted by the device (reported by Udo Richter).
- Changed the EIT filter setup to save a few handles on devices that do hardware
filtering.
- Fixed deleting expired timers if they have the VPS flag set, but the event they
are assigned to doesn't have a VPS tag.
- Fixed handling file name length on VFAT systems in case they
contain UTF-8 characters (thanks to Rolf Ahrenberg).
- Fixed generating CaPmts in case audio and video are encrypted using different
ECM pids.
- Updated vdr.1 to use the new file names in recording directories.
- Fixed cRecordings::DelByName() to avoid compilation errors with gcc 4.4
(thanks to Matthias Schwarzott).
- Increased the value of MAXFRAMESIZE to better suit HD recordings (thanks to
Reinhard Nissl).
- Implemented full handling of subtitling descriptors (thanks to Mikko Tuumanen).

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: channels.c 2.6 2009/04/25 13:57:32 kls Exp $ * $Id: channels.c 2.7 2009/08/16 15:08:49 kls Exp $
*/ */
#include "channels.h" #include "channels.h"
@ -533,6 +533,22 @@ void cChannel::SetPids(int Vpid, int Ppid, int Vtype, int *Apids, char ALangs[][
} }
} }
void cChannel::SetSubtitlingDescriptors(uchar *SubtitlingTypes, uint16_t *CompositionPageIds, uint16_t *AncillaryPageIds)
{
if (SubtitlingTypes) {
for (int i = 0; i < MAXSPIDS; i++)
subtitlingTypes[i] = SubtitlingTypes[i];
}
if (CompositionPageIds) {
for (int i = 0; i < MAXSPIDS; i++)
compositionPageIds[i] = CompositionPageIds[i];
}
if (AncillaryPageIds) {
for (int i = 0; i < MAXSPIDS; i++)
ancillaryPageIds[i] = AncillaryPageIds[i];
}
}
void cChannel::SetCaIds(const int *CaIds) void cChannel::SetCaIds(const int *CaIds)
{ {
if (caids[0] && caids[0] <= CA_USER_MAX) if (caids[0] && caids[0] <= CA_USER_MAX)

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: channels.h 2.4 2008/11/22 13:35:52 kls Exp $ * $Id: channels.h 2.5 2009/08/16 14:58:26 kls Exp $
*/ */
#ifndef __CHANNELS_H #ifndef __CHANNELS_H
@ -129,6 +129,9 @@ private:
char dlangs[MAXDPIDS][MAXLANGCODE2]; char dlangs[MAXDPIDS][MAXLANGCODE2];
int spids[MAXSPIDS + 1]; // list is zero-terminated int spids[MAXSPIDS + 1]; // list is zero-terminated
char slangs[MAXSPIDS][MAXLANGCODE2]; char slangs[MAXSPIDS][MAXLANGCODE2];
uchar subtitlingTypes[MAXSPIDS];
uint16_t compositionPageIds[MAXSPIDS];
uint16_t ancillaryPageIds[MAXSPIDS];
int tpid; int tpid;
int caids[MAXCAIDS + 1]; // list is zero-terminated int caids[MAXCAIDS + 1]; // list is zero-terminated
int nid; int nid;
@ -185,6 +188,9 @@ public:
const char *Alang(int i) const { return (0 <= i && i < MAXAPIDS) ? alangs[i] : ""; } const char *Alang(int i) const { return (0 <= i && i < MAXAPIDS) ? alangs[i] : ""; }
const char *Dlang(int i) const { return (0 <= i && i < MAXDPIDS) ? dlangs[i] : ""; } const char *Dlang(int i) const { return (0 <= i && i < MAXDPIDS) ? dlangs[i] : ""; }
const char *Slang(int i) const { return (0 <= i && i < MAXSPIDS) ? slangs[i] : ""; } const char *Slang(int i) const { return (0 <= i && i < MAXSPIDS) ? slangs[i] : ""; }
uchar SubtitlingType(int i) const { return (0 <= i && i < MAXSPIDS ? subtitlingTypes[i] : 0); }
uint16_t CompositionPageId(int i) const { return (0 <= i && i < MAXSPIDS ? compositionPageIds[i] : 0); }
uint16_t AncillaryPageId(int i) const { return (0 <= i && i < MAXSPIDS ? ancillaryPageIds[i] : 0); }
int Tpid(void) const { return tpid; } int Tpid(void) const { return tpid; }
const int *Caids(void) const { return caids; } const int *Caids(void) const { return caids; }
int Ca(int Index = 0) const { return Index < MAXCAIDS ? caids[Index] : 0; } int Ca(int Index = 0) const { return Index < MAXCAIDS ? caids[Index] : 0; }
@ -226,6 +232,7 @@ public:
void SetCaDescriptors(int Level); void SetCaDescriptors(int Level);
void SetLinkChannels(cLinkChannels *LinkChannels); void SetLinkChannels(cLinkChannels *LinkChannels);
void SetRefChannel(cChannel *RefChannel); void SetRefChannel(cChannel *RefChannel);
void SetSubtitlingDescriptors(uchar *SubtitlingTypes, uint16_t *CompositionPageIds, uint16_t *AncillaryPageIds);
}; };
class cChannels : public cRwLock, public cConfig<cChannel> { class cChannels : public cRwLock, public cConfig<cChannel> {

40
ci.c
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: ci.c 2.1 2008/04/13 13:28:52 kls Exp $ * $Id: ci.c 2.3 2009/08/16 13:21:07 kls Exp $
*/ */
#include "ci.h" #include "ci.h"
@ -551,6 +551,8 @@ bool cCiApplicationInformation::EnterMenu(void)
// --- cCiCaPmt -------------------------------------------------------------- // --- cCiCaPmt --------------------------------------------------------------
#define MAXCASYSTEMIDS 64
// Ca Pmt List Management: // Ca Pmt List Management:
#define CPLM_MORE 0x00 #define CPLM_MORE 0x00
@ -574,9 +576,10 @@ private:
int length; int length;
int esInfoLengthPos; int esInfoLengthPos;
uint8_t capmt[2048]; ///< XXX is there a specified maximum? uint8_t capmt[2048]; ///< XXX is there a specified maximum?
int caDescriptorsLength; int source;
uint8_t caDescriptors[2048]; int transponder;
bool streamFlag; int programNumber;
int caSystemIds[MAXCASYSTEMIDS + 1]; // list is zero terminated!
void AddCaDescriptors(int Length, const uint8_t *Data); void AddCaDescriptors(int Length, const uint8_t *Data);
public: public:
cCiCaPmt(uint8_t CmdId, int Source, int Transponder, int ProgramNumber, const int *CaSystemIds); cCiCaPmt(uint8_t CmdId, int Source, int Transponder, int ProgramNumber, const int *CaSystemIds);
@ -589,7 +592,17 @@ public:
cCiCaPmt::cCiCaPmt(uint8_t CmdId, int Source, int Transponder, int ProgramNumber, const int *CaSystemIds) cCiCaPmt::cCiCaPmt(uint8_t CmdId, int Source, int Transponder, int ProgramNumber, const int *CaSystemIds)
{ {
cmdId = CmdId; cmdId = CmdId;
caDescriptorsLength = GetCaDescriptors(Source, Transponder, ProgramNumber, CaSystemIds, sizeof(caDescriptors), caDescriptors, streamFlag); source = Source;
transponder = Transponder;
programNumber = ProgramNumber;
int i = 0;
if (CaSystemIds) {
for (; CaSystemIds[i]; i++)
caSystemIds[i] = CaSystemIds[i];
}
caSystemIds[i] = 0;
uint8_t caDescriptors[512];
int caDescriptorsLength = GetCaDescriptors(source, transponder, programNumber, caSystemIds, sizeof(caDescriptors), caDescriptors, 0);
length = 0; length = 0;
capmt[length++] = CPLM_ONLY; capmt[length++] = CPLM_ONLY;
capmt[length++] = (ProgramNumber >> 8) & 0xFF; capmt[length++] = (ProgramNumber >> 8) & 0xFF;
@ -597,8 +610,9 @@ cCiCaPmt::cCiCaPmt(uint8_t CmdId, int Source, int Transponder, int ProgramNumber
capmt[length++] = 0x01; // version_number, current_next_indicator - apparently vn doesn't matter, but cni must be 1 capmt[length++] = 0x01; // version_number, current_next_indicator - apparently vn doesn't matter, but cni must be 1
esInfoLengthPos = length; esInfoLengthPos = length;
capmt[length++] = 0x00; // program_info_length H (at program level) capmt[length++] = 0x00; // program_info_length H (at program level)
capmt[length++] = 0x00; // program_info_length L capmt[length++] = 0x01; // program_info_length L
if (!streamFlag) capmt[length++] = cmdId;
if (caDescriptorsLength > 0)
AddCaDescriptors(caDescriptorsLength, caDescriptors); AddCaDescriptors(caDescriptorsLength, caDescriptors);
} }
@ -610,14 +624,17 @@ void cCiCaPmt::SetListManagement(uint8_t ListManagement)
void cCiCaPmt::AddPid(int Pid, uint8_t StreamType) void cCiCaPmt::AddPid(int Pid, uint8_t StreamType)
{ {
if (Pid) { if (Pid) {
uint8_t caDescriptors[512];
int caDescriptorsLength = GetCaDescriptors(source, transponder, programNumber, caSystemIds, sizeof(caDescriptors), caDescriptors, Pid);
//XXX buffer overflow check??? //XXX buffer overflow check???
capmt[length++] = StreamType; capmt[length++] = StreamType;
capmt[length++] = (Pid >> 8) & 0xFF; capmt[length++] = (Pid >> 8) & 0xFF;
capmt[length++] = Pid & 0xFF; capmt[length++] = Pid & 0xFF;
esInfoLengthPos = length; esInfoLengthPos = length;
capmt[length++] = 0x00; // ES_info_length H (at ES level) capmt[length++] = 0x00; // ES_info_length H (at ES level)
capmt[length++] = 0x00; // ES_info_length L capmt[length++] = 0x01; // ES_info_length L
if (streamFlag) capmt[length++] = cmdId;
if (caDescriptorsLength > 0)
AddCaDescriptors(caDescriptorsLength, caDescriptors); AddCaDescriptors(caDescriptorsLength, caDescriptors);
} }
} }
@ -625,8 +642,7 @@ void cCiCaPmt::AddPid(int Pid, uint8_t StreamType)
void cCiCaPmt::AddCaDescriptors(int Length, const uint8_t *Data) void cCiCaPmt::AddCaDescriptors(int Length, const uint8_t *Data)
{ {
if (esInfoLengthPos) { if (esInfoLengthPos) {
if (length + Length < int(sizeof(capmt))) { if (length + Length <= int(sizeof(capmt))) {
capmt[length++] = cmdId;
memcpy(capmt + length, Data, Length); memcpy(capmt + length, Data, Length);
length += Length; length += Length;
int l = length - esInfoLengthPos - 2; int l = length - esInfoLengthPos - 2;
@ -643,8 +659,6 @@ void cCiCaPmt::AddCaDescriptors(int Length, const uint8_t *Data)
// --- cCiConditionalAccessSupport ------------------------------------------- // --- cCiConditionalAccessSupport -------------------------------------------
#define MAXCASYSTEMIDS 64
// CA Enable Ids: // CA Enable Ids:
#define CAEI_POSSIBLE 0x01 #define CAEI_POSSIBLE 0x01

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: config.h 2.13 2009/05/21 11:11:32 kls Exp $ * $Id: config.h 2.14 2009/06/21 10:02:49 kls Exp $
*/ */
#ifndef __CONFIG_H #ifndef __CONFIG_H
@ -22,13 +22,13 @@
// VDR's own version number: // VDR's own version number:
#define VDRVERSION "1.7.8" #define VDRVERSION "1.7.9"
#define VDRVERSNUM 10708 // Version * 10000 + Major * 100 + Minor #define VDRVERSNUM 10709 // Version * 10000 + Major * 100 + Minor
// The plugin API's version number: // The plugin API's version number:
#define APIVERSION "1.7.8" #define APIVERSION "1.7.9"
#define APIVERSNUM 10708 // Version * 10000 + Major * 100 + Minor #define APIVERSNUM 10709 // Version * 10000 + Major * 100 + Minor
// When loading plugins, VDR searches them by their APIVERSION, which // When loading plugins, VDR searches them by their APIVERSION, which
// may be smaller than VDRVERSION in case there have been no changes to // may be smaller than VDRVERSION in case there have been no changes to

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: device.c 2.23 2009/06/06 13:25:58 kls Exp $ * $Id: device.c 2.25 2009/08/16 10:54:36 kls Exp $
*/ */
#include "device.h" #include "device.h"
@ -1293,9 +1293,11 @@ int cDevice::PlayTsVideo(const uchar *Data, int Length)
int l; int l;
while (const uchar *p = tsToPesVideo.GetPes(l)) { while (const uchar *p = tsToPesVideo.GetPes(l)) {
int w = PlayVideo(p, l); int w = PlayVideo(p, l);
if (w <= 0) if (w <= 0) {
tsToPesVideo.SetRepeatLast();
return w; return w;
} }
}
tsToPesVideo.Reset(); tsToPesVideo.Reset();
} }
tsToPesVideo.PutTs(Data, Length); tsToPesVideo.PutTs(Data, Length);
@ -1308,8 +1310,10 @@ int cDevice::PlayTsAudio(const uchar *Data, int Length)
int l; int l;
if (const uchar *p = tsToPesAudio.GetPes(l)) { if (const uchar *p = tsToPesAudio.GetPes(l)) {
int w = PlayAudio(p, l, 0); int w = PlayAudio(p, l, 0);
if (w <= 0) if (w <= 0) {
tsToPesAudio.SetRepeatLast();
return w; return w;
}
tsToPesAudio.Reset(); tsToPesAudio.Reset();
} }
tsToPesAudio.PutTs(Data, Length); tsToPesAudio.PutTs(Data, Length);

9
eit.c
View File

@ -8,7 +8,7 @@
* Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>. * Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>.
* Adapted to 'libsi' for VDR 1.3.0 by Marcel Wiesweg <marcel.wiesweg@gmx.de>. * Adapted to 'libsi' for VDR 1.3.0 by Marcel Wiesweg <marcel.wiesweg@gmx.de>.
* *
* $Id: eit.c 2.5 2009/05/15 12:34:43 kls Exp $ * $Id: eit.c 2.6 2009/06/21 13:46:20 kls Exp $
*/ */
#include "eit.h" #include "eit.h"
@ -322,9 +322,8 @@ cTDT::cTDT(const u_char *Data)
cEitFilter::cEitFilter(void) cEitFilter::cEitFilter(void)
{ {
Set(0x12, 0x4E, 0xFE); // event info, actual(0x4E)/other(0x4F) TS, present/following Set(0x12, 0x40, 0xC0); // event info now&next actual/other TS (0x4E/0x4F), future actual/other TS (0x5X/0x6X)
Set(0x12, 0x50, 0xF0); // event info, actual TS, schedule(0x50)/schedule for future days(0x5X) if (Setup.SetSystemTime && Setup.TimeTransponder)
Set(0x12, 0x60, 0xF0); // event info, other TS, schedule(0x60)/schedule for future days(0x6X)
Set(0x14, 0x70); // TDT Set(0x14, 0x70); // TDT
} }
@ -332,6 +331,7 @@ void cEitFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length
{ {
switch (Pid) { switch (Pid) {
case 0x12: { case 0x12: {
if (Tid >= 0x4E && Tid <= 0x6F) {
cSchedulesLock SchedulesLock(true, 10); cSchedulesLock SchedulesLock(true, 10);
cSchedules *Schedules = (cSchedules *)cSchedules::Schedules(SchedulesLock); cSchedules *Schedules = (cSchedules *)cSchedules::Schedules(SchedulesLock);
if (Schedules) if (Schedules)
@ -347,6 +347,7 @@ void cEitFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length
cEIT EIT(Schedules, Source(), Tid, Data, true); cEIT EIT(Schedules, Source(), Tid, Data, true);
} }
} }
}
break; break;
case 0x14: { case 0x14: {
if (Setup.SetSystemTime && Setup.TimeTransponder && ISTRANSPONDER(Transponder(), Setup.TimeTransponder)) if (Setup.SetSystemTime && Setup.TimeTransponder && ISTRANSPONDER(Transponder(), Setup.TimeTransponder))

3
menu.c
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: menu.c 2.8 2009/05/21 11:10:38 kls Exp $ * $Id: menu.c 2.9 2009/06/21 09:56:06 kls Exp $
*/ */
#include "menu.h" #include "menu.h"
@ -2133,6 +2133,7 @@ cMenuSetupBase::cMenuSetupBase(void)
void cMenuSetupBase::Store(void) void cMenuSetupBase::Store(void)
{ {
Setup = data; Setup = data;
cOsdProvider::UpdateOsdSize(true);
Setup.Save(); Setup.Save();
} }

71
pat.c
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: pat.c 2.2 2008/07/06 14:01:32 kls Exp $ * $Id: pat.c 2.4 2009/08/16 15:01:03 kls Exp $
*/ */
#include "pat.h" #include "pat.h"
@ -21,23 +21,23 @@
class cCaDescriptor : public cListObject { class cCaDescriptor : public cListObject {
private: private:
int caSystem; int caSystem;
bool stream; int esPid;
int length; int length;
uchar *data; uchar *data;
public: public:
cCaDescriptor(int CaSystem, int CaPid, bool Stream, int Length, const uchar *Data); cCaDescriptor(int CaSystem, int CaPid, int EsPid, int Length, const uchar *Data);
virtual ~cCaDescriptor(); virtual ~cCaDescriptor();
bool operator== (const cCaDescriptor &arg) const; bool operator== (const cCaDescriptor &arg) const;
int CaSystem(void) { return caSystem; } int CaSystem(void) { return caSystem; }
int Stream(void) { return stream; } int EsPid(void) { return esPid; }
int Length(void) const { return length; } int Length(void) const { return length; }
const uchar *Data(void) const { return data; } const uchar *Data(void) const { return data; }
}; };
cCaDescriptor::cCaDescriptor(int CaSystem, int CaPid, bool Stream, int Length, const uchar *Data) cCaDescriptor::cCaDescriptor(int CaSystem, int CaPid, int EsPid, int Length, const uchar *Data)
{ {
caSystem = CaSystem; caSystem = CaSystem;
stream = Stream; esPid = EsPid;
length = Length + 6; length = Length + 6;
data = MALLOC(uchar, length); data = MALLOC(uchar, length);
data[0] = SI::CaDescriptorTag; data[0] = SI::CaDescriptorTag;
@ -57,7 +57,7 @@ cCaDescriptor::~cCaDescriptor()
bool cCaDescriptor::operator== (const cCaDescriptor &arg) const bool cCaDescriptor::operator== (const cCaDescriptor &arg) const
{ {
return length == arg.length && memcmp(data, arg.data, length) == 0; return esPid == arg.esPid && length == arg.length && memcmp(data, arg.data, length) == 0;
} }
// --- cCaDescriptors -------------------------------------------------------- // --- cCaDescriptors --------------------------------------------------------
@ -77,8 +77,8 @@ public:
bool Is(int Source, int Transponder, int ServiceId); bool Is(int Source, int Transponder, int ServiceId);
bool Is(cCaDescriptors * CaDescriptors); bool Is(cCaDescriptors * CaDescriptors);
bool Empty(void) { return caDescriptors.Count() == 0; } bool Empty(void) { return caDescriptors.Count() == 0; }
void AddCaDescriptor(SI::CaDescriptor *d, bool Stream); void AddCaDescriptor(SI::CaDescriptor *d, int EsPid);
int GetCaDescriptors(const int *CaSystemIds, int BufSize, uchar *Data, bool &StreamFlag); int GetCaDescriptors(const int *CaSystemIds, int BufSize, uchar *Data, int EsPid);
const int *CaIds(void) { return caIds; } const int *CaIds(void) { return caIds; }
}; };
@ -126,9 +126,9 @@ void cCaDescriptors::AddCaId(int CaId)
} }
} }
void cCaDescriptors::AddCaDescriptor(SI::CaDescriptor *d, bool Stream) void cCaDescriptors::AddCaDescriptor(SI::CaDescriptor *d, int EsPid)
{ {
cCaDescriptor *nca = new cCaDescriptor(d->getCaType(), d->getCaPid(), Stream, d->privateData.getLength(), d->privateData.getData()); cCaDescriptor *nca = new cCaDescriptor(d->getCaType(), d->getCaPid(), EsPid, d->privateData.getLength(), d->privateData.getData());
for (cCaDescriptor *ca = caDescriptors.First(); ca; ca = caDescriptors.Next(ca)) { for (cCaDescriptor *ca = caDescriptors.First(); ca; ca = caDescriptors.Next(ca)) {
if (*ca == *nca) { if (*ca == *nca) {
delete nca; delete nca;
@ -141,28 +141,30 @@ void cCaDescriptors::AddCaDescriptor(SI::CaDescriptor *d, bool Stream)
#ifdef DEBUG_CA_DESCRIPTORS #ifdef DEBUG_CA_DESCRIPTORS
char buffer[1024]; char buffer[1024];
char *q = buffer; char *q = buffer;
q += sprintf(q, "CAM: %04X %5d %5d %04X %d -", source, transponder, serviceId, d->getCaType(), Stream); q += sprintf(q, "CAM: %04X %5d %5d %04X %04X -", source, transponder, serviceId, d->getCaType(), EsPid);
for (int i = 0; i < nca->Length(); i++) for (int i = 0; i < nca->Length(); i++)
q += sprintf(q, " %02X", nca->Data()[i]); q += sprintf(q, " %02X", nca->Data()[i]);
dsyslog(buffer); dsyslog(buffer);
#endif #endif
} }
int cCaDescriptors::GetCaDescriptors(const int *CaSystemIds, int BufSize, uchar *Data, bool &StreamFlag) // EsPid is to select the "type" of CaDescriptor to be returned
// >0 - CaDescriptor for the particular esPid
// =0 - common CaDescriptor
// <0 - all CaDescriptors regardless of type (old default)
int cCaDescriptors::GetCaDescriptors(const int *CaSystemIds, int BufSize, uchar *Data, int EsPid)
{ {
if (!CaSystemIds || !*CaSystemIds) if (!CaSystemIds || !*CaSystemIds)
return 0; return 0;
if (BufSize > 0 && Data) { if (BufSize > 0 && Data) {
int length = 0; int length = 0;
int IsStream = -1;
for (cCaDescriptor *d = caDescriptors.First(); d; d = caDescriptors.Next(d)) { for (cCaDescriptor *d = caDescriptors.First(); d; d = caDescriptors.Next(d)) {
if (EsPid < 0 || d->EsPid() == EsPid) {
const int *caids = CaSystemIds; const int *caids = CaSystemIds;
do { do {
if (d->CaSystem() == *caids) { if (d->CaSystem() == *caids) {
if (length + d->Length() <= BufSize) { if (length + d->Length() <= BufSize) {
if (IsStream >= 0 && IsStream != d->Stream())
dsyslog("CAM: different stream flag in CA descriptors");
IsStream = d->Stream();
memcpy(Data + length, d->Data(), d->Length()); memcpy(Data + length, d->Data(), d->Length());
length += d->Length(); length += d->Length();
} }
@ -171,7 +173,7 @@ int cCaDescriptors::GetCaDescriptors(const int *CaSystemIds, int BufSize, uchar
} }
} while (*++caids); } while (*++caids);
} }
StreamFlag = IsStream == 1; }
return length; return length;
} }
return -1; return -1;
@ -187,7 +189,7 @@ public:
// Returns 0 if this is an already known descriptor, // Returns 0 if this is an already known descriptor,
// 1 if it is an all new descriptor with actual contents, // 1 if it is an all new descriptor with actual contents,
// and 2 if an existing descriptor was changed. // and 2 if an existing descriptor was changed.
int GetCaDescriptors(int Source, int Transponder, int ServiceId, const int *CaSystemIds, int BufSize, uchar *Data, bool &StreamFlag); int GetCaDescriptors(int Source, int Transponder, int ServiceId, const int *CaSystemIds, int BufSize, uchar *Data, int EsPid);
}; };
int cCaDescriptorHandler::AddCaDescriptors(cCaDescriptors *CaDescriptors) int cCaDescriptorHandler::AddCaDescriptors(cCaDescriptors *CaDescriptors)
@ -208,22 +210,21 @@ int cCaDescriptorHandler::AddCaDescriptors(cCaDescriptors *CaDescriptors)
return CaDescriptors->Empty() ? 0 : 1; return CaDescriptors->Empty() ? 0 : 1;
} }
int cCaDescriptorHandler::GetCaDescriptors(int Source, int Transponder, int ServiceId, const int *CaSystemIds, int BufSize, uchar *Data, bool &StreamFlag) int cCaDescriptorHandler::GetCaDescriptors(int Source, int Transponder, int ServiceId, const int *CaSystemIds, int BufSize, uchar *Data, int EsPid)
{ {
cMutexLock MutexLock(&mutex); cMutexLock MutexLock(&mutex);
StreamFlag = false;
for (cCaDescriptors *ca = First(); ca; ca = Next(ca)) { for (cCaDescriptors *ca = First(); ca; ca = Next(ca)) {
if (ca->Is(Source, Transponder, ServiceId)) if (ca->Is(Source, Transponder, ServiceId))
return ca->GetCaDescriptors(CaSystemIds, BufSize, Data, StreamFlag); return ca->GetCaDescriptors(CaSystemIds, BufSize, Data, EsPid);
} }
return 0; return 0;
} }
cCaDescriptorHandler CaDescriptorHandler; cCaDescriptorHandler CaDescriptorHandler;
int GetCaDescriptors(int Source, int Transponder, int ServiceId, const int *CaSystemIds, int BufSize, uchar *Data, bool &StreamFlag) int GetCaDescriptors(int Source, int Transponder, int ServiceId, const int *CaSystemIds, int BufSize, uchar *Data, int EsPid)
{ {
return CaDescriptorHandler.GetCaDescriptors(Source, Transponder, ServiceId, CaSystemIds, BufSize, Data, StreamFlag); return CaDescriptorHandler.GetCaDescriptors(Source, Transponder, ServiceId, CaSystemIds, BufSize, Data, EsPid);
} }
// --- cPatFilter ------------------------------------------------------------ // --- cPatFilter ------------------------------------------------------------
@ -322,7 +323,7 @@ void cPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length
cCaDescriptors *CaDescriptors = new cCaDescriptors(Channel->Source(), Channel->Transponder(), Channel->Sid()); cCaDescriptors *CaDescriptors = new cCaDescriptors(Channel->Source(), Channel->Transponder(), Channel->Sid());
// Scan the common loop: // Scan the common loop:
for (SI::Loop::Iterator it; (d = (SI::CaDescriptor*)pmt.commonDescriptors.getNext(it, SI::CaDescriptorTag)); ) { for (SI::Loop::Iterator it; (d = (SI::CaDescriptor*)pmt.commonDescriptors.getNext(it, SI::CaDescriptorTag)); ) {
CaDescriptors->AddCaDescriptor(d, false); CaDescriptors->AddCaDescriptor(d, 0);
delete d; delete d;
} }
// Scan the stream-specific loop: // Scan the stream-specific loop:
@ -333,6 +334,9 @@ void cPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length
int Apids[MAXAPIDS + 1] = { 0 }; // these lists are zero-terminated int Apids[MAXAPIDS + 1] = { 0 }; // these lists are zero-terminated
int Dpids[MAXDPIDS + 1] = { 0 }; int Dpids[MAXDPIDS + 1] = { 0 };
int Spids[MAXSPIDS + 1] = { 0 }; int Spids[MAXSPIDS + 1] = { 0 };
uchar SubtitlingTypes[MAXSPIDS + 1] = { 0 };
uint16_t CompositionPageIds[MAXSPIDS + 1] = { 0 };
uint16_t AncillaryPageIds[MAXSPIDS + 1] = { 0 };
char ALangs[MAXAPIDS][MAXLANGCODE2] = { "" }; char ALangs[MAXAPIDS][MAXLANGCODE2] = { "" };
char DLangs[MAXDPIDS][MAXLANGCODE2] = { "" }; char DLangs[MAXDPIDS][MAXLANGCODE2] = { "" };
char SLangs[MAXSPIDS][MAXLANGCODE2] = { "" }; char SLangs[MAXSPIDS][MAXLANGCODE2] = { "" };
@ -341,11 +345,12 @@ void cPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length
int NumDpids = 0; int NumDpids = 0;
int NumSpids = 0; int NumSpids = 0;
for (SI::Loop::Iterator it; pmt.streamLoop.getNext(stream, it); ) { for (SI::Loop::Iterator it; pmt.streamLoop.getNext(stream, it); ) {
int esPid = stream.getPid();
switch (stream.getStreamType()) { switch (stream.getStreamType()) {
case 1: // STREAMTYPE_11172_VIDEO case 1: // STREAMTYPE_11172_VIDEO
case 2: // STREAMTYPE_13818_VIDEO case 2: // STREAMTYPE_13818_VIDEO
case 0x1B: // MPEG4 case 0x1B: // MPEG4
Vpid = stream.getPid(); Vpid = esPid;
Ppid = pmt.getPCRPid(); Ppid = pmt.getPCRPid();
Vtype = stream.getStreamType(); Vtype = stream.getStreamType();
break; break;
@ -353,7 +358,7 @@ void cPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length
case 4: // STREAMTYPE_13818_AUDIO case 4: // STREAMTYPE_13818_AUDIO
{ {
if (NumApids < MAXAPIDS) { if (NumApids < MAXAPIDS) {
Apids[NumApids] = stream.getPid(); Apids[NumApids] = esPid;
SI::Descriptor *d; SI::Descriptor *d;
for (SI::Loop::Iterator it; (d = stream.streamDescriptors.getNext(it)); ) { for (SI::Loop::Iterator it; (d = stream.streamDescriptors.getNext(it)); ) {
switch (d->getDescriptorTag()) { switch (d->getDescriptorTag()) {
@ -392,17 +397,20 @@ void cPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length
for (SI::Loop::Iterator it; (d = stream.streamDescriptors.getNext(it)); ) { for (SI::Loop::Iterator it; (d = stream.streamDescriptors.getNext(it)); ) {
switch (d->getDescriptorTag()) { switch (d->getDescriptorTag()) {
case SI::AC3DescriptorTag: case SI::AC3DescriptorTag:
dpid = stream.getPid(); dpid = esPid;
break; break;
case SI::SubtitlingDescriptorTag: case SI::SubtitlingDescriptorTag:
if (NumSpids < MAXSPIDS) { if (NumSpids < MAXSPIDS) {
Spids[NumSpids] = stream.getPid(); Spids[NumSpids] = esPid;
SI::SubtitlingDescriptor *sd = (SI::SubtitlingDescriptor *)d; SI::SubtitlingDescriptor *sd = (SI::SubtitlingDescriptor *)d;
SI::SubtitlingDescriptor::Subtitling sub; SI::SubtitlingDescriptor::Subtitling sub;
char *s = SLangs[NumSpids]; char *s = SLangs[NumSpids];
int n = 0; int n = 0;
for (SI::Loop::Iterator it; sd->subtitlingLoop.getNext(sub, it); ) { for (SI::Loop::Iterator it; sd->subtitlingLoop.getNext(sub, it); ) {
if (sub.languageCode[0]) { if (sub.languageCode[0]) {
SubtitlingTypes[NumSpids] = sub.getSubtitlingType();
CompositionPageIds[NumSpids] = sub.getCompositionPageId();
AncillaryPageIds[NumSpids] = sub.getAncillaryPageId();
if (n > 0) if (n > 0)
*s++ = '+'; *s++ = '+';
strn0cpy(s, I18nNormalizeLanguageCode(sub.languageCode), MAXLANGCODE1); strn0cpy(s, I18nNormalizeLanguageCode(sub.languageCode), MAXLANGCODE1);
@ -415,7 +423,7 @@ void cPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length
} }
break; break;
case SI::TeletextDescriptorTag: case SI::TeletextDescriptorTag:
Tpid = stream.getPid(); Tpid = esPid;
break; break;
case SI::ISO639LanguageDescriptorTag: { case SI::ISO639LanguageDescriptorTag: {
SI::ISO639LanguageDescriptor *ld = (SI::ISO639LanguageDescriptor *)d; SI::ISO639LanguageDescriptor *ld = (SI::ISO639LanguageDescriptor *)d;
@ -438,13 +446,14 @@ void cPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length
//default: printf("PID: %5d %5d %2d %3d %3d\n", pmt.getServiceId(), stream.getPid(), stream.getStreamType(), pmt.getVersionNumber(), Channel->Number());//XXX //default: printf("PID: %5d %5d %2d %3d %3d\n", pmt.getServiceId(), stream.getPid(), stream.getStreamType(), pmt.getVersionNumber(), Channel->Number());//XXX
} }
for (SI::Loop::Iterator it; (d = (SI::CaDescriptor*)stream.streamDescriptors.getNext(it, SI::CaDescriptorTag)); ) { for (SI::Loop::Iterator it; (d = (SI::CaDescriptor*)stream.streamDescriptors.getNext(it, SI::CaDescriptorTag)); ) {
CaDescriptors->AddCaDescriptor(d, true); CaDescriptors->AddCaDescriptor(d, esPid);
delete d; delete d;
} }
} }
if (Setup.UpdateChannels >= 2) { if (Setup.UpdateChannels >= 2) {
Channel->SetPids(Vpid, Ppid, Vtype, Apids, ALangs, Dpids, DLangs, Spids, SLangs, Tpid); Channel->SetPids(Vpid, Ppid, Vtype, Apids, ALangs, Dpids, DLangs, Spids, SLangs, Tpid);
Channel->SetCaIds(CaDescriptors->CaIds()); Channel->SetCaIds(CaDescriptors->CaIds());
Channel->SetSubtitlingDescriptors(SubtitlingTypes, CompositionPageIds, AncillaryPageIds);
} }
Channel->SetCaDescriptors(CaDescriptorHandler.AddCaDescriptors(CaDescriptors)); Channel->SetCaDescriptors(CaDescriptorHandler.AddCaDescriptors(CaDescriptors));
} }

4
pat.h
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: pat.h 2.0 2007/01/05 10:42:11 kls Exp $ * $Id: pat.h 2.1 2009/06/14 11:14:00 kls Exp $
*/ */
#ifndef __PAT_H #ifndef __PAT_H
@ -32,7 +32,7 @@ public:
void Trigger(void); void Trigger(void);
}; };
int GetCaDescriptors(int Source, int Transponder, int ServiceId, const int *CaSystemIds, int BufSize, uchar *Data, bool &StreamFlag); int GetCaDescriptors(int Source, int Transponder, int ServiceId, const int *CaSystemIds, int BufSize, uchar *Data, int EsPid);
///< Gets all CA descriptors for a given channel. ///< Gets all CA descriptors for a given channel.
///< Copies all available CA descriptors for the given Source, Transponder and ServiceId ///< Copies all available CA descriptors for the given Source, Transponder and ServiceId
///< into the provided buffer at Data (at most BufSize bytes). Only those CA descriptors ///< into the provided buffer at Data (at most BufSize bytes). Only those CA descriptors

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: recording.c 2.16 2009/06/13 13:34:08 kls Exp $ * $Id: recording.c 2.17 2009/08/16 10:39:43 kls Exp $
*/ */
#include "recording.h" #include "recording.h"
@ -1156,7 +1156,7 @@ void cRecordings::DelByName(const char *FileName)
if (recording) { if (recording) {
cThreadLock DeletedRecordingsLock(&DeletedRecordings); cThreadLock DeletedRecordingsLock(&DeletedRecordings);
Del(recording, false); Del(recording, false);
char *ext = strrchr(recording->FileName(), '.'); char *ext = strrchr(recording->fileName, '.');
if (ext) { if (ext) {
strncpy(ext, DELEXT, strlen(ext)); strncpy(ext, DELEXT, strlen(ext));
recording->fileSizeMB = DirSizeMB(recording->FileName()); recording->fileSizeMB = DirSizeMB(recording->FileName());

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: recording.h 2.8 2009/05/23 12:14:42 kls Exp $ * $Id: recording.h 2.9 2009/08/16 15:35:30 kls Exp $
*/ */
#ifndef __RECORDING_H #ifndef __RECORDING_H
@ -207,7 +207,7 @@ public:
}; };
// The maximum size of a single frame (up to HDTV 1920x1080): // The maximum size of a single frame (up to HDTV 1920x1080):
#define MAXFRAMESIZE (KILOBYTE(512) / TS_SIZE * TS_SIZE) // multiple of TS_SIZE to avoid breaking up TS packets #define MAXFRAMESIZE (KILOBYTE(1024) / TS_SIZE * TS_SIZE) // multiple of TS_SIZE to avoid breaking up TS packets
// The maximum file size is limited by the range that can be covered // The maximum file size is limited by the range that can be covered
// with a 40 bit 'unsigned int', which is 1TB. The actual maximum value // with a 40 bit 'unsigned int', which is 1TB. The actual maximum value

36
remux.c
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: remux.c 2.24 2009/06/06 13:24:57 kls Exp $ * $Id: remux.c 2.26 2009/08/16 15:13:42 kls Exp $
*/ */
#include "remux.h" #include "remux.h"
@ -198,7 +198,7 @@ int cPatPmtGenerator::MakeAC3Descriptor(uchar *Target)
return i; return i;
} }
int cPatPmtGenerator::MakeSubtitlingDescriptor(uchar *Target, const char *Language) int cPatPmtGenerator::MakeSubtitlingDescriptor(uchar *Target, const char *Language, uchar SubtitlingType, uint16_t CompositionPageId, uint16_t AncillaryPageId)
{ {
int i = 0; int i = 0;
Target[i++] = SI::SubtitlingDescriptorTag; Target[i++] = SI::SubtitlingDescriptorTag;
@ -206,11 +206,11 @@ int cPatPmtGenerator::MakeSubtitlingDescriptor(uchar *Target, const char *Langua
Target[i++] = *Language++; Target[i++] = *Language++;
Target[i++] = *Language++; Target[i++] = *Language++;
Target[i++] = *Language++; Target[i++] = *Language++;
Target[i++] = 0x00; // subtitling type Target[i++] = SubtitlingType;
Target[i++] = 0x00; // composition page id hi Target[i++] = CompositionPageId >> 8;
Target[i++] = 0x01; // composition page id lo Target[i++] = CompositionPageId & 0xFF;
Target[i++] = 0x00; // ancillary page id hi Target[i++] = AncillaryPageId >> 8;
Target[i++] = 0x01; // ancillary page id lo Target[i++] = AncillaryPageId & 0xFF;
IncEsInfoLength(i); IncEsInfoLength(i);
return i; return i;
} }
@ -327,7 +327,7 @@ void cPatPmtGenerator::GeneratePmt(cChannel *Channel)
} }
for (int n = 0; Channel->Spid(n); n++) { for (int n = 0; Channel->Spid(n); n++) {
i += MakeStream(buf + i, 0x06, Channel->Spid(n)); i += MakeStream(buf + i, 0x06, Channel->Spid(n));
i += MakeSubtitlingDescriptor(buf + i, Channel->Slang(n)); i += MakeSubtitlingDescriptor(buf + i, Channel->Slang(n), Channel->SubtitlingType(n), Channel->CompositionPageId(n), Channel->AncillaryPageId(n));
} }
int sl = i - SectionLength - 2 + 4; // -2 = SectionLength storage, +4 = length of CRC int sl = i - SectionLength - 2 + 4; // -2 = SectionLength storage, +4 = length of CRC
@ -610,7 +610,8 @@ bool cPatPmtParser::GetVersions(int &PatVersion, int &PmtVersion)
cTsToPes::cTsToPes(void) cTsToPes::cTsToPes(void)
{ {
data = NULL; data = NULL;
size = length = offset = 0; size = 0;
Reset();
} }
cTsToPes::~cTsToPes() cTsToPes::~cTsToPes()
@ -641,6 +642,11 @@ void cTsToPes::PutTs(const uchar *Data, int Length)
const uchar *cTsToPes::GetPes(int &Length) const uchar *cTsToPes::GetPes(int &Length)
{ {
if (repeatLast) {
repeatLast = false;
Length = lastLength;
return lastData;
}
if (offset < length && PesLongEnough(length)) { if (offset < length && PesLongEnough(length)) {
if (!PesHasLength(data)) // this is a video PES packet with undefined length if (!PesHasLength(data)) // this is a video PES packet with undefined length
offset = 6; // trigger setting PES length for initial slice offset = 6; // trigger setting PES length for initial slice
@ -661,12 +667,16 @@ const uchar *cTsToPes::GetPes(int &Length)
p[4] = l / 256; p[4] = l / 256;
p[5] = l & 0xFF; p[5] = l & 0xFF;
Length = l + 6; Length = l + 6;
lastLength = Length;
lastData = p;
return p; return p;
} }
else { else {
Length = PesLength(data); Length = PesLength(data);
if (Length <= length) { if (Length <= length) {
offset = Length; // to make sure we break out in case of garbage data offset = Length; // to make sure we break out in case of garbage data
lastLength = Length;
lastData = data;
return data; return data;
} }
} }
@ -674,9 +684,17 @@ const uchar *cTsToPes::GetPes(int &Length)
return NULL; return NULL;
} }
void cTsToPes::SetRepeatLast(void)
{
repeatLast = true;
}
void cTsToPes::Reset(void) void cTsToPes::Reset(void)
{ {
length = offset = 0; length = offset = 0;
lastData = NULL;
lastLength = 0;
repeatLast = false;
} }
// --- Some helper functions for debugging ----------------------------------- // --- Some helper functions for debugging -----------------------------------

10
remux.h
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: remux.h 2.17 2009/06/06 13:26:23 kls Exp $ * $Id: remux.h 2.19 2009/08/16 15:15:33 kls Exp $
*/ */
#ifndef __REMUX_H #ifndef __REMUX_H
@ -168,7 +168,7 @@ private:
protected: protected:
int MakeStream(uchar *Target, uchar Type, int Pid); int MakeStream(uchar *Target, uchar Type, int Pid);
int MakeAC3Descriptor(uchar *Target); int MakeAC3Descriptor(uchar *Target);
int MakeSubtitlingDescriptor(uchar *Target, const char *Language); int MakeSubtitlingDescriptor(uchar *Target, const char *Language, uchar SubtitlingType, uint16_t CompositionPageId, uint16_t AncillaryPageId);
int MakeLanguageDescriptor(uchar *Target, const char *Language); int MakeLanguageDescriptor(uchar *Target, const char *Language);
int MakeCRC(uchar *Target, const uchar *Data, int Length); int MakeCRC(uchar *Target, const uchar *Data, int Length);
void GeneratePmtPid(cChannel *Channel); void GeneratePmtPid(cChannel *Channel);
@ -252,6 +252,9 @@ private:
int size; int size;
int length; int length;
int offset; int offset;
uchar *lastData;
int lastLength;
bool repeatLast;
public: public:
cTsToPes(void); cTsToPes(void);
~cTsToPes(); ~cTsToPes();
@ -279,6 +282,9 @@ public:
///< TS packet that will be given to PutTs() has the "payload start" flag ///< TS packet that will be given to PutTs() has the "payload start" flag
///< set, because this is the only way to determine the end of a video PES ///< set, because this is the only way to determine the end of a video PES
///< packet. ///< packet.
void SetRepeatLast(void);
///< Makes the next call to GetPes() return exactly the same data as the
///< last one (provided there was no call to Reset() in the meantime).
void Reset(void); void Reset(void);
///< Resets the converter. This needs to be called after a PES packet has ///< Resets the converter. This needs to be called after a PES packet has
///< been fetched by a call to GetPes(), and before the next call to ///< been fetched by a call to GetPes(), and before the next call to

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: timers.c 2.1 2008/04/13 12:41:41 kls Exp $ * $Id: timers.c 2.3 2009/08/09 12:43:20 kls Exp $
*/ */
#include "timers.h" #include "timers.h"
@ -51,6 +51,11 @@ cTimer::cTimer(bool Instant, bool Pause, cChannel *Channel)
event = NULL; event = NULL;
if (Instant && channel) if (Instant && channel)
snprintf(file, sizeof(file), "%s%s", Setup.MarkInstantRecord ? "@" : "", *Setup.NameInstantRecord ? Setup.NameInstantRecord : channel->Name()); snprintf(file, sizeof(file), "%s%s", Setup.MarkInstantRecord ? "@" : "", *Setup.NameInstantRecord ? Setup.NameInstantRecord : channel->Name());
if (VfatFileSystem && (Utf8StrLen(file) > VFAT_MAX_FILENAME)) {
dsyslog("timer file name too long for VFAT file system: '%s'", file);
file[Utf8SymChars(file, VFAT_MAX_FILENAME)] = 0;
dsyslog("timer file name truncated to '%s'", file);
}
} }
cTimer::cTimer(const cEvent *Event) cTimer::cTimer(const cEvent *Event)
@ -83,6 +88,11 @@ cTimer::cTimer(const cEvent *Event)
const char *Title = Event->Title(); const char *Title = Event->Title();
if (!isempty(Title)) if (!isempty(Title))
Utf8Strn0Cpy(file, Event->Title(), sizeof(file)); Utf8Strn0Cpy(file, Event->Title(), sizeof(file));
if (VfatFileSystem && (Utf8StrLen(file) > VFAT_MAX_FILENAME)) {
dsyslog("timer file name too long for VFAT file system: '%s'", file);
file[Utf8SymChars(file, VFAT_MAX_FILENAME)] = 0;
dsyslog("timer file name truncated to '%s'", file);
}
aux = NULL; aux = NULL;
event = NULL; // let SetEvent() be called to get a log message event = NULL; // let SetEvent() be called to get a log message
} }
@ -296,13 +306,13 @@ bool cTimer::Parse(const char *s)
p++; p++;
else else
p = filebuffer; p = filebuffer;
if (strlen(p) > VFAT_MAX_FILENAME) { if (Utf8StrLen(p) > VFAT_MAX_FILENAME) {
dsyslog("timer file name too long for VFAT file system: '%s'", p); dsyslog("timer file name too long for VFAT file system: '%s'", p);
p[VFAT_MAX_FILENAME] = 0; p[Utf8SymChars(p, VFAT_MAX_FILENAME)] = 0;
dsyslog("timer file name truncated to '%s'", p); dsyslog("timer file name truncated to '%s'", p);
} }
} }
Utf8Strn0Cpy(file, filebuffer, MaxFileName); Utf8Strn0Cpy(file, filebuffer, sizeof(file));
strreplace(file, '|', ':'); strreplace(file, '|', ':');
if (isnumber(channelbuffer)) if (isnumber(channelbuffer))
channel = Channels.GetByNumber(atoi(channelbuffer)); channel = Channels.GetByNumber(atoi(channelbuffer));
@ -463,7 +473,7 @@ int cTimer::Matches(const cEvent *Event, int *Overlap) const
bool cTimer::Expired(void) const bool cTimer::Expired(void) const
{ {
return IsSingleEvent() && !Recording() && StopTime() + EXPIRELATENCY <= time(NULL) && (!HasFlags(tfVps) || !event); return IsSingleEvent() && !Recording() && StopTime() + EXPIRELATENCY <= time(NULL) && (!HasFlags(tfVps) || !event || !event->Vps());
} }
time_t cTimer::StartTime(void) const time_t cTimer::StartTime(void) const

12
vdr.1
View File

@ -8,7 +8,7 @@
.\" License as specified in the file COPYING that comes with the .\" License as specified in the file COPYING that comes with the
.\" vdr distribution. .\" vdr distribution.
.\" .\"
.\" $Id: vdr.1 2.1 2009/01/18 11:05:56 kls Exp $ .\" $Id: vdr.1 2.2 2009/08/16 10:28:39 kls Exp $
.\" .\"
.TH vdr 1 "10 Feb 2008" "1.6" "Video Disk Recorder" .TH vdr 1 "10 Feb 2008" "1.6" "Video Disk Recorder"
.SH NAME .SH NAME
@ -205,16 +205,16 @@ User definable commands (executed from the \fBCommands\fR menu).
SVDRP host configuration, defining which hosts or networks are given SVDRP host configuration, defining which hosts or networks are given
access to the SVDRP port. access to the SVDRP port.
.TP .TP
.I marks.vdr .I marks
Contains the editing marks defined for a recording. Contains the editing marks defined for a recording.
.TP .TP
.I info.vdr .I info
Contains a description of the recording. Contains a description of the recording.
.TP .TP
.I resume.vdr .I resume
Contains the index into the recording where the last replay session left off. Contains the index into the recording where the last replay session left off.
.TP .TP
.I index.vdr .I index
Contains the file number, offset and type of each frame of the recording. Contains the file number, offset and type of each frame of the recording.
.TP .TP
.I remote.conf .I remote.conf
@ -223,7 +223,7 @@ Contains the key assignments for the remote control.
.I keymacros.conf .I keymacros.conf
Contains user defined remote control key macros. Contains user defined remote control key macros.
.TP .TP
.IR 001.vdr\ ...\ 255.vdr .IR 00001.ts\ ...\ 65535.ts
The actual data files of a recording. The actual data files of a recording.
.TP .TP
.I epg.data .I epg.data