From patchwork Sat Jun 17 11:16:39 2006 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Klaus Schmidinger X-Patchwork-Id: 12336 Received: from raven.cadsoft.de ([217.7.101.211]) by www.linuxtv.org with esmtp (Exim 4.50) id 1FrYnE-0002kb-Be for vdr@linuxtv.org; Sat, 17 Jun 2006 13:16:44 +0200 Received: from [192.168.100.10] (hawk.cadsoft.de [192.168.100.10]) by raven.cadsoft.de (8.13.3/8.13.3) with ESMTP id k5HBGgOL005012 for ; Sat, 17 Jun 2006 13:16:42 +0200 Message-ID: <4493E497.8050301@cadsoft.de> Date: Sat, 17 Jun 2006 13:16:39 +0200 From: Klaus Schmidinger Organization: CadSoft Computer GmbH User-Agent: Thunderbird 1.5.0.4 (X11/20060516) MIME-Version: 1.0 To: vdr@linuxtv.org Subject: Re: [vdr] Explaining VPS References: <4485CB9B.1060504@fastmail.fm> <4485E96F.4040700@cadsoft.de> In-Reply-To: <4485E96F.4040700@cadsoft.de> X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-2.0 (raven.cadsoft.de [192.168.1.1]); Sat, 17 Jun 2006 13:16:43 +0200 (CEST) X-BeenThere: vdr@linuxtv.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: VDR Mailing List List-Id: VDR Mailing List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 17 Jun 2006 11:16:44 -0000 Status: O X-Status: X-Keywords: X-UID: 9809 Klaus Schmidinger wrote: > Suur Karu wrote: >> Hi, all! >> Please explain me how VPS works in VDR? >> I reside in GMT+2 (+3h in summertime) timezone and >> when watching for example ZDF EPG shows correct time, but >> VPS reports +1h. Is it transmitted in localtime? >> Example: >> EPG: 06.06.2006 21:15-22:00 (45 min) >> VPS: 06.06 20:14 >> and as result +1:01 >> >> Is it correct? > > The "Programme Identification Label" (PIL) is the "first > published start time of a certain event", and it is in local > time. So if you're not in the same time zone as the broadcast > station, there's a problem. > > Maybe we also need to take into account the "local time offset descriptor" > to find out the actual time offset of the broadcast station, but > IIRC that descriptor wasn't broadcast back when I started > implementing VPS. I'll take a look at this... After some testing it appears like most broadcasters do send the TOT data. This one also carries the current time in UTC, and since the TOT is CRC32 protected, it would even have an advantage over the TDT, which might contain garbage without being noticed (that's why VDR's cTDT uses 'lastDiff' in an attempt to detect invalid time data). However, some broadcasters only send TDT, so we would probably have to parse both of them. So switching from TDT to TOT would have two advantages: having the current time in a CRC32 protected way, plus giving us information about the broadcaster's time zone. Unfortunately the time zone information is not given directly, but rather as a "current offset from UTC", thus also including any DST (daylight saving time). Fortunately, though, it contains both the current and the next offset (i.e. the one for DST and the one without DST), so taking the smaller one of these should give us the actual time zone. The attached patch adds parsing the TPT to VDR/eit.c and writes some debug output to the console. For the German RTL channels this looks like this: TDT Sat Jun 17 11:55:18 2006 TOT Sat Jun 17 11:55:18 2006 58 DEU 0 0 200 Sun Oct 29 02:00:00 2006 100 AUT 0 0 200 Sun Oct 29 02:00:00 2006 100 CHE 0 0 200 Sun Oct 29 02:00:00 2006 100 Apparently the TOT can contain information for various time zones, so I'm not quite sure as to how exactly this can be used in case the entries would lead to different results. Note that the attached patch is just for investigating the TOT. It does not add any functionality, and it turns off setting the system time. So don't use it in a production system unless you know what you are doing. I'm just posting it in case somebody is interested. The remaining problem is that the time zone information needs to be assigned to the individual channels, so that it is available when an EPG event with VPS information is detected. However, the TOT's repeat frequency varies greatly between broadcasters. Some repeat it every second, while others send it only twice per minute. This means that EPG events with VPS information can only be processed correctly after the TOT has been seen - which can take quite a while. Anyway, since this would require some incompatible changes (channels would need to store their time zone), I'm afraid I can't make changes here in version 1.4. I'll see what I can do in version 1.5. It's a real pitty that the authors of the DVB standard have totally messed up the Programme Identification Label. Instead of making this a sequence of digits, they really should have made this a "time in UTC". Then we wouldn't have this problem... Klaus --- eit.c 2006/05/25 14:35:19 1.118 +++ eit.c 2006/06/17 11:02:32 @@ -282,6 +282,8 @@ :SI::TDT(Data, false) { CheckParse(); + fprintf(stderr, "TDT %s\n", *TimeToString(getTime()));//XXX + return;//XXX time_t sattim = getTime(); time_t loctim = time(NULL); @@ -300,6 +302,47 @@ } } +// --- cTOT ------------------------------------------------------------------ + +class cTOT : public SI::TOT { +public: + cTOT(const u_char *Data); + }; + +cTOT::cTOT(const u_char *Data) +:SI::TOT(Data, false) +{ + if (!CheckCRCAndParse()) + return; + fprintf(stderr, "TOT %s\n", *TimeToString(getTime()));//XXX + SI::Descriptor *d; + for (SI::Loop::Iterator it; (d = descriptorLoop.getNext(it)); ) { + fprintf(stderr, "%02X\n", d->getDescriptorTag());//XXX + switch (d->getDescriptorTag()) { + case SI::LocalTimeOffsetDescriptorTag: { + SI::LocalTimeOffsetDescriptor *ltod = (SI::LocalTimeOffsetDescriptor *)d; + SI::LocalTimeOffsetDescriptor::LocalTimeOffset lto; + for (SI::Loop::Iterator it2; ltod->localTimeOffsetLoop.getNext(lto, it2); ) { + fprintf(stderr, "%s\n", lto.countryCode);//XXX + fprintf(stderr, "%d\n", lto.getCountryId());//XXX + fprintf(stderr, "%d\n", lto.getLocalTimeOffsetPolarity());//XXX + fprintf(stderr, "%d\n", BCD2INT(lto.getLocalTimeOffset()));//XXX + fprintf(stderr, "%s\n", *TimeToString(lto.getTimeOfChange()));//XXX + fprintf(stderr, "%d\n", BCD2INT(lto.getNextTimeOffset()));//XXX + int pol = lto.getLocalTimeOffsetPolarity() ? -1 : 1; + int lto1 = BCD2INT(lto.getLocalTimeOffset()); + int lto2 = BCD2INT(lto.getNextTimeOffset()); + lto1 = pol * (lto1 / 100 * 60 + lto1 % 100) * 60;//XXX cTimer::TimeToInt() -> tools.c + lto2 = pol * (lto2 / 100 * 60 + lto2 % 100) * 60; + fprintf(stderr, "==> Offset from UTC = %d\n", min(lto1, lto2));//XXX + } + } + default: ; + } + delete d; + } +} + // --- cEitFilter ------------------------------------------------------------ cEitFilter::cEitFilter(void) @@ -308,6 +351,7 @@ 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(0x14, 0x73); // TOT//XXX } void cEitFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length) @@ -331,7 +375,11 @@ } break; case 0x14: { - if (Setup.SetSystemTime && Setup.TimeTransponder && ISTRANSPONDER(Transponder(), Setup.TimeTransponder)) + if (Tid == 0x73) {//XXX + cTOT TOT(Data); + } + else//XXX +//XXX if (Setup.SetSystemTime && Setup.TimeTransponder && ISTRANSPONDER(Transponder(), Setup.TimeTransponder)) cTDT TDT(Data); } break;