summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKlaus Schmidinger <vdr@tvdr.de>2004-02-08 11:05:22 +0100
committerKlaus Schmidinger <vdr@tvdr.de>2004-02-08 11:05:22 +0100
commitda3c91f01bab52add46a3de24d20b760dfaf9708 (patch)
tree49f69feb8f1f228c65dfe6911e1a5772e3827197
parent8c71aab9bc8e0a7879eb2337de59de1028f92b7a (diff)
downloadvdr-da3c91f01bab52add46a3de24d20b760dfaf9708.tar.gz
vdr-da3c91f01bab52add46a3de24d20b760dfaf9708.tar.bz2
Now handling "linked services"
-rw-r--r--HISTORY6
-rw-r--r--README.developer4
-rw-r--r--channels.c83
-rw-r--r--channels.h22
-rw-r--r--eit.c36
5 files changed, 141 insertions, 10 deletions
diff --git a/HISTORY b/HISTORY
index d6a8284a..dde28ea6 100644
--- a/HISTORY
+++ b/HISTORY
@@ -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).
diff --git a/README.developer b/README.developer
index d079d637..4fe75c81 100644
--- a/README.developer
+++ b/README.developer
@@ -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.
diff --git a/channels.c b/channels.c
index 4b3930d4..b5bd9bd4 100644
--- a/channels.c
+++ b/channels.c
@@ -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);
diff --git a/channels.h b/channels.h
index 532a1121..fa55d951 100644
--- a/channels.h
+++ b/channels.h
@@ -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> {
diff --git a/eit.c b/eit.c
index d71cad82..c24a3d0a 100644
--- a/eit.c
+++ b/eit.c
@@ -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);
}
}