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

📄 ts.cpp

📁 可用该程序将avi的电影文件转化为TS流
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************** ts.cpp: TS packet manipulation*-------------------------------------------------------------------------------* (c)1999-2001 VideoLAN* $Id: ts.cpp,v 1.2 2002/03/17 23:20:22 bozo Exp $** Authors: Benoit Steiner <benny@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 "config.h"#include "../core/core.h"#include "mpeg.h"#include "ts.h"//******************************************************************************// C_TsPacket class//******************************************************************************////******************************************************************************//------------------------------------------------------------------------------// //------------------------------------------------------------------------------// Give direct access to the raw buffer//------------------------------------------------------------------------------C_TsPacket::operator byte* (){  return bData;}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------// Mark the packet as being invalid//------------------------------------------------------------------------------void C_TsPacket::IncrementCounter(){  u8 iByte = bData[3];  bData[3] = ((iByte + 1) & 0x0F) | (iByte & 0xF0);}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------// Mark the packet as being invalid//------------------------------------------------------------------------------void C_TsPacket::SetErrorFlag(bool bError/* = true*/){  if(bError)    bData[1] &= 0xFF;  else    bData[1] &= 0x7F;}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------// Set the discontinuity flag. This is only possible if the packet carries an// adaption field// Return false if the flag could not be set//------------------------------------------------------------------------------bool C_TsPacket::SetDiscontinuityFlag(bool bDiscontinuity/* = true*/){  bool bDone = true;  // The job has to be done only if the flag must be set to true  if(bDiscontinuity)  {    // Check that the adaptation_field_control is set and that the    // adaptation_field_length is not 0    if((bData[3] & 0x20) && bData[4])    {      // Set the discontinuity indicator      bData[5] |= 0x80;    }  }  else  {    // The flag can't be set    bDone = false;  }    return bDone;}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------// Get the PID//------------------------------------------------------------------------------u16 C_TsPacket::GetPid() const{  return ((u16)(bData[1] & 0x1f) << 8) + bData[2];}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------// Look for a PCR field in the TS header//------------------------------------------------------------------------------bool C_TsPacket::HasPCR() const{  // Return true only if adaptation_field_control is set,  // adaptation_field_length is not 0 and PCR_flag is set  return ((bData[3] & 0x20) && bData[4] && (bData[5] & 0x10));}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------////------------------------------------------------------------------------------bool C_TsPacket::IsDiscontinuity() const{  // Return true only if adaptation_field_control is set,  // adaptation_field_length is not 0 and discontinuity_flag is set  return ((bData[3] & 0x20) && bData[4] && (bData[5] & 0x80));}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------// Extracts and converts the PCR to return a date in microseconds//------------------------------------------------------------------------------s64 C_TsPacket::GetPCRTime() const{  ASSERT(HasPCR());                   // Make sure that the packet carries a PCR#ifdef SOLARIS  // We need to align the data to avoid a bus error  s64 i = *((s64*)(bData+4));  i = i >> 16;  i = U32_AT(i);  return ((( i << 1) | (bData[10] >> 7)) * 300) / 27;#else  return ((( ((s64)U32_AT(bData[6])) << 1) | (bData[10] >> 7)) * 300) / 27;#endif}//------------------------------------------------------------------------------// BuildHeader: Build a TS header and return its size//------------------------------------------------------------------------------// Beware: only the 13 first bits of the iPid field are taken into account, and// only the 4 first bits of the iCounter are used// No adaption field can yet be put in the header// The method returns the length of the header//------------------------------------------------------------------------------u8 C_TsPacket::BuildHeader(u16 iPid, bool bUnitStart, u8 iCounter){  // For a PID is 13 bytes max  ASSERT((iPid & 0xE000) == 0);  // Sync byte  bData[0] = 0x47;  // Set PID value and both error indicator and priority to 0  SET_U16_TO(bData[1], iPid & 0x1FFF);  // Payload unit start  bData[1] |= bUnitStart << 6;  // Continuity counter and no scrambling  bData[3] = iCounter & 0x0F;  // Adaption field control: always payload and never adaption field  bData[3] |= 0x10;  return 4;}//------------------------------------------------------------------------------// BuildAdaptionField: Build an adaption field for TS header and return its size//------------------------------------------------------------------------------// Append a PCR base to the adaption field. Overwrite all data that can follow// the header, so this method is to use before writing the actual payload//------------------------------------------------------------------------------u8 C_TsPacket::BuildAdaptionField(u64 iPCR){  // Adaption field control: adaption field is present  bData[3] |= 0x20;  // Adaption field length  bData[4] = 1+6;  // PCR_base is the only extension present in the adaption field  bData[5] = 0x10;  // PCR_base value  SET_U32_TO(bData[6], (iPCR >> 1) & 0xFFFFFFFF);  bData[10] = (iPCR & 0x1);  return 4+2+6;}//------------------------------------------------------------------------------// AddStuffingBytes: Add stuff to complete the TS packet//------------------------------------------------------------------------------// Modify the TS header so that the necessary stuffing bytes are added to// complete the payload// Overwrite all data that can follow the header and the adaption field, so// this method is to use before writing the actual payload in the packet//------------------------------------------------------------------------------u8 C_TsPacket::AddStuffingBytes(u8 iPayloadLen){  // Check that the given payload length can fit in the packet and that it  // is not big enough to fill it completely  ASSERT(iPayloadLen < TS_PACKET_LEN - 4 - ((bData[3]&0x20)?bData[4]:0));  if(bData[3] & 0x20)  {    // There is an adaption field, we just have to extend it    ASSERT(bData[4] > 0);       // (Empty adaption fields are for stuffing only)    ASSERT(TS_PACKET_LEN - 4 - 1 - bData[4] - iPayloadLen > 0);    u8 iStuffStart = 4+1+bData[4];    bData[4] += TS_PACKET_LEN - iStuffStart - iPayloadLen;    for(u8 i = 0; i < bData[4]; i++)      bData[iStuffStart+i] = 0xFF;  }  else  {    // We must create the adaption field    bData[3] |= 0x20;    ASSERT(TS_PACKET_LEN - 4 - 1 - iPayloadLen >= 0);    bData[4] = TS_PACKET_LEN - 4 - 1 - iPayloadLen;    if(bData[4] > 0)    {      // We won't put any extension in the header      bData[5] = 0;      // Now write the stuffing bytes      for(u8 i = 0; i < bData[4]; i++)        bData[6+i] = 0xFF;    }  }  // Check that we didn't made any error  ASSERT(4+1+bData[4] + iPayloadLen == TS_PACKET_LEN);    return TS_PACKET_LEN - iPayloadLen;}//******************************************************************************// C_PsiSection class//******************************************************************************// In the MPEG2 system norm, a section can be split into several TS packets, but// as this is really unuseful, our implementation don't allow sections biggest// than the size of the available payload of a TS packet.//******************************************************************************//------------------------------------------------------------------------------// //------------------------------------------------------------------------------C_PsiSection::C_PsiSection(){  // Init the CRC encoder  BuildCrc32Table();  ZERO(m_iPsiStart);}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------/*C_PsiSection::~C_PsiSection(){}*///------------------------------------------------------------------------------// //------------------------------------------------------------------------------// //------------------------------------------------------------------------------u8 C_PsiSection::BuildHeader(u16 iPid, u8 iCounter, u8 iTableId, u16 iPsiId,                             u8 iVersion, bool bCurrentNext, u8 iCurrentSection,                             u8 iLastSection){  // For a PID is 13 bits max  ASSERT((iPid & 0xE000) == 0);  // For the version is 5 bits max  ASSERT((iVersion & 0xE0) == 0);  // First build the TS header: the unit_start indicator will be set to 1  // indicating that a PSI section begins in the packet  m_iPsiStart = C_TsPacket::BuildHeader(iPid, true, iCounter);

⌨️ 快捷键说明

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