?? dvbinput.cpp
字號:
/******************************************************************************** dvbinput.cpp: DVB streams*-------------------------------------------------------------------------------* (c)1999-2002 VideoLAN* $Id: dvbinput.cpp,v 1.21.4.6 2004/01/10 21:54:57 alexis Exp $** Authors: Arnaud de Bossoreille de Ribou <bozo@via.ecp.fr>* Damien Lucas <nitrox@videolan.org>** This program is free software; you can redistribute it and/or* modify it under the terms of the GNU General Public License* as published by the Free Software Foundation; either version 2* of the License, or (at your option) any later version.** This program is distributed in the hope that it will be useful,* but WITHOUT ANY WARRANTY; without even the implied warranty of* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the* GNU General Public License for more details.** You should have received a copy of the GNU General Public License* along with this program; if not, write to the Free Software* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.**-------------------------------------------------------------------------------********************************************************************************///------------------------------------------------------------------------------// Preamble//------------------------------------------------------------------------------#include "../../core/defs.h"#include "../../core/core.h"#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 <DVB.hh>#include "../../mpeg/mpeg.h"#include "../../mpeg/ts.h"#include "../../mpeg/rtp.h"#include "../../server/program.h"#include "../../server/buffer.h"#include "../../server/output.h"#include "../../server/channel.h"#include "../../server/broadcast.h"#include "../../server/request.h"#include "../../server/input.h"#include "../../server/tsstreamer.h"#include "../../mpeg/reader.h"#include "../../mpeg/converter.h"#include "../../mpeg/tsdemux.h"#include "../../mpeg/dvbpsi.h"#include "../../mpeg/tsmux.h"#include "dvbinput.h"#define FILELEN 256//------------------------------------------------------------------------------// Library declaration//------------------------------------------------------------------------------#ifdef __PLUGIN__GENERATE_LIB_ARGS(C_DvbInputModule, handle);#endif//------------------------------------------------------------------------------// Builtin declaration//------------------------------------------------------------------------------#ifdef __BUILTIN__C_Module* NewBuiltin_dvbinput(handle hLog){ return new C_DvbInputModule(hLog);}#endif/******************************************************************************** C_DvbInput class****************************************************************************************************************************************************************///------------------------------------------------------------------------------// Constructor//------------------------------------------------------------------------------C_DvbInput::C_DvbInput(C_Module* pModule, const C_String& strName) : C_Input(pModule, strName), C_TsDemux(&m_cTsProvider), m_cTsProvider(500), m_cInputProgram(/*0,*/ "Input DVB " + strName), m_cInputBroadcast(&m_cInputProgram, this, NULL), m_cPatDecoder(&m_cTsProvider, this), m_cCurrentPat(0, 0, true){ dvb = new DVB; m_iGotTpid = 0; // Did not set the transponder yet m_iDemuxUsageCount = 0; // Nothing using the demux yet m_bIgnoreTimeout = false; m_pConverter = NULL; for(int i =0; i < 512; i++) m_iDemuxes[i] = -1;}//------------------------------------------------------------------------------// Destructor//------------------------------------------------------------------------------C_DvbInput::~C_DvbInput(){}//------------------------------------------------------------------------------// Initialization//------------------------------------------------------------------------------void C_DvbInput::OnInit(){ int iNumber; C_String strType; C_String dvbrc; char filen[FILELEN]; char devname[80]; // Retrieve config C_Application* pApp = C_Application::GetApp(); ASSERT(pApp); iNumber = pApp->GetSetting(GetName() + ".DeviceNumber", "0").ToInt(); m_iSendMethod = pApp->GetSetting(GetName() + ".SendMethod", "0").ToInt(); m_bIgnoreTimeout = pApp->GetSetting(GetName()+".IgnoreTimeout", "0").ToInt(); dvbrc = pApp->GetSetting(GetName()+ ".Dvbrc", ""); if(dvbrc.Length() != 0) { strncpy(filen, dvbrc.GetString(), dvbrc.Length()+1); } dvb->init("", "", 0, iNumber); sprintf(devname, DVR_DEV, iNumber, 0); m_strDVR = C_String(devname); sprintf(devname, DEMUX_DEV, iNumber, 0); m_strDEMUX = C_String(devname); sprintf(devname, VIDEO_DEV, iNumber, 0); m_strVIDEO = C_String(devname); //Check whether card has a decoder: //When opening the video device, we should get an error int iDummy=open(m_strVIDEO.GetString(), O_RDWR|O_NONBLOCK); m_bHasDecoder=(iDummy<0) ? false : true; close(iDummy); switch(dvb->front_type) { case FE_QPSK: strType = "DVB-S"; break; case FE_QAM: strType= "DVB-C"; break; case FE_OFDM: strType = "DVB_T"; break; default: throw E_Exception(GEN_ERR, "No DVB card found"); break; } Log(m_hLog, LOG_NOTE, strType + " Card registered "+ (m_bHasDecoder ? "with decoder\n" : "without decoder\n")); // Enable DVR (sets the DMX_OUT_TS_TAP in the lib) dvb->enable_DVR(); dvb->enable_DVR_other(); //Get the .dvbrc file if (!get_dvbrc(filen,*dvb,iNumber,FILELEN)) throw E_Exception(GEN_ERR, "Unable to find any dvbrc file"); for(int i=0; i<dvb->NumChannel(); i++) { C_String* pStr=new C_String(dvb->chans[i].name); /* Let's replace all spaces by '_' */ pStr->Replace(' ', '_'); m_vProgramNames.Add(pStr); Log(m_hLog, LOG_NOTE, "Added program '" + *pStr+"'"); } // PAT decoder initialization m_cPatDecoder.Attach(); // Reader C_MpegReaderModule* pReaderModule = (C_MpegReaderModule*) C_Application::GetModuleManager() ->GetModule("mpegreader", "dvb"); ASSERT(pReaderModule); m_cInputBroadcast.SetOption("device", m_strDVR); m_cInputBroadcast.SetOption("IgnoreTimeout", m_bIgnoreTimeout); m_pReader = pReaderModule->NewMpegReader(&m_cInputBroadcast); ASSERT(m_pReader); // 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_pHandler = this; cConfig.m_iInitFill = 0; cConfig.m_pEventHandler = this; m_pConverter = pConverterModule->NewMpegConverter(cConfig); ASSERT(m_pConverter);}//------------------------------------------------------------------------------// Destruction//------------------------------------------------------------------------------void C_DvbInput::OnDestroy(){ // PAT Decoder destruction m_cPatDecoder.Detach(); if(m_pConverter) { // 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; } m_cEndInit.Release();}//------------------------------------------------------------------------------// Return the programs read in the dvbrc file//------------------------------------------------------------------------------C_List<C_Program> C_DvbInput::OnGetAvailablePgrms(){ C_List<C_Program> cPgrmList; m_cLock.Lock(); for(int i=0; i<dvb->NumChannel(); i++) { C_String pStr=dvb->chans[i].name; /* Let's replace all spaces by '_' */ pStr.Replace(' ', '_'); C_Program* pProgram = new C_Program(pStr, dvb->chans[i].pnr); ASSERT(pProgram); cPgrmList.PushEnd(pProgram); } m_cLock.UnLock(); return cPgrmList;}//------------------------------------------------------------------------------// Hardware PID selection//------------------------------------------------------------------------------void C_DvbInput::OnSelectPid(u16 iPid, u8 iType){ int i; int iRc; // Look for the first available demux for(i = 0; (i < 256) && (m_iDemuxes[2 * i] != -1); i++); // Check for the 256 Pid filters hardware limitation // note that dvb->init open 4 demuxes if(i < 256 - 4) { // TODO: test if it is not a required pid (PCR for example) if((m_iSendMethod == 0) || (iType < TS_TYPE_MPEG2_PRIVATE)) { int iFd = open(m_strDEMUX.GetString(), O_RDWR|O_NONBLOCK); if(iFd < 0) { Log(m_hLog, LOG_ERROR, "Unable to open demux"); } else { switch(iType) { case TS_TYPE_MPEG1_VIDEO: case TS_TYPE_MPEG2_VIDEO: iRc = dvb->set_vpid_fd(iPid, iFd); break; case TS_TYPE_MPEG1_AUDIO: iRc = dvb->set_apid_fd(iPid, iFd); break; default: iRc = dvb->set_otherpid_fd(iPid, iFd); break; } } if(iRc < 0) { Log(m_hLog, LOG_ERROR, C_String("Unable to set demux filter for PID ") + iPid + C_String("type : ") + iType); close(iFd); } else { LogDbg(m_hLog, C_String("Demux filter n
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -