diff --git a/HISTORY b/HISTORY index a7f86b5..1b128f3 100644 --- a/HISTORY +++ b/HISTORY @@ -319,3 +319,4 @@ VDR Plugin 'femon' Revision History - Added a check for the minimum OSD height. - Replaced "Use single area (8bpp)" option with VDR's "Setup/OSD/Anti-alias". - Removed the FEMON_NTSC option. +- Fixed a deadlock in cFemonReceiver. diff --git a/README b/README index 201bdcb..2879315 100644 --- a/README +++ b/README @@ -15,7 +15,7 @@ See the file COPYING for license information. Requirements: -VDR & DVB. BMW & Ph.D.. BEER. YARRR! +VDR and a DVB card. Description: diff --git a/femonosd.c b/femonosd.c index e6a4bad..9faa5a9 100644 --- a/femonosd.c +++ b/femonosd.c @@ -173,10 +173,12 @@ cFemonOsd::~cFemonOsd(void) if (m_SvdrpPlugin) m_SvdrpPlugin->Service("SvdrpConnection-v1.0", &m_SvdrpConnection); } - if (m_Receiver) - delete m_Receiver; + if (m_Receiver) { + m_Receiver->Deactivate(); + DELETENULL(m_Receiver); + } if (m_Osd) - delete m_Osd; + DELETENULL(m_Osd); pInstance = NULL; } @@ -529,8 +531,10 @@ void cFemonOsd::Show(void) OSDCLEARSTATUS(); OSDCLEARINFO(); m_Osd->Flush(); - if (m_Receiver) - delete m_Receiver; + if (m_Receiver) { + m_Receiver->Deactivate(); + DELETENULL(m_Receiver); + } if (femonConfig.analyzestream) { cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel()); if (channel) { @@ -572,8 +576,10 @@ void cFemonOsd::ChannelSwitch(const cDevice * device, int channelNumber) return; } - if (m_Receiver) - delete m_Receiver; + if (m_Receiver) { + m_Receiver->Deactivate(); + DELETENULL(m_Receiver); + } if (femonConfig.analyzestream) { cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel()); if (channel) { @@ -591,8 +597,10 @@ void cFemonOsd::SetAudioTrack(int Index, const char * const *Tracks) int apid[2] = {0, 0}; int dpid[2] = {0, 0}; eTrackType track = cDevice::PrimaryDevice()->GetCurrentAudioTrack(); - if (m_Receiver) - delete m_Receiver; + if (m_Receiver) { + m_Receiver->Deactivate(); + DELETENULL(m_Receiver); + } if (femonConfig.analyzestream) { cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel()); if (channel) { diff --git a/femonreceiver.c b/femonreceiver.c index 65cf421..78a6fec 100644 --- a/femonreceiver.c +++ b/femonreceiver.c @@ -23,6 +23,8 @@ cFemonReceiver::cFemonReceiver(tChannelID ChannelID, int Ca, int Vpid, int Apid[], int Dpid[]) : cReceiver(ChannelID, -1, Vpid, Apid, Dpid, NULL), cThread("femon receiver"), + m_Sleep(), + m_Active(false), m_VideoPid(Vpid), m_VideoPacketCount(0), m_VideoBitrate(0.0), @@ -75,10 +77,19 @@ cFemonReceiver::cFemonReceiver(tChannelID ChannelID, int Ca, int Vpid, int Apid[ cFemonReceiver::~cFemonReceiver(void) { Dprintf("%s()\n", __PRETTY_FUNCTION__); - m_Sleep.Signal(); - if (Running()) - Cancel(3); - Detach(); + Deactivate(); +} + +void cFemonReceiver::Deactivate(void) +{ + Dprintf("%s()\n", __PRETTY_FUNCTION__); + if (m_Active) { + m_Active = false; + m_Sleep.Signal(); + if (Running()) + Cancel(3); + Detach(); + } } void cFemonReceiver::GetVideoInfo(uint8_t *buf, int len) @@ -165,7 +176,7 @@ void cFemonReceiver::Activate(bool On) if (On) Start(); else - Cancel(); + Deactivate(); } void cFemonReceiver::Receive(uchar *Data, int Length) @@ -214,7 +225,8 @@ void cFemonReceiver::Action(void) { Dprintf("%s()\n", __PRETTY_FUNCTION__); cTimeMs t; - while (Running()) { + m_Active = true; + while (Running() && m_Active) { t.Set(0); // TS packet 188 bytes - 4 byte header; MPEG standard defines 1Mbit = 1000000bit m_VideoBitrate = (10.0 * 8.0 * 184.0 * m_VideoPacketCount) / femonConfig.calcinterval; diff --git a/femonreceiver.h b/femonreceiver.h index b6bdcca..e28c6c1 100644 --- a/femonreceiver.h +++ b/femonreceiver.h @@ -17,6 +17,7 @@ class cFemonReceiver : public cReceiver, public cThread { private: cCondWait m_Sleep; + bool m_Active; int m_VideoPid; int m_VideoPacketCount; @@ -54,6 +55,7 @@ protected: public: cFemonReceiver(tChannelID ChannelID, int Ca, int Vpid, int Apid[], int Dpid[]); virtual ~cFemonReceiver(); + void Deactivate(void); bool VideoValid(void) { return m_VideoValid; }; // boolean double VideoBitrate(void) { return m_VideoBitrate; }; // bit/s