Now handling "linked services"

This commit is contained in:
Klaus Schmidinger 2004-02-08 11:05:22 +01:00
parent 8c71aab9bc
commit da3c91f01b
5 changed files with 141 additions and 10 deletions

View File

@ -2627,10 +2627,14 @@ Video Disk Recorder Revision History
- Added a call to cStatus::MsgOsdCurrentItem() to cMenuEditItem::SetValue()
(thanks to Martin Hammerschmid).
2004-01-31: Version 1.3.4
2004-02-08: Version 1.3.4
- Fixed handling language codes in case there is no audio or Dolby PID.
- Fixed handling CA ids (was broken in 1.3.4).
- Fixed the SVDRP command 'STAT DISK' to avoid a 'division by 0' in case the
disk is full (thanks to Jens Rosenboom).
- Fixed handling bitmap indexes for 256 color mode (thanks to Andreas Regel).
- Now handling "linked services" (based on the 'autopid' patch from Andreas
Schultz). Linked channels are detected and added to 'channels.conf', but
currently they are not yet presented to the user other than being in the
normal channel list (this will come later).

View File

@ -30,7 +30,7 @@ Here's a list of the highlights - and what _not_ to expect yet
to have them start at some high number.
- Improved CAM support. Channels with conditional access now automatically
use the device that contains the proper CAM.
- No NVOD or "linked services" support yet.
- No NVOD support yet.
Note that this is currently work in progress, so there may be some
areas that don't work as smooth as expected, yet.
@ -47,7 +47,7 @@ Known issues:
EURO1080:12168:v:S19.2E:27500:308:256:0:FF:21100:1:1088:0
in your 'channels.conf' file. Note the Ca parameter 'F' (255 in hex),
in your 'channels.conf' file. Note the Ca parameter 'FF' (255 in hex),
which gives this channel a non-existent Ca mode, so that it won't
be tuned to at all. If you really want to tune to this channel for
tests, do it on your own risk.

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: channels.c 1.22 2004/01/26 16:28:35 kls Exp $
* $Id: channels.c 1.23 2004/02/08 11:05:22 kls Exp $
*/
#include "channels.h"
@ -169,11 +169,13 @@ cChannel::cChannel(void)
guard = GUARD_INTERVAL_AUTO;
hierarchy = HIERARCHY_AUTO;
modification = CHANNELMOD_NONE;
linkChannels = NULL;
refChannel = NULL;
}
cChannel::cChannel(const cChannel *Channel)
cChannel::cChannel(const cChannel &Channel)
{
*this = *Channel;
*this = Channel;
*name = 0;
vpid = 0;
ppid = 0;
@ -188,6 +190,28 @@ cChannel::cChannel(const cChannel *Channel)
number = 0;
groupSep = false;
modification = CHANNELMOD_NONE;
linkChannels = NULL;
refChannel = NULL;
}
cChannel::~cChannel()
{
delete linkChannels;
linkChannels = NULL; // more than one channel can link to this one, so we need the following loop
for (cChannel *Channel = Channels.First(); Channel; Channel = Channels.Next(Channel)) {
if (Channel->linkChannels) {
for (cLinkChannel *lc = Channel->linkChannels->First(); lc; lc = Channel->linkChannels->Next(lc)) {
if (lc->Channel() == this) {
Channel->linkChannels->Del(lc);
break;
}
}
if (Channel->linkChannels->Count() == 0) {
delete Channel->linkChannels;
Channel->linkChannels = NULL;
}
}
}
}
cChannel& cChannel::operator= (const cChannel &Channel)
@ -397,6 +421,57 @@ void cChannel::SetCaDescriptors(int Level)
}
}
void cChannel::SetLinkChannels(cLinkChannels *LinkChannels)
{
if (!linkChannels && !LinkChannels)
return;
if (linkChannels && LinkChannels) {
cLinkChannel *lca = linkChannels->First();
cLinkChannel *lcb = LinkChannels->First();
while (lca && lcb) {
if (lca->Channel() != lcb->Channel()) {
lca = NULL;
break;
}
lca = linkChannels->Next(lca);
lcb = LinkChannels->Next(lcb);
}
if (!lca && !lcb) {
delete LinkChannels;
return; // linkage has not changed
}
}
char buffer[((linkChannels ? linkChannels->Count() : 0) + (LinkChannels ? LinkChannels->Count() : 0)) * 6 + 256]; // 6: 5 digit channel number plus blank, 256: other texts (see below) plus reserve
char *q = buffer;
q += sprintf(q, "linking channel %d from", Number());
if (linkChannels) {
for (cLinkChannel *lc = linkChannels->First(); lc; lc = linkChannels->Next(lc)) {
lc->Channel()->SetRefChannel(NULL);
q += sprintf(q, " %d", lc->Channel()->Number());
}
delete linkChannels;
}
else
q += sprintf(q, " none");
q += sprintf(q, " to");
linkChannels = LinkChannels;
if (linkChannels) {
for (cLinkChannel *lc = linkChannels->First(); lc; lc = linkChannels->Next(lc)) {
lc->Channel()->SetRefChannel(this);
q += sprintf(q, " %d", lc->Channel()->Number());
//dsyslog("link %4d -> %4d: %s", Number(), lc->Channel()->Number(), lc->Channel()->Name());
}
}
else
q += sprintf(q, " none");
dsyslog(buffer);
}
void cChannel::SetRefChannel(cChannel *RefChannel)
{
refChannel = RefChannel;
}
static int PrintParameter(char *p, char Name, int Value)
{
return Value >= 0 && Value != 999 ? sprintf(p, "%c%d", Name, Value) : 0;
@ -776,7 +851,7 @@ cChannel *cChannels::NewChannel(const cChannel *Transponder, const char *Name, i
{
if (Transponder) {
dsyslog("creating new channel '%s' on %s transponder %d with id %d-%d-%d-%d", Name, cSource::ToString(Transponder->Source()), Transponder->Transponder(), Nid, Tid, Sid, Rid);
cChannel *NewChannel = new cChannel(Transponder);
cChannel *NewChannel = new cChannel(*Transponder);
Add(NewChannel);
ReNumber();
NewChannel->SetId(Nid, Tid, Sid, Rid, false);

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: channels.h 1.13 2004/01/25 15:31:16 kls Exp $
* $Id: channels.h 1.14 2004/02/07 22:04:26 kls Exp $
*/
#ifndef __CHANNELS_H
@ -66,6 +66,19 @@ public:
static const tChannelID InvalidID;
};
class cChannel;
class cLinkChannel : public cListObject {
private:
cChannel *channel;
public:
cLinkChannel(cChannel *Channel) { channel = Channel; }
cChannel *Channel(void) { return channel; }
};
class cLinkChannels : public cList<cLinkChannel> {
};
class cChannel : public cListObject {
friend class cMenuEditChannel;
private:
@ -102,11 +115,14 @@ private:
int hierarchy;
int __EndData__;
int modification;
cLinkChannels *linkChannels;
cChannel *refChannel;
const char *ParametersToString(void);
bool StringToParameters(const char *s);
public:
cChannel(void);
cChannel(const cChannel *Channel);
cChannel(const cChannel &Channel);
~cChannel();
cChannel& operator= (const cChannel &Channel);
const char *ToText(void);
bool Parse(const char *s, bool AllowNonUniqueID = false);
@ -153,6 +169,8 @@ public:
void SetPids(int Vpid, int Ppid, int *Apids, char ALangs[][4], int *Dpids, char DLangs[][4], int Tpid);
void SetCaIds(const int *CaIds); // list must be zero-terminated
void SetCaDescriptors(int Level);
void SetLinkChannels(cLinkChannels *LinkChannels);
void SetRefChannel(cChannel *RefChannel);
};
class cChannels : public cRwLock, public cConfig<cChannel> {

36
eit.c
View File

@ -8,7 +8,7 @@
* Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>.
* Adapted to 'libsi' for VDR 1.3.0 by Marcel Wiesweg <marcel.wiesweg@gmx.de>.
*
* $Id: eit.c 1.85 2004/01/09 15:44:43 kls Exp $
* $Id: eit.c 1.86 2004/02/08 10:26:54 kls Exp $
*/
#include "eit.h"
@ -95,6 +95,7 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data)
SI::Descriptor *d;
SI::ExtendedEventDescriptors *ExtendedEventDescriptors = NULL;
SI::ShortEventDescriptor *ShortEventDescriptor = NULL;
cLinkChannels *LinkChannels = NULL;
for (SI::Loop::Iterator it2; (d = SiEitEvent.eventDescriptors.getNext(it2)); ) {
switch (d->getDescriptorTag()) {
case SI::ExtendedEventDescriptorTag: {
@ -138,6 +139,36 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data)
pEvent->SetDescription(rEvent->Description());
}
break;
case SI::LinkageDescriptorTag: {
SI::LinkageDescriptor *ld = (SI::LinkageDescriptor *)d;
tChannelID linkID(Source, ld->getOriginalNetworkId(), ld->getTransportStreamId(), ld->getServiceId());
if (ld->getLinkageType() == 0xB0) { // Premiere World
time_t now = time(NULL);
bool hit = SiEitEvent.getStartTime() <= now && now < SiEitEvent.getStartTime() + SiEitEvent.getDuration();
if (hit) {
cChannel *link = Channels.GetByChannelID(linkID);
if (link != channel) { // only link to other channels, not the same one
char linkName[ld->privateData.getLength() + 1];
strn0cpy(linkName, (const char *)ld->privateData.getData(), sizeof(linkName));
//fprintf(stderr, "Linkage %s %4d %4d %5d %5d %5d %5d %02X '%s'\n", hit ? "*" : "", channel->Number(), link ? link->Number() : -1, SiEitEvent.getEventId(), ld->getOriginalNetworkId(), ld->getTransportStreamId(), ld->getServiceId(), ld->getLinkageType(), linkName);//XXX
if (link) {
if (Setup.UpdateChannels >= 1)
link->SetName(linkName);
}
else if (Setup.UpdateChannels >= 3) {
link = Channels.NewChannel(channel, linkName, ld->getOriginalNetworkId(), ld->getTransportStreamId(), ld->getServiceId());
//XXX patFilter->Trigger();
}
if (link) {
if (!LinkChannels)
LinkChannels = new cLinkChannels;
LinkChannels->Add(new cLinkChannel(link));
}
}
}
}
}
break;
default: ;
}
delete d;
@ -167,6 +198,9 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data)
else if (SiEitEvent.getRunningStatus() == SI::RunningStatusStartsInAFewSeconds)
pSchedule->SetFollowingEvent(pEvent);
}
if (LinkChannels)
channel->SetLinkChannels(LinkChannels);
}
}