📄 umc_mpeg2_muxer_chunk.cpp
字号:
if (m_uiPESPacketLength > 0xFFFF)
m_uiPESPacketLength = 0;
uiMaxPayloadSize -= m_uiSpecialHeaderSize;
uiMaxPayloadSize -= m_uiPESHeaderDataLength; // PTS/DTS
uiMaxPayloadSize -= 3; // PES flags and PES_header_data_length field
uiMaxPayloadSize -= 6; // PES_start_code and PES_packet_length
// prepare special header fields
if (MPEG2MUX_ES_LPCM_AUDIO == m_ESType)
{
m_uiNOfFrames = (payload.uiSize - m_uiOffset + MPEG2MUX_LPCM_FRAME_SIZE - 1) / MPEG2MUX_LPCM_FRAME_SIZE;
m_uiNextOffset = m_uiOffset + m_uiNOfFrames * MPEG2MUX_LPCM_FRAME_SIZE - payload.uiSize;
}
}
if (payload.uiSize < uiMaxPayloadSize)
{ // frame (or rest of frame) is smaller than available space
if (0x03 == m_uiAdaptFieldCtrl)
{ // adapration field already exists, just add stuffing bytes
m_uiNOfTSStuffingBytes = (Ipp8u)(m_uiNOfTSStuffingBytes + uiMaxPayloadSize - payload.uiSize);
m_uiAdaptFieldLen = (Ipp8u)(m_uiAdaptFieldLen + m_uiNOfTSStuffingBytes);
}
else
{ // adapration field is needed to add stuffing bytes
m_uiAdaptFieldCtrl = 0x03;
m_uiAdaptFieldLen = (Ipp8u)(uiMaxPayloadSize - payload.uiSize - 1);
if (m_uiAdaptFieldLen > 0)
m_uiNOfTSStuffingBytes = m_uiAdaptFieldLen - 1;
}
}
else
{
payload.uiSize = uiMaxPayloadSize;
}
if ((MPEG2MUX_ES_LPCM_AUDIO == m_ESType) && (payload.uiSize & 1))
{ // even number of byte of LPCM should be written
payload.uiSize--;
m_uiNOfStuffingBytes++;
m_uiPESHeaderDataLength++;
}
return UMC_OK;
} //Status MPEG2TSChunkWriter::PrepareChunk(void)
void MPEG2TSChunkWriter::GenerateNonPESHeaders(void)
{
AdvancedBitStream bs;
bs.Reset(m_pHeaderBuf, MPEG2MUX_CHUNK_HEADER_SIZE);
bs.AddBits(0x47, 8); // sync_byte
bs.AddBits(0x00, 1); // transport_error_indicator
bs.AddBits(m_uiStartIndicator, 1); // payload_unit_start_indicator
bs.AddBits(0x00, 1); // transport_priority
bs.AddBits(m_uiPID, 13); // PID
bs.AddBits(0x00, 2); // transport_scrambling_control
bs.AddBits(m_uiAdaptFieldCtrl, 2); // adaptation_field_control
bs.AddBits(m_uiCounter, 4); // continuity_counter
if (0x03 == m_uiAdaptFieldCtrl)
{
bs.AddBits(m_uiAdaptFieldLen, 8); // adaptation_field_length
if (m_uiAdaptFieldLen > 0)
{
bs.AddBits(0x00, 1); // discontinuity_indicator
bs.AddBits(0x00, 1); // random_access_indicator
bs.AddBits(0x00, 1); // elementary_stream_priority_indicator
bs.AddBits(m_uiPCRFlag, 1); // PCR_flag
bs.AddBits(0x00, 1); // OPCR_flag
bs.AddBits(0x00, 1); // splicing_point_flag
bs.AddBits(0x00, 1); // transport_private_data_flag
bs.AddBits(0x00, 1); // adaptation_field_extension_flag
if (m_uiPCRFlag)
{
Ipp64u pcr = (Ipp64u)(m_dPCR * 27000000 + 0.5);
Ipp64u pcr_base = (pcr / 300) & CONST_LL(0x1FFFFFFFF);
Ipp32u pcr_ext = (Ipp32u)((pcr % 300) & 0x1FF);
bs.AddBits((Ipp32s)(pcr_base >> 32), 1); // program_clock_reference_base[32..32]
bs.AddBits((Ipp32s)(pcr_base & 0xFFFFFFFF), 32); // program_clock_reference_base[31..0]
bs.AddBits(0x3F, 6); // reserved
bs.AddBits((pcr_ext), 9); // program_clock_reference_extension
}
Ipp32u i;
for (i = 0; i < m_uiNOfTSStuffingBytes; i++)
bs.AddBits(0xFF, 8); // stuffing byte
}
}
m_uiCounter = (m_uiCounter + 1) & 0x0f;
m_uiHeaderBufSize = bs.m_lpb - bs.m_lpbBuffer;
} //void MPEG2TSChunkWriter::GenerateNonPESHeaders(void)
void MPEG2TSChunkWriter::GenerateSpecialHeader(void)
{
if (MPEG2MUX_ES_LPCM_AUDIO == m_ESType)
{
AdvancedBitStream bs;
bs.Reset(&m_pHeaderBuf[m_uiHeaderBufSize], MPEG2MUX_CHUNK_HEADER_SIZE - m_uiHeaderBufSize);
bs.AddBits(m_uiNOfFrames, 8); // number_of_frames
bs.AddBits(m_uiOffset + 4, 16); // first_access_unit_pointer (4)
bs.AddBits(0x00, 1); // emphasis_flag (off)
bs.AddBits(0x00, 1); // mute_flag (off)
bs.AddBits(0x00, 1); // reserved
bs.AddBits(m_uiFrameNumber, 5); // number_of_frame
bs.AddBits(0x00, 2); // sample_size_code (16bit)
bs.AddBits(0x00, 2); // sample_rate_code (48k)
bs.AddBits(0x09, 4); // number_of_channels_code (dual_mono)
bs.AddBits(0x80, 8); // dynamic_range_control
// update special header fields
m_uiFrameNumber = (m_uiFrameNumber + m_uiNOfFrames) % 20;
m_uiOffset = m_uiNextOffset;
m_uiNOfFrames = 0;
m_uiHeaderBufSize = bs.m_lpb - m_pHeaderBuf;
}
} //void MPEG2TSChunkWriter::GenerateSpecialHeader(void)
Status MPEG2TSChunkWriter::WriteChunk(void)
{
UMC_CALL(PrepareChunk());
GenerateNonPESHeaders();
if (m_uiStartIndicator && m_ESType != MPEG2MUX_ES_VBI_DATA)
{
GeneratePESHeader();
if (m_uiSpecialHeaderSize > 0)
GenerateSpecialHeader();
}
// write headers
Ipp32s iToWrite = (Ipp32s)m_uiHeaderBufSize;
UMC_CALL(m_pDataWriter->PutData(m_pHeaderBuf, iToWrite));
#ifndef _BIG_ENDIAN_
if (MPEG2MUX_ES_LPCM_AUDIO == m_ESType)
ippsSwapBytes_16u_I((Ipp16u *)payload.pData, payload.uiSize / 2);
#endif
// write payload data
iToWrite = (Ipp32s)payload.uiSize;
UMC_CALL(m_pDataWriter->PutData(payload.pData, iToWrite));
m_uiStartIndicator = 0;
return UnLockOutputBuffer(&payload);
} //Status MPEG2TSChunkWriter::WriteChunk(void)
/*
* PATTableWriter
*/
PATTableWriter::PATTableWriter()
{
m_iNOfPrograms = 0;
m_pProgramPID = NULL;
m_pHeaderBuf = NULL;
m_uiCounter = 0;
} //PATTableWriter::PATTableWriter()
PATTableWriter::~PATTableWriter()
{
Close();
} //PATTableWriter::~PATTableWriter()
Status PATTableWriter::Close(void)
{
MPEG2ChunkWriter::Close();
UMC_FREE(m_pHeaderBuf);
UMC_FREE(m_pProgramPID);
m_iNOfPrograms = 0;
m_uiCounter = 0;
return UMC_OK;
} //Status PATTableWriter::Close(void)
Status PATTableWriter::Init(MediaReceiverParams *pInit)
{
//DO NOT initialize linear buffer here
Close();
PATTableWriterParams *pParams = DynamicCast<PATTableWriterParams>(pInit);
UMC_CHECK_PTR(pParams);
UMC_CHECK_PTR(pParams->pDataWriter);
UMC_CHECK_PTR(pParams->pProgramPID);
m_pDataWriter = pParams->pDataWriter;
m_iNOfPrograms = pParams->iNOfPrograms;
UMC_CHECK(m_iNOfPrograms > 0, UMC_ERR_INVALID_PARAMS);
UMC_ALLOC_ARR(m_pProgramPID, Ipp16u, m_iNOfPrograms);
ippsCopy_16s((Ipp16s *)pParams->pProgramPID, (Ipp16s *)m_pProgramPID, m_iNOfPrograms);
UMC_ALLOC_ARR(m_pHeaderBuf, Ipp8u, MPEG2MUX_TS_PACKET_LENGTH);
ippsSet_8u(0xFF, m_pHeaderBuf, MPEG2MUX_TS_PACKET_LENGTH);
AdvancedBitStream bs;
bs.Reset(m_pHeaderBuf, MPEG2MUX_TS_PACKET_LENGTH);
// write Program Association Table
bs.AddBits(0x47, 8); // sync_byte
bs.AddBits(0x00, 1); // transport_error_indicator
bs.AddBits(0x01, 1); // payload_unit_start_indicator
bs.AddBits(0x00, 1); // transport_priority
bs.AddBits(0x00, 13); // PID
bs.AddBits(0x00, 2); // transport_scrambling_control
bs.AddBits(0x01, 2); // adaptation_field_control
bs.AddBits(m_uiCounter, 4); // continuity_counter
bs.AddBits(0x00, 8); // pointer_field
bs.AddBits(0x00, 8); // table_id
bs.AddBits(0x01, 1); // section_syntax_indicator
bs.AddBits(0x00, 1); // '0'
bs.AddBits(0x03, 2); // reserved
bs.AddBits(4 * m_iNOfPrograms + 9, 12); // section_length
bs.AddBits(0x00, 16); // transport_stream_id
bs.AddBits(0x03, 2); // reserved
bs.AddBits(0x00, 5); // version_number
bs.AddBits(0x01, 1); // current_next_indicator
bs.AddBits(0x00, 8); // section_number
bs.AddBits(0x00, 8); // last_section_number
Ipp32s i;
for (i = 0; i < m_iNOfPrograms; i++)
{
bs.AddBits(i + 1, 16); // program_number
bs.AddBits(0x07, 3); // reserved
bs.AddBits(m_pProgramPID[i], 13); // program_map_PID
}
Ipp32u uiCRCDataLen = 4 * m_iNOfPrograms + 8;
Ipp32u uiCRC32 = 0;
ippsCRC32_BZ2_8u(bs.m_lpb - uiCRCDataLen, uiCRCDataLen, &uiCRC32);
uiCRC32 ^= 0xFFFFFFFF;
bs.AddBits(uiCRC32, 32); // CRC_32
return UMC_OK;
} //Status PATTableWriter::Init(MediaReceiverParams *pInit)
Status PATTableWriter::WriteChunk(void)
{
Ipp32s iToWrite = MPEG2MUX_TS_PACKET_LENGTH;
Status umcRes = m_pDataWriter->PutData(m_pHeaderBuf, iToWrite);
AdvancedBitStream bs;
bs.Reset(m_pHeaderBuf, MPEG2MUX_TS_PACKET_LENGTH);
// update continuity_counter
m_uiCounter = (m_uiCounter + 1) & 0x0f;
bs.SkipBits(8 + 1 + 1 + 1 + 13 + 2 + 2);
bs.AddBits(m_uiCounter, 4);
return umcRes;
} //Status PATTableWriter::WriteChunk(void)
/*
* PMTTableWriter
*/
PMTTableWriter::PMTTableWriter()
{
m_pStreamType = NULL;
m_pPID = NULL;
m_pHeaderBuf = NULL;
} //PMTTableWriter::PMTTableWriter()
PMTTableWriter::~PMTTableWriter()
{
Close();
} //PMTTableWriter::~PMTTableWriter()
Status PMTTableWriter::Close(void)
{
MPEG2ChunkWriter::Close();
UMC_FREE(m_pHeaderBuf);
UMC_FREE(m_pStreamType);
UMC_FREE(m_pPID);
m_uiProgramPID = 0;
m_uiProgramNumber = 0;
m_uiNOfStreams = 0;
m_uiPCRPID = 0;
m_uiCounter = 0;
return UMC_OK;
} //Status PMTTableWriter::Close(void)
Status PMTTableWriter::Init(MediaReceiverParams *pInit)
{
//DO NOT initialize linear buffer here
Close();
PMTTableWriterParams *pParams = DynamicCast<PMTTableWriterParams>(pInit);
UMC_CHECK_PTR(pParams);
UMC_CHECK_PTR(pParams->pDataWriter);
UMC_CHECK_PTR(pParams->pStreamType);
UMC_CHECK_PTR(pParams->pPID);
UMC_CHECK(pParams->uiNOfStreams > 0, UMC_ERR_INVALID_PARAMS);
m_pDataWriter = pParams->pDataWriter;
m_uiNOfStreams = pParams->uiNOfStreams;
m_uiProgramNumber = pParams->uiProgramNumber;
m_uiProgramPID = pParams->uiProgramPID;
m_uiPCRPID = pParams->uiPCRPID;
UMC_ALLOC_ARR(m_pStreamType, MPEG2MuxerESType, m_uiNOfStreams);
UMC_ALLOC_ARR(m_pPID, Ipp32u, m_uiNOfStreams);
UMC_ALLOC_ARR(m_pHeaderBuf, Ipp8u, MPEG2MUX_TS_PACKET_LENGTH);
ippsCopy_8u((Ipp8u *)pParams->pStreamType, (Ipp8u *)m_pStreamType, m_uiNOfStreams * sizeof(MPEG2MuxerESType));
ippsCopy_32s((Ipp32s *)pParams->pPID, (Ipp32s *)m_pPID, m_uiNOfStreams);
ippsSet_8u(0xFF, m_pHeaderBuf, MPEG2MUX_TS_PACKET_LENGTH);
AdvancedBitStream bs;
bs.Reset(m_pHeaderBuf, MPEG2MUX_TS_PACKET_LENGTH);
// write Program Map Table
bs.AddBits(0x47, 8); // sync_byte
bs.AddBits(0x00, 1); // transport_error_indicator
bs.AddBits(0x01, 1); // payload_unit_start_indicator
bs.AddBits(0x00, 1); // transport_priority
bs.AddBits(m_uiProgramPID, 13); // PID
bs.AddBits(0x00, 2); // transport_scrambling_control
bs.AddBits(0x01, 2); // adaptation_field_control
bs.AddBits(m_uiCounter, 4); // continuity_counter
bs.AddBits(0x00, 8); // pointer_field
bs.AddBits(0x02, 8); // table_id
bs.AddBits(0x01, 1); // section_syntax_indicator
bs.AddBits(0x00, 1); // '0'
bs.AddBits(0x03, 2); // reserved
bs.AddBits(13 + 5 * m_uiNOfStreams, 12); // section_length
bs.AddBits(m_uiProgramNumber, 16); // program_number
bs.AddBits(0x03, 2); // reserved
bs.AddBits(0x00, 5); // version_number
bs.AddBits(0x01, 1); // current_next_indicator
bs.AddBits(0x00, 8); // section_number
bs.AddBits(0x00, 8); // last_section_number
bs.AddBits(0x07, 3); // reserved
bs.AddBits(m_uiPCRPID, 13); // PRC_PID
bs.AddBits(0x0F, 4); // reserved
bs.AddBits(0x00, 12); // program_info_length
Ipp32u uiNum;
for (uiNum = 0; uiNum < m_uiNOfStreams; uiNum++)
{
bs.AddBits(m_pStreamType[uiNum], 8); // stream_type
bs.AddBits(0x07, 3); // reserved
bs.AddBits(m_pPID[uiNum], 13); // elementary_PID
bs.AddBits(0x0F, 4); // reserved
bs.AddBits(0x00, 12); // ES_info_length
}
Ipp32u uiCRC32 = 0;
Ipp32u uiCRCDataLen = 12 + 5 * m_uiNOfStreams;
ippsCRC32_BZ2_8u(bs.m_lpb - uiCRCDataLen, uiCRCDataLen, &uiCRC32);
uiCRC32 ^= 0xFFFFFFFF;
bs.AddBits(uiCRC32, 32); // CRC_32
return UMC_OK;
} //Status PMTTableWriter::Init(MediaReceiverParams *pInit)
Status PMTTableWriter::WriteChunk(void)
{
Ipp32s iToWrite = MPEG2MUX_TS_PACKET_LENGTH;
Status umcRes = m_pDataWriter->PutData(m_pHeaderBuf, iToWrite);
AdvancedBitStream bs;
bs.Reset(m_pHeaderBuf, MPEG2MUX_TS_PACKET_LENGTH);
// update continuity_counter
m_uiCounter = (m_uiCounter + 1) & 0x0f;
bs.SkipBits(8 + 1 + 1 + 1 + 13 + 2 + 2);
bs.AddBits(m_uiCounter, 4);
return umcRes;
} //Status PMTTableWriter::WriteChunk(void)
/*
* MPEG2TTS
*/
Status MPEG2TTSChunkWriter::WriteChunk(void)
{
Ipp32s iToWrite = 4;
Ipp32u uiTimeStamp = LITTLE_ENDIAN_SWAP32((Ipp32u)(m_dReferenceClock * MPEG2MUX_SYS_CLOCK_FREQ));
m_pDataWriter->PutData(&uiTimeStamp, iToWrite);
return MPEG2TSChunkWriter::WriteChunk();
} //Status MPEG2TTSChunkWriter::WriteChunk(void)
Status TTSPATTableWriter::WriteChunk(void)
{
Ipp32s iToWrite = 4;
Ipp32u uiTimeStamp = LITTLE_ENDIAN_SWAP32((Ipp32u)(m_dReferenceClock * MPEG2MUX_SYS_CLOCK_FREQ));
m_pDataWriter->PutData(&uiTimeStamp, iToWrite);
return PATTableWriter::WriteChunk();
} //Status TTSPATTableWriter::WriteChunk(void)
Status TTSPMTTableWriter::WriteChunk(void)
{
Ipp32s iToWrite = 4;
Ipp32u uiTimeStamp = LITTLE_ENDIAN_SWAP32((Ipp32u)(m_dReferenceClock * MPEG2MUX_SYS_CLOCK_FREQ));
m_pDataWriter->PutData(&uiTimeStamp, iToWrite);
return PMTTableWriter::WriteChunk();
} //Status TTSPMTTableWriter::WriteChunk(void)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -