Commit 56410655 authored by Andrew de Quincey's avatar Andrew de Quincey

This change moves the precaching from InitWork() to DoWork() in tsstreamer.

The caching can take a while to finish on certain sources and I don't think
it should force the rest of vls to wait for it.

Also, with the MPEX MPEG2 encoder card (spits out a TS stream): If it gets no
video signal, it outputs no TS packets until it gets one. This causes VLS to
hang when starting this input until a video feed is plugged in.
parent 2d1863f9
......@@ -3,7 +3,7 @@
* start, stop, suspend and resume operations.
*-------------------------------------------------------------------------------
* (c)1999-2003 VideoLAN
* $Id: normaltrickplay.cpp,v 1.12 2003/08/14 15:22:35 adq Exp $
* $Id: normaltrickplay.cpp,v 1.13 2003/08/14 17:20:36 adq Exp $
*
* Authors: Jean-Paul Saman <jpsaman@wxs.nl>
*
......@@ -64,7 +64,7 @@ GENERATE_LIB_ARGS(C_NormalTrickPlayModule, handle);
//------------------------------------------------------------------------------
#ifdef __BUILTIN__
C_Module* NewBuiltin_normaltrickplay(handle hLog)
{
{
return new C_NormalTrickPlayModule(hLog);
}
#endif
......@@ -100,19 +100,19 @@ void C_NormalTrickPlay::HandlePacket(C_TsPacket* pPacket)
void C_NormalTrickPlay::DoWork()
{
C_TsPacket * pPacket;
int iRc = NO_ERR;
// printf("C_NormalTrickPlay::DoWork()\n");
// Initialize the condition in the new thread.
m_cResumeCond.Protect();
// log it
C_String strPgrmName = m_pBroadcast->GetProgram()->GetName();
LogDbg(m_hLog, "Starting to read program \"" + strPgrmName + "\"");
int iRc = NO_ERR;
C_Fifo<C_TsPacket> * pPackets = new C_Fifo<C_TsPacket>(700);
C_TsPacket * pPacket;
// the main loop
unsigned int prefillCount = 0;
while(!m_bStop && !iRc)
{
......@@ -150,24 +150,34 @@ void C_NormalTrickPlay::DoWork()
}
}
iRc = m_pConverter->GetNextTsPackets(pPackets);
iRc = m_pConverter->GetNextTsPackets(m_pPackets);
int iVectorSize = pPackets->Size();
int iVectorSize = m_pPackets->Size();
if ((iRc == NO_ERR) && (!m_bStop))
{
for(int i = 0; i < iVectorSize; i++)
{
pPacket = pPackets->Pop();
pPacket = m_pPackets->Pop();
ASSERT(pPacket);
HandlePacket(pPacket);
if (prefillCount >= m_iInitFill) {
HandlePacket(pPacket);
} else {
if (!m_pHandler->HandlePrefillPacket(pPacket)) {
HandlePacket(pPacket);
m_pHandler->PrefillComplete();
prefillCount = m_iInitFill+1; // make sure we don't do any more prefilling
} else if (++prefillCount >= m_iInitFill) {
m_pHandler->PrefillComplete();
}
}
}
}
else
{
for(int i = 0; i < iVectorSize; i++)
{
pPacket = pPackets->Pop();
pPacket = m_pPackets->Pop();
ASSERT(pPacket);
if (pPacket->RefCount()>0)
m_pTsProvider->ReleasePacket(pPacket);
......@@ -185,6 +195,9 @@ void C_NormalTrickPlay::DoWork()
m_pEventHandler->HandleEvent(cEvent);
}
m_pHandler->PrefillComplete();
delete m_pPackets;
m_cResumeCond.Release();
LogDbg(m_hLog, "Converter stopped for program " + strPgrmName);
}
......@@ -211,24 +224,8 @@ void C_NormalTrickPlay::InitWork()
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);
if (iRc != NO_ERR)
throw E_Exception(GEN_ERR, "Normal TrickPlay failed to start");
iVectorSize = pPackets->Size();
for(int i = 0; i < iVectorSize; i++)
{
pPacket = pPackets->Pop();
ASSERT(pPacket);
HandlePacket(pPacket);
}
}
m_pPackets = new C_Fifo<C_TsPacket>(700);
m_pHandler->PrefillStart();
}
void C_NormalTrickPlay::CleanWork()
......
......@@ -2,7 +2,7 @@
* normaltrickplay.h: Header file for the normal trickplay implementation
*-------------------------------------------------------------------------------
* (c)1999-2003 VideoLAN
* $Id: normaltrickplay.h,v 1.3 2003/08/05 19:01:15 tooney Exp $
* $Id: normaltrickplay.h,v 1.4 2003/08/14 17:20:36 adq Exp $
*
* Authors: Jean-Paul Saman <jpsaman@wxs.nl>
*
......@@ -52,6 +52,9 @@ class C_NormalTrickPlay : public C_TrickPlay
virtual void DoWork();
virtual void StopWork();
virtual void CleanWork();
private:
C_Fifo<C_TsPacket>* m_pPackets;
};
// Declaration and implementation of C_TrickPlayModule
......
......@@ -2,7 +2,7 @@
* dvbpsi.h: common tools to use the libdvbpsi
*-------------------------------------------------------------------------------
* (c)1999-2002 VideoLAN
* $Id: dvbpsi.h,v 1.3 2003/08/14 15:22:35 adq Exp $
* $Id: dvbpsi.h,v 1.4 2003/08/14 17:20:36 adq Exp $
*
* Authors: Arnaud de Bossoreille de Ribou <bozo@via.ecp.fr>
*
......@@ -138,8 +138,10 @@ public:
void Detach();
virtual bool HandlePacket(C_TsPacket* pPacket);
virtual void Shutdown() {};
virtual bool HandlePrefillPacket(C_TsPacket* pPacket) { return false; }
virtual void Shutdown() {}
virtual void PrefillStart() {}
virtual void PrefillComplete() {}
private:
static void Callback(C_DvbPsiPatDecoder *pThis, dvbpsi_pat_t* p_new_pat);
......@@ -229,7 +231,10 @@ public:
void Detach();
virtual bool HandlePacket(C_TsPacket* pPacket);
virtual bool HandlePrefillPacket(C_TsPacket* pPacket) { return false; }
virtual void Shutdown() {}
virtual void PrefillStart() {}
virtual void PrefillComplete() {}
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.11 2003/08/14 15:22:35 adq Exp $
* $Id: ts.h,v 1.12 2003/08/14 17:20:36 adq Exp $
*
* Authors: Benoit Steiner <benny@via.ecp.fr>
* Jean-Paul Saman <jpsaman@wxs.n>
......@@ -94,13 +94,17 @@ class C_TsPacket
//------------------------------------------------------------------------------
//
//
//------------------------------------------------------------------------------
class I_TsPacketHandler
{
public:
virtual bool HandlePacket(C_TsPacket* pPacket) = 0;
virtual bool HandlePrefillPacket(C_TsPacket* pPacket) = 0;
virtual void Shutdown() = 0;
virtual void PrefillStart() = 0;
virtual void PrefillComplete() = 0;
bool operator == (const I_TsPacketHandler& cHandler) const
{
......@@ -133,13 +137,13 @@ class C_PsiSection : protected C_TsPacket
inline byte* GetDataForUpdate(u8 iDataPos);
// Read the data at the given position
inline const byte* GetDataForRead(u8 iDataPos) const;
//
//
inline void Finalize();
//
//
u8 GetVersion();
protected:
void UpdateVersion();
......
......@@ -2,7 +2,7 @@
* tsdemux.h: TS demultiplexer
*-------------------------------------------------------------------------------
* (c)1999-2002 VideoLAN
* $Id: tsdemux.h,v 1.2 2003/08/14 15:22:35 adq Exp $
* $Id: tsdemux.h,v 1.3 2003/08/14 17:20:36 adq Exp $
*
* Authors: Arnaud de Bossoreille de Ribou <bozo@via.ecp.fr>
*
......@@ -65,7 +65,10 @@ public:
void UnLock();
virtual bool HandlePacket(C_TsPacket* pPacket);
virtual void Shutdown() {};
virtual bool HandlePrefillPacket(C_TsPacket* pPacket) { return false; }
virtual void Shutdown() {}
virtual void PrefillStart() {}
virtual void PrefillComplete() {}
protected:
// Selection hooks
......
......@@ -2,7 +2,7 @@
* tsmux.h: TS multiplexer
*-------------------------------------------------------------------------------
* (c)1999-2002 VideoLAN
* $Id: tsmux.h,v 1.3 2003/08/14 15:22:35 adq Exp $
* $Id: tsmux.h,v 1.4 2003/08/14 17:20:36 adq Exp $
*
* Authors: Arnaud de Bossoreille de Ribou <bozo@via.ecp.fr>
*
......@@ -85,7 +85,10 @@ public:
void DetachProgram(u16 iPmtPid);
virtual bool HandlePacket(C_TsPacket* pPacket);
virtual void Shutdown() {};
virtual bool HandlePrefillPacket(C_TsPacket* pPacket) { return false; }
virtual void Shutdown() {}
virtual void PrefillStart() {}
virtual void PrefillComplete() {}
protected:
// PMT PID -> PMT decoder
......
......@@ -2,7 +2,7 @@
* buffer.cpp: Buffers management
*-------------------------------------------------------------------------------
* (c)1999-2001 VideoLAN
* $Id: buffer.cpp,v 1.10 2003/08/14 15:22:35 adq Exp $
* $Id: buffer.cpp,v 1.11 2003/08/14 17:20:36 adq Exp $
*
* Authors: Benoit Steiner <benny@via.ecp.fr>
*
......@@ -72,11 +72,11 @@ C_SyncFifo::~C_SyncFifo()
//------------------------------------------------------------------------------
bool C_SyncFifo::HandlePacket(C_TsPacket* pPacket)
{
int iRc;
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) && (!m_bShutdown))
{
#ifdef WIN32
......@@ -105,6 +105,45 @@ bool C_SyncFifo::HandlePacket(C_TsPacket* pPacket)
return true;
}
//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
bool C_SyncFifo::HandlePrefillPacket(C_TsPacket* pPacket)
{
int iRc;
ASSERT(pPacket);
// see if there is any space left (don't block though)
if (m_cNotFullSignal.TryWait() == -1) return false;
// add on the packet
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::PrefillStart() {
m_cPrefilling.Protect();
}
//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
void C_SyncFifo::PrefillComplete() {
m_cPrefilling.Release();
}
//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
......@@ -119,6 +158,8 @@ void C_SyncFifo::Shutdown()
//------------------------------------------------------------------------------
C_TsPacket* C_SyncFifo::Pop()
{
m_cPrefilling.Protect();
// Pop the data (wait for them if the fifo is empty)
int iRc;
while( (iRc = m_cNotEmptySignal.TryWait()) == -1)
......@@ -127,14 +168,14 @@ C_TsPacket* C_SyncFifo::Pop()
Sleep((int)(1 / 1000));
#elif defined(HAVE_NANOSLEEP)
struct timespec tsDelay;
tsDelay.tv_sec = 0;
tsDelay.tv_sec = 0;
tsDelay.tv_nsec = 50 * 1000 * 1000; // sleep 50 ms
// Wait for the given delay
nanosleep(&tsDelay, NULL);
#else
# error nanosleep not present !
#endif
#endif
}
ASSERT(!iRc);
......@@ -145,11 +186,13 @@ C_TsPacket* C_SyncFifo::Pop()
iRc = m_cNotFullSignal.Post();
ASSERT(!iRc);
m_cPrefilling.Release();
return pPacket;
}
C_TsPacket* C_SyncFifo::Peek(unsigned int uiIndex)
{
{
C_TsPacket* pPacket = m_cFifo.Peek(uiIndex);
ASSERT(pPacket);
......@@ -159,7 +202,7 @@ C_TsPacket* C_SyncFifo::Peek(unsigned int uiIndex)
//******************************************************************************
// C_DatedFifo class
//******************************************************************************
//
//
//******************************************************************************
//------------------------------------------------------------------------------
......
......@@ -2,7 +2,7 @@
* buffer.h: Buffer classes definitions
*-------------------------------------------------------------------------------
* (c)1999-2001 VideoLAN
* $Id: buffer.h,v 1.6 2003/08/14 15:22:35 adq Exp $
* $Id: buffer.h,v 1.7 2003/08/14 17:20:36 adq Exp $
*
* Authors: Benoit Steiner <benny@via.ecp.fr>
*
......@@ -46,6 +46,9 @@ class C_SyncFifo : public I_TsPacketHandler
{ return m_cFifo.Size(); }
virtual bool HandlePacket(C_TsPacket* pPacket);
virtual bool HandlePrefillPacket(C_TsPacket* pPacket);
virtual void PrefillStart();
virtual void PrefillComplete();
virtual void Shutdown();
C_TsPacket* Pop();
C_TsPacket* Peek(unsigned int uiIndex);
......@@ -54,6 +57,7 @@ class C_SyncFifo : public I_TsPacketHandler
// Thread synchro objects
C_Semaphore m_cNotEmptySignal;
C_Semaphore m_cNotFullSignal;
C_Condition m_cPrefilling;
// Fifo
C_Fifo<C_TsPacket> m_cFifo;
......
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