📄 umc_stream_parser.cpp
字号:
m_pInfo[iTrack]->m_uiProgNum = pmt.uiProgInd;
AudioStreamType aType = UNDEF_AUDIO;
if (0x01 == pmt.pESs[i].uiType)
m_pInfo[iTrack]->m_Type = TRACK_MPEG1V;
else if (0x02 == pmt.pESs[i].uiType)
m_pInfo[iTrack]->m_Type = TRACK_MPEG2V;
else if (0x03 == pmt.pESs[i].uiType || 0x04 == pmt.pESs[i].uiType)
{
m_pInfo[iTrack]->m_Type = TRACK_MPEGA;
aType = (0x03 == pmt.pESs[i].uiType) ? MPEG1_AUDIO : MPEG2_AUDIO;
}
else if (0x06 == pmt.pESs[i].uiType)
{ // we should wait for decriptor to determine type
m_pInfo[iTrack]->m_Type = TRACK_UNKNOWN;
}
else if (0x0F == pmt.pESs[i].uiType)
m_pInfo[iTrack]->m_Type = TRACK_AAC;
else if (0x10 == pmt.pESs[i].uiType)
m_pInfo[iTrack]->m_Type = TRACK_MPEG4V;
else if (0x11 == pmt.pESs[i].uiType)
{
m_pInfo[iTrack]->m_Type = TRACK_AAC;
aType = AAC_MPEG4_STREAM;
}
else if (0x1A == pmt.pESs[i].uiType || 0x1B == pmt.pESs[i].uiType)
m_pInfo[iTrack]->m_Type = TRACK_H264;
else if (0x81 == pmt.pESs[i].uiType)
m_pInfo[iTrack]->m_Type = TRACK_AC3;
else if (0x83 == pmt.pESs[i].uiType)
m_pInfo[iTrack]->m_Type = TRACK_LPCM;
else
m_pInfo[iTrack]->m_Type = TRACK_UNKNOWN;
m_pInfo[iTrack]->ReleaseStreamInfo();
Status umcRes = m_pInfo[iTrack]->Alloc();
if (UMC_OK != umcRes)
return umcRes;
if (m_pInfo[iTrack]->m_Type & TRACK_ANY_AUDIO)
{
if (UNDEF_AUDIO == aType)
aType = (AudioStreamType)ConvertTrackType(m_pInfo[iTrack]->m_Type);
((AudioStreamInfo *)m_pInfo[iTrack]->m_pStreamInfo)->stream_type = aType;
}
if (pmt.pESs[i].pEsInfo && pmt.pESs[i].uiEsInfoLen)
{
// parse descriptors if present
DescriptorNavigator descrNav(pmt.pESs[i].pEsInfo, pmt.pESs[i].uiEsInfoLen);
while (NULL != (pPtr = descrNav.GetNextDescriptor(&uiTag, &uiLen)))
{
if (DESC_VIDEO == uiTag && m_pInfo[iTrack]->m_Type & TRACK_ANY_VIDEO)
{
VideoStreamInfo *pVideoSpec = (VideoStreamInfo *)m_pInfo[iTrack]->m_pStreamInfo;
Ipp8u frame_rate_code = (pPtr[0] >> 3) & 0x0F;
Ipp8u MPEG_1_only_flag = (pPtr[0] >> 2) & 0x01;
pVideoSpec->framerate = Mpeg2FrameConstructor::FrameRate[frame_rate_code < 9 ? frame_rate_code : 0];
pVideoSpec->stream_type = MPEG_1_only_flag ? MPEG1_VIDEO : MPEG2_VIDEO;
m_pInfo[iTrack]->m_Type = MPEG_1_only_flag ? TRACK_MPEG1V : TRACK_MPEG2V;
}
else if (DESC_AUDIO == uiTag && m_pInfo[iTrack]->m_Type & TRACK_ANY_AUDIO)
{
AudioStreamInfo *pAudioSpec = (AudioStreamInfo *)m_pInfo[iTrack]->m_pStreamInfo;
Ipp8u id = (pPtr[0] >> 6) & 0x01;
Ipp8u layer = 4 - (pPtr[0] >> 4) & 0x03;
pAudioSpec->stream_type = AudioFrameConstructor::MpegAStreamType[id][layer - 1];
m_pInfo[iTrack]->m_Type = TRACK_MPEGA;
}
else if ((DESC_AC3 == uiTag || DESC_ENH_AC3 == uiTag) && pmt.pESs[i].uiType == 0x06)
{
m_pInfo[iTrack]->m_Type = TRACK_AC3;
((AudioStreamInfo *)m_pInfo[iTrack]->m_pStreamInfo)->stream_type = AC3_AUDIO;
((AudioStreamInfo *)m_pInfo[iTrack]->m_pStreamInfo)->streamPID = m_pInfo[iTrack]->m_PID;
}
else if ((DESC_TXT == uiTag || DESC_VBI_TXT == uiTag) && pmt.pESs[i].uiType == 0x06)
{
if (uiLen < 5) continue;
m_pInfo[iTrack]->m_Type = TRACK_VBI_TXT;
TeletextStreamInfo *pTxtSpec = (TeletextStreamInfo *)m_pInfo[iTrack]->m_pStreamInfo;
pTxtSpec->szLanguage[0] = pPtr[0];
pTxtSpec->szLanguage[1] = pPtr[1];
pTxtSpec->szLanguage[2] = pPtr[2];
pTxtSpec->szLanguage[3] = 0;
pTxtSpec->uiType = (pPtr[3] >> 3) & 0x1f;
pTxtSpec->uiMagazineNumber = pPtr[3] & 0x07;
pTxtSpec->uiPageNumber = pPtr[4];
}
else if (DESC_VBI == uiTag && pmt.pESs[i].uiType == 0x06)
{
m_pInfo[iTrack]->m_Type = TRACK_ANY_VBI;
}
else if (DESC_FMC == uiTag)
{
if (uiLen < 2) continue;
Ipp16u esId = GET_16U(pPtr);
Ipp32u i;
for (i = 0; i < pmt.uiESs; i++)
{
if (pmt.pESs[i].pESDSs && pmt.pESs[i].pESDSs->uiEsId == esId)
{
UMC_NEW(m_pInfo[iTrack]->m_pDecSpecInfo, MediaData);
m_pInfo[iTrack]->m_pDecSpecInfo->SetBufferPointer(
pmt.pESs[i].pESDSs->pDecSpecInfo, pmt.pESs[i].pESDSs->uiDecSpecInfoLen);
m_pInfo[iTrack]->m_pDecSpecInfo->SetDataSize(pmt.pESs[i].pESDSs->uiDecSpecInfoLen);
if (m_pInfo[iTrack]->m_Type & TRACK_ANY_VIDEO)
((VideoStreamInfo *)m_pInfo[iTrack]->m_pStreamInfo)->bitrate = pmt.pESs[i].pESDSs->avgBitrate;
else if (m_pInfo[iTrack]->m_Type & TRACK_ANY_AUDIO)
((AudioStreamInfo *)m_pInfo[iTrack]->m_pStreamInfo)->bitrate = pmt.pESs[i].pESDSs->avgBitrate;
break;
}
}
}
}
}
if (TRACK_UNKNOWN == m_pInfo[iTrack]->m_Type)
{ // oops, seems it's unsupported type
m_uiTracks--;
continue;
}
}
return UMC_OK;
}
Status WaveParser::CheckNextData(MediaData *pData, Ipp32u *pTrack)
{
PARSER_CHECK_INIT;
if (!pData || !pTrack)
return UMC_ERR_NULL_PTR;
if (0 == m_uiTracks)
{
Status err;
Ipp32u longCode, fmtSize;
Ipp16u shortCode;
m_uiTracks = 1;
m_pInfo[0] = new Mpeg2TrackInfo;
if (!m_pInfo[0])
return UMC_ERR_ALLOC;
err = m_pDataReader->Get32uSwap(&longCode); // 'RIFF'
if (UMC_OK != err || longCode != 'RIFF') return UMC_ERR_INVALID_STREAM;
err = m_pDataReader->Get32uNoSwap(&longCode); // size
if (UMC_OK != err) return err;
err = m_pDataReader->Get32uSwap(&longCode); // 'WAVE'
if (UMC_OK != err || longCode != 'WAVE') return UMC_ERR_INVALID_STREAM;
err = m_pDataReader->Get32uSwap(&longCode); // 'fmt '
if (UMC_OK != err || longCode != 'fmt ') return UMC_ERR_INVALID_STREAM;
err = m_pDataReader->Get32uNoSwap(&fmtSize); // size
if (UMC_OK != err) return err;
err = m_pDataReader->Get16uNoSwap(&shortCode); // AudioFormat
if (UMC_OK != err) return err;
fmtSize -= 2;
if (WAVE_FORMAT_PCM == shortCode)
m_pInfo[0]->m_Type = TRACK_PCM;
else if (WAVE_FORMAT_MPEGLAYER3 == shortCode)
m_pInfo[0]->m_Type = TRACK_MPEGA;
err = m_pInfo[0]->Alloc();
if (UMC_OK != err)
return err;
AudioStreamInfo *pASI = (AudioStreamInfo *)m_pInfo[0]->m_pStreamInfo;
err = m_pDataReader->Get16uNoSwap(&shortCode); // NumChannels
if (UMC_OK != err) return err;
pASI->channels = shortCode;
fmtSize -= 2;
err = m_pDataReader->Get32uNoSwap(&longCode); // SampleRate
if (UMC_OK != err) return err;
pASI->sample_frequency = longCode;
fmtSize -= 4;
err = m_pDataReader->Get32uNoSwap(&longCode); // ByteRate
if (UMC_OK != err) return err;
pASI->bitrate = 8 * longCode;
fmtSize -= 4;
err = m_pDataReader->Get16uNoSwap(&shortCode); // BlockAlign
if (UMC_OK != err) return err;
fmtSize -= 2;
err = m_pDataReader->Get16uNoSwap(&shortCode); // BitsPerSample
if (UMC_OK != err) return err;
pASI->bitPerSample = shortCode;
fmtSize -= 2;
err = m_pDataReader->MovePosition(fmtSize); // skip fmt header
if (UMC_OK != err) return err;
err = m_pDataReader->Check32u(&longCode, 0);
while (UMC_OK == err && 'data' != longCode)
{
err = m_pDataReader->Get32uSwap(&longCode);
err = m_pDataReader->Get32uNoSwap(&longCode);
err = m_pDataReader->MovePosition(longCode);
err = m_pDataReader->Check32u(&longCode, 0);
}
err = m_pDataReader->Get32uSwap(&longCode); // 'data'
if (UMC_OK != err) return err;
err = m_pDataReader->Get32uNoSwap(&longCode); // size of 'data'
if (UMC_OK != err) return err;
if (m_dDuration < 0.0)
{
if (m_pInfo[0]->m_Type & TRACK_MPEGA)
{
EstimateMPEGAudioDuration();
}
else if (TRACK_PCM == m_pInfo[0]->m_Type)
{
if (m_uiSourceSize && pASI->bitrate)
m_dDuration = (Ipp64f)(Ipp64s)m_uiSourceSize / (pASI->bitrate / 8);
}
}
pASI->duration = m_dDuration;
}
m_ParserState = PAYLOAD;
pTrack[0] = 0;
m_pPacket->uiSize = 16 * 1024;
m_pPacket->uiAbsPos = m_pDataReader->GetPosition();
PacketToMediaData(*m_pPacket, *pData);
return UMC_OK;
}
Status Mpeg2PesParser::ParsePesHeader(Packet &packet, Ipp32s &iPos, bool bWrapped)
{
Ipp32s iInnerPos = 0;
// we save 9 bytes for start_code, pes_len, flags and pes_header_len
// 256 bytes are maximum for pes_packet_len and 1 is for first byte of private_1
Ipp8u pesPacket[9 + 256 + 1];
CACHE_N_BYTES(&pesPacket[0], 9, iPos);
if (pesPacket[0] != 0 || pesPacket[1] != 0 || pesPacket[2] != 1)
return UMC_ERR_INVALID_STREAM;
if (!IS_PES_PACKET(pesPacket[3]))
return UMC_ERR_INVALID_STREAM;
if (!bWrapped)
packet.iPid = pesPacket[3];
Ipp32s PES_packet_len = GET_16U(&pesPacket[4]);
packet.dPTS = packet.dDTS = -1.0;
if (bWrapped || MPEG2_PROGRAMM_STREAM == m_SystemType)
{
Ipp32u PTS_DTS_flag = (pesPacket[iInnerPos + 7] >> 6) & 0x03;
Ipp32s PES_header_data_length = pesPacket[iInnerPos + 8];
if (0 == PES_packet_len && !bWrapped)
return UMC_ERR_INVALID_STREAM;
if (PES_packet_len > 0 && PES_packet_len < PES_header_data_length + 3)
return UMC_ERR_INVALID_STREAM;
CACHE_N_BYTES(&pesPacket[9], PES_header_data_length + 1, iPos + 9);
if (PTS_DTS_flag & 2)
{
packet.dPTS = GetTimeStampFromPes(&pesPacket[iInnerPos + 9]);
if (3 == PTS_DTS_flag)
packet.dDTS = GetTimeStampFromPes(&pesPacket[iInnerPos + 9 + 5]);
}
iInnerPos += 9 + PES_header_data_length;
if (!bWrapped)
packet.uiSize = PES_packet_len - 3 - PES_header_data_length;
// Private_stream_1 may contain more then one elementary stream
if (0xBD == packet.iPid && !bWrapped)
packet.iPid = pesPacket[iInnerPos];
}
else if (MPEG1_PROGRAMM_STREAM == m_SystemType)
{
Ipp32s i;
// 34 bytes are maximum that needed for mpeg1 pes header, 9 have been already read
CACHE_N_BYTES(&pesPacket[9], 34 - 9, iPos + 9);
iInnerPos += 6;
// skip stuffing bytes, they are start from '1' and not more than 16
for (i = 0; 0x80 == (pesPacket[iInnerPos] & 0x80) && i < 16; i++, iInnerPos++);
if ((pesPacket[iInnerPos] & 0xc0) == 0x40)
iInnerPos += 2;
if ((pesPacket[iInnerPos] & 0xf0) == 0x20)
{
packet.dPTS = GetTimeStampFromPes(&pesPacket[iInnerPos]);
iInnerPos += 5;
}
else if ((pesPacket[iInnerPos] & 0xf0) == 0x30)
{
packet.dPTS = GetTimeStampFromPes(&pesPacket[iInnerPos]);
iInnerPos += 5;
packet.dDTS = GetTimeStampFromPes(&pesPacket[iInnerPos]);
iInnerPos += 5;
}
else if (0x0f == pesPacket[iInnerPos])
iInnerPos += 1;
else
return UMC_ERR_INVALID_STREAM;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -