Commit 11f3d459 authored by Damien Lucas's avatar Damien Lucas

. ASI input version 2

parent cb26f293
......@@ -2,7 +2,7 @@
* asiinput.cpp: Input for ASI boards
*-------------------------------------------------------------------------------
* (c)2003 Anevia
* $Id: asiinput.cpp,v 1.1 2003/08/31 11:46:16 nitrox Exp $
* $Id: asiinput.cpp,v 1.2 2003/09/21 01:13:01 nitrox Exp $
*
* Authors: Damien Lucas <damien.lucas@anevia.com>
*
......@@ -36,6 +36,20 @@
#include <fcntl.h>
#include <sys/ioctl.h>
#ifdef HAVE_DVBPSI_DVBPSI_H
# include <dvbpsi/dvbpsi.h>
# include <dvbpsi/descriptor.h>
# include <dvbpsi/pat.h>
# include <dvbpsi/pmt.h>
#else
# include "src/dvbpsi.h"
# include "src/descriptor.h"
# include "src/tables/pat.h"
# include "src/tables/pmt.h"
#endif
#include "../../mpeg/mpeg.h"
#include "../../mpeg/ts.h"
#include "../../mpeg/rtp.h"
......@@ -51,6 +65,9 @@
#include "../../mpeg/reader.h"
#include "../../mpeg/trickplay.h"
#include "../../mpeg/converter.h"
#include "../../mpeg/tsdemux.h"
#include "../../mpeg/dvbpsi.h"
#include "../../mpeg/tsmux.h"
#include <asi.h>
......@@ -85,9 +102,19 @@ C_Module* NewBuiltin_asiinput(handle hLog)
//------------------------------------------------------------------------------
C_AsiInput::C_AsiInput(C_Module* pModule, const C_String& strName)
: C_Input(pModule, strName)
: C_Input(pModule, strName),
C_TsDemux(&m_cTsProvider),
m_cTsProvider(500),
m_cInputProgram(/*0,*/ "Input ASI " + strName),
m_cInputBroadcast(&m_cInputProgram, this, NULL, strName),
m_cPatDecoder(&m_cTsProvider, this),
m_cCurrentPat(0, 0, true)
{
m_hFd = 0;
m_iDemuxUsageCount = 0; // Nothing using the demux yet
m_pConverter = NULL;
m_pTrickPlay = NULL;
m_strTrickPlayType = "normal"; //TODO
}
......@@ -165,9 +192,77 @@ void C_AsiInput::OnInit()
throw E_Exception(GEN_ERR, e.Dump());
}
C_String* pStr = new C_String("asi");
m_vProgramNames.Add(pStr);
Log(m_hLog, LOG_NOTE, "Added program '" + *pStr+"'");
// C_String* pStr = new C_String("asi");
// m_vProgramNames.Add(pStr);
// Log(m_hLog, LOG_NOTE, "Added program '" + *pStr+"'");
// Just proceed the same way as the dvb input: we attach a PAT decoder
// in order to be able to get the list of the programs on the device
m_cPatDecoder.Attach();
// So we create the reader there
C_MpegReaderModule* pReaderModule = (C_MpegReaderModule*)
C_Application::GetModuleManager()
->GetModule("mpegreader", "asi");
ASSERT(pReaderModule);
m_pReader = pReaderModule->NewMpegReader(&m_cInputBroadcast);
ASSERT(m_pReader);
// And the converter
C_MpegConverterModule* pConverterModule = (C_MpegConverterModule*)
C_Application::GetModuleManager()
->GetModule("mpegconverter",
"ts2ts");
ASSERT(pConverterModule);
C_MpegConverterConfig cConfig;
cConfig.m_hLog = m_hLog;
cConfig.m_pBroadcast = &m_cInputBroadcast;
cConfig.m_pReader = m_pReader;
cConfig.m_pTsProvider = m_pTsProvider;
cConfig.m_pEventHandler = this;
m_pConverter = pConverterModule->NewMpegConverter(cConfig);
ASSERT(m_pConverter);
// And the trickplay
C_TrickPlayModule* pTrickPlayModule = (C_TrickPlayModule*)
C_Application::GetModuleManager()
->GetModule("trickplay",
m_strTrickPlayType);
if (pTrickPlayModule)
{
C_TrickPlayConfig cTrickPlayConfig;
cTrickPlayConfig.m_hLog = m_hLog;
cTrickPlayConfig.m_pBroadcast = &m_cInputBroadcast;
cTrickPlayConfig.m_pReader = m_pReader;
cTrickPlayConfig.m_pEventHandler = this;
cTrickPlayConfig.m_pTsProvider = m_pTsProvider;
cTrickPlayConfig.m_pConverter = m_pConverter;
cTrickPlayConfig.m_pHandler = this;
cTrickPlayConfig.m_iInitFill = 0;
m_pTrickPlay = pTrickPlayModule->NewTrickPlay(cTrickPlayConfig);
ASSERT(m_pTrickPlay);
}
else
{
throw E_Exception(GEN_ERR, "Module TrickPlay:" + m_strTrickPlayType +
" not present");
}
m_pTrickPlay->Create();
// Select the PAT pid TODO
SelectPid(&m_cPatDecoder, 0x0000, TS_TYPE_NULL);
// Wait for the first PAT arrival
m_cEndInit.Protect();
m_cEndInit.Wait();
}
//------------------------------------------------------------------------------
......@@ -175,6 +270,32 @@ void C_AsiInput::OnInit()
//------------------------------------------------------------------------------
void C_AsiInput::OnDestroy()
{
// Destroy the "PAT decoder"
m_cPatDecoder.Detach();
//Then the converter and the trickplay
try
{
if(m_pConverter)
{
delete m_pConverter;
}
if(m_pTrickPlay)
{
if(m_pTrickPlay->IsRunning())
m_pTrickPlay->Stop();
delete m_pTrickPlay;
}
}
catch(E_Exception e)
{
m_cEndInit.Release();
if (m_pConverter) delete m_pConverter;
if (m_pTrickPlay) delete m_pTrickPlay;
throw e;
}
m_cEndInit.Release();
return;
}
......@@ -183,15 +304,24 @@ void C_AsiInput::OnDestroy()
//------------------------------------------------------------------------------
C_List<C_Program> C_AsiInput::OnGetAvailablePgrms()
{
C_List<C_Program> cPgrmList;
C_List<C_Program> cPgrmList;
for(unsigned int ui = 0; ui < m_vProgramNames.Size(); ui++)
{
C_Program* pProgram = new C_Program(m_vProgramNames[ui]);
ASSERT(pProgram);
cPgrmList.PushEnd(pProgram);
}
return cPgrmList;
m_cLock.Lock();
dvbpsi_pat_program_t *pPatProgram =
m_cCurrentPat.GetLowLevelPat()->p_first_program;
while(pPatProgram)
{
C_Program* pProgram = new C_Program(pPatProgram->i_number,
pPatProgram->i_number);
ASSERT(pProgram);
cPgrmList.PushEnd(pProgram);
pPatProgram = pPatProgram->p_next;
}
m_cLock.UnLock();
return cPgrmList;
}
//------------------------------------------------------------------------------
......@@ -199,114 +329,76 @@ C_List<C_Program> C_AsiInput::OnGetAvailablePgrms()
//------------------------------------------------------------------------------
void C_AsiInput::OnStartStreaming(C_Broadcast* pBroadcast)
{
C_String strReaderType = "asi";
// Only TS streams are sent through ASI interfaces.
C_String strConverterType = "ts2ts";
// You cannot control trickplay since ASI is a real-time device
C_String strTrickPlayType = "normal";
uint16_t uiSize;
// Create the netlist and the fifo
const C_Channel* pChannel = pBroadcast->GetChannel();
C_NetList* pTsProvider = new C_NetList(3*3*797);
uiSize = pTsProvider->Capacity() - pChannel->GetBuffCapacity()-2;
C_SyncFifo* pBuffer = new C_SyncFifo(uiSize);
// Create the reader
C_MpegReader* pReader;
C_MpegReaderModule* pReaderModule = (C_MpegReaderModule*)
C_Application::GetModuleManager()
->GetModule("mpegreader",
strReaderType);
if(pReaderModule)
{
pReader = pReaderModule->NewMpegReader(pBroadcast);
}
else
// Lock the demux usage
m_cDemuxUsageM.Lock();
// If we have not already Started the demux, do so and wait
// for the first PAT arrival
// XXX
#if 0
if ( m_iDemuxUsageCount == 0 )
{
throw E_Exception(GEN_ERR, "Module mpegreader:" + strConverterType +
" not present");
}
// Create the trickplay
m_pTrickPlay->Create();
// Create the converter
C_MpegConverter* pConverter;
C_MpegConverterModule* pConverterModule = (C_MpegConverterModule*)
C_Application::GetModuleManager()
->GetModule("mpegconverter",
strConverterType);
if(pConverterModule)
{
C_MpegConverterConfig cConfig;
cConfig.m_hLog = m_hLog;
cConfig.m_pBroadcast = pBroadcast;
cConfig.m_pReader = pReader;
cConfig.m_pTsProvider = pTsProvider;
cConfig.m_pEventHandler = m_pEventHandler;
pConverter = pConverterModule->NewMpegConverter(cConfig);
ASSERT(pConverter);
}
else
{
throw E_Exception(GEN_ERR, "Module mpegconverter:" +
strConverterType + " not present");
// Add a filter for the PAT
// TODO
// Wait for the first PAT
fprintf(stderr, "Waiting for PAT\n"); //XXX nitrox
m_cEndInit.Wait();
m_cEndInit.Release();
}
#endif
fprintf(stderr, "C'est parti\n"); //XXX nitrox
// Update Demux Counter and unlock
m_iDemuxUsageCount++;
m_cDemuxUsageM.UnLock();
pReader->SetConverter(pConverter);
// Get the program
dvbpsi_pat_program_t *pProgram =
m_cCurrentPat.GetProgram(pBroadcast->GetProgram()->GetName().ToInt());
// Create the trickplay
C_TrickPlay* pTrickPlay;
C_TrickPlayModule* pTrickPlayModule = (C_TrickPlayModule*)
C_Application::GetModuleManager()
->GetModule("trickplay",
strTrickPlayType);
if (pTrickPlayModule)
m_cLock.Lock();
// Finaly we can laucnh the streaming line
if ( pProgram )
{
C_TrickPlayConfig cTrickPlayConfig;
cTrickPlayConfig.m_hLog = m_hLog;
cTrickPlayConfig.m_pBroadcast = pBroadcast;
cTrickPlayConfig.m_pReader = pReader;
cTrickPlayConfig.m_pHandler = pBuffer;
cTrickPlayConfig.m_iInitFill = 0;
cTrickPlayConfig.m_pEventHandler = m_pEventHandler;
cTrickPlayConfig.m_pTsProvider = pTsProvider;
cTrickPlayConfig.m_pConverter = pConverter;
C_SyncFifo* pBuffer =
new C_SyncFifo(2* pBroadcast->GetChannel()->GetBuffCapacity());
C_TsStreamer *pStreamer = new C_TsStreamer(m_hLog, pBroadcast,
m_pTsProvider, pBuffer,
m_pEventHandler,
false, false);
C_TsMux *pMux = new C_TsMux(m_pTsProvider, this, pBuffer);
try
{
u16 iNumber = pBroadcast->GetProgram()->GetName().ToInt();
pStreamer->Create();
pMux->Attach();
pMux->AttachProgram(pProgram->i_number, pProgram->i_pid);
pTrickPlay = pTrickPlayModule->NewTrickPlay(cTrickPlayConfig);
ASSERT(pTrickPlay);
m_cMuxes.Add(iNumber, pMux);
m_cStreamers.Add(iNumber, pStreamer);
}
catch(E_Exception e)
{
delete pStreamer,
delete pMux;
throw e;
}
}
else
{
throw E_Exception(GEN_ERR,
"Module TrickPlay:" + strTrickPlayType +
" not present");
throw E_Exception(GEN_ERR, "Program \""+
pBroadcast->GetProgram()->GetName() +
"\" does not exist");
}
// Create the streamer
C_TsStreamer* pStreamer = new C_TsStreamer(m_hLog, pBroadcast,
pTsProvider, pBuffer,
m_pEventHandler, true, true);
ASSERT(pStreamer);
m_cTrickPlay.Add(pBroadcast, pTrickPlay);
m_cStreamers.Add(pBroadcast, pStreamer);
m_cConverters.Add(pBroadcast, pConverter);
try
{
pTrickPlay->Create();
pStreamer->Create();
}
catch(E_Exception e)
{
pStreamer->Stop();
pTrickPlay->Stop();
//Unregister the 2 thread and delete them
m_cTrickPlay.Delete(pBroadcast);
m_cStreamers.Delete(pBroadcast);
throw E_Exception(GEN_ERR, "unable to start streaming of program "+
pBroadcast->GetProgram()->GetName(), e);
}
m_cLock.UnLock();
return;
}
......@@ -353,32 +445,46 @@ void C_AsiInput::OnRewindStreaming(C_Broadcast* pBroadcast, int speed)
//------------------------------------------------------------------------------
void C_AsiInput::OnStopStreaming(C_Broadcast* pBroadcast)
{
ASSERT(pBroadcast);
// Find the reader and the streamer that receive the pgrm
C_TrickPlay* pTrickPlay = m_cTrickPlay.Remove(pBroadcast);
ASSERT(pTrickPlay);
C_TsStreamer* pStreamer = m_cStreamers.Remove(pBroadcast);
m_cLock.Lock();
//Lock the demux counter and dcrement usage counter
m_cDemuxUsageM.Lock();
m_iDemuxUsageCount--;
// If the usage counter reached 0, we have to remove the PAT filter
// and suspend the demux
if ( m_iDemuxUsageCount == 0 )
{
// TODO - Remove Selection on PID 0
m_pTrickPlay->Stop();
}
m_cDemuxUsageM.UnLock();
// Get a pointer to the Mux and the Streamer
// and delete them
u16 iNumber = pBroadcast->GetProgram()->GetName().ToInt();
C_TsMux *pMux = m_cMuxes.Remove(iNumber);
ASSERT(pMux);
C_TsStreamer *pStreamer = m_cStreamers.Remove(iNumber);
ASSERT(pStreamer);
C_MpegConverter* pConverter = m_cConverters.Remove(pBroadcast);
ASSERT(pConverter);
m_cLock.UnLock();
pMux->Detach();
delete pMux;
// Stop the threads
try
{
pStreamer->Stop();
pTrickPlay->Stop();
delete pTrickPlay;
delete pConverter;
delete pStreamer; // streamer MUST be deleted last
}
catch(E_Exception e)
{
delete pStreamer;
throw E_Exception(GEN_ERR, "Unable to stop streaming of program "+
pBroadcast->GetProgram()->GetName(), e);
pBroadcast->GetProgram()->GetName(), e);
}
return;
delete pStreamer;
}
//------------------------------------------------------------------------------
......@@ -399,6 +505,90 @@ void C_AsiInput::OnDeleteProgram(C_String strProgram)
}
//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
void C_AsiInput::HandleEvent(const C_Event& cEvent)
{
ASSERT(false);
}
//------------------------------------------------------------------------------
// New version of the PAT
//------------------------------------------------------------------------------
void C_AsiInput::OnDvbPsiPatEvent(int iEvent)
{
if(iEvent == DVBPSI_EVENT_CURRENT)
{
dvbpsi_pat_t *pLLPat = m_pCurrentPat->GetLowLevelPat();
dvbpsi_pat_program_t* p_program = pLLPat->p_first_program;
Log(m_hLog, LOG_NOTE, C_String("New PAT\n") );
Log(m_hLog, LOG_NOTE, C_String(" transport_stream_id : ")
+ pLLPat->i_ts_id);
Log(m_hLog, LOG_NOTE, C_String(" version_number : ")
+ pLLPat->i_version);
Log(m_hLog, LOG_NOTE, C_String(" | program_number @ [NIT|PMT]_PID"));
while(p_program)
{
Log(m_hLog, LOG_NOTE, C_String(" | ") + p_program->i_number +
C_String(" @ 0x") +p_program->i_pid + C_String(" (")
+ p_program->i_pid + C_String(")") );
p_program = p_program->p_next;
}
Log(m_hLog, LOG_NOTE, " active : " +pLLPat->b_current_next);
C_DvbPsiPat DiffPatSub(0, 0, false);
C_DvbPsiPat DiffPatAdd(0, 0, false);
if(m_pPreviousPat)
{
DiffPatSub = *m_pPreviousPat - *m_pCurrentPat;
DiffPatAdd = *m_pCurrentPat - *m_pPreviousPat;
}
else
{
DiffPatAdd = *m_pCurrentPat;
}
pLLPat = DiffPatSub.GetLowLevelPat();
p_program = pLLPat->p_first_program;
Log(m_hLog, LOG_NOTE, "\n");
Log(m_hLog, LOG_NOTE, "Deleted programs\n");
while(p_program)
{
Log(m_hLog, LOG_NOTE, C_String(" | ") + p_program->i_number +
C_String(" @ 0x") +p_program->i_pid + C_String(" (") +
p_program->i_pid + C_String(")") );
p_program = p_program->p_next;
}
pLLPat = DiffPatAdd.GetLowLevelPat();
p_program = pLLPat->p_first_program;
Log(m_hLog, LOG_NOTE, "\n");
Log(m_hLog, LOG_NOTE, "Added programs\n");
while(p_program)
{
Log(m_hLog, LOG_NOTE, C_String(" | ") + p_program->i_number +
C_String(" @ 0x") +p_program->i_pid + C_String(" (") +
p_program->i_pid + C_String(")") );
p_program = p_program->p_next;
}
m_cLock.Lock();
m_cCurrentPat = *m_pCurrentPat;
m_cLock.UnLock();
// Kludge: signal the first PAT arrival.
m_cEndInit.Protect();
m_cEndInit.Signal();
m_cEndInit.Release();
}
}
//Local private functions
//TODO documentation about them !
......
......@@ -2,7 +2,7 @@
* asiinput.h: ASI Input class definition
*-------------------------------------------------------------------------------
* (c)2003 Anevia
* $Id: asiinput.h,v 1.2 2003/09/20 13:46:25 nitrox Exp $
* $Id: asiinput.h,v 1.3 2003/09/21 01:13:01 nitrox Exp $
*
* Authors: Damien Lucas <damien.lucas@anevia.com>
*
......@@ -30,7 +30,10 @@
//------------------------------------------------------------------------------
// C_AsiInput class
//------------------------------------------------------------------------------
class C_AsiInput : public C_Input
class C_AsiInput : public C_Input,
public C_EventHandler,
public C_TsDemux,
public I_DvbPsiPatHandler
{
public:
C_AsiInput(C_Module* pModule, const C_String& strName);
......@@ -53,6 +56,11 @@ protected:
virtual void OnDeleteProgram(C_String strProgram);
virtual C_List<C_Program> OnGetAvailablePgrms();
// The input is the event handler of its converter
virtual void HandleEvent(const C_Event& cEvent);
// PAT event handler
void C_AsiInput::OnDvbPsiPatEvent(int iEvent);
private:
void OpenDevice();
void GetReceiverCapabilities();
......@@ -64,7 +72,6 @@ private:
void SetDoubleSynchro(int iDoubleSynchro);
void SetPIDCounter(int iPid, int iMode);
void SetBufferSize(int, int);
C_String m_strDeviceName; /* Name of the ASI receiver device */
int m_hFd; /* Handle for the ASI receiver device */
int m_iCap; /* Capacities of the ASI receiver device */
......@@ -73,10 +80,32 @@ private:
// the program ID is m_vProgramNames.Find(strName) + 1
C_Vector<C_String> m_vProgramNames;
// List of currently running trickplay, streamers and converters
C_HashTable<handle, C_TsStreamer> m_cStreamers;
C_HashTable<handle, C_TrickPlay> m_cTrickPlay;
C_HashTable<handle, C_MpegConverter> m_cConverters;
//Kludge: signal the first PAT arrival
C_Condition m_cEndInit;
int m_iDemuxUsageCount;
C_Mutex m_cDemuxUsageM;
// Only one netlist for all the programs
C_NetList m_cTsProvider;
// Input stream (demux)
C_Program m_cInputProgram;
C_Broadcast m_cInputBroadcast;
C_MpegReader *m_pReader;
C_MpegConverter *m_pConverter;
// TrickPlay Module
C_TrickPlay *m_pTrickPlay;
C_String m_strTrickPlayType;
// PAT stuffs
C_DvbPsiPatDecoder m_cPatDecoder;
C_Mutex m_cLock;
C_DvbPsiPat m_cCurrentPat;
// Muxes and streamers
C_HashTable<u16, C_TsMux> m_cMuxes;
C_HashTable<u16, C_TsStreamer> m_cStreamers;
};
// Declaration and implementation of C_AsiInputModule
......
......@@ -2,7 +2,7 @@
* dvbinput.cpp: DVB streams
*-------------------------------------------------------------------------------
* (c)1999-2002 VideoLAN
* $Id: dvbinput.cpp,v 1.34 2003/08/19 21:31:41 nitrox Exp $
* $Id: dvbinput.cpp,v 1.35 2003/09/21 01:13:01 nitrox Exp $
*
* Authors: Arnaud de Bossoreille de Ribou <bozo@via.ecp.fr>
* Damien Lucas <nitrox@videolan.org>
......@@ -383,17 +383,17 @@ void C_DvbInput::OnSelectPid(u16 iPid, u8 iType)
}
}
pesFilterParams.flags = DMX_IMMEDIATE_START;
if(ioctl(iFd, DMX_SET_PES_FILTER, &pesFilterParams) < 0)
{
Log(m_hLog, LOG_ERROR, C_String("Unable to set demux filter for PID ")
+ iPid + C_String("type : ") + pesFilterParams.pes_type);
+ iPid + C_String("type : ") + pesFilterParams.pes_type);
close(iFd);
}
else
{
LogDbg(m_hLog, C_String("Demux filter n")+i+ C_String(" type: ") +
pesFilterParams.pes_type + C_String(" set for PID ") + iPid);
pesFilterParams.pes_type + C_String(" set for PID ") + iPid);
m_iDemuxes[2 * i] = iPid;
m_iDemuxes[2 * i + 1] = iFd;
}
......@@ -408,7 +408,7 @@ void C_DvbInput::OnSelectPid(u16 iPid, u8 iType)
else
{
LogDbg(m_hLog, C_String("Too many Demux filter set"));
}
}
}
......@@ -457,13 +457,12 @@ void C_DvbInput::OnDvbPsiPatEvent(int iEvent)
Log(m_hLog, LOG_NOTE, C_String(" | program_number @ [NIT|PMT]_PID"));
while(p_program)
{
// Log(m_hLog, LOG_NOTE, " | %14d @ 0x%x (%d)\n",
// p_program->i_number, p_program->i_pid, p_program->i_pid);
Log(m_hLog, LOG_NOTE, C_String(" | ") + p_program->i_number +
C_String(" @ 0x") +p_program->i_pid + C_String(" (") + p_program->i_pid + C_String(")") );
C_String(" @ 0x") +p_program->i_pid + C_String(" (")
+ p_program->i_pid + C_String(")") );
p_program = p_program->p_next;
}
Log(m_hLog, LOG_NOTE, " active : " + pLLPat->b_current_next);
Log(m_hLog, LOG_NOTE, " active : " +pLLPat->b_current_next);
C_DvbPsiPat DiffPatSub(0, 0, false);
C_DvbPsiPat DiffPatAdd(0, 0, false);
......@@ -483,10 +482,9 @@ void C_DvbInput::OnDvbPsiPatEvent(int iEvent)
Log(m_hLog, LOG_NOTE, "Deleted programs\n");
while(p_program)
{
// Log(m_hLog, LOG_NOTE, " | %14d @ 0x%x (%d)\n",
// p_program->i_number, p_program->i_pid, p_program->i_pid);
Log(m_hLog, LOG_NOTE, C_String(" | ") + p_program->i_number +
C_String(" @ 0x") +p_program->i_pid + C_String(" (") + p_program->i_pid + C_String(")") );
C_String(" @ 0x") +p_program->i_pid + C_String(" (") +
p_program->i_pid + C_String(")") );
p_program = p_program->p_next;
}
pLLPat = DiffPatAdd.GetLowLevelPat();
......@@ -495,10 +493,9 @@ void C_DvbInput::OnDvbPsiPatEvent(int iEvent)
Log(m_hLog, LOG_NOTE, "Added programs\n");
while(p_program)
{
// Log(m_hLog, LOG_NOTE, " | %14d @ 0x%x (%d)\n",
// p_program->i_number, p_program->i_pid, p_program->i_pid);
Log(m_hLog, LOG_NOTE, C_String(" | ") + p_program->i_number +
C_String(" @ 0x") +p_program->i_pid + C_String(" (") + p_program->i_pid + C_String(")") );
C_String(" @ 0x") +p_program->i_pid + C_String(" (") +
p_program->i_pid + C_String(")") );
p_program = p_program->p_next;
}
......@@ -537,7 +534,7 @@ void C_DvbInput::OnStartStreaming(C_Broadcast* pBroadcast)
//Launch the demux
m_pTrickPlay->Create();
// Add a filter for PAT
SelectPid(&m_cPatDecoder, 0x0000, TS_TYPE_NULL);
......@@ -554,7 +551,7 @@ void C_DvbInput::OnStartStreaming(C_Broadcast* pBroadcast)
{
Log(m_hLog, LOG_ERROR, C_String("Attempting to start reception from" \
" different transponder.Existing Transponder is") +m_iGotTpid +
" New transponder is" + dvb->chans[iIndex].tpid);
" New transponder is" + dvb->chans[iIndex].tpid);
m_cDemuxUsageM.UnLock();
return;
}
......@@ -563,16 +560,16 @@ void C_DvbInput::OnStartStreaming(C_Broadcast* pBroadcast)
// Update Demux Counter and unlock
m_iDemuxUsageCount++;
m_cDemuxUsageM.UnLock();
// Get the program
dvbpsi_pat_program_t *pProgram =
m_cCurrentPat.GetProgram(dvb->chans[iIndex].pnr);
m_cLock.Lock();
// And launch the streaming line
if(pProgram)
{
{
C_SyncFifo* pBuffer =
new C_SyncFifo(2 * pBroadcast->GetChannel()->GetBuffCapacity());
......@@ -580,7 +577,7 @@ void C_DvbInput::OnStartStreaming(C_Broadcast* pBroadcast)
m_pTsProvider, pBuffer,
m_pEventHandler, false, false);
C_TsMux *pMux = new C_TsMux(m_pTsProvider, this, pBuffer);
try
{
u16 iNumber = pBroadcast->GetProgram()->GetName().ToInt();
......@@ -604,12 +601,12 @@ void C_DvbInput::OnStartStreaming(C_Broadcast* pBroadcast)
{
if (!m_bIgnoreMissing) {
throw E_Exception(GEN_ERR, "Program \"" +
pBroadcast->GetProgram()->GetName() +
"\" doesn't exist");
pBroadcast->GetProgram()->GetName() +
"\" doesn't exist");