diff options
| -rw-r--r-- | HISTORY | 6 | ||||
| -rw-r--r-- | ci.c | 18 | ||||
| -rw-r--r-- | ci.h | 5 | ||||
| -rw-r--r-- | device.c | 21 | ||||
| -rw-r--r-- | device.h | 13 | ||||
| -rw-r--r-- | dvbdevice.c | 11 | ||||
| -rw-r--r-- | dvbdevice.h | 3 | ||||
| -rw-r--r-- | vdr.c | 5 | 
8 files changed, 74 insertions, 8 deletions
| @@ -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. @@ -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);           }        } @@ -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); @@ -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(); @@ -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 diff --git a/dvbdevice.c b/dvbdevice.c index ccd9a982..c47717bb 100644 --- a/dvbdevice.c +++ b/dvbdevice.c @@ -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) { diff --git a/dvbdevice.h b/dvbdevice.h index 4a705367..7da7e4f1 100644 --- a/dvbdevice.h +++ b/dvbdevice.h @@ -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; @@ -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(); | 
