diff -p -up vdr-1.6.0/device.c.orig vdr-1.6.0/device.c --- vdr-1.6.0/device.c.orig 2009-03-20 23:52:45.000000000 +0200 +++ vdr-1.6.0/device.c 2009-03-20 23:52:46.000000000 +0200 @@ -214,6 +214,8 @@ int cPesAssembler::PacketSize(const ucha int cDevice::numDevices = 0; int cDevice::useDevice = 0; +int cDevice::useDeviceOnlyIn = 0; +int cDevice::useDeviceOnlyOut = 0; int cDevice::nextCardIndex = 0; int cDevice::currentChannel = 1; cDevice *cDevice::device[MAXDEVICES] = { NULL }; @@ -290,6 +292,18 @@ void cDevice::SetUseDevice(int n) useDevice |= (1 << n); } +void cDevice::SetUseDeviceOnlyIn(int n) +{ + if (n < MAXDEVICES) + useDeviceOnlyIn |= (1 << n); +} + +void cDevice::SetUseDeviceOnlyOut(int n) +{ + if (n < MAXDEVICES) + useDeviceOnlyOut |= (1 << n); +} + int cDevice::NextCardIndex(int n) { if (n > 0) { diff -p -up vdr-1.6.0/device.h.orig vdr-1.6.0/device.h --- vdr-1.6.0/device.h.orig 2008-02-23 15:13:04.000000000 +0200 +++ vdr-1.6.0/device.h 2009-03-20 23:52:46.000000000 +0200 @@ -99,6 +99,8 @@ class cDevice : public cThread { private: static int numDevices; static int useDevice; + static int useDeviceOnlyIn; + static int useDeviceOnlyOut; static cDevice *device[MAXDEVICES]; static cDevice *primaryDevice; static cDevice *avoidDevice; @@ -115,6 +117,14 @@ public: ///< Sets the 'useDevice' flag of the given device. ///< If this function is not called before initializing, all devices ///< will be used. + static void SetUseDeviceOnlyIn(int n); + ///< Sets the 'useDeviceOnlyIn' flag of the given device. + ///< If this function is not called before initializing, all devices + ///< will be used for output purposes as well. + static void SetUseDeviceOnlyOut(int n); + ///< Sets the 'useDeviceOnlyOut' flag of the given device. + ///< If this function is not called before initializing, all devices + ///< will be used for input purposes as well. static bool UseDevice(int n) { return useDevice == 0 || (useDevice & (1 << n)) != 0; } ///< Tells whether the device with the given card index shall be used in ///< this instance of VDR. @@ -180,6 +190,12 @@ protected: ///< anything the device needs to set up when it becomes the primary ///< device (On = true) or to shut down when it no longer is the primary ///< device (On = false), it should do so in this function. + bool UseDeviceInput(void) const { return (useDeviceOnlyOut & (1 << cardIndex)) == 0; } + ///< Tells whether this device shall be used for input purposes in this + ///< instance of VDR. + bool UseDeviceOutput(void) const { return (useDeviceOnlyIn & (1 << cardIndex)) == 0; } + ///< Tells whether this device shall be used for output purposes in this + ///< instance of VDR. public: bool IsPrimaryDevice(void) const { return this == primaryDevice; } int CardIndex(void) const { return cardIndex; } diff -p -up vdr-1.6.0/dvbdevice.c.orig vdr-1.6.0/dvbdevice.c --- vdr-1.6.0/dvbdevice.c.orig 2009-03-20 23:52:45.000000000 +0200 +++ vdr-1.6.0/dvbdevice.c 2009-03-20 23:52:46.000000000 +0200 @@ -353,6 +353,12 @@ int cDvbDevice::setTransferModeForDolbyD cDvbDevice::cDvbDevice(int n) { + int fd_frontend = -1; + fd_stc = -1; + fd_ca = -1; + fd_osd = -1; + fd_video = -1; + fd_audio = -1; ciAdapter = NULL; dvbTuner = NULL; frontendType = fe_type_t(-1); // don't know how else to initialize this - there is no FE_UNKNOWN @@ -360,22 +366,27 @@ cDvbDevice::cDvbDevice(int n) digitalAudio = false; playMode = pmNone; + if (UseDeviceInput()) { // Devices that are present on all card types: - int fd_frontend = DvbOpen(DEV_DVB_FRONTEND, n, O_RDWR | O_NONBLOCK); + fd_frontend = DvbOpen(DEV_DVB_FRONTEND, n, O_RDWR | O_NONBLOCK); + fd_stc = DvbOpen(DEV_DVB_DEMUX, n, O_RDWR); - // Devices that are only present on cards with decoders: + // Common Interface: - fd_osd = DvbOpen(DEV_DVB_OSD, n, O_RDWR); - fd_video = DvbOpen(DEV_DVB_VIDEO, n, O_RDWR | O_NONBLOCK); - fd_audio = DvbOpen(DEV_DVB_AUDIO, n, O_RDWR | O_NONBLOCK); - fd_stc = DvbOpen(DEV_DVB_DEMUX, n, O_RDWR); + fd_ca = DvbOpen(DEV_DVB_CA, n, O_RDWR); + if (fd_ca >= 0) + ciAdapter = cDvbCiAdapter::CreateCiAdapter(this, fd_ca); - // Common Interface: + } - fd_ca = DvbOpen(DEV_DVB_CA, n, O_RDWR); - if (fd_ca >= 0) - ciAdapter = cDvbCiAdapter::CreateCiAdapter(this, fd_ca); + // Devices that are only present on cards with decoders: + + if (UseDeviceOutput()) { + fd_osd = DvbOpen(DEV_DVB_OSD, n, O_RDWR); + fd_video = DvbOpen(DEV_DVB_VIDEO, n, O_RDWR | O_NONBLOCK); + fd_audio = DvbOpen(DEV_DVB_AUDIO, n, O_RDWR | O_NONBLOCK); + } // The DVR device (will be opened and closed as needed): @@ -416,19 +427,21 @@ cDvbDevice::cDvbDevice(int n) // We only check the devices that must be present - the others will be checked before accessing them://XXX - if (fd_frontend >= 0) { - dvb_frontend_info feinfo; - if (ioctl(fd_frontend, FE_GET_INFO, &feinfo) >= 0) { - frontendType = feinfo.type; - dvbTuner = new cDvbTuner(fd_frontend, CardIndex(), frontendType); + if (UseDeviceInput()) { + if (fd_frontend >= 0) { + dvb_frontend_info feinfo; + if (ioctl(fd_frontend, FE_GET_INFO, &feinfo) >= 0) { + frontendType = feinfo.type; + dvbTuner = new cDvbTuner(fd_frontend, CardIndex(), frontendType); + } + else + LOG_ERROR; } else - LOG_ERROR; - } - else - esyslog("ERROR: can't open DVB device %d", n); + esyslog("ERROR: can't open DVB device %d", n); - StartSectionHandler(); + StartSectionHandler(); + } } cDvbDevice::~cDvbDevice() diff -p -up vdr-1.6.0/vdr.c.orig vdr-1.6.0/vdr.c --- vdr-1.6.0/vdr.c.orig 2009-03-20 23:52:45.000000000 +0200 +++ vdr-1.6.0/vdr.c 2009-03-20 23:52:46.000000000 +0200 @@ -236,6 +236,8 @@ int main(int argc, char *argv[]) { "log-ident",required_argument, NULL, 'l' | 0x300 }, { "mute", no_argument, NULL, 'm' }, { "no-kbd", no_argument, NULL, 'n' | 0x100 }, + { "only-in", required_argument, NULL, 'o' | 0x100 }, + { "only-out", required_argument, NULL, 'o' | 0x200 }, { "plugin", required_argument, NULL, 'P' }, { "port", required_argument, NULL, 'p' }, { "rcu", optional_argument, NULL, 'r' | 0x100 }, @@ -327,6 +329,26 @@ int main(int argc, char *argv[]) case 'n' | 0x100: UseKbd = false; break; + case 'o' | 0x100: if (isnumber(optarg)) { + int n = atoi(optarg); + if (0 <= n && n < MAXDEVICES) { + cDevice::SetUseDeviceOnlyIn(n); + break; + } + } + fprintf(stderr, "vdr: invalid DVB device number: %s\n", optarg); + return 2; + break; + case 'o' | 0x200: if (isnumber(optarg)) { + int n = atoi(optarg); + if (0 <= n && n < MAXDEVICES) { + cDevice::SetUseDeviceOnlyOut(n); + break; + } + } + fprintf(stderr, "vdr: invalid DVB device number: %s\n", optarg); + return 2; + break; case 'p': if (isnumber(optarg)) SVDRPport = atoi(optarg); else { @@ -432,6 +454,14 @@ int main(int argc, char *argv[]) " %s)\n" " -m, --mute mute audio of the primary DVB device at startup\n" " --no-kbd don't use the keyboard as an input device\n" + " --only-in=NUM use the given DVB device as input device only\n" + " (NUM = 0, 1, 2...)\n" + " there may be several --only-in= options (default:\n" + " output features of all cards are used if present)\n" + " --only-out=NUM use the given DVB device as output device only\n" + " (NUM = 0, 1, 2...)\n" + " there may be several --only-out= options (default:\n" + " all DVB devices will be used for input as well)\n" " -p PORT, --port=PORT use PORT for SVDRP (default: %d)\n" " 0 turns off SVDRP\n" " -P OPT, --plugin=OPT load a plugin defined by the given options\n"