diff options
| author | Lars Hanisch <dvb@flensrocker.de> | 2011-01-20 20:18:12 +0100 |
|---|---|---|
| committer | Lars Hanisch <dvb@flensrocker.de> | 2011-01-20 20:18:12 +0100 |
| commit | 035cab576d7b01720d02ea6485146bb7ec501aa1 (patch) | |
| tree | f36a4c7e2fdea30bcb2a2313997fb6fca774f7e6 | |
| parent | 89508dfcc23ce215b97b46cbb5b8e9062235986c (diff) | |
| download | vdr-plugin-pvrinput-035cab576d7b01720d02ea6485146bb7ec501aa1.tar.gz vdr-plugin-pvrinput-035cab576d7b01720d02ea6485146bb7ec501aa1.tar.bz2 | |
patch to work with the dynamite-plugin
With dynamite pvrinput-devices can now be attached/detached dynamically while vdr is running.
e.g.
svdrpsend plug dynamite attd /dev/video0
svdrpsend plug dynamite detd /dev/video0
| -rwxr-xr-x | device.c | 77 | ||||
| -rwxr-xr-x | device.h | 20 | ||||
| -rwxr-xr-x | pvrinput.c | 12 |
3 files changed, 92 insertions, 17 deletions
@@ -15,8 +15,12 @@ cPvrDevice *PvrDevices[kMaxPvrDevices]; cString cPvrDevice::externChannelSwitchScript; int cPvrDevice::VBIDeviceCount = 0; -cPvrDevice::cPvrDevice(int DeviceNumber) -: number(DeviceNumber), +cPvrDevice::cPvrDevice(int DeviceNumber, cDevice *ParentDevice) +: +#ifdef __DYNAMIC_DEVICE_PROBE + cDevice(ParentDevice), +#endif + number(DeviceNumber), CurrentNorm(0), //uint64_t can't be negative CurrentLinesPerFrame(-1), CurrentFrequency(-1), @@ -199,13 +203,26 @@ cPvrDevice::cPvrDevice(int DeviceNumber) } ReInit(); StartSectionHandler(); + index = 0; + while ((index < kMaxPvrDevices) && (PvrDevices[index] != NULL)) + index++; + if (index < kMaxPvrDevices) + PvrDevices[index] = this; + else { + index = -1; + esyslog("ERROR: too many cPvrDevices!"); + } } cPvrDevice::~cPvrDevice() { + if ((index >= 0) && (index < kMaxPvrDevices) && (PvrDevices[index] == this)) + PvrDevices[index] = NULL; #if VDRVERSNUM >= 10600 StopSectionHandler(); #endif + DetachAllReceivers(); + Stop(); cRingBufferLinear *tsBuffer_tmp = tsBuffer; log(pvrDEBUG2, "~cPvrDevice()"); tsBuffer = NULL; @@ -255,7 +272,13 @@ bool cPvrDevice::Initialize(void) for (int i = 0; i < kMaxPvrDevices; i++) { PvrDevices[i] = NULL; if (Probe(i)) { - PvrDevices[i] = new cPvrDevice(i); +#ifdef __DYNAMIC_DEVICE_PROBE + if (cPluginManager::GetPlugin("dynamite")) + cDynamicDeviceProbe::QueueDynamicDeviceCommand(ddpcAttach, *cString::sprintf("/dev/video%d", i)); + else +#else + new cPvrDevice(i); +#endif found++; } } @@ -267,19 +290,23 @@ bool cPvrDevice::Initialize(void) return found > 0; } -void cPvrDevice::Stop(void) +void cPvrDevice::StopAll(void) { /* recursively stop all threads inside pvrinputs devices */ for (int i = 0; i < kMaxPvrDevices; i++) { - if (PvrDevices[i]) { - if (PvrDevices[i]->readThread) { - log(pvrDEBUG2,"cPvrDevice::Stop() for Device %i", i); - PvrDevices[i]->StopReadThread(); - PvrDevices[i]->SetEncoderState(eStop); - PvrDevices[i]->SetVBImode(PvrDevices[i]->CurrentLinesPerFrame, V4L2_MPEG_STREAM_VBI_FMT_NONE); - } + if (PvrDevices[i]) + PvrDevices[i]->Stop(); } - } +} + +void cPvrDevice::Stop(void) +{ + if (readThread) { + log(pvrDEBUG2,"cPvrDevice::Stop() for Device %i", index); + StopReadThread(); + SetEncoderState(eStop); + SetVBImode(CurrentLinesPerFrame, V4L2_MPEG_STREAM_VBI_FMT_NONE); + } } void cPvrDevice::GetStandard(void) @@ -1437,3 +1464,29 @@ bool cPvrDevice::QueryAllControls(void) INIT(PvrSetup.FilterChromaMedianTop); return true; } + + +#ifdef __DYNAMIC_DEVICE_PROBE +cPvrDeviceProbe *cPvrDeviceProbe::probe = NULL; + +void cPvrDeviceProbe::Init(void) +{ + if (!probe) + probe = new cPvrDeviceProbe(); +} + +void cPvrDeviceProbe::Shutdown(void) +{ + if (probe) + delete probe; + probe = NULL; +} + +cDevice *cPvrDeviceProbe::Attach(cDevice *ParentDevice, const char *DevPath) +{ + int nr = -1; + if ((sscanf(DevPath, "/dev/video%d", &nr) == 1) && cPvrDevice::Probe(nr)) + return new cPvrDevice(nr, ParentDevice); + return NULL; +} +#endif @@ -52,6 +52,9 @@ class cPvrReadThread; class cPvrDevice : public cDevice { friend class cPvrReadThread; +#ifdef __DYNAMIC_DEVICE_PROBE + friend class cPvrDeviceProbe; +#endif private: static bool Probe(int DeviceNumber); static cString externChannelSwitchScript; @@ -59,12 +62,13 @@ private: public: static bool Initialize(void); - static void Stop(void); + static void StopAll(void); static void ReInitAll(void); static int Count(); static cPvrDevice * Get(int index); private: + int index; int number; int v4l2_fd; int mpeg_fd; @@ -125,7 +129,7 @@ protected: bool IsBuffering(); virtual bool GetTSPacket(uchar *&Data); public: - cPvrDevice(int DeviceNumber); + cPvrDevice(int DeviceNumber, cDevice *ParentDevice = NULL); virtual ~cPvrDevice(void); virtual bool ProvidesSource(int Source) const; virtual bool ProvidesTransponder(const cChannel *Channel) const; @@ -135,6 +139,7 @@ public: eInputType *inputType, int *apid, int *vpid, int *tpid) const; int ReOpen(void); void ReInit(void); + void Stop(void); void StopReadThread(void); void GetStandard(void); void TurnOffSlicedVBI(void); @@ -156,4 +161,15 @@ public: bool QueryAllControls(void); }; +#ifdef __DYNAMIC_DEVICE_PROBE +class cPvrDeviceProbe : public cDynamicDeviceProbe { +private: + static cPvrDeviceProbe *probe; +public: + static void Init(void); + static void Shutdown(void); + virtual cDevice *Attach(cDevice *ParentDevice, const char *DevPath); +}; +#endif + #endif @@ -6,7 +6,7 @@ #endif #endif -static const char *VERSION = "2010-09-02"; +static const char *VERSION = "2011-01-20"; static const char *DESCRIPTION = tr("use Hauppauge PVR as input device"); static const char *MAINMENUENTRY = tr("PVR picture settings"); @@ -16,10 +16,16 @@ cPluginPvrInput *PluginPvrInput; cPluginPvrInput::cPluginPvrInput(void) { PluginPvrInput = this; +#ifdef __DYNAMIC_DEVICE_PROBE + cPvrDeviceProbe::Init(); +#endif } cPluginPvrInput::~cPluginPvrInput() { +#ifdef __DYNAMIC_DEVICE_PROBE + cPvrDeviceProbe::Shutdown(); +#endif PluginPvrInput = NULL; } @@ -48,6 +54,7 @@ bool cPluginPvrInput::Initialize(void) #if VDRVERSNUM < 10507 RegisterI18n(pvrinput_Phrases); #endif //VDRVERSNUM < 10507 + cPvrDevice::Initialize(); return true; } @@ -56,7 +63,6 @@ bool cPluginPvrInput::Start(void) /* Start() is called after the primary device and user interface has been set up, but before the main program loop is entered. Is called after Initialize(). */ - cPvrDevice::Initialize(); return true; } @@ -64,7 +70,7 @@ void cPluginPvrInput::Stop(void) { /* Any threads the plugin may have created shall be stopped in the Stop() function. See VDR/PLUGINS.html */ - cPvrDevice::Stop(); + cPvrDevice::StopAll(); }; void cPluginPvrInput::Housekeeping(void) |
