📄 ts.cpp
字号:
// Now add the pointer field immediatly after the header: as we don't know // its size yet, the payload will began immediatly after the pointer field // and its end will be marked by 0xFF stuffing bytes bData[m_iPsiStart] = 0; m_iPsiStart++; // Table id bData[m_iPsiStart] = iTableId; // Set section length to the minimum (id est no payload) SET_U16_TO(bData[m_iPsiStart+1], 9 & 0xFFF); // Section syntax set to one bData[m_iPsiStart+1] |= 0x80; // Id SET_U16_TO(bData[m_iPsiStart+3], iPsiId); // Versioning bData[m_iPsiStart+5] = (iVersion) << 1; bData[m_iPsiStart+5] |= (bCurrentNext & 0x01); // Section management bData[m_iPsiStart+6] = iCurrentSection; bData[m_iPsiStart+7] = iLastSection; // m_bIsModified = true; return m_iPsiStart + 8;}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------byte* C_PsiSection::AppendData(u8 iDataLen){ byte* pDataPos = NULL; u8 iPsiLen = (U16_AT(bData[m_iPsiStart+1]) & 0xFFF) + 3; if(iPsiLen + m_iPsiStart + iDataLen <= TS_PACKET_LEN) { // pDataPos = bData+m_iPsiStart+iPsiLen-4; // New length SET_U16_TO(bData[m_iPsiStart+1], (iDataLen+iPsiLen-3 & 0xFFF)); // Section syntax indicator must be kept to 1 bData[m_iPsiStart+1] |= 0x80; // m_bIsModified = true; } return pDataPos;}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------byte* C_PsiSection::GetDataForUpdate(u8 iDataPos){ ASSERT(iDataPos < m_iPsiStart + (U16_AT(bData[m_iPsiStart+1]) & 0xFFF) + 3); m_bIsModified = true; return bData + m_iPsiStart + iDataPos;}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------const byte* C_PsiSection::GetDataForRead(u8 iDataPos) const{ ASSERT(iDataPos < m_iPsiStart + (U16_AT(bData[m_iPsiStart+1]) & 0xFFF) + 3); return bData + m_iPsiStart + iDataPos;}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------// //------------------------------------------------------------------------------void C_PsiSection::Finalize(){ if(m_bIsModified) { UpdateVersion(); ComputeCrc32(); AddFinalStuffing(); m_bIsModified = false; }}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------void C_PsiSection::UpdateVersion(){ // The version number is left-shifted of 1 bit, and is coded on 5 bits u8 iVersion = bData[m_iPsiStart+5] & 0x3E; iVersion = (iVersion + 2) & 0x3E; u8 iCurrentNext = bData[m_iPsiStart+5] & 0x1; bData[m_iPsiStart+5] = iVersion | iCurrentNext;}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------void C_PsiSection::BuildCrc32Table(){ u32 i, j, k; for( i = 0 ; i < 256 ; i++ ) { k = 0; for (j = (i << 24) | 0x800000 ; j != 0x80000000 ; j <<= 1) k = (k << 1) ^ (((k ^ j) & 0x80000000) ? 0x04c11db7 : 0); iCrc32Table[i] = k; }}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------void C_PsiSection::ComputeCrc32(){ u32 iCrc = 0xffffffff; u8 iPsiLen = (U16_AT(bData[m_iPsiStart+1]) & 0xFFF) + 3 - 4; for(u8 i = m_iPsiStart; i < m_iPsiStart+iPsiLen; i++) iCrc = (iCrc << 8) ^ iCrc32Table[(iCrc >> 24) ^ bData[i]]; SET_U32_TO(bData[m_iPsiStart+iPsiLen], iCrc);}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------void C_PsiSection::AddFinalStuffing(){ u8 iStuffStart = (U16_AT(bData[m_iPsiStart+1])&0xFFF)+m_iPsiStart+3; memset(bData+iStuffStart, 0xFF, TS_PACKET_LEN - iStuffStart);}//******************************************************************************// C_Pat class//******************************************************************************// A PAT can contain the description of several program, but as we just want to// build PAT for one program, this class has been restricted//******************************************************************************//------------------------------------------------------------------------------// //------------------------------------------------------------------------------// //------------------------------------------------------------------------------void C_Pat::BuildHeader(u16 iStreamId, u8 iVersion, bool bCurrentNext){ C_PsiSection::BuildHeader(0, 0, 0, iStreamId, iVersion, bCurrentNext, 0, 0);}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------// //------------------------------------------------------------------------------int C_Pat::AddPgrm(u16 iPgrmNumber, u16 iPmtPid){ int iRc = NO_ERR; byte* pPgrmDescr = AppendData(4); if(pPgrmDescr) { SET_U16_TO(pPgrmDescr[0], iPgrmNumber); SET_U16_TO(pPgrmDescr[2], iPmtPid); } else { // There was not enougn sace left on the packet iRc = GEN_ERR; } return iRc;}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------// //------------------------------------------------------------------------------void C_Pat::Write(C_TsPacket* pPacket){ ASSERT(pPacket); // Finalize(); // Copy the PAT in the TS packet memcpy((byte*)(*pPacket), bData, TS_PACKET_LEN); // Increment the continuity counter IncrementCounter();}//******************************************************************************// C_Pmt class//******************************************************************************// //******************************************************************************//------------------------------------------------------------------------------// //------------------------------------------------------------------------------// //------------------------------------------------------------------------------void C_Pmt::BuildHeader(u16 iPid, u16 iPgrmNumber, u16 iPcrPid, u8 iVersion, bool bCurrentNext/* = true*/){ ASSERT((iPcrPid & 0xE000) == 0); C_PsiSection::BuildHeader(iPid, 0, 2, iPgrmNumber, iVersion, bCurrentNext, 0, 0); // Set the PCR pid and the no pgrm info (->Pgrm_info_length is 0) byte* pAdditionalFields = AppendData(4); ASSERT(pAdditionalFields); SET_U16_TO(pAdditionalFields[0], iPcrPid); SET_U16_TO(pAdditionalFields[2], 0);}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------u16 C_Pmt::GetPcrPid() const{ const byte* pPcrPid = GetDataForRead(8); return U16_AT(pPcrPid[0]);}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------void C_Pmt::UpdatePcrPid(u16 iNewPid){ ASSERT((iNewPid & 0xE000) == 0); byte* pPcrPid = GetDataForUpdate(8); SET_U16_TO(pPcrPid[0], iNewPid);}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------// //------------------------------------------------------------------------------int C_Pmt::AddEs(u8 iType, u16 iPid/*, const C_Vector<C_Descriptor*>& cDescriptors*/){ ASSERT((iPid & 0xE000) == 0); int iRc = NO_ERR; byte* pEsDescr = AppendData(5); if(pEsDescr) { pEsDescr[0] = iType; SET_U16_TO(pEsDescr[1], iPid); SET_U16_TO(pEsDescr[3], 0); } else { // Not enough space left on TS packet iRc = GEN_ERR; } return iRc;}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------// //------------------------------------------------------------------------------void C_Pmt::Write(C_TsPacket* pPacket){ ASSERT(pPacket); // Finalize(); // Copy the PAT in the TS packet memcpy((byte*)(*pPacket), bData, TS_PACKET_LEN); // Increment the continuity counter IncrementCounter();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -