summaryrefslogtreecommitdiff
path: root/channels.c
diff options
context:
space:
mode:
authorKlaus Schmidinger <kls (at) cadsoft (dot) de>2005-09-11 18:00:00 +0200
committerKlaus Schmidinger <kls (at) cadsoft (dot) de>2005-09-11 18:00:00 +0200
commitd5c85f5ff84ffea666c63eca5dbe04632283cb04 (patch)
tree6500dbf4fff9aaa7ccd7ae29f1ffacea36eed934 /channels.c
parentad40eaa28e6e9f0fa594937453b5ae53b88dce75 (diff)
downloadvdr-patch-lnbsharing-d5c85f5ff84ffea666c63eca5dbe04632283cb04.tar.gz
vdr-patch-lnbsharing-d5c85f5ff84ffea666c63eca5dbe04632283cb04.tar.bz2
Version 1.3.32vdr-1.3.32
- Added some missing braces in remux.c (thanks to Wayne Keer for reporting this one). - Removed unused MAINMENUENTRY from svdrpdemo.c (thanks to Udo Richter for reporting this one). - Fixed appending sequence end code in cDvbPlayer::Goto() (thanks to Reinhard Nissl). - Fixed syncing in cRepacker (thanks to Reinhard Nissl). - Now always using stream id 0xE0 for the video stream, to avoid problems with post processing tools that choke on different ids (suggested by Reinhard Nissl). - Updated the Estonian OSD texts (thanks to Arthur Konovalov). - Fixed cDvbPlayer::SkipFrames() to properly handle radio recordings (thanks to Reinhard Nissl). - Updated the Swedish OSD texts (thanks to Tomas Prybil). - Updated the Slovenian OSD texts (thanks to Matjaz Thaler). - Updated the Danish OSD texts (thanks to Mogens Elneff). - Made LIRC command parsing more robust (thanks to Ville Skyttä). - Introduced a separate 'plugins-install' target in the Makefile (thanks to Daniel Thompson). - Re-introduced the code that waits for a tuner lock in VDR/device.c, since apparently some users actually need it. It's not active by default, you'll have to define the WAIT_FOR_TUNER_LOCK macro in that file if you need it (suggested by Malcolm Caldwell). - Adjusted the Makefile to the dvb-kernel driver on kernel 2.6 and up (thanks to Lauri Tischler). - Repeat keys are now ignored when waiting for a keypress to cancel an operation (thanks to Marko Mäkelä). - The main menu function of a plugin can now be activated through a key macro of the form "@plugin" even if that plugin doesn't have a main menu entry (using part of a patch by Hardy Flor, which originally implemented calling plugins from SVDRP). - The menu timeout handling is now done centrally in the main program loop. - Added missing help for the 'help' keyword in the SVDRP command PLUG. - The main menu function of a plugin can now be called programmatically through the static function cRemote::CallPlugin(). - The SVDRP command PLUG now has a new option 'main' which can be used to initiate a call to the main menu function of a plugin (using part of a patch by Hardy Flor). - The new command line option '--vfat' can be used to make VDR encode special characters in recording file names, even if it wasn't compiled with VFAT=1 (suggested by Peter Bieringer). The compile time option VFAT still exists and creates a VDR that always behaves as if it were called with '--vfat'. - Replaced the ':' delimiter between hour and minute in recording file names with a '.' under Linux, too. Existing recordings with ':' as delimiter will still work. - Implemented the SVDRP command MOVC (thanks to Andreas Brachold). - Added support for multiple audio language codes in ISO639LanguageDescriptors to 'libsi' (thanks to Marcel Wiesweg). - Changed the audio PID language codes to hold up to two 3 letter codes, separated by '+', to store separate languages broadcast in two channel audio mode. - If the preferred audio language is broadcast on a PID that has two different languages in the two stereo channels, the audio channel is now properly set when switching to such a channel (thanks to Mogens Elneff for his help in testing this). - Fixed some typos in MANUAL (thanks to Ville Skyttä). - Fixed the default value for "Setup/EPG bugfix level" (thanks to Ville Skyttä for reporting this one). - Fixed defining timers that only differ in the day of week (thanks to Patrick Rother for reporting this one). - Fixed converting summary.vdr files that would result in a very long 'short text' (thanks to Carsten Koch). - Implemented a hash for the channels to reduce the system load in the EIT scanning thread (based on a patch by Georg Acher).
Diffstat (limited to 'channels.c')
-rw-r--r--channels.c89
1 files changed, 59 insertions, 30 deletions
diff --git a/channels.c b/channels.c
index 8577852..939c29f 100644
--- a/channels.c
+++ b/channels.c
@@ -4,12 +4,13 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: channels.c 1.44 2005/08/06 12:22:41 kls Exp $
+ * $Id: channels.c 1.46 2005/09/11 14:22:24 kls Exp $
*/
#include "channels.h"
#include <linux/dvb/frontend.h>
#include <ctype.h>
+#include "device.h"
// IMPORTANT NOTE: in the 'sscanf()' calls there is a blank after the '%d'
// format characters in order to allow any number of blanks after a numeric
@@ -341,11 +342,14 @@ void cChannel::SetId(int Nid, int Tid, int Sid, int Rid)
dsyslog("changing id of channel %d from %d-%d-%d-%d to %d-%d-%d-%d", Number(), nid, tid, sid, rid, Nid, Tid, Sid, Rid);
modification |= CHANNELMOD_ID;
Channels.SetModified();
+ Channels.UnhashChannel(this);
}
nid = Nid;
tid = Tid;
sid = Sid;
rid = Rid;
+ if (Number())
+ Channels.HashChannel(this);
}
}
@@ -386,7 +390,7 @@ void cChannel::SetPortalName(const char *PortalName)
#define STRDIFF 0x01
#define VALDIFF 0x02
-static int IntArraysDiffer(const int *a, const int *b, const char na[][4] = NULL, const char nb[][4] = NULL)
+static int IntArraysDiffer(const int *a, const int *b, const char na[][MAXLANGCODE2] = NULL, const char nb[][MAXLANGCODE2] = NULL)
{
int result = 0;
for (int i = 0; a[i] || b[i]; i++) {
@@ -400,7 +404,7 @@ static int IntArraysDiffer(const int *a, const int *b, const char na[][4] = NULL
return result;
}
-static int IntArrayToString(char *s, const int *a, int Base = 10, const char n[][4] = NULL)
+static int IntArrayToString(char *s, const int *a, int Base = 10, const char n[][MAXLANGCODE2] = NULL)
{
char *q = s;
int i = 0;
@@ -416,7 +420,7 @@ static int IntArrayToString(char *s, const int *a, int Base = 10, const char n[]
return q - s;
}
-void cChannel::SetPids(int Vpid, int Ppid, int *Apids, char ALangs[][4], int *Dpids, char DLangs[][4], int Tpid)
+void cChannel::SetPids(int Vpid, int Ppid, int *Apids, char ALangs[][MAXLANGCODE2], int *Dpids, char DLangs[][MAXLANGCODE2], int Tpid)
{
int mod = CHANNELMOD_NONE;
if (vpid != Vpid || ppid != Ppid || tpid != Tpid)
@@ -427,8 +431,9 @@ void cChannel::SetPids(int Vpid, int Ppid, int *Apids, char ALangs[][4], int *Dp
if (m & VALDIFF)
mod |= CHANNELMOD_PIDS;
if (mod) {
- char OldApidsBuf[(MAXAPIDS + MAXDPIDS) * 10 + 10]; // 10: 5 digits plus delimiting ',' or ';' plus optional '=cod', +10: paranoia
- char NewApidsBuf[(MAXAPIDS + MAXDPIDS) * 10 + 10];
+ const int BufferSize = (MAXAPIDS + MAXDPIDS) * (5 + 1 + MAXLANGCODE2) + 10; // 5 digits plus delimiting ',' or ';' plus optional '=cod+cod', +10: paranoia
+ char OldApidsBuf[BufferSize];
+ char NewApidsBuf[BufferSize];
char *q = OldApidsBuf;
q += IntArrayToString(q, apids, 10, alangs);
if (dpids[0]) {
@@ -448,12 +453,12 @@ void cChannel::SetPids(int Vpid, int Ppid, int *Apids, char ALangs[][4], int *Dp
ppid = Ppid;
for (int i = 0; i < MAXAPIDS; i++) {
apids[i] = Apids[i];
- strn0cpy(alangs[i], ALangs[i], 4);
+ strn0cpy(alangs[i], ALangs[i], MAXLANGCODE2);
}
apids[MAXAPIDS] = 0;
for (int i = 0; i < MAXDPIDS; i++) {
dpids[i] = Dpids[i];
- strn0cpy(dlangs[i], DLangs[i], 4);
+ strn0cpy(dlangs[i], DLangs[i], MAXLANGCODE2);
}
dpids[MAXDPIDS] = 0;
tpid = Tpid;
@@ -633,7 +638,8 @@ cString cChannel::ToText(const cChannel *Channel)
if (Channel->ppid && Channel->ppid != Channel->vpid)
q += snprintf(q, sizeof(vpidbuf) - (q - vpidbuf), "+%d", Channel->ppid);
*q = 0;
- char apidbuf[(MAXAPIDS + MAXDPIDS) * 10 + 10]; // 10: 5 digits plus delimiting ',' or ';' plus optional '=cod', +10: paranoia
+ const int BufferSize = (MAXAPIDS + MAXDPIDS) * (5 + 1 + MAXLANGCODE2) + 10; // 5 digits plus delimiting ',' or ';' plus optional '=cod+cod', +10: paranoia
+ char apidbuf[BufferSize];
q = apidbuf;
q += IntArrayToString(q, Channel->apids, 10, Channel->alangs);
if (Channel->dpids[0]) {
@@ -722,7 +728,7 @@ bool cChannel::Parse(const char *s)
char *l = strchr(q, '=');
if (l) {
*l++ = 0;
- strn0cpy(alangs[NumApids], l, 4);
+ strn0cpy(alangs[NumApids], l, MAXLANGCODE2);
}
else
*alangs[NumApids] = 0;
@@ -743,7 +749,7 @@ bool cChannel::Parse(const char *s)
char *l = strchr(q, '=');
if (l) {
*l++ = 0;
- strn0cpy(dlangs[NumDpids], l, 4);
+ strn0cpy(dlangs[NumDpids], l, MAXLANGCODE2);
}
else
*dlangs[NumDpids] = 0;
@@ -865,6 +871,16 @@ bool cChannels::Load(const char *FileName, bool AllowComments, bool MustExist)
return false;
}
+void cChannels::HashChannel(cChannel *Channel)
+{
+ channelsHashSid.Add(Channel, Channel->Sid());
+}
+
+void cChannels::UnhashChannel(cChannel *Channel)
+{
+ channelsHashSid.Del(Channel, Channel->Sid());
+}
+
int cChannels::GetNextGroup(int Idx)
{
cChannel *channel = Get(++Idx);
@@ -891,6 +907,7 @@ int cChannels::GetNextNormal(int Idx)
void cChannels::ReNumber( void )
{
+ channelsHashSid.Clear();
int Number = 1;
for (cChannel *channel = First(); channel; channel = Next(channel)) {
if (channel->GroupSep()) {
@@ -898,6 +915,7 @@ void cChannels::ReNumber( void )
Number = channel->Number();
}
else {
+ HashChannel(channel);
maxNumber = Number;
channel->SetNumber(Number++);
}
@@ -921,32 +939,43 @@ cChannel *cChannels::GetByNumber(int Number, int SkipGap)
cChannel *cChannels::GetByServiceID(int Source, int Transponder, unsigned short ServiceID)
{
- for (cChannel *channel = First(); channel; channel = Next(channel)) {
- if (!channel->GroupSep() && channel->Source() == Source && ISTRANSPONDER(channel->Transponder(), Transponder) && channel->Sid() == ServiceID)
- return channel;
- }
+ cList<cHashObject> *list = channelsHashSid.GetList(ServiceID);
+ if (list) {
+ for (cHashObject *hobj = list->First(); hobj; hobj = list->Next(hobj)) {
+ cChannel *channel = (cChannel *)hobj->Object();
+ if (channel->Sid() == ServiceID && channel->Source() == Source && ISTRANSPONDER(channel->Transponder(), Transponder))
+ return channel;
+ }
+ }
return NULL;
}
cChannel *cChannels::GetByChannelID(tChannelID ChannelID, bool TryWithoutRid, bool TryWithoutPolarization)
{
- for (cChannel *channel = First(); channel; channel = Next(channel)) {
- if (!channel->GroupSep() && channel->GetChannelID() == ChannelID)
- return channel;
- }
- if (TryWithoutRid) {
- ChannelID.ClrRid();
- for (cChannel *channel = First(); channel; channel = Next(channel)) {
- if (!channel->GroupSep() && channel->GetChannelID().ClrRid() == ChannelID)
- return channel;
- }
- }
- if (TryWithoutPolarization) {
- ChannelID.ClrPolarization();
- for (cChannel *channel = First(); channel; channel = Next(channel)) {
- if (!channel->GroupSep() && channel->GetChannelID().ClrPolarization() == ChannelID)
+ int sid = ChannelID.Sid();
+ cList<cHashObject> *list = channelsHashSid.GetList(sid);
+ if (list) {
+ for (cHashObject *hobj = list->First(); hobj; hobj = list->Next(hobj)) {
+ cChannel *channel = (cChannel *)hobj->Object();
+ if (channel->Sid() == sid && channel->GetChannelID() == ChannelID)
return channel;
}
+ if (TryWithoutRid) {
+ ChannelID.ClrRid();
+ for (cHashObject *hobj = list->First(); hobj; hobj = list->Next(hobj)) {
+ cChannel *channel = (cChannel *)hobj->Object();
+ if (channel->Sid() == sid && channel->GetChannelID().ClrRid() == ChannelID)
+ return channel;
+ }
+ }
+ if (TryWithoutPolarization) {
+ ChannelID.ClrPolarization();
+ for (cHashObject *hobj = list->First(); hobj; hobj = list->Next(hobj)) {
+ cChannel *channel = (cChannel *)hobj->Object();
+ if (channel->Sid() == sid && channel->GetChannelID().ClrPolarization() == ChannelID)
+ return channel;
+ }
+ }
}
return NULL;
}