From a3c5ea40e89aeabc37ddd9271538b536604411bc Mon Sep 17 00:00:00 2001 From: Dave Date: Mon, 18 Apr 2011 19:44:17 +0100 Subject: Updated for vdr-1.7.18 --- vdrtva-1.7.17.diff | 482 ----------------------------------------------------- vdrtva-1.7.18.diff | 482 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 482 insertions(+), 482 deletions(-) delete mode 100644 vdrtva-1.7.17.diff create mode 100644 vdrtva-1.7.18.diff diff --git a/vdrtva-1.7.17.diff b/vdrtva-1.7.17.diff deleted file mode 100644 index df0fc71..0000000 --- a/vdrtva-1.7.17.diff +++ /dev/null @@ -1,482 +0,0 @@ -diff -ur vdr-1.7.17/channels.c vdr-1.7/channels.c ---- vdr-1.7.17/channels.c 2010-11-07 12:24:59.000000000 +0000 -+++ vdr-1.7/channels.c 2011-03-13 11:57:00.000000000 +0000 -@@ -61,6 +61,7 @@ - shortName = strdup(""); - provider = strdup(""); - portalName = strdup(""); -+ defaultAuthority = strdup(""); - memset(&__BeginData__, 0, (char *)&__EndData__ - (char *)&__BeginData__); - parameters = ""; - modification = CHANNELMOD_NONE; -@@ -75,6 +76,7 @@ - shortName = NULL; - provider = NULL; - portalName = NULL; -+ defaultAuthority = NULL; - schedule = NULL; - linkChannels = NULL; - refChannel = NULL; -@@ -103,6 +105,7 @@ - free(shortName); - free(provider); - free(portalName); -+ free(defaultAuthority); - } - - cChannel& cChannel::operator= (const cChannel &Channel) -@@ -111,6 +114,7 @@ - shortName = strcpyrealloc(shortName, Channel.shortName); - provider = strcpyrealloc(provider, Channel.provider); - portalName = strcpyrealloc(portalName, Channel.portalName); -+ defaultAuthority = strcpyrealloc(defaultAuthority, Channel.defaultAuthority); - memcpy(&__BeginData__, &Channel.__BeginData__, (char *)&Channel.__EndData__ - (char *)&Channel.__BeginData__); - parameters = Channel.parameters; - return *this; -@@ -255,6 +259,13 @@ - } - } - -+void cChannel::SetDefaultAuthority(const char *DefaultAuthority) -+{ -+ if (!isempty(DefaultAuthority) && strcmp(defaultAuthority, DefaultAuthority) != 0) { -+ defaultAuthority = strcpyrealloc(defaultAuthority, DefaultAuthority); -+ } -+} -+ - #define STRDIFF 0x01 - #define VALDIFF 0x02 - -@@ -506,11 +517,11 @@ - q += IntArrayToString(q, Channel->dpids, 10, Channel->dlangs, Channel->dtypes); - } - *q = 0; -- char caidbuf[MAXCAIDS * 5 + 10]; // 5: 4 digits plus delimiting ',', 10: paranoia -+ char caidbuf[MAXCAIDS * 5 + 10 + 256]; // 5: 4 digits plus delimiting ',', 10 + max DNS domain length: paranoia - q = caidbuf; - q += IntArrayToString(q, Channel->caids, 16); - *q = 0; -- buffer = cString::sprintf("%s:%d:%s:%s:%d:%s:%s:%d:%s:%d:%d:%d:%d\n", FullName, Channel->frequency, *Channel->parameters, *cSource::ToString(Channel->source), Channel->srate, vpidbuf, apidbuf, Channel->tpid, caidbuf, Channel->sid, Channel->nid, Channel->tid, Channel->rid); -+ buffer = cString::sprintf("%s:%d:%s:%s:%d:%s:%s:%d:%s:%d:%d:%d:%d:%s\n", FullName, Channel->frequency, *Channel->parameters, *cSource::ToString(Channel->source), Channel->srate, vpidbuf, apidbuf, Channel->tpid, caidbuf, Channel->sid, Channel->nid, Channel->tid, Channel->rid, Channel->defaultAuthority); - } - return buffer; - } -@@ -545,13 +556,16 @@ - char *vpidbuf = NULL; - char *apidbuf = NULL; - char *caidbuf = NULL; -- int fields = sscanf(s, "%a[^:]:%d :%a[^:]:%a[^:] :%d :%a[^:]:%a[^:]:%d :%a[^:]:%d :%d :%d :%d ", &namebuf, &frequency, ¶mbuf, &sourcebuf, &srate, &vpidbuf, &apidbuf, &tpid, &caidbuf, &sid, &nid, &tid, &rid); -+ char *dabuf = NULL; -+ int fields = sscanf(s, "%a[^:]:%d :%a[^:]:%a[^:] :%d :%a[^:]:%a[^:]:%d :%a[^:]:%d :%d :%d :%d :%a[^:]", &namebuf, &frequency, ¶mbuf, &sourcebuf, &srate, &vpidbuf, &apidbuf, &tpid, &caidbuf, &sid, &nid, &tid, &rid, &dabuf); - if (fields >= 9) { - if (fields == 9) { - // allow reading of old format - sid = atoi(caidbuf); - delete caidbuf; - caidbuf = NULL; -+ delete dabuf; -+ dabuf = NULL; - caids[0] = tpid; - caids[1] = 0; - tpid = 0; -@@ -677,12 +691,17 @@ - } - name = strcpyrealloc(name, namebuf); - -+ if (dabuf) { -+ defaultAuthority = strcpyrealloc(defaultAuthority, dabuf); -+ } -+ - free(parambuf); - free(sourcebuf); - free(vpidbuf); - free(apidbuf); - free(caidbuf); - free(namebuf); -+ free(dabuf); - if (!GetChannelID().Valid()) { - esyslog("ERROR: channel data results in invalid ID!"); - return false; -diff -ur vdr-1.7.17/channels.h vdr-1.7/channels.h ---- vdr-1.7.17/channels.h 2010-06-05 14:12:54.000000000 +0100 -+++ vdr-1.7/channels.h 2011-03-13 11:57:00.000000000 +0000 -@@ -96,6 +96,7 @@ - char *shortName; - char *provider; - char *portalName; -+ char *defaultAuthority; - int __BeginData__; - int frequency; // MHz - int source; -@@ -141,6 +142,7 @@ - const char *ShortName(bool OrName = false) const { return (OrName && isempty(shortName)) ? name : shortName; } - const char *Provider(void) const { return provider; } - const char *PortalName(void) const { return portalName; } -+ const char *DefaultAuthority(void) const { return defaultAuthority; } - int Frequency(void) const { return frequency; } ///< Returns the actual frequency, as given in 'channels.conf' - int Transponder(void) const; ///< Returns the transponder frequency in MHz, plus the polarization in case of sat - static int Transponder(int Frequency, char Polarization); ///< builds the transponder from the given Frequency and Polarization -@@ -189,6 +191,7 @@ - void SetId(int Nid, int Tid, int Sid, int Rid = 0); - void SetName(const char *Name, const char *ShortName, const char *Provider); - void SetPortalName(const char *PortalName); -+ void SetDefaultAuthority(const char *DefaultAuthority); - void SetPids(int Vpid, int Ppid, int Vtype, int *Apids, int *Atypes, char ALangs[][MAXLANGCODE2], int *Dpids, int *Dtypes, char DLangs[][MAXLANGCODE2], int *Spids, char SLangs[][MAXLANGCODE2], int Tpid); - void SetCaIds(const int *CaIds); // list must be zero-terminated - void SetCaDescriptors(int Level); -diff -ur vdr-1.7.17/config.c vdr-1.7/config.c ---- vdr-1.7.17/config.c 2010-06-06 11:06:43.000000000 +0100 -+++ vdr-1.7/config.c 2011-03-13 11:57:00.000000000 +0000 -@@ -353,6 +353,7 @@ - UseSubtitle = 1; - UseVps = 0; - VpsMargin = 120; -+ VpsFallback = 0; - RecordingDirs = 1; - FoldersInTimerMenu = 1; - NumberKeysForChars = 1; -@@ -544,6 +545,7 @@ - else if (!strcasecmp(Name, "UseSubtitle")) UseSubtitle = atoi(Value); - else if (!strcasecmp(Name, "UseVps")) UseVps = atoi(Value); - else if (!strcasecmp(Name, "VpsMargin")) VpsMargin = atoi(Value); -+ else if (!strcasecmp(Name, "VpsFallback")) VpsFallback = atoi(Value); - else if (!strcasecmp(Name, "RecordingDirs")) RecordingDirs = atoi(Value); - else if (!strcasecmp(Name, "FoldersInTimerMenu")) FoldersInTimerMenu = atoi(Value); - else if (!strcasecmp(Name, "NumberKeysForChars")) NumberKeysForChars = atoi(Value); -@@ -640,6 +642,7 @@ - Store("UseSubtitle", UseSubtitle); - Store("UseVps", UseVps); - Store("VpsMargin", VpsMargin); -+ Store("VpsFallback", VpsFallback); - Store("RecordingDirs", RecordingDirs); - Store("FoldersInTimerMenu", FoldersInTimerMenu); - Store("NumberKeysForChars", NumberKeysForChars); -diff -ur vdr-1.7.17/config.h vdr-1.7/config.h ---- vdr-1.7.17/config.h 2010-10-24 12:22:35.000000000 +0100 -+++ vdr-1.7/config.h 2011-03-13 11:57:00.000000000 +0000 -@@ -252,6 +252,7 @@ - int UseSubtitle; - int UseVps; - int VpsMargin; -+ int VpsFallback; - int RecordingDirs; - int FoldersInTimerMenu; - int NumberKeysForChars; -diff -ur vdr-1.7.17/eit.c vdr-1.7/eit.c ---- vdr-1.7.17/eit.c 2010-05-14 15:08:35.000000000 +0100 -+++ vdr-1.7/eit.c 2011-03-13 11:57:00.000000000 +0000 -@@ -265,6 +265,27 @@ - } - } - break; -+ case SI::ContentIdentifierDescriptorTag: { -+ SI::ContentIdentifierDescriptor *cd = (SI::ContentIdentifierDescriptor *)d; -+ SI::ContentIdentifierDescriptor::Identifier cde; -+ for (SI::Loop::Iterator ite; (cd->identifierLoop.getNext(cde,ite)); ) { -+ if (cde.getCridLocation() == 0) { -+ char buffer[Utf8BufSize(256)]; -+ strcpy (buffer, channel->DefaultAuthority()); -+ strcat(buffer, cde.identifier.getText()); -+ switch (cde.getCridType()) { -+ case 0x01: -+ case 0x31: -+ pEvent->SetItemCRID(buffer); -+ break; -+ case 0x02: -+ case 0x32: -+ pEvent->SetSeriesCRID(buffer); -+ break; -+ } -+ } -+ } -+ } - default: ; - } - delete d; -diff -ur vdr-1.7.17/epg.c vdr-1.7/epg.c ---- vdr-1.7.17/epg.c 2011-02-25 15:16:05.000000000 +0000 -+++ vdr-1.7/epg.c 2011-03-13 11:57:00.000000000 +0000 -@@ -126,6 +126,8 @@ - startTime = 0; - duration = 0; - vps = 0; -+ itemCRID = NULL; -+ seriesCRID = NULL; - SetSeen(); - } - -@@ -134,6 +136,8 @@ - free(title); - free(shortText); - free(description); -+ free(itemCRID); -+ free(seriesCRID); - delete components; - } - -@@ -229,6 +233,16 @@ - vps = Vps; - } - -+void cEvent::SetItemCRID(const char *CRID) -+{ -+ itemCRID = strcpyrealloc(itemCRID, CRID); -+} -+ -+void cEvent::SetSeriesCRID(const char *CRID) -+{ -+ seriesCRID = strcpyrealloc(seriesCRID, CRID); -+} -+ - void cEvent::SetSeen(void) - { - seen = time(NULL); -@@ -457,6 +471,10 @@ - } - if (vps) - fprintf(f, "%sV %ld\n", Prefix, vps); -+ if (!isempty(itemCRID)) -+ fprintf(f, "%sY %s\n", Prefix, itemCRID); -+ if (!isempty(seriesCRID)) -+ fprintf(f, "%sZ %s\n", Prefix, seriesCRID); - if (!InfoOnly) - fprintf(f, "%se\n", Prefix); - } -@@ -495,6 +513,10 @@ - break; - case 'V': SetVps(atoi(t)); - break; -+ case 'Y': SetItemCRID(t); -+ break; -+ case 'Z': SetSeriesCRID(t); -+ break; - default: esyslog("ERROR: unexpected tag while reading EPG data: %s", s); - return false; - } -diff -ur vdr-1.7.17/epg.h vdr-1.7/epg.h ---- vdr-1.7.17/epg.h 2011-02-25 14:14:38.000000000 +0000 -+++ vdr-1.7/epg.h 2011-03-13 11:57:00.000000000 +0000 -@@ -86,6 +86,8 @@ - int duration; // Duration of this event in seconds - time_t vps; // Video Programming Service timestamp (VPS, aka "Programme Identification Label", PIL) - time_t seen; // When this event was last seen in the data stream -+ char *itemCRID; // Item CRID -+ char *seriesCRID; // Series CRID - public: - cEvent(tEventID EventID); - ~cEvent(); -@@ -106,6 +108,8 @@ - time_t EndTime(void) const { return startTime + duration; } - int Duration(void) const { return duration; } - time_t Vps(void) const { return vps; } -+ const char *ItemCRID(void) const { return itemCRID; } -+ const char *SeriesCRID(void) const { return seriesCRID; } - time_t Seen(void) const { return seen; } - bool SeenWithin(int Seconds) const { return time(NULL) - seen < Seconds; } - bool HasTimer(void) const; -@@ -129,6 +133,8 @@ - void SetStartTime(time_t StartTime); - void SetDuration(int Duration); - void SetVps(time_t Vps); -+ void SetItemCRID(const char *CRID); -+ void SetSeriesCRID(const char *CRID); - void SetSeen(void); - cString ToDescr(void) const; - void Dump(FILE *f, const char *Prefix = "", bool InfoOnly = false) const; -diff -ur vdr-1.7.17/libsi/descriptor.c vdr-1.7/libsi/descriptor.c ---- vdr-1.7.17/libsi/descriptor.c 2010-11-01 15:24:31.000000000 +0000 -+++ vdr-1.7/libsi/descriptor.c 2011-03-13 11:57:00.000000000 +0000 -@@ -643,6 +643,33 @@ - textualServiceIdentifier.setData(data+sizeof(descr_service_identifier), getLength()-sizeof(descr_service_identifier)); - } - -+void ContentIdentifierDescriptor::Parse() { -+ identifierLoop.setData(data+sizeof(descr_content_identifier), getLength()-sizeof(descr_content_identifier)); -+} -+ -+void ContentIdentifierDescriptor::Identifier::Parse() { -+ int offset=0; -+ data.setPointerAndOffset(s, offset); -+ if (s->crid_location == 0) { -+ identifier.setData(data+(offset-1), s->crid_length); -+ } -+ else { -+ identifier.setData(data+(offset-1), 2); -+ } -+} -+ -+int ContentIdentifierDescriptor::Identifier::getCridType() const { -+ return s->crid_type; -+} -+ -+int ContentIdentifierDescriptor::Identifier::getCridLocation() const { -+ return s->crid_location; -+} -+ -+void DefaultAuthorityDescriptor::Parse() { -+ DefaultAuthority.setData(data+sizeof(descr_default_authority), getLength()-sizeof(descr_default_authority)); -+} -+ - void MultilingualNameDescriptor::Parse() { - nameLoop.setData(data+sizeof(descr_multilingual_network_name), getLength()-sizeof(descr_multilingual_network_name)); - } -diff -ur vdr-1.7.17/libsi/descriptor.h vdr-1.7/libsi/descriptor.h ---- vdr-1.7.17/libsi/descriptor.h 2010-11-01 15:24:32.000000000 +0000 -+++ vdr-1.7/libsi/descriptor.h 2011-03-13 11:57:00.000000000 +0000 -@@ -361,6 +361,31 @@ - virtual void Parse(); - }; - -+class ContentIdentifierDescriptor : public Descriptor { -+public: -+ class Identifier : public LoopElement { -+ public: -+ String identifier; -+ int getCridType() const; -+ int getCridLocation() const; -+ virtual int getLength() { return sizeof(content_identifier_entry)+identifier.getLength(); } -+ protected: -+ virtual void Parse(); -+ private: -+ const content_identifier_entry *s; -+ }; -+ StructureLoop identifierLoop; -+protected: -+ virtual void Parse(); -+}; -+ -+class DefaultAuthorityDescriptor : public Descriptor { -+public: -+ String DefaultAuthority; //ID -+protected: -+ virtual void Parse(); -+}; -+ - //abstract base class - class MultilingualNameDescriptor : public Descriptor { - public: -diff -ur vdr-1.7.17/libsi/headers.h vdr-1.7/libsi/headers.h ---- vdr-1.7.17/libsi/headers.h 2010-11-01 15:24:32.000000000 +0000 -+++ vdr-1.7/libsi/headers.h 2011-03-13 11:57:00.000000000 +0000 -@@ -1680,6 +1680,24 @@ - u_char descriptor_length :8; - }; - -+struct content_identifier_entry { -+#if BYTE_ORDER == BIG_ENDIAN -+ u_char crid_type :6; -+ u_char crid_location :2; -+#else -+ u_char crid_location :2; -+ u_char crid_type :6; -+#endif -+ union { -+ u_char crid_length :8; -+ u_char crid_ref_hi :8; -+ }; -+ union { -+ u_char crid_byte :8; -+ u_char crid_ref_lo :8; -+ }; -+}; -+ - /* 0x77 time_slice_fec_identifier_descriptor (ETSI EN 301 192) */ - - struct descr_time_slice_fec_identifier { -diff -ur vdr-1.7.17/libsi/si.c vdr-1.7/libsi/si.c ---- vdr-1.7.17/libsi/si.c 2010-11-01 15:24:32.000000000 +0000 -+++ vdr-1.7/libsi/si.c 2011-03-13 11:57:00.000000000 +0000 -@@ -609,6 +609,12 @@ - case RegistrationDescriptorTag: - d=new RegistrationDescriptor(); - break; -+ case ContentIdentifierDescriptorTag: -+ d=new ContentIdentifierDescriptor(); -+ break; -+ case DefaultAuthorityDescriptorTag: -+ d=new DefaultAuthorityDescriptor(); -+ break; - - //note that it is no problem to implement one - //of the unimplemented descriptors. -@@ -650,10 +656,8 @@ - case TransportStreamDescriptorTag: - - //defined in ETSI EN 300 468 v 1.7.1 -- case DefaultAuthorityDescriptorTag: - case RelatedContentDescriptorTag: - case TVAIdDescriptorTag: -- case ContentIdentifierDescriptorTag: - case TimeSliceFecIdentifierDescriptorTag: - case ECMRepetitionRateDescriptorTag: - case EnhancedAC3DescriptorTag: -diff -ur vdr-1.7.17/menu.c vdr-1.7/menu.c ---- vdr-1.7.17/menu.c 2011-02-27 12:37:48.000000000 +0000 -+++ vdr-1.7/menu.c 2011-03-13 11:57:00.000000000 +0000 -@@ -3057,6 +3057,7 @@ - Add(new cMenuEditBoolItem(tr("Setup.Recording$Use episode name"), &data.UseSubtitle)); - Add(new cMenuEditBoolItem(tr("Setup.Recording$Use VPS"), &data.UseVps)); - Add(new cMenuEditIntItem( tr("Setup.Recording$VPS margin (s)"), &data.VpsMargin, 0)); -+ Add(new cMenuEditBoolItem(tr("Setup.Recording$Use running status as VPS fallback"), &data.VpsFallback)); - Add(new cMenuEditBoolItem(tr("Setup.Recording$Mark instant recording"), &data.MarkInstantRecord)); - Add(new cMenuEditStrItem( tr("Setup.Recording$Name instant recording"), data.NameInstantRecord, sizeof(data.NameInstantRecord))); - Add(new cMenuEditIntItem( tr("Setup.Recording$Instant rec. time (min)"), &data.InstantRecordTime, 1, MAXINSTANTRECTIME)); -diff -ur vdr-1.7.17/sdt.c vdr-1.7/sdt.c ---- vdr-1.7.17/sdt.c 2010-05-16 15:23:21.000000000 +0100 -+++ vdr-1.7/sdt.c 2011-03-13 11:57:00.000000000 +0000 -@@ -128,6 +128,12 @@ - } - } - break; -+ case SI::DefaultAuthorityDescriptorTag: { -+ SI::DefaultAuthorityDescriptor *da = (SI::DefaultAuthorityDescriptor *)d; -+ char DaBuf[Utf8BufSize(1024)]; -+ da->DefaultAuthority.getText(DaBuf, sizeof(DaBuf)); -+ channel->SetDefaultAuthority(DaBuf); -+ } - default: ; - } - delete d; -diff -ur vdr-1.7.17/timers.c vdr-1.7/timers.c ---- vdr-1.7.17/timers.c 2010-01-16 11:18:53.000000000 +0000 -+++ vdr-1.7/timers.c 2011-03-13 11:57:00.000000000 +0000 -@@ -423,7 +423,7 @@ - } - - if (HasFlags(tfActive)) { -- if (HasFlags(tfVps) && event && event->Vps()) { -+ if (HasFlags(tfVps) && event && (Setup.VpsFallback || event->Vps())) { - if (Margin || !Directly) { - startTime = event->StartTime(); - stopTime = event->EndTime(); -diff -ur vdr-1.7.17/vdr.5 vdr-1.7/vdr.5 ---- vdr-1.7.17/vdr.5 2010-12-24 15:19:21.000000000 +0000 -+++ vdr-1.7/vdr.5 2011-03-13 11:57:00.000000000 +0000 -@@ -247,6 +247,9 @@ - .B RID - The Radio ID of this channel (typically 0, may be used to distinguish channels where - NID, TID and SID are all equal). -+.TP -+.B Default Authority -+The Default Authority for CRIDs on this channel (TVAnytime). - .PP - A particular channel can be uniquely identified by its \fBchannel\ ID\fR, - which is a string that looks like this: -@@ -778,6 +781,8 @@ - \fBR\fR@ - \fBX\fR@ - \fBV\fR@ -+\fBY\fR@ -+\fBZ\fR@ - \fBe\fR@ - \fBc\fR@ - .TE -@@ -812,6 +817,8 @@ - @is the three letter language code (optionally two codes, separated by '+') - @is the description of this stream component - @is the Video Programming Service time of this event -+ @is the CRID of this event (TVAnytime) -+ @is the CRID of the series which this event is part of (TVAnytime) - .TE - - This file will be read at program startup in order to restore the results of diff --git a/vdrtva-1.7.18.diff b/vdrtva-1.7.18.diff new file mode 100644 index 0000000..775ebaa --- /dev/null +++ b/vdrtva-1.7.18.diff @@ -0,0 +1,482 @@ +diff -ur vdr-1.7.18/channels.c vdr-1.7/channels.c +--- vdr-1.7.18/channels.c 2010-11-07 12:24:59.000000000 +0000 ++++ vdr-1.7/channels.c 2011-04-17 16:04:26.000000000 +0100 +@@ -61,6 +61,7 @@ + shortName = strdup(""); + provider = strdup(""); + portalName = strdup(""); ++ defaultAuthority = strdup(""); + memset(&__BeginData__, 0, (char *)&__EndData__ - (char *)&__BeginData__); + parameters = ""; + modification = CHANNELMOD_NONE; +@@ -75,6 +76,7 @@ + shortName = NULL; + provider = NULL; + portalName = NULL; ++ defaultAuthority = NULL; + schedule = NULL; + linkChannels = NULL; + refChannel = NULL; +@@ -103,6 +105,7 @@ + free(shortName); + free(provider); + free(portalName); ++ free(defaultAuthority); + } + + cChannel& cChannel::operator= (const cChannel &Channel) +@@ -111,6 +114,7 @@ + shortName = strcpyrealloc(shortName, Channel.shortName); + provider = strcpyrealloc(provider, Channel.provider); + portalName = strcpyrealloc(portalName, Channel.portalName); ++ defaultAuthority = strcpyrealloc(defaultAuthority, Channel.defaultAuthority); + memcpy(&__BeginData__, &Channel.__BeginData__, (char *)&Channel.__EndData__ - (char *)&Channel.__BeginData__); + parameters = Channel.parameters; + return *this; +@@ -255,6 +259,13 @@ + } + } + ++void cChannel::SetDefaultAuthority(const char *DefaultAuthority) ++{ ++ if (!isempty(DefaultAuthority) && strcmp(defaultAuthority, DefaultAuthority) != 0) { ++ defaultAuthority = strcpyrealloc(defaultAuthority, DefaultAuthority); ++ } ++} ++ + #define STRDIFF 0x01 + #define VALDIFF 0x02 + +@@ -506,11 +517,11 @@ + q += IntArrayToString(q, Channel->dpids, 10, Channel->dlangs, Channel->dtypes); + } + *q = 0; +- char caidbuf[MAXCAIDS * 5 + 10]; // 5: 4 digits plus delimiting ',', 10: paranoia ++ char caidbuf[MAXCAIDS * 5 + 10 + 256]; // 5: 4 digits plus delimiting ',', 10 + max DNS domain length: paranoia + q = caidbuf; + q += IntArrayToString(q, Channel->caids, 16); + *q = 0; +- buffer = cString::sprintf("%s:%d:%s:%s:%d:%s:%s:%d:%s:%d:%d:%d:%d\n", FullName, Channel->frequency, *Channel->parameters, *cSource::ToString(Channel->source), Channel->srate, vpidbuf, apidbuf, Channel->tpid, caidbuf, Channel->sid, Channel->nid, Channel->tid, Channel->rid); ++ buffer = cString::sprintf("%s:%d:%s:%s:%d:%s:%s:%d:%s:%d:%d:%d:%d:%s\n", FullName, Channel->frequency, *Channel->parameters, *cSource::ToString(Channel->source), Channel->srate, vpidbuf, apidbuf, Channel->tpid, caidbuf, Channel->sid, Channel->nid, Channel->tid, Channel->rid, Channel->defaultAuthority); + } + return buffer; + } +@@ -545,13 +556,16 @@ + char *vpidbuf = NULL; + char *apidbuf = NULL; + char *caidbuf = NULL; +- int fields = sscanf(s, "%a[^:]:%d :%a[^:]:%a[^:] :%d :%a[^:]:%a[^:]:%d :%a[^:]:%d :%d :%d :%d ", &namebuf, &frequency, ¶mbuf, &sourcebuf, &srate, &vpidbuf, &apidbuf, &tpid, &caidbuf, &sid, &nid, &tid, &rid); ++ char *dabuf = NULL; ++ int fields = sscanf(s, "%a[^:]:%d :%a[^:]:%a[^:] :%d :%a[^:]:%a[^:]:%d :%a[^:]:%d :%d :%d :%d :%a[^:]", &namebuf, &frequency, ¶mbuf, &sourcebuf, &srate, &vpidbuf, &apidbuf, &tpid, &caidbuf, &sid, &nid, &tid, &rid, &dabuf); + if (fields >= 9) { + if (fields == 9) { + // allow reading of old format + sid = atoi(caidbuf); + delete caidbuf; + caidbuf = NULL; ++ delete dabuf; ++ dabuf = NULL; + caids[0] = tpid; + caids[1] = 0; + tpid = 0; +@@ -677,12 +691,17 @@ + } + name = strcpyrealloc(name, namebuf); + ++ if (dabuf) { ++ defaultAuthority = strcpyrealloc(defaultAuthority, dabuf); ++ } ++ + free(parambuf); + free(sourcebuf); + free(vpidbuf); + free(apidbuf); + free(caidbuf); + free(namebuf); ++ free(dabuf); + if (!GetChannelID().Valid()) { + esyslog("ERROR: channel data results in invalid ID!"); + return false; +diff -ur vdr-1.7.18/channels.h vdr-1.7/channels.h +--- vdr-1.7.18/channels.h 2010-06-05 14:12:54.000000000 +0100 ++++ vdr-1.7/channels.h 2011-04-17 16:04:26.000000000 +0100 +@@ -96,6 +96,7 @@ + char *shortName; + char *provider; + char *portalName; ++ char *defaultAuthority; + int __BeginData__; + int frequency; // MHz + int source; +@@ -141,6 +142,7 @@ + const char *ShortName(bool OrName = false) const { return (OrName && isempty(shortName)) ? name : shortName; } + const char *Provider(void) const { return provider; } + const char *PortalName(void) const { return portalName; } ++ const char *DefaultAuthority(void) const { return defaultAuthority; } + int Frequency(void) const { return frequency; } ///< Returns the actual frequency, as given in 'channels.conf' + int Transponder(void) const; ///< Returns the transponder frequency in MHz, plus the polarization in case of sat + static int Transponder(int Frequency, char Polarization); ///< builds the transponder from the given Frequency and Polarization +@@ -189,6 +191,7 @@ + void SetId(int Nid, int Tid, int Sid, int Rid = 0); + void SetName(const char *Name, const char *ShortName, const char *Provider); + void SetPortalName(const char *PortalName); ++ void SetDefaultAuthority(const char *DefaultAuthority); + void SetPids(int Vpid, int Ppid, int Vtype, int *Apids, int *Atypes, char ALangs[][MAXLANGCODE2], int *Dpids, int *Dtypes, char DLangs[][MAXLANGCODE2], int *Spids, char SLangs[][MAXLANGCODE2], int Tpid); + void SetCaIds(const int *CaIds); // list must be zero-terminated + void SetCaDescriptors(int Level); +diff -ur vdr-1.7.18/config.c vdr-1.7/config.c +--- vdr-1.7.18/config.c 2010-06-06 11:06:43.000000000 +0100 ++++ vdr-1.7/config.c 2011-04-17 16:04:26.000000000 +0100 +@@ -353,6 +353,7 @@ + UseSubtitle = 1; + UseVps = 0; + VpsMargin = 120; ++ VpsFallback = 0; + RecordingDirs = 1; + FoldersInTimerMenu = 1; + NumberKeysForChars = 1; +@@ -544,6 +545,7 @@ + else if (!strcasecmp(Name, "UseSubtitle")) UseSubtitle = atoi(Value); + else if (!strcasecmp(Name, "UseVps")) UseVps = atoi(Value); + else if (!strcasecmp(Name, "VpsMargin")) VpsMargin = atoi(Value); ++ else if (!strcasecmp(Name, "VpsFallback")) VpsFallback = atoi(Value); + else if (!strcasecmp(Name, "RecordingDirs")) RecordingDirs = atoi(Value); + else if (!strcasecmp(Name, "FoldersInTimerMenu")) FoldersInTimerMenu = atoi(Value); + else if (!strcasecmp(Name, "NumberKeysForChars")) NumberKeysForChars = atoi(Value); +@@ -640,6 +642,7 @@ + Store("UseSubtitle", UseSubtitle); + Store("UseVps", UseVps); + Store("VpsMargin", VpsMargin); ++ Store("VpsFallback", VpsFallback); + Store("RecordingDirs", RecordingDirs); + Store("FoldersInTimerMenu", FoldersInTimerMenu); + Store("NumberKeysForChars", NumberKeysForChars); +diff -ur vdr-1.7.18/config.h vdr-1.7/config.h +--- vdr-1.7.18/config.h 2011-03-13 12:02:31.000000000 +0000 ++++ vdr-1.7/config.h 2011-04-17 16:04:26.000000000 +0100 +@@ -252,6 +252,7 @@ + int UseSubtitle; + int UseVps; + int VpsMargin; ++ int VpsFallback; + int RecordingDirs; + int FoldersInTimerMenu; + int NumberKeysForChars; +diff -ur vdr-1.7.18/eit.c vdr-1.7/eit.c +--- vdr-1.7.18/eit.c 2010-05-14 15:08:35.000000000 +0100 ++++ vdr-1.7/eit.c 2011-04-17 16:04:26.000000000 +0100 +@@ -265,6 +265,27 @@ + } + } + break; ++ case SI::ContentIdentifierDescriptorTag: { ++ SI::ContentIdentifierDescriptor *cd = (SI::ContentIdentifierDescriptor *)d; ++ SI::ContentIdentifierDescriptor::Identifier cde; ++ for (SI::Loop::Iterator ite; (cd->identifierLoop.getNext(cde,ite)); ) { ++ if (cde.getCridLocation() == 0) { ++ char buffer[Utf8BufSize(256)]; ++ strcpy (buffer, channel->DefaultAuthority()); ++ strcat(buffer, cde.identifier.getText()); ++ switch (cde.getCridType()) { ++ case 0x01: ++ case 0x31: ++ pEvent->SetItemCRID(buffer); ++ break; ++ case 0x02: ++ case 0x32: ++ pEvent->SetSeriesCRID(buffer); ++ break; ++ } ++ } ++ } ++ } + default: ; + } + delete d; +diff -ur vdr-1.7.18/epg.c vdr-1.7/epg.c +--- vdr-1.7.18/epg.c 2011-02-25 15:16:05.000000000 +0000 ++++ vdr-1.7/epg.c 2011-04-17 16:04:26.000000000 +0100 +@@ -126,6 +126,8 @@ + startTime = 0; + duration = 0; + vps = 0; ++ itemCRID = NULL; ++ seriesCRID = NULL; + SetSeen(); + } + +@@ -134,6 +136,8 @@ + free(title); + free(shortText); + free(description); ++ free(itemCRID); ++ free(seriesCRID); + delete components; + } + +@@ -229,6 +233,16 @@ + vps = Vps; + } + ++void cEvent::SetItemCRID(const char *CRID) ++{ ++ itemCRID = strcpyrealloc(itemCRID, CRID); ++} ++ ++void cEvent::SetSeriesCRID(const char *CRID) ++{ ++ seriesCRID = strcpyrealloc(seriesCRID, CRID); ++} ++ + void cEvent::SetSeen(void) + { + seen = time(NULL); +@@ -457,6 +471,10 @@ + } + if (vps) + fprintf(f, "%sV %ld\n", Prefix, vps); ++ if (!isempty(itemCRID)) ++ fprintf(f, "%sY %s\n", Prefix, itemCRID); ++ if (!isempty(seriesCRID)) ++ fprintf(f, "%sZ %s\n", Prefix, seriesCRID); + if (!InfoOnly) + fprintf(f, "%se\n", Prefix); + } +@@ -495,6 +513,10 @@ + break; + case 'V': SetVps(atoi(t)); + break; ++ case 'Y': SetItemCRID(t); ++ break; ++ case 'Z': SetSeriesCRID(t); ++ break; + default: esyslog("ERROR: unexpected tag while reading EPG data: %s", s); + return false; + } +diff -ur vdr-1.7.18/epg.h vdr-1.7/epg.h +--- vdr-1.7.18/epg.h 2011-02-25 14:14:38.000000000 +0000 ++++ vdr-1.7/epg.h 2011-04-17 16:04:26.000000000 +0100 +@@ -86,6 +86,8 @@ + int duration; // Duration of this event in seconds + time_t vps; // Video Programming Service timestamp (VPS, aka "Programme Identification Label", PIL) + time_t seen; // When this event was last seen in the data stream ++ char *itemCRID; // Item CRID ++ char *seriesCRID; // Series CRID + public: + cEvent(tEventID EventID); + ~cEvent(); +@@ -106,6 +108,8 @@ + time_t EndTime(void) const { return startTime + duration; } + int Duration(void) const { return duration; } + time_t Vps(void) const { return vps; } ++ const char *ItemCRID(void) const { return itemCRID; } ++ const char *SeriesCRID(void) const { return seriesCRID; } + time_t Seen(void) const { return seen; } + bool SeenWithin(int Seconds) const { return time(NULL) - seen < Seconds; } + bool HasTimer(void) const; +@@ -129,6 +133,8 @@ + void SetStartTime(time_t StartTime); + void SetDuration(int Duration); + void SetVps(time_t Vps); ++ void SetItemCRID(const char *CRID); ++ void SetSeriesCRID(const char *CRID); + void SetSeen(void); + cString ToDescr(void) const; + void Dump(FILE *f, const char *Prefix = "", bool InfoOnly = false) const; +diff -ur vdr-1.7.18/libsi/descriptor.c vdr-1.7/libsi/descriptor.c +--- vdr-1.7.18/libsi/descriptor.c 2010-11-01 15:24:31.000000000 +0000 ++++ vdr-1.7/libsi/descriptor.c 2011-04-17 16:04:26.000000000 +0100 +@@ -643,6 +643,33 @@ + textualServiceIdentifier.setData(data+sizeof(descr_service_identifier), getLength()-sizeof(descr_service_identifier)); + } + ++void ContentIdentifierDescriptor::Parse() { ++ identifierLoop.setData(data+sizeof(descr_content_identifier), getLength()-sizeof(descr_content_identifier)); ++} ++ ++void ContentIdentifierDescriptor::Identifier::Parse() { ++ int offset=0; ++ data.setPointerAndOffset(s, offset); ++ if (s->crid_location == 0) { ++ identifier.setData(data+(offset-1), s->crid_length); ++ } ++ else { ++ identifier.setData(data+(offset-1), 2); ++ } ++} ++ ++int ContentIdentifierDescriptor::Identifier::getCridType() const { ++ return s->crid_type; ++} ++ ++int ContentIdentifierDescriptor::Identifier::getCridLocation() const { ++ return s->crid_location; ++} ++ ++void DefaultAuthorityDescriptor::Parse() { ++ DefaultAuthority.setData(data+sizeof(descr_default_authority), getLength()-sizeof(descr_default_authority)); ++} ++ + void MultilingualNameDescriptor::Parse() { + nameLoop.setData(data+sizeof(descr_multilingual_network_name), getLength()-sizeof(descr_multilingual_network_name)); + } +diff -ur vdr-1.7.18/libsi/descriptor.h vdr-1.7/libsi/descriptor.h +--- vdr-1.7.18/libsi/descriptor.h 2010-11-01 15:24:32.000000000 +0000 ++++ vdr-1.7/libsi/descriptor.h 2011-04-17 16:04:26.000000000 +0100 +@@ -361,6 +361,31 @@ + virtual void Parse(); + }; + ++class ContentIdentifierDescriptor : public Descriptor { ++public: ++ class Identifier : public LoopElement { ++ public: ++ String identifier; ++ int getCridType() const; ++ int getCridLocation() const; ++ virtual int getLength() { return sizeof(content_identifier_entry)+identifier.getLength(); } ++ protected: ++ virtual void Parse(); ++ private: ++ const content_identifier_entry *s; ++ }; ++ StructureLoop identifierLoop; ++protected: ++ virtual void Parse(); ++}; ++ ++class DefaultAuthorityDescriptor : public Descriptor { ++public: ++ String DefaultAuthority; //ID ++protected: ++ virtual void Parse(); ++}; ++ + //abstract base class + class MultilingualNameDescriptor : public Descriptor { + public: +diff -ur vdr-1.7.18/libsi/headers.h vdr-1.7/libsi/headers.h +--- vdr-1.7.18/libsi/headers.h 2010-11-01 15:24:32.000000000 +0000 ++++ vdr-1.7/libsi/headers.h 2011-04-17 16:04:26.000000000 +0100 +@@ -1680,6 +1680,24 @@ + u_char descriptor_length :8; + }; + ++struct content_identifier_entry { ++#if BYTE_ORDER == BIG_ENDIAN ++ u_char crid_type :6; ++ u_char crid_location :2; ++#else ++ u_char crid_location :2; ++ u_char crid_type :6; ++#endif ++ union { ++ u_char crid_length :8; ++ u_char crid_ref_hi :8; ++ }; ++ union { ++ u_char crid_byte :8; ++ u_char crid_ref_lo :8; ++ }; ++}; ++ + /* 0x77 time_slice_fec_identifier_descriptor (ETSI EN 301 192) */ + + struct descr_time_slice_fec_identifier { +diff -ur vdr-1.7.18/libsi/si.c vdr-1.7/libsi/si.c +--- vdr-1.7.18/libsi/si.c 2010-11-01 15:24:32.000000000 +0000 ++++ vdr-1.7/libsi/si.c 2011-04-17 16:04:26.000000000 +0100 +@@ -609,6 +609,12 @@ + case RegistrationDescriptorTag: + d=new RegistrationDescriptor(); + break; ++ case ContentIdentifierDescriptorTag: ++ d=new ContentIdentifierDescriptor(); ++ break; ++ case DefaultAuthorityDescriptorTag: ++ d=new DefaultAuthorityDescriptor(); ++ break; + + //note that it is no problem to implement one + //of the unimplemented descriptors. +@@ -650,10 +656,8 @@ + case TransportStreamDescriptorTag: + + //defined in ETSI EN 300 468 v 1.7.1 +- case DefaultAuthorityDescriptorTag: + case RelatedContentDescriptorTag: + case TVAIdDescriptorTag: +- case ContentIdentifierDescriptorTag: + case TimeSliceFecIdentifierDescriptorTag: + case ECMRepetitionRateDescriptorTag: + case EnhancedAC3DescriptorTag: +diff -ur vdr-1.7.18/menu.c vdr-1.7/menu.c +--- vdr-1.7.18/menu.c 2011-02-27 12:37:48.000000000 +0000 ++++ vdr-1.7/menu.c 2011-04-17 16:04:26.000000000 +0100 +@@ -3057,6 +3057,7 @@ + Add(new cMenuEditBoolItem(tr("Setup.Recording$Use episode name"), &data.UseSubtitle)); + Add(new cMenuEditBoolItem(tr("Setup.Recording$Use VPS"), &data.UseVps)); + Add(new cMenuEditIntItem( tr("Setup.Recording$VPS margin (s)"), &data.VpsMargin, 0)); ++ Add(new cMenuEditBoolItem(tr("Setup.Recording$Use running status as VPS fallback"), &data.VpsFallback)); + Add(new cMenuEditBoolItem(tr("Setup.Recording$Mark instant recording"), &data.MarkInstantRecord)); + Add(new cMenuEditStrItem( tr("Setup.Recording$Name instant recording"), data.NameInstantRecord, sizeof(data.NameInstantRecord))); + Add(new cMenuEditIntItem( tr("Setup.Recording$Instant rec. time (min)"), &data.InstantRecordTime, 1, MAXINSTANTRECTIME)); +diff -ur vdr-1.7.18/sdt.c vdr-1.7/sdt.c +--- vdr-1.7.18/sdt.c 2010-05-16 15:23:21.000000000 +0100 ++++ vdr-1.7/sdt.c 2011-04-17 16:04:26.000000000 +0100 +@@ -128,6 +128,12 @@ + } + } + break; ++ case SI::DefaultAuthorityDescriptorTag: { ++ SI::DefaultAuthorityDescriptor *da = (SI::DefaultAuthorityDescriptor *)d; ++ char DaBuf[Utf8BufSize(1024)]; ++ da->DefaultAuthority.getText(DaBuf, sizeof(DaBuf)); ++ channel->SetDefaultAuthority(DaBuf); ++ } + default: ; + } + delete d; +diff -ur vdr-1.7.18/timers.c vdr-1.7/timers.c +--- vdr-1.7.18/timers.c 2010-01-16 11:18:53.000000000 +0000 ++++ vdr-1.7/timers.c 2011-04-17 16:04:26.000000000 +0100 +@@ -423,7 +423,7 @@ + } + + if (HasFlags(tfActive)) { +- if (HasFlags(tfVps) && event && event->Vps()) { ++ if (HasFlags(tfVps) && event && (Setup.VpsFallback || event->Vps())) { + if (Margin || !Directly) { + startTime = event->StartTime(); + stopTime = event->EndTime(); +diff -ur vdr-1.7.18/vdr.5 vdr-1.7/vdr.5 +--- vdr-1.7.18/vdr.5 2011-04-03 11:21:36.000000000 +0100 ++++ vdr-1.7/vdr.5 2011-04-17 16:04:26.000000000 +0100 +@@ -247,6 +247,9 @@ + .B RID + The Radio ID of this channel (typically 0, may be used to distinguish channels where + NID, TID and SID are all equal). ++.TP ++.B Default Authority ++The Default Authority for CRIDs on this channel (TVAnytime). + .PP + A particular channel can be uniquely identified by its \fBchannel\ ID\fR, + which is a string that looks like this: +@@ -778,6 +781,8 @@ + \fBR\fR@ + \fBX\fR@ + \fBV\fR@ ++\fBY\fR@ ++\fBZ\fR@ + \fBe\fR@ + \fBc\fR@ + .TE +@@ -812,6 +817,8 @@ + @is the three letter language code (optionally two codes, separated by '+') + @is the description of this stream component + @is the Video Programming Service time of this event ++ @is the CRID of this event (TVAnytime) ++ @is the CRID of the series which this event is part of (TVAnytime) + .TE + + This file will be read at program startup in order to restore the results of -- cgit v1.2.3