📄 ts2ts.cpp
字号:
/******************************************************************************** ts2ts.cpp: threaded TS to TS converter*-------------------------------------------------------------------------------* (c)1999-2001 VideoLAN* $Id: ts2ts.cpp,v 1.4 2002/04/02 16:15:11 bozo 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"#include "../../mpeg/mpeg.h"#include "../../mpeg/ts.h"#include "../../server/buffer.h"#include "../../server/program.h"#include "../../server/broadcast.h"#include "../../server/request.h"#include "../../server/input.h"#include "../../mpeg/reader.h"#include "../../mpeg/converter.h"#include "ts2ts.h"//------------------------------------------------------------------------------// Library declaration//------------------------------------------------------------------------------#ifdef __PLUGIN__GENERATE_LIB_ARGS(C_Ts2TsMpegConverterModule, handle);#endif//------------------------------------------------------------------------------// Builtin declaration//------------------------------------------------------------------------------#ifdef __BUILTIN__C_Module* NewBuiltin_ts2ts(handle hLog){ return new C_Ts2TsMpegConverterModule(hLog);}#endif/******************************************************************************** C_Ts2TsConverter****************************************************************************************************************************************************************///------------------------------------------------------------------------------// Constructor//------------------------------------------------------------------------------C_Ts2TsMpegConverter::C_Ts2TsMpegConverter(C_Module* pModule, C_MpegConverterConfig& cConfig) : C_MpegConverter(pModule, cConfig){}//------------------------------------------------------------------------------// Initialization//------------------------------------------------------------------------------void C_Ts2TsMpegConverter::InitWork(){ // Inherited method C_MpegConverter::InitWork(); int iRc = 0; if(m_iInitFill) { // Fill the buffer C_TsPacket* pPacket = m_pTsProvider->GetPacket(); ASSERT(pPacket); iRc = SyncFillPacket(pPacket); m_pHandler->HandlePacket(pPacket); if(!iRc) { for(unsigned int ui = 1; ui < m_iInitFill; ui++) { C_TsPacket* pPacket = m_pTsProvider->GetPacket(); ASSERT(pPacket); iRc = SyncFillPacket(pPacket); m_pHandler->HandlePacket(pPacket); if(iRc) break; } } } if(iRc == MPEG_ENDOFSTREAM) iRc = NO_ERR; else if(iRc) throw E_Exception(GEN_ERR, "TS to TS converter failed to start");}//------------------------------------------------------------------------------// Main job//------------------------------------------------------------------------------void C_Ts2TsMpegConverter::DoWork(){ // Initialize the condition in the new thread. m_cResumeCond.Protect(); C_String strPgrmName = m_pBroadcast->GetProgram()->GetName(); LogDbg(m_hLog, "Starting to read program \"" + strPgrmName + "\""); int iRc = 0; bool bDiscontinuity = false; // Stream the file while(!m_bStop && !iRc) { // Suspend/Resume handling if(m_iShortPauseStatus == STATUS_PAUSE_REQUEST) { m_cResumeCond.Wait(); m_iShortPauseStatus = STATUS_RUNNING; } if(m_iLongPauseStatus == STATUS_PAUSE_REQUEST) { m_cResumeCond.Wait(); m_iLongPauseStatus = STATUS_RUNNING; bDiscontinuity = true; } // Get a packet to fill C_TsPacket* pPacket = m_pTsProvider->GetPacket(); ASSERT(pPacket); // Fill it with the data from the file iRc = FillPacket(pPacket); if ((*pPacket)[0] != 0x47) bDiscontinuity = true; // Check stream discontinuity if(!iRc && (m_pReader->HasDiscontinuity() || bDiscontinuity)) { while((((*pPacket)[0] != 0x47) || !pPacket->HasPCR()) && !iRc) iRc = SyncFillPacket(pPacket); if(!iRc) { ASSERT(pPacket->SetDiscontinuityFlag()); pPacket->SetDiscontinuityFlag(); m_pReader->ResetDiscontinuity(); bDiscontinuity = false; } } if(!iRc) { // Stores the packet in the buffer m_pHandler->HandlePacket(pPacket); } else if(iRc == MPEG_ENDOFSTREAM) { C_String strPgrmName = m_pBroadcast->GetProgram()->GetName(); LogDbg(m_hLog, "End of program \"" + strPgrmName + "\" reached"); m_pTsProvider->ReleasePacket(pPacket); } else { C_String strPgrmName = m_pBroadcast->GetProgram()->GetName(); Log(m_hLog, LOG_ERROR, "Read error for program \"" + strPgrmName + "\""); m_pTsProvider->ReleasePacket(pPacket); } } if(!m_bStop) { LogDbg(m_hLog, "Stopping converter by callback for program " + strPgrmName); m_bStop = true; C_Event cEvent(m_pBroadcast->GetInput()->GetName()); cEvent.SetCode(EOF_EVENT); cEvent.SetBroadcast(m_pBroadcast); m_pEventHandler->HandleEvent(cEvent); } m_cResumeCond.Release(); LogDbg(m_hLog, "Converter stopped for program " + strPgrmName);}//------------------------------------------------------------------------------// Get the next 188 bytes to fill the TS packet//------------------------------------------------------------------------------int C_Ts2TsMpegConverter::FillPacket(C_TsPacket* pPacket){ int iRc = m_pReader->Read((*pPacket), TS_PACKET_LEN); if(iRc == TS_PACKET_LEN) { iRc = NO_ERR; } else if(iRc >= 0) { // Mark the packet as bad pPacket->SetErrorFlag(); iRc = NO_ERR; } else if(iRc == MPEG_ENDOFSTREAM) { // Pad the end of the packet with 0 and mark it as bad if not some // decoders could crash (*pPacket)[0] = 0x47; for(int i = 1; i < TS_PACKET_LEN; i++) (*pPacket)[i] = 0; pPacket->SetErrorFlag(); } else { // Mark the packet as bad pPacket->SetErrorFlag(); iRc = MPEG_STREAMERROR; } return iRc;}//------------------------------------------------------------------------------// Synchronize in the TS stream and then fill the TS packet//------------------------------------------------------------------------------int C_Ts2TsMpegConverter::SyncFillPacket(C_TsPacket* pPacket){ (*pPacket)[0] = 0; int iRc = 1; while(((*pPacket)[0] != 0x47) && (iRc == 1)) iRc = m_pReader->Read((*pPacket), 1); if(iRc == 1) { iRc = NO_ERR; } else if(iRc >= 0) { // Mark the packet as bad pPacket->SetErrorFlag(); iRc = NO_ERR; } else if(iRc == MPEG_ENDOFSTREAM) { // Pad the end of the packet with 0 and mark it as bad if not some // decoders could crash (*pPacket)[0] = 0x47; for(int i = 1; i < TS_PACKET_LEN; i++) (*pPacket)[i] = 0; pPacket->SetErrorFlag(); } else { // Mark the packet as bad pPacket->SetErrorFlag(); iRc = MPEG_STREAMERROR; } if(!iRc) { iRc = m_pReader->Read((byte*)(*pPacket) + 1, TS_PACKET_LEN - 1); if(iRc == TS_PACKET_LEN - 1) { iRc = NO_ERR; } else if(iRc >= 0) { // Mark the packet as bad pPacket->SetErrorFlag(); iRc = NO_ERR; } else if(iRc == MPEG_ENDOFSTREAM) { // Pad the end of the packet with 0 and mark it as bad if not some // decoders could crash for(int i = 1; i < TS_PACKET_LEN; i++) (*pPacket)[i] = 0; pPacket->SetErrorFlag(); } else { // Mark the packet as bad pPacket->SetErrorFlag(); iRc = MPEG_STREAMERROR; } } return iRc;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -