📄 umc_stream_parser.cpp
字号:
if (iInnerPos > PES_packet_len + 6)
return UMC_ERR_INVALID_STREAM;
packet.uiSize = PES_packet_len + 6 - iInnerPos;
}
iPos += iInnerPos;
packet.iBufOffset = iPos;
return UMC_OK;
}
Status StreamParser::EstimateMPEGAudioDuration(void)
{
Ipp8u buf[BUF_LEN];
Ipp32u ndata;
Ipp32s frame_len;
Ipp32u offset, offset_add, offset_save, i;
Ipp32s frame_counter;
Ipp32s next_header;
Ipp32s layer, samplingFreq, bitRate, emphasis, id, mpg25, MP3Header, paddingBit;
Ipp32s layer_ref = 0, samplingFreq_ref = 0, id_ref = 0, mpg25_ref = 0;
Ipp32s free_format = 0;
Ipp64u iPosition = 0;
Status status = UMC_OK;
if (!(m_pInfo[0]->m_Type & TRACK_MPEGA))
return UMC_OK;
iPosition = m_pDataReader->GetPosition();
frame_counter = 0;
ndata = BUF_LEN;
offset = BUF_LEN;
offset_add = 0;
for(;;)
{
offset_save = ndata - offset;
if (offset_save)
{
ndata -= offset_save;
for (i = 0; i < offset_save; i++)
buf[i] = buf[offset + i];
status = m_pDataReader->GetData(buf + offset_save, &ndata);
}
else
status = m_pDataReader->GetData(buf, &ndata);
if (ndata == 0)
break;
ndata += offset_save;
offset = offset_add;
offset_add = 0;
while(offset < ndata - 3)
{
if (buf[offset] != 0xff || ((buf[offset + 1]) & 0xe0) != 0xe0)
{
offset++;
continue;
}
MP3Header = (buf[offset] << 24) | (buf[offset+1] << 16) | (buf[offset+2] << 8) | buf[offset+3];
layer = MPEGA_HDR_LAYER(MP3Header);
samplingFreq = MPEGA_HDR_SAMPLINGFREQ(MP3Header);
bitRate = MPEGA_HDR_BITRADEINDEX(MP3Header);
emphasis = MPEGA_HDR_EMPH(MP3Header);
id = MPEGA_HDR_VERSION(MP3Header);
mpg25 = ((MP3Header >> 20) & 1) ? 0 : 2;
paddingBit = MPEGA_HDR_PADDING(MP3Header);
if (frame_counter)
{
if ((samplingFreq != samplingFreq_ref) ||
(layer != layer_ref) ||
(id != id_ref) ||
(mpg25 != mpg25_ref) ||
(bitRate == 15) ||
(emphasis == 2) ||
(free_format != (bitRate == 0)))
{
offset++;
continue;
}
if (free_format)
{
offset ++;
if (bitRate)
continue;
frame_counter++;
}
else
{
frame_len = 0;
if (layer == 3)
frame_len = 72000 * (id + 1);
else if (layer == 2)
frame_len = 72000 * 2;
else if (layer == 1)
frame_len = 12000;
frame_len = frame_len * AudioFrameConstructor::MpegABitrate[id][layer - 1][bitRate] /
AudioFrameConstructor::MpegAFrequency[id + mpg25][samplingFreq] + paddingBit;
if (layer == 1)
frame_len *= 4;
frame_counter++;
offset += frame_len;
}
}
else
{
if ((samplingFreq == 3) ||
(layer == 4) ||
(bitRate == 15) ||
#ifdef FREE_FORMAT_PROHIBIT
(bitRate == 0) ||
#endif
(emphasis == 2) ||
(((MP3Header >> 19) & 3) == 1))
{
offset++;
continue;
}
if (bitRate == 0)
{
samplingFreq_ref = samplingFreq;
layer_ref = layer;
id_ref = id;
mpg25_ref = mpg25;
free_format = 1;
frame_counter++;
offset++;
}
else
{
frame_len = 0;
if (layer == 3)
frame_len = 72000 * (id + 1);
else if (layer == 2)
frame_len = 72000 * 2;
else if (layer == 1)
frame_len = 12000;
frame_len = frame_len * AudioFrameConstructor::MpegABitrate[id][layer - 1][bitRate] /
AudioFrameConstructor::MpegAFrequency[id + mpg25][samplingFreq] + paddingBit;
if (layer == 1)
frame_len *= 4;
if (offset + frame_len + 3 >= ndata)
break;
next_header = (buf[offset + frame_len + 0] << 16) |
(buf[offset + frame_len + 1] << 8) |
(buf[offset + frame_len + 2]);
if ((next_header ^ (MP3Header >> 8)) & 0xfffe0c)
{
offset++;
continue;
}
frame_counter++;
offset += frame_len;
samplingFreq_ref = samplingFreq;
layer_ref = layer;
id_ref = id;
mpg25_ref = mpg25;
}
}
if (offset >= ndata)
{
offset_add = offset - ndata;
offset = ndata;
break;
}
}
}
status = m_pDataReader->SetPosition(iPosition);
if (status != UMC::UMC_OK)
return status;
m_dDuration = frame_counter * AudioFrameConstructor::MpegAFramesize[id_ref][layer_ref] /
AudioFrameConstructor::MpegAFrequency[id_ref + mpg25_ref][samplingFreq_ref];
return status;
}
DescriptorNavigator::DescriptorNavigator(Ipp8u *pPtr, Ipp32u uiLen)
{
m_pPtr = pPtr;
m_uiLen = uiLen;
}
Ipp8u *DescriptorNavigator::GetNextDescriptor(Ipp32u *pTag, Ipp32u *pLen)
{
if (m_uiLen < 2)
return NULL;
*pTag = m_pPtr[0];
*pLen = m_pPtr[1];
if (m_uiLen < 2 + *pLen)
return NULL;
Ipp8u *ptr = m_pPtr + 2;
m_pPtr += 2 + *pLen;
m_uiLen -= 2 + *pLen;
return ptr;
}
Ipp32u GetSizeOfInstance(BitstreamReader &bs)
{
Ipp32u size = 0, n = 0;
Ipp8u nextByte;
do {
nextByte = (Ipp8u)bs.CopyBit();
size = (size << 7) | (bs.GetBits(8) & 0x7f);
n++;
} while (nextByte && n < 4);
return size;
}
Status ParseInitialObjectDescriptor(Mpeg2TsPmt &pmt, Ipp8u *pParam, Ipp32s iBufLen)
{
BitstreamReader bs;
bs.Init(pParam);
// check InitialObjectDescriptorTag
if (0x02 != bs.GetBits(8))
return UMC_ERR_FAILED;
Ipp32u uiIodSize = GetSizeOfInstance(bs);
if (bs.Stream() + uiIodSize > pParam + iBufLen)
return UMC_ERR_FAILED;
bs.SkipBits(10); //skip ObjectDescriptorID
if (bs.GetBits(1)) //URL_flag
return UMC_ERR_FAILED;
bs.SkipBits(5); // skip includeInlineProfileLevelFlag and reserved bits
bs.SkipBits(32); // skip OD-, scene-, audio-, visualProfileLevelIndication
bs.SkipBits(8); // graphicsProfileLevelIndication
while (0x03 == bs.GetBits(8))
{
Ipp32u uiEsdSize = GetSizeOfInstance(bs);
Ipp8u *pEsd = bs.Stream();
if (pEsd + uiEsdSize > pParam + iBufLen)
return UMC_ERR_FAILED;
Ipp16u ES_ID = (Ipp16u)bs.GetBits(16);
Ipp32u i;
for (i = 0; i < pmt.uiESs; i++)
{
Ipp8u *ptr;
Ipp32u tag = 0, len;
DescriptorNavigator nav(pmt.pESs[i].pEsInfo, pmt.pESs[i].uiEsInfoLen);
while (NULL != (ptr = nav.GetNextDescriptor(&tag, &len)))
if (DESC_FMC == tag)
break;
if (DESC_FMC == tag && len >= 2 && GET_16U(ptr) == ES_ID)
break;
}
if (i < pmt.uiESs)
{
Ipp32u streamDependenceFlag = bs.GetBit();
Ipp32u URL_Flag = bs.GetBit();
Ipp32u OCRstreamFlag = bs.GetBit();
bs.SkipBits(5); // streamPriority
if (streamDependenceFlag)
bs.SkipBits(16);
if (URL_Flag)
bs.SkipBits(8 * bs.GetBits(8));
if (OCRstreamFlag)
bs.SkipBits(16);
if (0x04 != bs.GetBits(8)) // DecoderConfigDescrTag
return UMC_ERR_FAILED;
/*Ipp32u uiDcdSize =*/ GetSizeOfInstance(bs);
bs.SkipBits(16); // skip objectTypeIndication, streamType, upStream, reserved
bs.SkipBits(24); // skip bufferSizeDB
bs.SkipBits(32); // skip maxBitrate
Ipp32u avgBitrate = bs.GetBits(32);
if (bs.Stream() > pEsd + uiEsdSize)
return UMC_ERR_FAILED;
if (0x05 != bs.GetBits(8)) // DecSpecificInfoTag
return UMC_ERR_FAILED;
Ipp32u uiDsiSize = GetSizeOfInstance(bs);
Ipp8u *pDecSpecificInfo = bs.Stream();
bs.SkipBits(8 * uiDsiSize);
if (0x06 != bs.GetBits(8)) // SLConfigDescriptorTag
return UMC_ERR_FAILED;
pmt.pESs[i].pESDSs = new ESDescriptor;
pmt.pESs[i].pESDSs->uiEsId = ES_ID;
pmt.pESs[i].pESDSs->avgBitrate = avgBitrate;
pmt.pESs[i].pESDSs->uiPredefinedSLConfig = (Ipp8u)bs.GetBits(8);
pmt.pESs[i].pESDSs->uiDecSpecInfoLen = uiDsiSize;
pmt.pESs[i].pESDSs->pDecSpecInfo = pDecSpecificInfo;
}
}
return UMC_OK;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -