⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tsmux.cpp

📁 可用该程序将avi的电影文件转化为TS流
💻 CPP
字号:
/******************************************************************************** tsmux.cpp: TS multiplexer*-------------------------------------------------------------------------------* (c)1999-2002 VideoLAN* $Id: tsmux.cpp,v 1.5 2002/10/07 15:01:22 sam Exp $** Authors: Arnaud de Bossoreille de Ribou <bozo@via.ecp.fr>** 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"#if defined(HAVE_INTTYPES_H)#   include <inttypes.h>#elif defined(HAVE_STDINT_H)#   include <stdint.h>#endif#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.h"#include "ts.h"#include "../server/buffer.h"#include "tsdemux.h"#include "dvbpsi.h"#include "tsmux.h"//******************************************************************************// C_TsMuxPmtDecoder class//******************************************************************************////******************************************************************************//------------------------------------------------------------------------------// Constructor//------------------------------------------------------------------------------C_TsMuxPmtDecoder::C_TsMuxPmtDecoder(C_NetList *pTsProvider,                                     C_TsMux *pMux,                                     u16 iProgramNumber) :                        C_DvbPsiPmtDecoder(iProgramNumber, pTsProvider, this){  ASSERT(pMux);  m_pMux = pMux;}//------------------------------------------------------------------------------// Destructor//------------------------------------------------------------------------------C_TsMuxPmtDecoder::~C_TsMuxPmtDecoder(){}//------------------------------------------------------------------------------// PID unselection//------------------------------------------------------------------------------void C_TsMuxPmtDecoder::Detach(){  m_pMux->m_pDemux->Lock();  if(m_pCurrentPmt)  {    dvbpsi_pmt_t *pLLPmt = m_pCurrentPmt->GetLowLevelPmt();    m_pMux->m_pDemux->UnselectPid(m_pMux, pLLPmt->i_pcr_pid);      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;    }  }  m_pMux->m_pDemux->UnLock();}//------------------------------------------------------------------------------// New PMT event//------------------------------------------------------------------------------void C_TsMuxPmtDecoder::OnDvbPsiPmtEvent(int iEvent){  if(iEvent == DVBPSI_EVENT_CURRENT)  {    C_DvbPsiPmt DiffPmtSub(0, 0, false, 0);    C_DvbPsiPmt DiffPmtAdd(0, 0, false, 0);    if(m_pPreviousPmt)    {      DiffPmtSub = *m_pPreviousPmt - *m_pCurrentPmt;      DiffPmtAdd = *m_pCurrentPmt - *m_pPreviousPmt;    }    else    {      DiffPmtAdd = *m_pCurrentPmt;    }    dvbpsi_pmt_t *pLLPmt = DiffPmtSub.GetLowLevelPmt();    if(pLLPmt->i_pcr_pid)    {      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;      }    }    pLLPmt = DiffPmtAdd.GetLowLevelPmt();    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);      pEs = pEs->p_next;    }    m_pMux->m_pDemux->SelectPid(m_pMux, pLLPmt->i_pcr_pid, TS_TYPE_NULL);  }}//******************************************************************************// C_TsMux class//******************************************************************************////******************************************************************************//------------------------------------------------------------------------------// Constructor//------------------------------------------------------------------------------C_TsMux::C_TsMux(C_NetList *pTsProvider, C_TsDemux *pDemux,                 I_TsPacketHandler *pHandler) : m_cPat(1, 0, true){  ASSERT(pTsProvider);  ASSERT(pDemux);  ASSERT(pHandler);  m_pTsProvider = pTsProvider;  m_pDemux = pDemux;  m_pHandler = pHandler;  m_bSendPat = true;}//------------------------------------------------------------------------------// Destructor//------------------------------------------------------------------------------C_TsMux::~C_TsMux(){}//------------------------------------------------------------------------------// Mux initialilzation//------------------------------------------------------------------------------void C_TsMux::Attach(){  // Lock the demux because we're running in another thread  m_pDemux->Lock();  m_pDemux->SelectPid(this, 0x0000, TS_TYPE_NULL);  m_pDemux->UnLock();}//------------------------------------------------------------------------------// Reset the multiplexer//------------------------------------------------------------------------------void C_TsMux::Detach(){  // Lock the demux because we're running in another thread  m_pDemux->Lock();  C_HashTableIterator<u16, C_TsMuxPmtDecoder> cIterator =                                        m_cPmtDecoders.CreateIterator();  while(cIterator.HasNext())  {    C_HashTableNode<u16, C_TsMuxPmtDecoder> *pNode = cIterator.GetNext();    ASSERT(pNode);    // Unlock the demux to allow DetachProgram to relock it.    m_pDemux->UnLock();    DetachProgram(pNode->GetKey());    m_pDemux->Lock();    cIterator.Reset();  }  m_pDemux->UnselectPid(this, 0x0000);  m_pDemux->UnLock();}//------------------------------------------------------------------------------// Program selection//------------------------------------------------------------------------------void C_TsMux::AttachProgram(u16 iProgramNumber, u16 iPmtPid){  // Lock the demux because we're running in another thread  m_pDemux->Lock();  ASSERT(!m_cPmtDecoders.Get(iPmtPid));  C_TsMuxPmtDecoder *pDecoder = new C_TsMuxPmtDecoder(m_pTsProvider, this,                                                      iProgramNumber);  ASSERT(pDecoder);  try  {    pDecoder->Attach();    m_cPmtDecoders.Add(iPmtPid, pDecoder);    m_pDemux->SelectPid(this, iPmtPid, TS_TYPE_NULL);    dvbpsi_pat_t *pLLPat = m_cPat.GetLowLevelPat();    pLLPat->i_version = (pLLPat->i_version + 1) & 0x1f;    dvbpsi_PATAddProgram(pLLPat, iProgramNumber, iPmtPid);    m_bSendPat = true;  }  catch(E_Exception e)  {    delete pDecoder;    m_pDemux->UnLock();    throw e;  }  m_pDemux->UnLock();}//------------------------------------------------------------------------------// Program unselection//------------------------------------------------------------------------------void C_TsMux::DetachProgram(u16 iPmtPid){  // Lock the demux because we're running in another thread  m_pDemux->Lock();  C_TsMuxPmtDecoder *pDecoder = m_cPmtDecoders.Remove(iPmtPid);  ASSERT(pDecoder);  // Unlock the demux to allow the PMT decoder to relock it.  m_pDemux->UnLock();  pDecoder->Detach();  m_pDemux->Lock();  m_pDemux->UnselectPid(this, iPmtPid);  dvbpsi_pat_t *pLLPat = m_cPat.GetLowLevelPat();  pLLPat->i_version = (pLLPat->i_version + 1) & 0x1f;  dvbpsi_pat_program_t *pProgram = pLLPat->p_first_program;  if(pProgram)  {    if(pProgram->i_pid == iPmtPid)    {      pLLPat->p_first_program = NULL;      free(pProgram);    }    else    {      dvbpsi_pat_program_t *pProgram2 = pProgram->p_next;      while((pProgram2) && (pProgram2->i_pid != iPmtPid))      {        pProgram = pProgram2;        pProgram2 = pProgram2->p_next;      }      if(pProgram2)      {        pProgram->p_next = pProgram2->p_next;        free(pProgram2);      }    }  }  m_bSendPat = true;  delete pDecoder;  m_pDemux->UnLock();}//------------------------------------------------------------------------------// Input of the multiplexer//------------------------------------------------------------------------------void C_TsMux::HandlePacket(C_TsPacket* pPacket){  u16 iPid = pPacket->GetPid();  if(iPid == 0x0000)  {    m_bSendPat = true;    m_pTsProvider->ReleasePacket(pPacket);  }  else  {    if(m_bSendPat)    {      m_cPat.Generate();      m_cPat.TsReset();      while(m_cPat.TsHasNext())      {        C_TsPacket *pTsPat = m_pTsProvider->GetPacket();        ASSERT(pTsPat);        m_cPat.TsWrite(pTsPat);        m_pHandler->HandlePacket(pTsPat);      }      m_bSendPat = false;    }    C_TsMuxPmtDecoder *pDecoder = m_cPmtDecoders.Get(iPid);    if(pDecoder)    {      pPacket->Ref();      pDecoder->HandlePacket(pPacket);    }    m_pHandler->HandlePacket(pPacket);  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -