DVB stream limitation patch (+ stability patches)
Andrew de Quincey <[email protected]>
| Newsgroups | gmane.comp.video.videolan.vls.devel |
|---|---|
| Message-ID | <[email protected]> |
Hi, this patch is against the latest CVS. It includes my various DVB stability patches. This one adds the ability to filter which types of stream are taken from DVB cards. If no configuration is given, the default is to behave exactly as before; i.e. with no filtering. Example configuration of a dvb input device: BEGIN "dvb1" DeviceNumber = "0" Dvbrc = "/tmp/dvbrc" StreamTypeList = "0x1,0x2,0x3,0x4" END This says stream types 1,2,3,4 should be streamed; all other types will be ignored. If the StreamTypeList item is omitted (or set to ""), all streams will be accepted. Merry christmas to everyone!
vls.patch
(text/x-patch, 12.8 KB)
diff -Naur vls.ORIGINAL/src/modules/dvbinput/dvbinput.cpp vls/src/modules/dvbinput/dvbinput.cpp
--- vls.ORIGINAL/src/modules/dvbinput/dvbinput.cpp 2002-12-08 15:55:29.000000000 +0000
+++ vls/src/modules/dvbinput/dvbinput.cpp 2002-12-23 23:51:33.000000000 +0000
@@ -114,8 +114,8 @@
m_cCurrentPat(0, 0, true)
{
dvb = new DVB;
- m_iGotPat = 0; // Did not get the first PAT yet
m_iGotTpid = 0; // Did not set the transponder yet
+ demuxUsageCount = 0; // nothing using the demux yet
m_pConverter = NULL;
for(int i =0; i < 512; i++)
m_iDemuxes[i] = -1;
@@ -137,13 +137,49 @@
{
int iNumber;
C_String strType;
+ C_String dvbrc;
+ C_String streamTypeList;
char filen[FILELEN];
+ int oldPos = 0;
+ int newPos = -1;
// Retrieve config
C_Application* pApp = C_Application::GetApp();
ASSERT(pApp);
iNumber = pApp->GetSetting(GetName() + ".DeviceNumber", "0").ToInt();
+ dvbrc = pApp->GetSetting(GetName() + ".Dvbrc", "");
+ if (dvbrc.Length() != 0) {
+ strncpy(filen, dvbrc.GetString(), dvbrc.Length()+1);
+ }
+
+ // parse the stream type list
+ streamTypeList = pApp->GetSetting(GetName() + ".StreamTypeList", "").Strip(" \t");
+ int streamTypeListLength = (int) streamTypeList.Length();
+ if (streamTypeListLength > 0) {
+ while(newPos < streamTypeListLength) {
+
+ // find the next token location
+ newPos = streamTypeList.Find(',', oldPos);
+
+ // if we didn't find it, use the end of the string
+ if (newPos == GEN_ERR) newPos = streamTypeListLength;
+
+ // extract the token
+ C_String curToken = streamTypeList.SubString(oldPos, newPos);
+
+ // parse it and add to the list
+ int* tmpInt = new int;
+ if (sscanf(curToken.GetString(), "%i", tmpInt) != 1) {
+ throw E_Exception(GEN_ERR, "Invalid entry in StreamTypeList");
+ }
+ m_validStreamTypes.Add(tmpInt);
+ Log(m_hLog, LOG_NOTE, "StreamType " + curToken + " added");
+
+ // update starting search position
+ oldPos = newPos+1;
+ }
+ }
dvb->init("", "", iNumber);
@@ -219,10 +255,6 @@
cConfig.m_pEventHandler = this;
m_pConverter = pConverterModule->NewMpegConverter(cConfig);
ASSERT(m_pConverter);
-
- // Launch the demux
- m_pConverter->Create();
-
}
@@ -237,16 +269,18 @@
if(m_pConverter)
{
- // Stop the input stream
- try
- {
- m_pConverter->Stop();
- }
- catch(E_Exception e)
- {
- m_cEndInit.Release();
- delete m_pConverter;
- throw e;
+ // Stop the input converter if necessary
+ if (m_pConverter->IsRunning()) {
+ try
+ {
+ m_pConverter->Stop();
+ }
+ catch(E_Exception e)
+ {
+ m_cEndInit.Release();
+ delete m_pConverter;
+ throw e;
+ }
}
delete m_pConverter;
@@ -455,7 +489,6 @@
// Kludge: signal the first PAT arrival.
m_cEndInit.Protect();
- m_iGotPat = 1;
m_cEndInit.Signal();
m_cEndInit.Release();
}
@@ -471,31 +504,46 @@
int iIndex=m_vProgramNames.Find(pBroadcast->GetProgram()->GetName());
LogDbg(m_hLog, "DVB Channel found: "+dvb->chans[iIndex].name);
- // Check that if we have already got one broadcast going that this
- // new one is on the same mux (transponder)
- if(m_iGotPat && m_iGotTpid != dvb->chans[iIndex].tpid)
- {
- LogDbg(m_hLog, "Attempting to start reception from different transponder." \
- "Existing transponder is " + m_iGotTpid + " asked transponder is " +
- dvb->chans[iIndex].tpid);
- return;
- }
-
- if (!m_iGotPat)
- {
+ // lock the demux usage
+ demuxUsageM.Lock();
+
+ // If we've not already started the demux, do so, and wait for the first
+ // PAT
+ if (demuxUsageCount == 0) {
// Set the frontend up
dvb->SetTP(dvb->chans[iIndex].tpid, dvb->chans[iIndex].satid);
dvb->set_front();
- // Put a filter on PAT
+ // Launch the demux
+ m_pConverter->Create();
+
+ // Add a filter for PAT
SelectPid(&m_cPatDecoder, 0x0000, TS_TYPE_NULL);
-
+
// Wait for the first PAT
m_cEndInit.Wait();
m_cEndInit.Release();
m_iGotTpid = dvb->chans[iIndex].tpid; // Remember the transponder
+
+ // update demux counter and unlock
+ demuxUsageCount++;
+ demuxUsageM.UnLock();
+ } else {
+ // Check that if we have already got one broadcast going that this
+ // new one is on the same mux (transponder)
+ if (m_iGotTpid != dvb->chans[iIndex].tpid) {
+ LogDbg(m_hLog, "Attempting to start reception from different " +
+ "transponder. Exiting transponder is " + m_iGotTpid +
+ " new transponder is " + dvb->chans[iIndex].tpid);
+ demuxUsageM.UnLock();
+ return;
+ }
+
+ // update counter and unlock
+ demuxUsageCount++;
+ demuxUsageM.UnLock();
}
-
+
// Get the program
dvbpsi_pat_program_t *pProgram =
m_cCurrentPat.GetProgram(dvb->chans[iIndex].pnr);
@@ -516,19 +564,21 @@
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);
+ pMux->AttachProgram(pProgram->i_number, pProgram->i_pid, m_validStreamTypes);
- m_cMuxes.Add(pProgram->i_number, pMux);
+ m_cMuxes.Add(iNumber, pMux);
- m_cStreamers.Add(pProgram->i_number, pStreamer);
+ m_cStreamers.Add(iNumber, pStreamer);
}
catch(E_Exception e)
@@ -573,8 +623,19 @@
{
m_cLock.Lock();
- //Unset the filter on PAT
- UnselectPid(&m_cPatDecoder, 0x0000);
+ // lock demux counter and decrement usage counter
+ demuxUsageM.Lock();
+ demuxUsageCount--;
+
+ // if the usage counter is 0, we'll have to remove the PAT filter
+ // and suspend the demux
+ if (demuxUsageCount == 0) {
+ UnselectPid(&m_cPatDecoder, 0x0000);
+ m_pConverter->Stop();
+ }
+
+ // unlock
+ demuxUsageM.UnLock();
u16 iNumber = pBroadcast->GetProgram()->GetName().ToInt();
diff -Naur vls.ORIGINAL/src/modules/dvbinput/dvbinput.h vls/src/modules/dvbinput/dvbinput.h
--- vls.ORIGINAL/src/modules/dvbinput/dvbinput.h 2002-12-08 15:55:29.000000000 +0000
+++ vls/src/modules/dvbinput/dvbinput.h 2002-12-23 23:16:45.000000000 +0000
@@ -87,8 +87,9 @@
int m_iSendMethod;
// Kludge: signal the first PAT arrival.
- int m_iGotPat;
- int m_iGotTpid;
+ int demuxUsageCount;
+ int m_iGotTpid;
+ C_Mutex demuxUsageM;
C_Condition m_cEndInit;
// Demuxes' file descriptors
@@ -113,6 +114,9 @@
// Muxes and streamers
C_HashTable<u16, C_TsMux> m_cMuxes;
C_HashTable<u16, C_TsStreamer> m_cStreamers;
+
+ // Valid streams
+ C_Vector<int> m_validStreamTypes;
};
diff -Naur vls.ORIGINAL/src/modules/dvbreader/dvbreader.h vls/src/modules/dvbreader/dvbreader.h
--- vls.ORIGINAL/src/modules/dvbreader/dvbreader.h 2002-09-22 02:38:54.000000000 +0100
+++ vls/src/modules/dvbreader/dvbreader.h 2002-12-22 14:29:52.000000000 +0000
@@ -46,6 +46,7 @@
virtual int Read(byte* pBuff, int iSize);
virtual int Seek(s64 iOffset, int bStartPos);
+ virtual int GetFrame(byte ** pBuff ,int iSize) { return 0;};
virtual s64 Size();
virtual s64 GetPos();
diff -Naur vls.ORIGINAL/src/mpeg/streamdescr.cpp vls/src/mpeg/streamdescr.cpp
--- vls.ORIGINAL/src/mpeg/streamdescr.cpp 2002-10-07 16:01:22.000000000 +0100
+++ vls/src/mpeg/streamdescr.cpp 2002-12-22 14:16:01.000000000 +0000
@@ -38,6 +38,8 @@
# include <stdint.h>
#endif
+#include <stdio.h>
+
#ifdef HAVE_DVBPSI_DVBPSI_H
# include <dvbpsi/dvbpsi.h>
# include <dvbpsi/descriptor.h>
diff -Naur vls.ORIGINAL/src/mpeg/tsmux.cpp vls/src/mpeg/tsmux.cpp
--- vls.ORIGINAL/src/mpeg/tsmux.cpp 2002-10-07 16:01:22.000000000 +0100
+++ vls/src/mpeg/tsmux.cpp 2002-12-23 23:54:30.000000000 +0000
@@ -72,11 +72,37 @@
C_TsMuxPmtDecoder::C_TsMuxPmtDecoder(C_NetList *pTsProvider,
C_TsMux *pMux,
u16 iProgramNumber) :
- C_DvbPsiPmtDecoder(iProgramNumber, pTsProvider, this)
+ C_DvbPsiPmtDecoder(iProgramNumber, pTsProvider, this)
{
ASSERT(pMux);
m_pMux = pMux;
+ m_streamFilterEnabled = false;
+}
+
+
+//------------------------------------------------------------------------------
+// Constructor
+//------------------------------------------------------------------------------
+C_TsMuxPmtDecoder::C_TsMuxPmtDecoder(C_NetList *pTsProvider,
+ C_TsMux *pMux,
+ u16 iProgramNumber,
+ C_Vector<int>& validStreamTypes) :
+ C_DvbPsiPmtDecoder(iProgramNumber, pTsProvider, this)
+{
+ ASSERT(pMux);
+
+ m_pMux = pMux;
+ if (validStreamTypes.Size() > 0) {
+ m_streamFilterEnabled = true;
+ for(unsigned int i=0; i< validStreamTypes.Size(); i++) {
+ int* tmp = new int;
+ *tmp = validStreamTypes[i];
+ m_validStreamTypes.Add(tmp);
+ }
+ } else {
+ m_streamFilterEnabled = false;
+ }
}
@@ -104,8 +130,10 @@
dvbpsi_pmt_es_t* pEs = pLLPmt->p_first_es;
while(pEs)
{
- m_pMux->m_pDemux->UnselectPid(m_pMux, pEs->i_pid);
- printf("--- %x\n", pEs->i_pid);
+ if (ValidStreamType(pEs->i_type)) {
+ m_pMux->m_pDemux->UnselectPid(m_pMux, pEs->i_pid);
+ printf("--- %x\n", pEs->i_pid);
+ }
pEs = pEs->p_next;
}
}
@@ -139,9 +167,11 @@
dvbpsi_pmt_es_t* pEs = pLLPmt->p_first_es;
while(pEs)
{
- m_pMux->m_pDemux->UnselectPid(m_pMux, pEs->i_pid);
- printf("--- %x\n", pEs->i_pid);
- pEs = pEs->p_next;
+ if (ValidStreamType(pEs->i_type)) {
+ m_pMux->m_pDemux->UnselectPid(m_pMux, pEs->i_pid);
+ printf("--- %x\n", pEs->i_pid);
+ }
+ pEs = pEs->p_next;
}
}
@@ -149,8 +179,10 @@
dvbpsi_pmt_es_t* pEs = pLLPmt->p_first_es;
while(pEs)
{
- m_pMux->m_pDemux->SelectPid(m_pMux, pEs->i_pid, pEs->i_type);
- printf("+++ %x\n", pEs->i_pid);
+ if (ValidStreamType(pEs->i_type)) {
+ m_pMux->m_pDemux->SelectPid(m_pMux, pEs->i_pid, pEs->i_type);
+ printf("+++ %x\n", pEs->i_pid);
+ }
pEs = pEs->p_next;
}
m_pMux->m_pDemux->SelectPid(m_pMux, pLLPmt->i_pcr_pid, TS_TYPE_NULL);
@@ -158,6 +190,19 @@
}
}
+//------------------------------------------------------------------------------
+// Check if videolan should stream a certain type of stream
+//------------------------------------------------------------------------------
+bool C_TsMuxPmtDecoder::ValidStreamType(int iStreamType) {
+ // if the stream type filter is enabled, and if it is not in the valid
+ // stream type vector, don't include it
+ if (m_streamFilterEnabled && (m_validStreamTypes.Find(iStreamType) == GEN_ERR)) {
+ return false;
+ }
+
+ // otherwise, it is a valid stream
+ return true;
+}
//******************************************************************************
// C_TsMux class
@@ -236,7 +281,17 @@
//------------------------------------------------------------------------------
// Program selection
//------------------------------------------------------------------------------
-void C_TsMux::AttachProgram(u16 iProgramNumber, u16 iPmtPid)
+void C_TsMux::AttachProgram(u16 iProgramNumber, u16 iPmtPid)
+{
+ C_Vector<int> emptyVector;
+ AttachProgram(iProgramNumber, iPmtPid, emptyVector);
+}
+
+
+//------------------------------------------------------------------------------
+// Program selection
+//------------------------------------------------------------------------------
+void C_TsMux::AttachProgram(u16 iProgramNumber, u16 iPmtPid, C_Vector<int>& validStreamTypes)
{
// Lock the demux because we're running in another thread
m_pDemux->Lock();
@@ -244,7 +299,8 @@
ASSERT(!m_cPmtDecoders.Get(iPmtPid));
C_TsMuxPmtDecoder *pDecoder = new C_TsMuxPmtDecoder(m_pTsProvider, this,
- iProgramNumber);
+ iProgramNumber,
+ validStreamTypes);
ASSERT(pDecoder);
try
diff -Naur vls.ORIGINAL/src/mpeg/tsmux.h vls/src/mpeg/tsmux.h
--- vls.ORIGINAL/src/mpeg/tsmux.h 2002-04-10 11:17:08.000000000 +0100
+++ vls/src/mpeg/tsmux.h 2002-12-23 23:14:02.000000000 +0000
@@ -54,16 +54,20 @@
{
public:
C_TsMuxPmtDecoder(C_NetList *pTsProvider, C_TsMux *pMux, u16 iProgramNumber);
+ C_TsMuxPmtDecoder(C_NetList *pTsProvider, C_TsMux *pMux, u16 iProgramNumber, C_Vector<int>& validStreamTypes);
virtual ~C_TsMuxPmtDecoder();
void Detach();
protected:
virtual void OnDvbPsiPmtEvent(int iEvent);
+ virtual bool ValidStreamType(int iStreamType);
private:
// Internal data
C_TsMux *m_pMux;
+ bool m_streamFilterEnabled;
+ C_Vector<int> m_validStreamTypes;
};
@@ -82,6 +86,7 @@
void Detach();
void AttachProgram(u16 iProgramNumber, u16 iPmtPid);
+ void AttachProgram(u16 iProgramNumber, u16 iPmtPid, C_Vector<int>& validStreamTypes);
void DetachProgram(u16 iPmtPid);
virtual void HandlePacket(C_TsPacket* pPacket);