mirror of
https://github.com/vdr-projects/vdr.git
synced 2025-03-01 10:50:46 +00:00
- 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.
141 lines
6.0 KiB
C
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();
|
|
}
|