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

📄 umc_stream_parser.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 3 页
字号:
        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 + -