Commit 2d1863f9 authored by Andrew de Quincey's avatar Andrew de Quincey

Rewrote my slightly hacky method for shutting down tsstreamers. I've added

a Shutdown() method to the I_TsPacketHandler interface (and all its derived
classes) so fix this issue.
parent b29bfda6
......@@ -3,7 +3,7 @@
* start, stop, suspend and resume operations.
*-------------------------------------------------------------------------------
* (c)1999-2003 VideoLAN
* $Id: normaltrickplay.cpp,v 1.11 2003/08/13 22:48:43 adq Exp $
* $Id: normaltrickplay.cpp,v 1.12 2003/08/14 15:22:35 adq Exp $
*
* Authors: Jean-Paul Saman <jpsaman@wxs.nl>
*
......@@ -93,13 +93,15 @@ C_NormalTrickPlay::C_NormalTrickPlay(C_Module* pModule,
void C_NormalTrickPlay::HandlePacket(C_TsPacket* pPacket)
{
m_pHandler->HandlePacket(pPacket);
if (!m_pHandler->HandlePacket(pPacket)) {
m_pTsProvider->ReleasePacket(pPacket);
}
}
void C_NormalTrickPlay::DoWork()
{
// printf("C_NormalTrickPlay::DoWork()\n");
// printf("C_NormalTrickPlay::DoWork()\n");
// Initialize the condition in the new thread.
m_cResumeCond.Protect();
......@@ -110,10 +112,10 @@ void C_NormalTrickPlay::DoWork()
C_Fifo<C_TsPacket> * pPackets = new C_Fifo<C_TsPacket>(700);
C_TsPacket * pPacket;
while(!m_bStop && !iRc)
{
if (m_iTrickPlayStatus != m_iRequestTrickPlayStatus)
{
switch (m_iRequestTrickPlayStatus)
......@@ -147,7 +149,7 @@ void C_NormalTrickPlay::DoWork()
break;
}
}
iRc = m_pConverter->GetNextTsPackets(pPackets);
int iVectorSize = pPackets->Size();
......@@ -162,7 +164,7 @@ void C_NormalTrickPlay::DoWork()
}
}
else
{
{
for(int i = 0; i < iVectorSize; i++)
{
pPacket = pPackets->Pop();
......@@ -195,16 +197,7 @@ void C_NormalTrickPlay::StopWork()
// nitrox
m_cResumeCond.Release();
C_TrickPlay::StopWork();
// if the thread isn't already stopped, wait a second.
// If it STILL hasn't stopped, we will be stuck in HandlePacket()
// waiting for the consumer thread to remove items from the buffer.
// As the consumer is likely already dead, this never occurs, causing
// deadlock. Kill it
if (IsRunning()) {
sleep(1);
if (IsRunning()) Interrupt();
}
m_pHandler->Shutdown();
}
void C_NormalTrickPlay::InitWork()
......@@ -213,14 +206,14 @@ void C_NormalTrickPlay::InitWork()
if (m_iInitFill < 1)
m_iInitFill = 1;
// Fill the buffer
int iRc = NO_ERR;
int iVectorSize = 0;
C_Fifo<C_TsPacket> * pPackets = new C_Fifo<C_TsPacket>(700);
C_TsPacket * pPacket;
for(unsigned int ui = 0; ui < m_iInitFill; ui += iVectorSize)
{
iRc = m_pConverter->GetNextTsPackets(pPackets);
......@@ -228,7 +221,7 @@ void C_NormalTrickPlay::InitWork()
throw E_Exception(GEN_ERR, "Normal TrickPlay failed to start");
iVectorSize = pPackets->Size();
for(int i = 0; i < iVectorSize; i++)
{
pPacket = pPackets->Pop();
......
......@@ -2,7 +2,7 @@
* dvbpsi.cpp: common tools to use the libdvbpsi
*-------------------------------------------------------------------------------
* (c)1999-2002 VideoLAN
* $Id: dvbpsi.cpp,v 1.7 2002/10/07 15:01:22 sam Exp $
* $Id: dvbpsi.cpp,v 1.8 2003/08/14 15:22:35 adq Exp $
*
* Authors: Arnaud de Bossoreille de Ribou <bozo@via.ecp.fr>
*
......@@ -425,11 +425,12 @@ void C_DvbPsiPatDecoder::Callback(C_DvbPsiPatDecoder *pThis,
//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
void C_DvbPsiPatDecoder::HandlePacket(C_TsPacket* pPacket)
bool C_DvbPsiPatDecoder::HandlePacket(C_TsPacket* pPacket)
{
dvbpsi_PushPacket(m_hDvbPsi, (byte*)pPacket);
m_pTsProvider->ReleasePacket(pPacket);
return true;
}
......@@ -761,10 +762,11 @@ void C_DvbPsiPmtDecoder::Callback(C_DvbPsiPmtDecoder *pThis,
//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
void C_DvbPsiPmtDecoder::HandlePacket(C_TsPacket* pPacket)
bool C_DvbPsiPmtDecoder::HandlePacket(C_TsPacket* pPacket)
{
dvbpsi_PushPacket(m_hDvbPsi, (byte*)pPacket);
m_pTsProvider->ReleasePacket(pPacket);
return true;
}
......@@ -2,7 +2,7 @@
* dvbpsi.h: common tools to use the libdvbpsi
*-------------------------------------------------------------------------------
* (c)1999-2002 VideoLAN
* $Id: dvbpsi.h,v 1.2 2002/05/14 22:10:08 bozo Exp $
* $Id: dvbpsi.h,v 1.3 2003/08/14 15:22:35 adq Exp $
*
* Authors: Arnaud de Bossoreille de Ribou <bozo@via.ecp.fr>
*
......@@ -137,7 +137,8 @@ public:
void Attach();
void Detach();
virtual void HandlePacket(C_TsPacket* pPacket);
virtual bool HandlePacket(C_TsPacket* pPacket);
virtual void Shutdown() {};
private:
static void Callback(C_DvbPsiPatDecoder *pThis, dvbpsi_pat_t* p_new_pat);
......@@ -227,7 +228,8 @@ public:
void Attach();
void Detach();
virtual void HandlePacket(C_TsPacket* pPacket);
virtual bool HandlePacket(C_TsPacket* pPacket);
virtual void Shutdown() {}
private:
static void Callback(C_DvbPsiPmtDecoder *pThis, dvbpsi_pmt_t* p_new_pmt);
......
......@@ -2,7 +2,7 @@
* ts.h: TsPacket class definition
*-------------------------------------------------------------------------------
* (c)1999-2001 VideoLAN
* $Id: ts.h,v 1.10 2003/08/08 16:54:18 tooney Exp $
* $Id: ts.h,v 1.11 2003/08/14 15:22:35 adq Exp $
*
* Authors: Benoit Steiner <benny@via.ecp.fr>
* Jean-Paul Saman <jpsaman@wxs.n>
......@@ -99,7 +99,8 @@ class C_TsPacket
class I_TsPacketHandler
{
public:
virtual void HandlePacket(C_TsPacket* pPacket) = 0;
virtual bool HandlePacket(C_TsPacket* pPacket) = 0;
virtual void Shutdown() = 0;
bool operator == (const I_TsPacketHandler& cHandler) const
{
......@@ -109,7 +110,7 @@ public:
//------------------------------------------------------------------------------
//
//
//------------------------------------------------------------------------------
// The section must fit in a single TS packet and its data are put immediately
// after the TS header
......
......@@ -2,7 +2,7 @@
* tsdemux.cpp: TS demultiplexer
*-------------------------------------------------------------------------------
* (c)1999-2002 VideoLAN
* $Id: tsdemux.cpp,v 1.1 2002/03/21 14:09:19 bozo Exp $
* $Id: tsdemux.cpp,v 1.2 2003/08/14 15:22:35 adq Exp $
*
* Authors: Arnaud de Bossoreille de Ribou <bozo@via.ecp.fr>
*
......@@ -154,7 +154,7 @@ void C_TsDemux::UnLock()
//------------------------------------------------------------------------------
// Input of the demux
//------------------------------------------------------------------------------
void C_TsDemux::HandlePacket(C_TsPacket* pPacket)
bool C_TsDemux::HandlePacket(C_TsPacket* pPacket)
{
m_cLock.Lock();
......@@ -184,6 +184,8 @@ void C_TsDemux::HandlePacket(C_TsPacket* pPacket)
m_iHandledPid = 0xffff;
m_cLock.UnLock();
return true;
}
......@@ -2,7 +2,7 @@
* tsdemux.h: TS demultiplexer
*-------------------------------------------------------------------------------
* (c)1999-2002 VideoLAN
* $Id: tsdemux.h,v 1.1 2002/03/21 14:09:19 bozo Exp $
* $Id: tsdemux.h,v 1.2 2003/08/14 15:22:35 adq Exp $
*
* Authors: Arnaud de Bossoreille de Ribou <bozo@via.ecp.fr>
*
......@@ -64,7 +64,8 @@ public:
void Lock();
void UnLock();
virtual void HandlePacket(C_TsPacket* pPacket);
virtual bool HandlePacket(C_TsPacket* pPacket);
virtual void Shutdown() {};
protected:
// Selection hooks
......
......@@ -2,7 +2,7 @@
* tsmux.cpp: TS multiplexer
*-------------------------------------------------------------------------------
* (c)1999-2002 VideoLAN
* $Id: tsmux.cpp,v 1.5 2002/10/07 15:01:22 sam Exp $
* $Id: tsmux.cpp,v 1.6 2003/08/14 15:22:35 adq Exp $
*
* Authors: Arnaud de Bossoreille de Ribou <bozo@via.ecp.fr>
*
......@@ -328,7 +328,7 @@ void C_TsMux::DetachProgram(u16 iPmtPid)
//------------------------------------------------------------------------------
// Input of the multiplexer
//------------------------------------------------------------------------------
void C_TsMux::HandlePacket(C_TsPacket* pPacket)
bool C_TsMux::HandlePacket(C_TsPacket* pPacket)
{
u16 iPid = pPacket->GetPid();
......@@ -365,6 +365,8 @@ void C_TsMux::HandlePacket(C_TsPacket* pPacket)
m_pHandler->HandlePacket(pPacket);
}
return true;
}
......@@ -2,7 +2,7 @@
* tsmux.h: TS multiplexer
*-------------------------------------------------------------------------------
* (c)1999-2002 VideoLAN
* $Id: tsmux.h,v 1.2 2002/04/10 10:17:08 bozo Exp $
* $Id: tsmux.h,v 1.3 2003/08/14 15:22:35 adq Exp $
*
* Authors: Arnaud de Bossoreille de Ribou <bozo@via.ecp.fr>
*
......@@ -84,7 +84,8 @@ public:
void AttachProgram(u16 iProgramNumber, u16 iPmtPid);
void DetachProgram(u16 iPmtPid);
virtual void HandlePacket(C_TsPacket* pPacket);
virtual bool HandlePacket(C_TsPacket* pPacket);
virtual void Shutdown() {};
protected:
// PMT PID -> PMT decoder
......
......@@ -2,7 +2,7 @@
* buffer.cpp: Buffers management
*-------------------------------------------------------------------------------
* (c)1999-2001 VideoLAN
* $Id: buffer.cpp,v 1.9 2003/08/11 16:57:50 tooney Exp $
* $Id: buffer.cpp,v 1.10 2003/08/14 15:22:35 adq Exp $
*
* Authors: Benoit Steiner <benny@via.ecp.fr>
*
......@@ -55,6 +55,7 @@ C_SyncFifo::C_SyncFifo(unsigned int iSize) : m_cNotEmptySignal(0),
m_cFifo(iSize)
{
ASSERT(iSize > 1);
m_bShutdown = false;
}
......@@ -67,16 +68,16 @@ C_SyncFifo::~C_SyncFifo()
//------------------------------------------------------------------------------
//
//
//------------------------------------------------------------------------------
void C_SyncFifo::HandlePacket(C_TsPacket* pPacket)
bool C_SyncFifo::HandlePacket(C_TsPacket* pPacket)
{
ASSERT(pPacket);
// Push the data (wait for a pop if the fifo is full)
// wait for a pop without blocking the thread permanently
int iRc;
while ( (iRc = m_cNotFullSignal.TryWait()) == -1)
while(((iRc = m_cNotFullSignal.TryWait()) == -1) && (!m_bShutdown))
{
#ifdef WIN32
Sleep((int)(1 / 1000));
......@@ -90,20 +91,31 @@ void C_SyncFifo::HandlePacket(C_TsPacket* pPacket)
#else
# error nanosleep not present !
#endif
}
}
ASSERT(!iRc);
if (m_bShutdown) return false;
iRc = m_cFifo.Push(pPacket);
ASSERT(!iRc);
// Warn the waiting threads if any that they have data to pop
iRc = m_cNotEmptySignal.Post();
ASSERT(!iRc);
return true;
}
//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
void C_SyncFifo::Shutdown()
{
m_bShutdown = true;
}
//------------------------------------------------------------------------------
//
//
//------------------------------------------------------------------------------
C_TsPacket* C_SyncFifo::Pop()
{
......
......@@ -2,7 +2,7 @@
* buffer.h: Buffer classes definitions
*-------------------------------------------------------------------------------
* (c)1999-2001 VideoLAN
* $Id: buffer.h,v 1.5 2003/06/30 21:37:05 jpsaman Exp $
* $Id: buffer.h,v 1.6 2003/08/14 15:22:35 adq Exp $
*
* Authors: Benoit Steiner <benny@via.ecp.fr>
*
......@@ -44,8 +44,9 @@ class C_SyncFifo : public I_TsPacketHandler
{ return m_cFifo.Capacity(); }
unsigned int Size() const
{ return m_cFifo.Size(); }
void HandlePacket(C_TsPacket* pPacket);
virtual bool HandlePacket(C_TsPacket* pPacket);
virtual void Shutdown();
C_TsPacket* Pop();
C_TsPacket* Peek(unsigned int uiIndex);
......@@ -53,9 +54,11 @@ class C_SyncFifo : public I_TsPacketHandler
// Thread synchro objects
C_Semaphore m_cNotEmptySignal;
C_Semaphore m_cNotFullSignal;
// Fifo
C_Fifo<C_TsPacket> m_cFifo;
bool m_bShutdown;
};
//------------------------------------------------------------------------------
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment