From b60eda5a8e8a9b9b96a90016fd27c03cd3f1ec8b Mon Sep 17 00:00:00 2001 From: Klaus Schmidinger Date: Wed, 19 Mar 2003 18:00:00 +0100 Subject: [PATCH] Version 1.1.26 - Removed signal handling and usleep(5000) from cDvbOsd::Cmd() (apparently this is no longer necessary with DVB driver 1.0.0pre2 or later). - If the primary device (as defined in setup.conf) doesn't have an MPEG decoder (and thus can't be used as a primary device) VDR now scans all devices at startup and uses the first one (if any) that actually has an MPEG decoder. That way this will also work automatically if the primary device is implemented by a plugin. - Fixed a possible deadlock when using the "Blue" button in the "Schedules" menu to switch to an other channel (thanks to Torsten Herz). - Fixed the EPG bugfix code number for the MAX_USEFUL_SUBTITLE_LENGTH fix (thanks to Torsten Herz for reporting this one). - Modified the EPG scanner to avoid CPU load peaks (thanks to Steffen Becker for reporting this one). - Fixed support for Viaccess CAMs (thanks to Axel Gruber for helping to debug this). --- CONTRIBUTORS | 9 ++++++++ HISTORY | 19 +++++++++++++++- ci.c | 4 ++-- config.h | 4 ++-- device.c | 21 +++++++++++------- dvbosd.c | 13 +---------- eit.c | 11 ++++------ eitscan.c | 61 ++++++++++++++++++++++------------------------------ eitscan.h | 5 +++-- vdr.c | 12 ++++++++++- 10 files changed, 89 insertions(+), 70 deletions(-) diff --git a/CONTRIBUTORS b/CONTRIBUTORS index fe70f1af..09a2bd6b 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -87,6 +87,7 @@ Peter Hofmann Axel Gruber for his support in keeping the Premiere World channels up to date in 'channels.conf' + for helping to debug support for Viaccess CAMs Arnold Niessen for translating OSD texts to the Dutch language @@ -544,3 +545,11 @@ Jan Ekholm Marcel Wiesweg for pointing out a problem with high CPU load during replay for reporting broken support for raw OSDs of plugins + +Torsten Herz + for fixing a possible deadlock when using the "Blue" button in the "Schedules" menu + to switch to an other channel + for reporting a wrong EPG bugfix code number for the MAX_USEFUL_SUBTITLE_LENGTH fix + +Steffen Becker + for reporting a problem with CPU load peaks (in the EPG scanner) diff --git a/HISTORY b/HISTORY index 50e5bf56..a5c70f0b 100644 --- a/HISTORY +++ b/HISTORY @@ -1959,7 +1959,7 @@ Video Disk Recorder Revision History 2003-02-16: Version 1.1.25 -- Fixed high CPU load during replay (thanks Marcel Wiesweg for pointing out this +- Fixed high CPU load during replay (thanks to Marcel Wiesweg for pointing out this one). - Fixed margin handling in cRingBufferLinear. - Now polling the output device in 'Transfer Mode' and retrying to put packets @@ -1970,3 +1970,20 @@ Video Disk Recorder Revision History - Fixed broken support for raw OSDs of plugins (thanks to Marcel Wiesweg for reporting this one). - Broken CAM connections are now restored automatically. + +2003-03-19: Version 1.1.26 + +- Removed signal handling and usleep(5000) from cDvbOsd::Cmd() (apparently this + is no longer necessary with DVB driver 1.0.0pre2 or later). +- If the primary device (as defined in setup.conf) doesn't have an MPEG decoder + (and thus can't be used as a primary device) VDR now scans all devices at + startup and uses the first one (if any) that actually has an MPEG decoder. + That way this will also work automatically if the primary device is implemented + by a plugin. +- Fixed a possible deadlock when using the "Blue" button in the "Schedules" menu + to switch to an other channel (thanks to Torsten Herz). +- Fixed the EPG bugfix code number for the MAX_USEFUL_SUBTITLE_LENGTH fix (thanks to + Torsten Herz for reporting this one). +- Modified the EPG scanner to avoid CPU load peaks (thanks to Steffen Becker for + reporting this one). +- Fixed support for Viaccess CAMs (thanks to Axel Gruber for helping to debug this). diff --git a/ci.c b/ci.c index d345a3ef..62bbed7e 100644 --- a/ci.c +++ b/ci.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: ci.c 1.7 2003/02/16 11:20:55 kls Exp $ + * $Id: ci.c 1.8 2003/03/16 22:32:47 kls Exp $ */ /* XXX TODO @@ -1232,7 +1232,7 @@ cCiCaPmt::cCiCaPmt(int ProgramNumber) capmt[length++] = CPLM_ONLY; capmt[length++] = (ProgramNumber >> 8) & 0xFF; capmt[length++] = ProgramNumber & 0xFF; - capmt[length++] = 0x00; //XXX version_number, current_next_indicator - apparently may be 0x00 + capmt[length++] = 0x01; // version_number, current_next_indicator - apparently vn doesn't matter, but cni must be 1 esInfoLengthPos = length; capmt[length++] = 0x00; // program_info_length H (at program level) capmt[length++] = 0x00; // program_info_length L diff --git a/config.h b/config.h index d050516c..20604586 100644 --- a/config.h +++ b/config.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: config.h 1.149 2003/02/15 11:01:04 kls Exp $ + * $Id: config.h 1.150 2003/03/09 10:01:02 kls Exp $ */ #ifndef __CONFIG_H @@ -19,7 +19,7 @@ #include "device.h" #include "tools.h" -#define VDRVERSION "1.1.25" +#define VDRVERSION "1.1.26" #define MAXPRIORITY 99 #define MAXLIFETIME 99 diff --git a/device.c b/device.c index 15628cd3..0f99e13b 100644 --- a/device.c +++ b/device.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: device.c 1.36 2003/01/03 15:41:14 kls Exp $ + * $Id: device.c 1.37 2003/03/09 14:05:23 kls Exp $ */ #include "device.h" @@ -106,14 +106,19 @@ bool cDevice::SetPrimaryDevice(int n) { n--; if (0 <= n && n < numDevices && device[n]) { - isyslog("setting primary device to %d", n + 1); - if (primaryDevice) - primaryDevice->MakePrimaryDevice(false); - primaryDevice = device[n]; - primaryDevice->MakePrimaryDevice(true); - return true; + if (device[n]->HasDecoder()) { + isyslog("setting primary device to %d", n + 1); + if (primaryDevice) + primaryDevice->MakePrimaryDevice(false); + primaryDevice = device[n]; + primaryDevice->MakePrimaryDevice(true); + return true; + } + else + esyslog("ERROR: device number %d has no MPEG decoder", n + 1); } - esyslog("invalid primary device number: %d", n + 1); + else + esyslog("ERROR: invalid primary device number: %d", n + 1); return false; } diff --git a/dvbosd.c b/dvbosd.c index 4b0c1ea8..428a3f04 100644 --- a/dvbosd.c +++ b/dvbosd.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: dvbosd.c 1.19 2002/08/25 09:53:51 kls Exp $ + * $Id: dvbosd.c 1.20 2003/03/09 09:59:13 kls Exp $ */ #include "dvbosd.h" @@ -60,18 +60,7 @@ void cDvbOsd::Cmd(OSD_Command cmd, int color, int x0, int y0, int x1, int y1, co dc.x1 = x1; dc.y1 = y1; dc.data = (void *)data; - // must block all signals, otherwise the command might not be fully executed - sigset_t set, oldset; - sigfillset(&set); - sigdelset(&set, SIGALRM); - sigprocmask(SIG_BLOCK, &set, &oldset); ioctl(osdDev, OSD_SEND_CMD, &dc); - if (cmd == OSD_SetBlock) // XXX this is the only command that takes longer - usleep(5000); // XXX Workaround for a driver bug (cInterface::DisplayChannel() displayed texts at wrong places - // XXX and sometimes the OSD was no longer displayed). - // XXX Increase the value if the problem still persists on your particular system. - // TODO Check if this is still necessary with driver versions after 0.7. - sigprocmask(SIG_SETMASK, &oldset, NULL); } } diff --git a/eit.c b/eit.c index eebe82c7..42740852 100644 --- a/eit.c +++ b/eit.c @@ -16,7 +16,7 @@ * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * - * $Id: eit.c 1.65 2003/02/02 15:41:03 kls Exp $ + * $Id: eit.c 1.67 2003/03/16 11:20:05 kls Exp $ ***************************************************************************/ #include "eit.h" @@ -607,7 +607,7 @@ void cEventInfo::FixEpgBugs(void) free(pExtendedDescription); pExtendedDescription = pSubtitle; pSubtitle = NULL; - EpgBugFixStat(5, GetChannelID()); + EpgBugFixStat(6, GetChannelID()); } } @@ -1250,12 +1250,13 @@ void cSIProcessor::Action() if (seclen == r) { //dsyslog("Received pid 0x%04X with table ID 0x%02X and length of %4d\n", pid, buf[0], seclen); + cMutexLock MutexLock(&schedulesMutex); // since the xMem... stuff is not thread safe, we need to use a "global" mutex + LOCK_THREAD; switch (pid) { case 0x00: if (buf[0] == 0x00) { - LOCK_THREAD; if (pmtPid && time(NULL) - lastPmtScan > PMT_SCAN_TIMEOUT) { DelFilter(pmtPid, 0x02); pmtPid = 0; @@ -1263,7 +1264,6 @@ void cSIProcessor::Action() lastPmtScan = time(NULL); } if (!pmtPid) { - cMutexLock MutexLock(&schedulesMutex); // since the xMem... stuff is not thread safe, we need to use a "global" mutex struct LIST *pat = siParsePAT(buf); if (pat) { int Index = 0; @@ -1301,7 +1301,6 @@ void cSIProcessor::Action() case 0x12: if (buf[0] != 0x72) { - cMutexLock MutexLock(&schedulesMutex); cEIT ceit(buf, seclen, schedules); ceit.ProcessEIT(buf, currentSource); } @@ -1310,9 +1309,7 @@ void cSIProcessor::Action() break; default: { - LOCK_THREAD; if (pid == pmtPid && buf[0] == 0x02 && currentSource && currentTransponder) { - cMutexLock MutexLock(&schedulesMutex); // since the xMem... stuff is not thread safe, we need to use a "global" mutex struct Pid *pi = siParsePMT(buf); if (pi) { for (struct LIST *d = (struct LIST *)pi->Descriptors; d; d = (struct LIST *)xSucc(d)) { diff --git a/eitscan.c b/eitscan.c index 5768a423..a5c1a7b9 100644 --- a/eitscan.c +++ b/eitscan.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: eitscan.c 1.11 2003/01/26 16:19:24 kls Exp $ + * $Id: eitscan.c 1.12 2003/03/16 13:29:55 kls Exp $ */ #include "eitscan.h" @@ -16,7 +16,7 @@ cEITScanner::cEITScanner(void) { lastScan = lastActivity = time(NULL); currentChannel = 0; - lastChannel = 0; + memset(lastChannel, 0, sizeof(lastChannel)); numTransponders = 0; transponders = NULL; } @@ -51,42 +51,33 @@ void cEITScanner::Process(void) if (Setup.EPGScanTimeout && Channels.MaxNumber() > 1) { time_t now = time(NULL); if (now - lastScan > ScanTimeout && now - lastActivity > ActivityTimeout) { - do { - int oldLastChannel = lastChannel; - for (int i = 0; i < cDevice::NumDevices(); i++) { - cDevice *Device = cDevice::GetDevice(i); - if (Device && Device->CardIndex() < MAXDVBDEVICES) { - if (Device != cDevice::PrimaryDevice() || (cDevice::NumDevices() == 1 && Setup.EPGScanTimeout && now - lastActivity > Setup.EPGScanTimeout * 3600)) { - if (!(Device->Receiving(true) || Device->Replaying())) { - int oldCh = lastChannel; - int ch = oldCh + 1; - while (ch != oldCh) { - if (ch > Channels.MaxNumber()) { - ch = 1; - numTransponders = 0; - } - cChannel *Channel = Channels.GetByNumber(ch, 1); - if (Channel) { - if (!Device->ProvidesChannel(Channel)) - break; - if (Channel->Sid() && !TransponderScanned(Channel)) { - if (Device == cDevice::PrimaryDevice() && !currentChannel) - currentChannel = Device->CurrentChannel(); - Device->SwitchChannel(Channel, false); - lastChannel = ch; - break; - } - } - ch = Channel->Number() + 1; - } - } + for (int i = 0; i < cDevice::NumDevices(); i++) { + cDevice *Device = cDevice::GetDevice(i); + if (Device && Device->CardIndex() < MAXDVBDEVICES) { + if (Device != cDevice::PrimaryDevice() || (cDevice::NumDevices() == 1 && Setup.EPGScanTimeout && now - lastActivity > Setup.EPGScanTimeout * 3600)) { + if (!(Device->Receiving(true) || Device->Replaying())) { + for (;;) { + cChannel *Channel = Channels.GetByNumber(lastChannel[Device->DeviceNumber()] + 1, 1); + if (Channel) { + lastChannel[Device->DeviceNumber()] = Channel->Number(); + if (Channel->Sid() && Device->ProvidesChannel(Channel) && !TransponderScanned(Channel)) { + if (Device == cDevice::PrimaryDevice() && !currentChannel) + currentChannel = Device->CurrentChannel(); + Device->SwitchChannel(Channel, false); + break; + } + } + else { + if (lastChannel[Device->DeviceNumber()]) + numTransponders = 0; + lastChannel[Device->DeviceNumber()] = 0; + break; + } + } } } } - if (lastChannel != oldLastChannel) - break; - lastChannel++; - } while (time(NULL) - now < 2); + } lastScan = time(NULL); } } diff --git a/eitscan.h b/eitscan.h index 7dacb822..5b40ddd6 100644 --- a/eitscan.h +++ b/eitscan.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: eitscan.h 1.1 2002/05/20 11:00:05 kls Exp $ + * $Id: eitscan.h 1.2 2003/03/16 13:20:40 kls Exp $ */ #ifndef __EITSCAN_H @@ -19,7 +19,8 @@ private: ScanTimeout = 20 }; time_t lastScan, lastActivity; - int currentChannel, lastChannel; + int currentChannel; + int lastChannel[MAXDEVICES]; int numTransponders, *transponders; bool TransponderScanned(cChannel *Channel); public: diff --git a/vdr.c b/vdr.c index 3e6a9ed3..50b1a290 100644 --- a/vdr.c +++ b/vdr.c @@ -22,7 +22,7 @@ * * The project's page is at http://www.cadsoft.de/people/kls/vdr * - * $Id: vdr.c 1.145 2003/02/16 10:34:24 kls Exp $ + * $Id: vdr.c 1.146 2003/03/09 14:07:46 kls Exp $ */ #include @@ -364,6 +364,16 @@ int main(int argc, char *argv[]) // Primary device: cDevice::SetPrimaryDevice(Setup.PrimaryDVB); + if (!cDevice::PrimaryDevice()) { + for (int i = 0; i < cDevice::NumDevices(); i++) { + cDevice *d = cDevice::GetDevice(i); + if (d && d->HasDecoder()) { + isyslog("trying device number %d instead", i + 1); + if (cDevice::SetPrimaryDevice(i + 1)) + Setup.PrimaryDVB = i + 1; + } + } + } if (!cDevice::PrimaryDevice()) { const char *msg = "no primary device found - giving up!"; fprintf(stderr, "vdr: %s\n", msg);