vdr/sdt.c
Klaus Schmidinger 335a572913 Version 1.3.12
- Removed all error messages from cRecordings::ScanVideoDir() and just skipping
  entries that cause errors in order to avoid failure in case of things like
  broken links etc.
- The function cTimers::SetEvents() now immediately returns if there is some user
  input.
- Fixed handling menu status messages when the list contents is scrolled (thanks to
  Alfred Zastrow for reporting this one).
- Fixed checking the last area for misalignment in cOsd::CanHandleAreas() (thanks
  to Reinhard Nissl for reporting this one).
- No longer adding section filters to the list of filters if they can't be opened
  (thanks to Marco Schlüßler for pointing this out).
- Fixed handling error case '-1' when polling section filters (thanks to Marco
  Schlüßler).
- Fixed handling error case '-1' when polling CAM connections.
- Making sure the OSD reports oeWrongAlignment errors before any oeAreasOverlap
  error (suggested by Reinhard Nissl).
- Avoiding flashing effects in the OSD of full featured DVB cards by explicitly
  clearing the OSD windows before opening them (suggested by Marco Schlüßler).
- Experimental support for NVOD channels. Currently these channels are detected
  and linked to their "base" channels using the same mechanisms as for the
  "linked services" (let's see if this is useful). Thanks to Mike parker for
  helping to test this. Also used some input from the 'autopid' patch by Andreas
  Schultz).
- Now storing the name of the service provider (aka "bouquet") in the channel
  name, separated by a semicolon (see man vdr(5) for details). Explicit usage
  of the various parts of the channel name is yet to come.
- The 'radio' channel icon is now only displayed in the ST:TNG skin if the channel
  actually has an APID.
2004-07-18 18:00:00 +02:00

141 lines
6.0 KiB
C

/*
* sdt.c: SDT section filter
*
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: sdt.c 1.11 2004/07/18 11:14:42 kls Exp $
*/
#include "sdt.h"
#include "channels.h"
#include "config.h"
#include "libsi/section.h"
#include "libsi/descriptor.h"
// --- cSdtFilter ------------------------------------------------------------
cSdtFilter::cSdtFilter(cPatFilter *PatFilter)
{
patFilter = PatFilter;
Set(0x11, 0x42); // SDT
}
void cSdtFilter::SetStatus(bool On)
{
cFilter::SetStatus(On);
sectionSyncer.Reset();
}
void cSdtFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length)
{
if (!(Source() && Transponder()))
return;
SI::SDT sdt(Data, false);
if (!sdt.CheckCRCAndParse())
return;
if (!sectionSyncer.Sync(sdt.getVersionNumber(), sdt.getSectionNumber(), sdt.getLastSectionNumber()))
return;
if (!Channels.Lock(true, 10))
return;
SI::SDT::Service SiSdtService;
for (SI::Loop::Iterator it; sdt.serviceLoop.hasNext(it); ) {
SiSdtService = sdt.serviceLoop.getNext(it);
cChannel *channel = Channels.GetByChannelID(tChannelID(Source(), sdt.getOriginalNetworkId(), sdt.getTransportStreamId(), SiSdtService.getServiceId()));
if (!channel)
channel = Channels.GetByChannelID(tChannelID(Source(), 0, Transponder(), SiSdtService.getServiceId()));
cLinkChannels *LinkChannels = NULL;
SI::Descriptor *d;
for (SI::Loop::Iterator it2; (d = SiSdtService.serviceDescriptors.getNext(it2)); ) {
switch (d->getDescriptorTag()) {
case SI::ServiceDescriptorTag: {
SI::ServiceDescriptor *sd = (SI::ServiceDescriptor *)d;
switch (sd->getServiceType()) {
case 0x01: // digital television service
case 0x02: // digital radio sound service
case 0x04: // NVOD reference service
case 0x05: // NVOD time-shifted service
{
char NameBuf[1024];
char ShortNameBuf[1024];
sd->serviceName.getText(NameBuf, ShortNameBuf, sizeof(NameBuf), sizeof(ShortNameBuf));
char *pn = compactspace(NameBuf);
char *ps = compactspace(ShortNameBuf);
if (*NameBuf && *ShortNameBuf && strcmp(NameBuf, ShortNameBuf) != 0) {
ps = ShortNameBuf + strlen(ShortNameBuf);
*ps++ = ',';
strcpy(ps, NameBuf);
pn = ShortNameBuf;
}
if (*pn) {
char ProviderNameBuf[1024];
sd->providerName.getText(ProviderNameBuf, sizeof(ProviderNameBuf));
if (*ProviderNameBuf) {
char *p = pn + strlen(pn);
*p++ = ';';
strcpy(p, ProviderNameBuf);
}
}
if (channel) {
channel->SetId(sdt.getOriginalNetworkId(), sdt.getTransportStreamId(), SiSdtService.getServiceId());
if (Setup.UpdateChannels >= 1)
channel->SetName(pn);
// Using SiSdtService.getFreeCaMode() is no good, because some
// tv stations set this flag even for non-encrypted channels :-(
// The special value 0xFFFF was supposed to mean "unknown encryption"
// and would have been overwritten with real CA values later:
// channel->SetCa(SiSdtService.getFreeCaMode() ? 0xFFFF : 0);
}
else if (*pn && Setup.UpdateChannels >= 3) {
channel = Channels.NewChannel(Channel(), pn, sdt.getOriginalNetworkId(), sdt.getTransportStreamId(), SiSdtService.getServiceId());
patFilter->Trigger();
}
}
}
}
break;
// Using the CaIdentifierDescriptor is no good, because some tv stations
// just don't use it. The actual CA values are collected in pat.c:
/*
case SI::CaIdentifierDescriptorTag: {
SI::CaIdentifierDescriptor *cid = (SI::CaIdentifierDescriptor *)d;
if (channel) {
for (SI::Loop::Iterator it; cid->identifiers.hasNext(it); )
channel->SetCa(cid->identifiers.getNext(it));
}
}
break;
*/
case SI::NVODReferenceDescriptorTag: {
SI::NVODReferenceDescriptor *nrd = (SI::NVODReferenceDescriptor *)d;
for (SI::Loop::Iterator it; nrd->serviceLoop.hasNext(it); ) {
SI::NVODReferenceDescriptor::Service Service = nrd->serviceLoop.getNext(it);
cChannel *link = Channels.GetByChannelID(tChannelID(Source(), Service.getOriginalNetworkId(), Service.getTransportStream(), Service.getServiceId()));
if (!link && Setup.UpdateChannels >= 3) {
link = Channels.NewChannel(Channel(), "NVOD", Service.getOriginalNetworkId(), Service.getTransportStream(), Service.getServiceId());
patFilter->Trigger();
}
if (link) {
if (!LinkChannels)
LinkChannels = new cLinkChannels;
LinkChannels->Add(new cLinkChannel(link));
}
}
}
break;
default: ;
}
delete d;
}
if (LinkChannels) {
if (channel)
channel->SetLinkChannels(LinkChannels);
else
delete LinkChannels;
}
}
Channels.Unlock();
}