📄 dvbinput.cpp
字号:
/******************************************************************************** dvbinput.cpp: DVB streams*-------------------------------------------------------------------------------* (c)1999-2002 VideoLAN* $Id: dvbinput.cpp,v 1.16 2002/10/08 21:52:58 nitrox 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 <ost/sec.h>#include <ost/frontend.h>#include <ost/dmx.h>#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"//------------------------------------------------------------------------------// 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){ m_pConverter = NULL; for(int i =0; i < 512; i++) m_iDemuxes[i] = -1;}//------------------------------------------------------------------------------// Destructor//------------------------------------------------------------------------------C_DvbInput::~C_DvbInput(){}//------------------------------------------------------------------------------// Initialization//------------------------------------------------------------------------------void C_DvbInput::OnInit(){ // Retrieve config C_Application* pApp = C_Application::GetApp(); ASSERT(pApp); C_String strNumber = pApp->GetSetting(GetName() + ".DeviceNumber", ""); m_strType = pApp->GetSetting(GetName() + ".DeviceType", "nova").ToLower(); m_strSec = "/dev/ost/sec" + strNumber; m_strFrontend = "/dev/ost/frontend" + strNumber; m_strDemux = "/dev/ost/demux" + strNumber; m_strDvr = "/dev/ost/dvr" + strNumber; m_iFrequency = pApp->GetSetting(GetName() + ".Frequency", "0").ToInt(); m_iPolarization = pApp->GetSetting(GetName() + ".Polarization", "0").ToInt(); m_iSymbolRate = pApp->GetSetting(GetName() + ".SymbolRate", "0").ToInt(); m_iDiSEqC = pApp->GetSetting(GetName() + ".DiSEqC", "0").ToInt(); m_iLnbLof1 = pApp->GetSetting(GetName() + ".LNB_Lof1", "0").ToInt(); m_iLnbLof2 = pApp->GetSetting(GetName() + ".LNB_Lof2", "0").ToInt(); m_iLnbSLof = pApp->GetSetting(GetName() + ".LNB_SLof", "0").ToInt(); m_iSendMethod = pApp->GetSetting(GetName() + ".SendMethod", "0").ToInt(); // Hardware initialization SecControl(); SetFrontend(); // PAT decoder initialization m_cPatDecoder.Attach(); // Select the PAT PID SelectPid(&m_cPatDecoder, 0x0000, TS_TYPE_NULL); // Reader C_MpegReaderModule* pReaderModule = (C_MpegReaderModule*) C_Application::GetModuleManager() ->GetModule("mpegreader", "dvb"); ASSERT(pReaderModule); m_cInputBroadcast.SetOption("device", m_strDvr); 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); m_cEndInit.Protect(); // Launch the demux m_pConverter->Create(); // Kludge: wait for the first PAT arrival. m_cEndInit.Wait();}//------------------------------------------------------------------------------// Destruction//------------------------------------------------------------------------------void C_DvbInput::OnDestroy(){ // Unselect the PAT PID C_TsDemux::Lock(); UnselectPid(&m_cPatDecoder, 0x0000); C_TsDemux::UnLock(); // PAT Decoder destruction m_cPatDecoder.Detach(); if(m_pConverter) { // Stop the input stream try { m_pConverter->Stop(); } catch(E_Exception e) { m_cEndInit.Release(); delete m_pConverter; throw e; } delete m_pConverter; } m_cEndInit.Release();}//------------------------------------------------------------------------------// Get the program table//------------------------------------------------------------------------------C_List<C_Program> C_DvbInput::OnGetAvailablePgrms(){ C_List<C_Program> 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;}//------------------------------------------------------------------------------// Hardware PID selection//------------------------------------------------------------------------------void C_DvbInput::OnSelectPid(u16 iPid, u8 iType){ int i; for(i = 0; (i < 256) && (m_iDemuxes[2 * i] != -1); i++); if(i < 256) { // We don't always need to send PES unknown by vlc // Thx to Marian Durkovic // but we may want to have private datas like subtitles 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 { struct dmxPesFilterParams pesFilterParams; pesFilterParams.pid = iPid; pesFilterParams.input = DMX_IN_FRONTEND; pesFilterParams.output = DMX_OUT_TS_TAP; // With Nova Cards, putting DMX_PES_VIDEO & DMX_PES_AUDIO // doesn't work when receiving severals programs // Putting DMX_PES_OTHER everywhere seems to work... // // But, with DVB-S Cards, you should put the exact type ... // It implicates that can receive only 1 audio channel if(m_strType=="nova") pesFilterParams.pesType = DMX_PES_OTHER; else { switch(iType) { case TS_TYPE_MPEG1_VIDEO: case TS_TYPE_MPEG2_VIDEO: pesFilterParams.pesType = DMX_PES_VIDEO; break; case TS_TYPE_MPEG1_AUDIO: case TS_TYPE_MPEG2_AUDIO: pesFilterParams.pesType = DMX_PES_AUDIO; break; default: pesFilterParams.pesType = DMX_PES_OTHER; break; } } 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.pesType); close(iFd); } else { LogDbg(m_hLog, C_String("Demux filter n
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -