Now waiting at startup until all DVB devices are ready

This commit is contained in:
Klaus Schmidinger 2005-08-21 08:56:49 +02:00
parent ba3437f7cc
commit 6de23d7d96
8 changed files with 74 additions and 8 deletions

View File

@ -3700,8 +3700,12 @@ Video Disk Recorder Revision History
- Removed the VIDEO_STILLPICTURE_WORKS_WITH_VDR_FRAMES stuff from
cDvbDevice::StillPicture(), since apparently the VIDEO_STILLPICTURE call works.
2005-08-20: Version 1.3.30
2005-08-21: Version 1.3.30
- Improved responsiveness inside CAM menus.
- Added handling of the 'Close MMI' tag to avoid error log messages with CAMs
that actually use it.
- Now waiting at startup until all DVB devices are ready. This includes having
all CAMs initialized and ready to decrypt, so that no more "channel not
available" happens if VDR is started with the current channel being an encrypted
one, or a timer on such a channel hits right after starting VDR.

18
ci.c
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: ci.c 1.25 2005/08/20 12:16:23 kls Exp $
* $Id: ci.c 1.26 2005/08/20 15:27:35 kls Exp $
*/
#include "ci.h"
@ -1354,6 +1354,8 @@ cCiHandler::cCiHandler(int Fd, int NumSlots)
hasUserIO = false;
for (int i = 0; i < MAX_CI_SESSION; i++)
sessions[i] = NULL;
for (int i = 0; i < MAX_CI_SLOT; i++)
moduleReady[i] = false;
tpl = new cCiTransportLayer(Fd, numSlots);
tc = NULL;
}
@ -1506,6 +1508,19 @@ int cCiHandler::CloseAllSessions(int Slot)
return result;
}
bool cCiHandler::Ready(void)
{
cMutexLock MutexLock(&mutex);
for (int Slot = 0; Slot < numSlots; Slot++) {
if (moduleReady[Slot]) {
cCiConditionalAccessSupport *cas = (cCiConditionalAccessSupport *)GetSessionByResourceId(RI_CONDITIONAL_ACCESS_SUPPORT, Slot);
if (!cas || !*cas->GetCaSystemIds())
return false;
}
}
return true;
}
bool cCiHandler::Process(void)
{
bool result = true;
@ -1543,6 +1558,7 @@ bool cCiHandler::Process(void)
}
else if (tpl->ModuleReady(Slot)) {
dbgprotocol("Module ready in slot %d\n", Slot);
moduleReady[Slot] = true;
tpl->NewConnection(Slot);
}
}

5
ci.h
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: ci.h 1.13 2004/02/08 14:36:23 kls Exp $
* $Id: ci.h 1.14 2005/08/20 14:56:11 kls Exp $
*/
#ifndef __CI_H
@ -77,6 +77,7 @@ public:
};
#define MAX_CI_SESSION 16 //XXX
#define MAX_CI_SLOT 16
class cCiSession;
class cCiTransportLayer;
@ -89,6 +90,7 @@ private:
int numSlots;
bool newCaSupport;
bool hasUserIO;
bool moduleReady[MAX_CI_SLOT];
cCiSession *sessions[MAX_CI_SESSION];
cCiTransportLayer *tpl;
cCiTransportConnection *tc;
@ -105,6 +107,7 @@ public:
~cCiHandler();
static cCiHandler *CreateCiHandler(const char *FileName);
int NumSlots(void) { return numSlots; }
bool Ready(void);
bool Process(void);
bool HasUserIO(void) { return hasUserIO; }
bool EnterMenu(int Slot);

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: device.c 1.105 2005/08/14 10:52:08 kls Exp $
* $Id: device.c 1.106 2005/08/21 08:56:49 kls Exp $
*/
#include "device.h"
@ -195,6 +195,20 @@ cDevice::~cDevice()
delete pesAssembler;
}
bool cDevice::WaitForAllDevicesReady(int Timeout)
{
for (time_t t0 = time(NULL); time(NULL) - t0 < Timeout; ) {
bool ready = true;
for (int i = 0; i < numDevices; i++) {
if (device[i] && !device[i]->Ready())
ready = false;
}
if (ready)
return true;
}
return false;
}
void cDevice::SetUseDevice(int n)
{
if (n < MAXDEVICES)
@ -1103,6 +1117,11 @@ int cDevice::CanShift(int Ca, int Priority, int UsedCards) const
XXX*/
}
bool cDevice::Ready(void)
{
return true;
}
int cDevice::ProvidesCa(const cChannel *Channel) const
{
int Ca = Channel->Ca();

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: device.h 1.61 2005/08/13 11:44:13 kls Exp $
* $Id: device.h 1.62 2005/08/21 08:52:20 kls Exp $
*/
#ifndef __DEVICE_H
@ -102,6 +102,12 @@ private:
public:
static int NumDevices(void) { return numDevices; }
///< Returns the total number of devices.
static bool WaitForAllDevicesReady(int Timeout = 0);
///< Waits until all devices have become ready, or the given Timeout
///< (seconds) has expired. While waiting, the Ready() function of each
///< device is called in turn, until they all return true.
///< \return True if all devices have become ready within the given
///< timeout.
static void SetUseDevice(int n);
///< Sets the 'useDevice' flag of the given device.
///< If this function is not called before initializing, all devices
@ -136,6 +142,11 @@ private:
protected:
cDevice(void);
virtual ~cDevice();
virtual bool Ready(void);
///< Returns true if this device is ready. Devices with conditional
///< access hardware may need some time until they are up and running.
///< This function is called in a loop at startup until all devices
///< are ready (see WaitForAllDevicesReady()).
static int NextCardIndex(int n = 0);
///< Calculates the next card index.
///< Each device in a given machine must have a unique card index, which

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: dvbdevice.c 1.134 2005/08/15 14:05:23 kls Exp $
* $Id: dvbdevice.c 1.135 2005/08/20 15:22:36 kls Exp $
*/
#include "dvbdevice.h"
@ -478,6 +478,15 @@ bool cDvbDevice::HasDecoder(void) const
return fd_video >= 0 && fd_audio >= 0;
}
bool cDvbDevice::Ready(void)
{
if (ciHandler) {
ciHandler->Process();
return ciHandler->Ready();
}
return true;
}
int cDvbDevice::ProvidesCa(const cChannel *Channel) const
{
if (Channel->Ca() >= 0x0100 && ciHandler) {

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: dvbdevice.h 1.34 2005/02/20 11:17:07 kls Exp $
* $Id: dvbdevice.h 1.35 2005/08/20 15:20:15 kls Exp $
*/
#ifndef __DVBDEVICE_H
@ -42,6 +42,7 @@ protected:
public:
cDvbDevice(int n);
virtual ~cDvbDevice();
virtual bool Ready(void);
virtual int ProvidesCa(const cChannel *Channel) const;
virtual bool HasDecoder(void) const;

5
vdr.c
View File

@ -22,7 +22,7 @@
*
* The project's page is at http://www.cadsoft.de/vdr
*
* $Id: vdr.c 1.210 2005/08/20 11:24:42 kls Exp $
* $Id: vdr.c 1.211 2005/08/21 08:47:06 kls Exp $
*/
#include <getopt.h>
@ -65,6 +65,7 @@
#define CHANNELSAVEDELTA 600 // seconds before saving channels.conf after automatic modifications
#define LASTCAMMENUTIMEOUT 3 // seconds to run the main loop 'fast' after a CAM menu has been closed
// in order to react on a possible new CAM menu as soon as possible
#define DEVICEREADYTIMEOUT 30 // seconds to wait until all devices are ready
#define EXIT(v) { ExitCode = (v); goto Exit; }
@ -520,6 +521,8 @@ int main(int argc, char *argv[])
// Channel:
if (!cDevice::WaitForAllDevicesReady(DEVICEREADYTIMEOUT))
dsyslog("not all devices ready after %d seconds", DEVICEREADYTIMEOUT);
Channels.SwitchTo(Setup.CurrentChannel);
if (MuteAudio)
cDevice::PrimaryDevice()->ToggleMute();