diff options
-rw-r--r-- | CONTRIBUTORS | 11 | ||||
-rw-r--r-- | HISTORY | 23 | ||||
-rw-r--r-- | channels.c | 18 | ||||
-rw-r--r-- | channels.h | 9 | ||||
-rw-r--r-- | ci.c | 40 | ||||
-rw-r--r-- | config.h | 10 | ||||
-rw-r--r-- | device.c | 10 | ||||
-rw-r--r-- | eit.c | 33 | ||||
-rw-r--r-- | menu.c | 3 | ||||
-rw-r--r-- | pat.c | 91 | ||||
-rw-r--r-- | pat.h | 4 | ||||
-rw-r--r-- | recording.c | 4 | ||||
-rw-r--r-- | recording.h | 4 | ||||
-rw-r--r-- | remux.c | 36 | ||||
-rw-r--r-- | remux.h | 10 | ||||
-rw-r--r-- | timers.c | 20 | ||||
-rw-r--r-- | vdr.1 | 12 |
17 files changed, 228 insertions, 110 deletions
diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 7cdfa22..f80bce2 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -1079,6 +1079,8 @@ Rolf Ahrenberg <rahrenbe@cc.hut.fi> for adding cThread::SetIOPriority() and using it in cRemoveDeletedRecordingsThread for suggesting to introduce cDevice::GetOsdSize() 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> 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() for reporting a problem with calculating menu colum widths in case the font has a 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> 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 split a large disk into separate areas for VDR's video data and other stuff 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> 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 fixing some compiler warnings with gcc-4.2.0 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> for fixing processing the PDCDescriptor in 'libsi' on big endian systems @@ -2478,3 +2486,6 @@ Günter Niedermeier <linuxtv@ncs-online.de> Martin Neuditschko <yosuke.tomoe@gmx.net> for reporting a problem with error messages from cDvbDevice::GetVideoSize() on systems with no real primary replay device + +Mikko Tuumanen <mikko.tuumanen@utu.fi> + for implementing full handling of subtitling descriptors @@ -6133,5 +6133,26 @@ Video Disk Recorder Revision History default size (reported by Reinhard Nissl). - Added a plausibility check for the OSD percentage parameters 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). + +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). @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * 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" @@ -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) { if (caids[0] && caids[0] <= CA_USER_MAX) @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * 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 @@ -129,6 +129,9 @@ private: char dlangs[MAXDPIDS][MAXLANGCODE2]; int spids[MAXSPIDS + 1]; // list is zero-terminated char slangs[MAXSPIDS][MAXLANGCODE2]; + uchar subtitlingTypes[MAXSPIDS]; + uint16_t compositionPageIds[MAXSPIDS]; + uint16_t ancillaryPageIds[MAXSPIDS]; int tpid; int caids[MAXCAIDS + 1]; // list is zero-terminated int nid; @@ -185,6 +188,9 @@ public: 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 *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; } const int *Caids(void) const { return caids; } int Ca(int Index = 0) const { return Index < MAXCAIDS ? caids[Index] : 0; } @@ -226,6 +232,7 @@ public: void SetCaDescriptors(int Level); void SetLinkChannels(cLinkChannels *LinkChannels); void SetRefChannel(cChannel *RefChannel); + void SetSubtitlingDescriptors(uchar *SubtitlingTypes, uint16_t *CompositionPageIds, uint16_t *AncillaryPageIds); }; class cChannels : public cRwLock, public cConfig<cChannel> { @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * 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" @@ -551,6 +551,8 @@ bool cCiApplicationInformation::EnterMenu(void) // --- cCiCaPmt -------------------------------------------------------------- +#define MAXCASYSTEMIDS 64 + // Ca Pmt List Management: #define CPLM_MORE 0x00 @@ -574,9 +576,10 @@ private: int length; int esInfoLengthPos; uint8_t capmt[2048]; ///< XXX is there a specified maximum? - int caDescriptorsLength; - uint8_t caDescriptors[2048]; - bool streamFlag; + int source; + int transponder; + int programNumber; + int caSystemIds[MAXCASYSTEMIDS + 1]; // list is zero terminated! void AddCaDescriptors(int Length, const uint8_t *Data); public: 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) { 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; capmt[length++] = CPLM_ONLY; 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 esInfoLengthPos = length; capmt[length++] = 0x00; // program_info_length H (at program level) - capmt[length++] = 0x00; // program_info_length L - if (!streamFlag) + capmt[length++] = 0x01; // program_info_length L + capmt[length++] = cmdId; + if (caDescriptorsLength > 0) AddCaDescriptors(caDescriptorsLength, caDescriptors); } @@ -610,14 +624,17 @@ void cCiCaPmt::SetListManagement(uint8_t ListManagement) void cCiCaPmt::AddPid(int Pid, uint8_t StreamType) { if (Pid) { + uint8_t caDescriptors[512]; + int caDescriptorsLength = GetCaDescriptors(source, transponder, programNumber, caSystemIds, sizeof(caDescriptors), caDescriptors, Pid); //XXX buffer overflow check??? capmt[length++] = StreamType; capmt[length++] = (Pid >> 8) & 0xFF; capmt[length++] = Pid & 0xFF; esInfoLengthPos = length; capmt[length++] = 0x00; // ES_info_length H (at ES level) - capmt[length++] = 0x00; // ES_info_length L - if (streamFlag) + capmt[length++] = 0x01; // ES_info_length L + capmt[length++] = cmdId; + if (caDescriptorsLength > 0) AddCaDescriptors(caDescriptorsLength, caDescriptors); } } @@ -625,8 +642,7 @@ void cCiCaPmt::AddPid(int Pid, uint8_t StreamType) void cCiCaPmt::AddCaDescriptors(int Length, const uint8_t *Data) { if (esInfoLengthPos) { - if (length + Length < int(sizeof(capmt))) { - capmt[length++] = cmdId; + if (length + Length <= int(sizeof(capmt))) { memcpy(capmt + length, Data, Length); length += Length; int l = length - esInfoLengthPos - 2; @@ -643,8 +659,6 @@ void cCiCaPmt::AddCaDescriptors(int Length, const uint8_t *Data) // --- cCiConditionalAccessSupport ------------------------------------------- -#define MAXCASYSTEMIDS 64 - // CA Enable Ids: #define CAEI_POSSIBLE 0x01 @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * 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 @@ -22,13 +22,13 @@ // VDR's own version number: -#define VDRVERSION "1.7.8" -#define VDRVERSNUM 10708 // Version * 10000 + Major * 100 + Minor +#define VDRVERSION "1.7.9" +#define VDRVERSNUM 10709 // Version * 10000 + Major * 100 + Minor // The plugin API's version number: -#define APIVERSION "1.7.8" -#define APIVERSNUM 10708 // Version * 10000 + Major * 100 + Minor +#define APIVERSION "1.7.9" +#define APIVERSNUM 10709 // Version * 10000 + Major * 100 + Minor // When loading plugins, VDR searches them by their APIVERSION, which // may be smaller than VDRVERSION in case there have been no changes to @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * 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" @@ -1293,8 +1293,10 @@ int cDevice::PlayTsVideo(const uchar *Data, int Length) int l; while (const uchar *p = tsToPesVideo.GetPes(l)) { int w = PlayVideo(p, l); - if (w <= 0) + if (w <= 0) { + tsToPesVideo.SetRepeatLast(); return w; + } } tsToPesVideo.Reset(); } @@ -1308,8 +1310,10 @@ int cDevice::PlayTsAudio(const uchar *Data, int Length) int l; if (const uchar *p = tsToPesAudio.GetPes(l)) { int w = PlayAudio(p, l, 0); - if (w <= 0) + if (w <= 0) { + tsToPesAudio.SetRepeatLast(); return w; + } tsToPesAudio.Reset(); } tsToPesAudio.PutTs(Data, Length); @@ -8,7 +8,7 @@ * 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>. * - * $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" @@ -322,29 +322,30 @@ cTDT::cTDT(const u_char *Data) cEitFilter::cEitFilter(void) { - Set(0x12, 0x4E, 0xFE); // event info, actual(0x4E)/other(0x4F) TS, present/following - Set(0x12, 0x50, 0xF0); // event info, actual TS, schedule(0x50)/schedule for future days(0x5X) - Set(0x12, 0x60, 0xF0); // event info, other TS, schedule(0x60)/schedule for future days(0x6X) - Set(0x14, 0x70); // TDT + Set(0x12, 0x40, 0xC0); // event info now&next actual/other TS (0x4E/0x4F), future actual/other TS (0x5X/0x6X) + if (Setup.SetSystemTime && Setup.TimeTransponder) + Set(0x14, 0x70); // TDT } void cEitFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length) { switch (Pid) { case 0x12: { - cSchedulesLock SchedulesLock(true, 10); - cSchedules *Schedules = (cSchedules *)cSchedules::Schedules(SchedulesLock); - if (Schedules) - cEIT EIT(Schedules, Source(), Tid, Data); - else { - // If we don't get a write lock, let's at least get a read lock, so - // that we can set the running status and 'seen' timestamp (well, actually - // with a read lock we shouldn't be doing that, but it's only integers that - // get changed, so it should be ok) - cSchedulesLock SchedulesLock; + if (Tid >= 0x4E && Tid <= 0x6F) { + cSchedulesLock SchedulesLock(true, 10); cSchedules *Schedules = (cSchedules *)cSchedules::Schedules(SchedulesLock); if (Schedules) - cEIT EIT(Schedules, Source(), Tid, Data, true); + cEIT EIT(Schedules, Source(), Tid, Data); + else { + // If we don't get a write lock, let's at least get a read lock, so + // that we can set the running status and 'seen' timestamp (well, actually + // with a read lock we shouldn't be doing that, but it's only integers that + // get changed, so it should be ok) + cSchedulesLock SchedulesLock; + cSchedules *Schedules = (cSchedules *)cSchedules::Schedules(SchedulesLock); + if (Schedules) + cEIT EIT(Schedules, Source(), Tid, Data, true); + } } } break; @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * 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" @@ -2133,6 +2133,7 @@ cMenuSetupBase::cMenuSetupBase(void) void cMenuSetupBase::Store(void) { Setup = data; + cOsdProvider::UpdateOsdSize(true); Setup.Save(); } @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * 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" @@ -21,23 +21,23 @@ class cCaDescriptor : public cListObject { private: int caSystem; - bool stream; + int esPid; int length; uchar *data; 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(); bool operator== (const cCaDescriptor &arg) const; int CaSystem(void) { return caSystem; } - int Stream(void) { return stream; } + int EsPid(void) { return esPid; } int Length(void) const { return length; } 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; - stream = Stream; + esPid = EsPid; length = Length + 6; data = MALLOC(uchar, length); data[0] = SI::CaDescriptorTag; @@ -57,7 +57,7 @@ cCaDescriptor::~cCaDescriptor() 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 -------------------------------------------------------- @@ -77,8 +77,8 @@ public: bool Is(int Source, int Transponder, int ServiceId); bool Is(cCaDescriptors * CaDescriptors); bool Empty(void) { return caDescriptors.Count() == 0; } - void AddCaDescriptor(SI::CaDescriptor *d, bool Stream); - int GetCaDescriptors(const int *CaSystemIds, int BufSize, uchar *Data, bool &StreamFlag); + void AddCaDescriptor(SI::CaDescriptor *d, int EsPid); + int GetCaDescriptors(const int *CaSystemIds, int BufSize, uchar *Data, int EsPid); 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)) { if (*ca == *nca) { delete nca; @@ -141,37 +141,39 @@ void cCaDescriptors::AddCaDescriptor(SI::CaDescriptor *d, bool Stream) #ifdef DEBUG_CA_DESCRIPTORS char buffer[1024]; 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++) q += sprintf(q, " %02X", nca->Data()[i]); dsyslog(buffer); #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) return 0; if (BufSize > 0 && Data) { int length = 0; - int IsStream = -1; for (cCaDescriptor *d = caDescriptors.First(); d; d = caDescriptors.Next(d)) { - const int *caids = CaSystemIds; - do { - if (d->CaSystem() == *caids) { - 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()); - length += d->Length(); + if (EsPid < 0 || d->EsPid() == EsPid) { + const int *caids = CaSystemIds; + do { + if (d->CaSystem() == *caids) { + if (length + d->Length() <= BufSize) { + memcpy(Data + length, d->Data(), d->Length()); + length += d->Length(); + } + else + return -1; } - else - return -1; - } - } while (*++caids); + } while (*++caids); + } } - StreamFlag = IsStream == 1; return length; } return -1; @@ -187,7 +189,7 @@ public: // Returns 0 if this is an already known descriptor, // 1 if it is an all new descriptor with actual contents, // 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) @@ -208,22 +210,21 @@ int cCaDescriptorHandler::AddCaDescriptors(cCaDescriptors *CaDescriptors) 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); - StreamFlag = false; for (cCaDescriptors *ca = First(); ca; ca = Next(ca)) { if (ca->Is(Source, Transponder, ServiceId)) - return ca->GetCaDescriptors(CaSystemIds, BufSize, Data, StreamFlag); + return ca->GetCaDescriptors(CaSystemIds, BufSize, Data, EsPid); } return 0; } 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 ------------------------------------------------------------ @@ -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()); // Scan the common loop: for (SI::Loop::Iterator it; (d = (SI::CaDescriptor*)pmt.commonDescriptors.getNext(it, SI::CaDescriptorTag)); ) { - CaDescriptors->AddCaDescriptor(d, false); + CaDescriptors->AddCaDescriptor(d, 0); delete d; } // 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 Dpids[MAXDPIDS + 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 DLangs[MAXDPIDS][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 NumSpids = 0; for (SI::Loop::Iterator it; pmt.streamLoop.getNext(stream, it); ) { + int esPid = stream.getPid(); switch (stream.getStreamType()) { case 1: // STREAMTYPE_11172_VIDEO case 2: // STREAMTYPE_13818_VIDEO case 0x1B: // MPEG4 - Vpid = stream.getPid(); + Vpid = esPid; Ppid = pmt.getPCRPid(); Vtype = stream.getStreamType(); 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 { if (NumApids < MAXAPIDS) { - Apids[NumApids] = stream.getPid(); + Apids[NumApids] = esPid; SI::Descriptor *d; for (SI::Loop::Iterator it; (d = stream.streamDescriptors.getNext(it)); ) { 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)); ) { switch (d->getDescriptorTag()) { case SI::AC3DescriptorTag: - dpid = stream.getPid(); + dpid = esPid; break; case SI::SubtitlingDescriptorTag: if (NumSpids < MAXSPIDS) { - Spids[NumSpids] = stream.getPid(); + Spids[NumSpids] = esPid; SI::SubtitlingDescriptor *sd = (SI::SubtitlingDescriptor *)d; SI::SubtitlingDescriptor::Subtitling sub; char *s = SLangs[NumSpids]; int n = 0; for (SI::Loop::Iterator it; sd->subtitlingLoop.getNext(sub, it); ) { if (sub.languageCode[0]) { + SubtitlingTypes[NumSpids] = sub.getSubtitlingType(); + CompositionPageIds[NumSpids] = sub.getCompositionPageId(); + AncillaryPageIds[NumSpids] = sub.getAncillaryPageId(); if (n > 0) *s++ = '+'; 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; case SI::TeletextDescriptorTag: - Tpid = stream.getPid(); + Tpid = esPid; break; case SI::ISO639LanguageDescriptorTag: { 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 } for (SI::Loop::Iterator it; (d = (SI::CaDescriptor*)stream.streamDescriptors.getNext(it, SI::CaDescriptorTag)); ) { - CaDescriptors->AddCaDescriptor(d, true); + CaDescriptors->AddCaDescriptor(d, esPid); delete d; } } if (Setup.UpdateChannels >= 2) { Channel->SetPids(Vpid, Ppid, Vtype, Apids, ALangs, Dpids, DLangs, Spids, SLangs, Tpid); Channel->SetCaIds(CaDescriptors->CaIds()); + Channel->SetSubtitlingDescriptors(SubtitlingTypes, CompositionPageIds, AncillaryPageIds); } Channel->SetCaDescriptors(CaDescriptorHandler.AddCaDescriptors(CaDescriptors)); } @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * 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 @@ -32,7 +32,7 @@ public: 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. ///< 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 diff --git a/recording.c b/recording.c index 2ff7f6f..f3c2c5a 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.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" @@ -1156,7 +1156,7 @@ void cRecordings::DelByName(const char *FileName) if (recording) { cThreadLock DeletedRecordingsLock(&DeletedRecordings); Del(recording, false); - char *ext = strrchr(recording->FileName(), '.'); + char *ext = strrchr(recording->fileName, '.'); if (ext) { strncpy(ext, DELEXT, strlen(ext)); recording->fileSizeMB = DirSizeMB(recording->FileName()); diff --git a/recording.h b/recording.h index 81c72fd..4014c5d 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.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 @@ -207,7 +207,7 @@ public: }; // 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 // with a 40 bit 'unsigned int', which is 1TB. The actual maximum value @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * 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" @@ -198,7 +198,7 @@ int cPatPmtGenerator::MakeAC3Descriptor(uchar *Target) 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; 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++] = 0x00; // subtitling type - Target[i++] = 0x00; // composition page id hi - Target[i++] = 0x01; // composition page id lo - Target[i++] = 0x00; // ancillary page id hi - Target[i++] = 0x01; // ancillary page id lo + Target[i++] = SubtitlingType; + Target[i++] = CompositionPageId >> 8; + Target[i++] = CompositionPageId & 0xFF; + Target[i++] = AncillaryPageId >> 8; + Target[i++] = AncillaryPageId & 0xFF; IncEsInfoLength(i); return i; } @@ -327,7 +327,7 @@ void cPatPmtGenerator::GeneratePmt(cChannel *Channel) } for (int n = 0; Channel->Spid(n); 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 @@ -610,7 +610,8 @@ bool cPatPmtParser::GetVersions(int &PatVersion, int &PmtVersion) cTsToPes::cTsToPes(void) { data = NULL; - size = length = offset = 0; + size = 0; + Reset(); } cTsToPes::~cTsToPes() @@ -641,6 +642,11 @@ void cTsToPes::PutTs(const uchar *Data, int Length) const uchar *cTsToPes::GetPes(int &Length) { + if (repeatLast) { + repeatLast = false; + Length = lastLength; + return lastData; + } if (offset < length && PesLongEnough(length)) { if (!PesHasLength(data)) // this is a video PES packet with undefined length offset = 6; // trigger setting PES length for initial slice @@ -661,12 +667,16 @@ const uchar *cTsToPes::GetPes(int &Length) p[4] = l / 256; p[5] = l & 0xFF; Length = l + 6; + lastLength = Length; + lastData = p; return p; } else { Length = PesLength(data); if (Length <= length) { offset = Length; // to make sure we break out in case of garbage data + lastLength = Length; + lastData = data; return data; } } @@ -674,9 +684,17 @@ const uchar *cTsToPes::GetPes(int &Length) return NULL; } +void cTsToPes::SetRepeatLast(void) +{ + repeatLast = true; +} + void cTsToPes::Reset(void) { length = offset = 0; + lastData = NULL; + lastLength = 0; + repeatLast = false; } // --- Some helper functions for debugging ----------------------------------- @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * 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 @@ -168,7 +168,7 @@ private: protected: int MakeStream(uchar *Target, uchar Type, int Pid); 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 MakeCRC(uchar *Target, const uchar *Data, int Length); void GeneratePmtPid(cChannel *Channel); @@ -252,6 +252,9 @@ private: int size; int length; int offset; + uchar *lastData; + int lastLength; + bool repeatLast; public: cTsToPes(void); ~cTsToPes(); @@ -279,6 +282,9 @@ public: ///< 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 ///< 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); ///< 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 @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * 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" @@ -51,6 +51,11 @@ cTimer::cTimer(bool Instant, bool Pause, cChannel *Channel) event = NULL; if (Instant && channel) 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) @@ -83,6 +88,11 @@ cTimer::cTimer(const cEvent *Event) const char *Title = Event->Title(); if (!isempty(Title)) 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; event = NULL; // let SetEvent() be called to get a log message } @@ -296,13 +306,13 @@ bool cTimer::Parse(const char *s) p++; else 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); - p[VFAT_MAX_FILENAME] = 0; + p[Utf8SymChars(p, VFAT_MAX_FILENAME)] = 0; dsyslog("timer file name truncated to '%s'", p); } } - Utf8Strn0Cpy(file, filebuffer, MaxFileName); + Utf8Strn0Cpy(file, filebuffer, sizeof(file)); strreplace(file, '|', ':'); if (isnumber(channelbuffer)) channel = Channels.GetByNumber(atoi(channelbuffer)); @@ -463,7 +473,7 @@ int cTimer::Matches(const cEvent *Event, int *Overlap) 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 @@ -8,7 +8,7 @@ .\" License as specified in the file COPYING that comes with the .\" 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" .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 access to the SVDRP port. .TP -.I marks.vdr +.I marks Contains the editing marks defined for a recording. .TP -.I info.vdr +.I info Contains a description of the recording. .TP -.I resume.vdr +.I resume Contains the index into the recording where the last replay session left off. .TP -.I index.vdr +.I index Contains the file number, offset and type of each frame of the recording. .TP .I remote.conf @@ -223,7 +223,7 @@ Contains the key assignments for the remote control. .I keymacros.conf Contains user defined remote control key macros. .TP -.IR 001.vdr\ ...\ 255.vdr +.IR 00001.ts\ ...\ 65535.ts The actual data files of a recording. .TP .I epg.data |