diff -ur vdr-1.7.20/channels.c vdr-1.7.20.new/channels.c --- vdr-1.7.20/channels.c 2010-11-07 12:24:59.000000000 +0000 +++ vdr-1.7.20.new/channels.c 2011-08-16 18:08: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.20/channels.h vdr-1.7.20.new/channels.h --- vdr-1.7.20/channels.h 2011-08-06 10:56:13.000000000 +0100 +++ vdr-1.7.20.new/channels.h 2011-08-16 18:08: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.20/config.c vdr-1.7.20.new/config.c --- vdr-1.7.20/config.c 2011-06-13 15:41:01.000000000 +0100 +++ vdr-1.7.20.new/config.c 2011-08-16 18:08:26.000000000 +0100 @@ -353,6 +353,7 @@ UseSubtitle = 1; UseVps = 0; VpsMargin = 120; + VpsFallback = 0; RecordingDirs = 1; FoldersInTimerMenu = 1; NumberKeysForChars = 1; @@ -545,6 +546,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); @@ -641,6 +643,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.20/config.h vdr-1.7.20.new/config.h --- vdr-1.7.20/config.h 2011-06-21 22:43:01.000000000 +0100 +++ vdr-1.7.20.new/config.h 2011-08-16 18:08: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.20/eit.c vdr-1.7.20.new/eit.c --- vdr-1.7.20/eit.c 2010-05-14 15:08:35.000000000 +0100 +++ vdr-1.7.20.new/eit.c 2011-08-16 18:08:26.000000000 +0100 @@ -265,6 +265,33 @@ } } 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()); + int i = strlen(buffer); + if (i) { + cde.identifier.getText(buffer+i, Utf8BufSize(256)-i); + switch (cde.getCridType()) { + case 0x01: // ETSI 102 363 code + case 0x31: // UK Freeview private code + pEvent->SetItemCRID(buffer); + break; + case 0x02: // ETSI 102 363 code + case 0x32: // UK Freeview private code + pEvent->SetSeriesCRID(buffer); + break; + // ETSI 102 323 defines CRID type 0x03, which describes 'related' or 'suggested' events. + // Freeview broadcasts these as CRID type 0x33. + // There can be more than one type 0x33 descriptor per event (each with one CRID). + } + } + } + } + } default: ; } delete d; diff -ur vdr-1.7.20/epg.c vdr-1.7.20.new/epg.c --- vdr-1.7.20/epg.c 2011-02-25 15:16:05.000000000 +0000 +++ vdr-1.7.20.new/epg.c 2011-08-16 18:08: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.20/epg.h vdr-1.7.20.new/epg.h --- vdr-1.7.20/epg.h 2011-02-25 14:14:38.000000000 +0000 +++ vdr-1.7.20.new/epg.h 2011-08-16 18:08: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.20/menu.c vdr-1.7.20.new/menu.c --- vdr-1.7.20/menu.c 2011-08-06 14:13:34.000000000 +0100 +++ vdr-1.7.20.new/menu.c 2011-08-16 18:08:26.000000000 +0100 @@ -3058,6 +3058,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.20/sdt.c vdr-1.7.20.new/sdt.c --- vdr-1.7.20/sdt.c 2010-05-16 15:23:21.000000000 +0100 +++ vdr-1.7.20.new/sdt.c 2011-08-16 18:08: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.20/timers.c vdr-1.7.20.new/timers.c --- vdr-1.7.20/timers.c 2011-08-06 14:13:54.000000000 +0100 +++ vdr-1.7.20.new/timers.c 2011-08-16 18:08:26.000000000 +0100 @@ -430,7 +430,7 @@ deferred = 0; 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.20/vdr.5 vdr-1.7.20.new/vdr.5 --- vdr-1.7.20/vdr.5 2011-04-03 11:21:36.000000000 +0100 +++ vdr-1.7.20.new/vdr.5 2011-08-16 18:08: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