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

📄 umc_stream_parser.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*//////////////////////////////////////////////////////////////////////////////
//
//                  INTEL CORPORATION PROPRIETARY INFORMATION
//     This software is supplied under the terms of a license agreement or
//     nondisclosure agreement with Intel Corporation and may not be copied
//     or disclosed except in accordance with the terms of that agreement.
//          Copyright(c) 2005-2007 Intel Corporation. All Rights Reserved.
//
*/

#include <ipps.h>
#include "umc_stream_parser.h"
#include "umc_frame_constructor.h"

#define PARSER_CHECK_INIT CHECK_OBJ_INIT(m_pDataReader)

namespace UMC
{

StreamParserParams::StreamParserParams(void)
{
    m_SystemType = UNDEF_STREAM;
    m_pDataReader = NULL;
}

StreamParserParams::~StreamParserParams()
{
}

StreamParser::StreamParser()
{
    m_pDataReader = NULL;
    m_pPacket = NULL;
}

StreamParser::~StreamParser()
{
    Close();
}

Status StreamParser::Init(StreamParserParams &init)
{
    if (m_pDataReader) // already initialized
        return UMC_ERR_FAILED;

    if (!init.m_pDataReader)
        return UMC_ERR_NULL_PTR;

    ippsZero_8u((Ipp8u *)m_pInfo, MAX_TRACK * sizeof(void *));
    m_ParserState = HEADER;
    m_dDuration = -1.0;
    m_uiTracks = 0;

    m_SystemType = init.m_SystemType;
    m_pDataReader = init.m_pDataReader;
    m_uiSourceSize = init.m_pDataReader->GetSize();

    if (!m_pPacket) m_pPacket = new Packet;
    return UMC_OK;
}

Status StreamParser::Close(void)
{
    PARSER_CHECK_INIT;
    Ipp32s i;
    for (i = 0; i < (Ipp32s)m_uiTracks; i++)
    {
        if (m_pInfo[i])
        {
            m_pInfo[i]->ReleaseAll();
            delete m_pInfo[i];
            m_pInfo[i] = NULL;
        }
    }
    if (m_pPacket)
    {
        delete m_pPacket;
        m_pPacket = NULL;
    }
    m_pDataReader = NULL;
    return UMC_OK;
}

Status StreamParser::CheckNextData(MediaData *pData, Ipp32u* pTrack)
{
    PARSER_CHECK_INIT;
    if (!pData || !pTrack)
        return UMC_ERR_NULL_PTR;

    if (0 == m_uiTracks)
    {
        m_uiTracks = 1;
        if (!m_pInfo[0])
            m_pInfo[0] = new Mpeg2TrackInfo;

        switch (m_SystemType)
        {
        case MPEG1_PURE_VIDEO_STREAM:
            m_pInfo[0]->m_Type = TRACK_MPEG1V; break;
        case MPEG2_PURE_VIDEO_STREAM:
            m_pInfo[0]->m_Type = TRACK_MPEG2V; break;
        case MPEG4_PURE_VIDEO_STREAM:
            m_pInfo[0]->m_Type = TRACK_MPEG4V; break;
        case H261_PURE_VIDEO_STREAM:
            m_pInfo[0]->m_Type = TRACK_H261; break;
        case H263_PURE_VIDEO_STREAM:
            m_pInfo[0]->m_Type = TRACK_H263; break;
        case H264_PURE_VIDEO_STREAM:
            m_pInfo[0]->m_Type = TRACK_H264; break;
        case MPEG1_PURE_AUDIO_STREAM:
        case MPEG2_PURE_AUDIO_STREAM:
        case MPEGx_PURE_AUDIO_STREAM:
            m_pInfo[0]->m_Type = TRACK_MPEGA; break;
        default:
            m_pInfo[0]->m_Type = TRACK_UNKNOWN; break;
        }

        Status err = m_pInfo[0]->Alloc();
        if (UMC_OK != err)
            return err;

        if (m_pInfo[0]->m_Type & TRACK_ANY_AUDIO)
        {
            if (m_dDuration < 0.0 && (m_pInfo[0]->m_Type & TRACK_MPEGA))
                EstimateMPEGAudioDuration();
            ((AudioStreamInfo *)m_pInfo[0]->m_pStreamInfo)->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 StreamParser::GetNextData(MediaData *pData, Ipp32u *pTrack)
{
    PARSER_CHECK_INIT;
    if (END_OF_STREAM == m_ParserState)
        return UMC_ERR_END_OF_STREAM;
    if (!pData || !pData->GetDataPointer() || !pTrack)
        return UMC_ERR_NULL_PTR;

    Status umcRes = UMC_OK;
    if (HEADER == m_ParserState)
    {
        umcRes = CheckNextData(pData, pTrack);
        if (UMC_OK != umcRes)
            return umcRes;
    }

    if (m_pPacket->uiSize > pData->GetBufferSize())
        return UMC_ERR_NOT_ENOUGH_BUFFER;

    // move to the beginning of payload
    umcRes = m_pDataReader->MovePosition((Ipp64u)m_pPacket->iBufOffset);
    if (UMC_ERR_END_OF_STREAM == umcRes)
    {
        m_ParserState = END_OF_STREAM;
        return umcRes;
    }

    umcRes = m_pDataReader->GetData(pData->GetDataPointer(), &m_pPacket->uiSize);
    if (UMC_ERR_END_OF_STREAM == umcRes)
    {
        m_ParserState = END_OF_STREAM;
        if (0 == m_pPacket->uiSize)
            return umcRes;
        umcRes = UMC_OK;
    }

    *pTrack = GetTrackByPidOrCreateNew(m_pPacket->iPid, NULL);
#ifdef _BIG_ENDIAN_
    if (*pTrack >= 0 && TRACK_PCM == m_pInfo[*pTrack]->m_Type)
        ippsSwapBytes_16u_I((Ipp16u *)pData->GetDataPointer(), m_pPacket->uiSize / 2);
#else
    if (*pTrack >= 0 && TRACK_LPCM == m_pInfo[*pTrack]->m_Type)
        ippsSwapBytes_16u_I((Ipp16u *)pData->GetDataPointer(), m_pPacket->uiSize / 2);
#endif // _BIG_ENDIAN_

    m_ParserState = HEADER;
    PacketToMediaData(*m_pPacket, *pData);
    return umcRes;
}

Ipp32u StreamParser::GetNumberOfTracks(void)
{
    return m_pDataReader ? m_uiTracks : 0;
}

Mpeg2TrackInfo *StreamParser::GetTrackInfo(Ipp32u uiTrack)
{
    return m_pDataReader && uiTrack < m_uiTracks ? m_pInfo[uiTrack] : NULL;
}

SystemStreamType StreamParser::GetSystemStreamType(void)
{
    return m_pDataReader ? m_SystemType : UNDEF_STREAM;
}

void StreamParser::Reset(void)
{
    m_ParserState = HEADER;
    if (m_pPacket) m_pPacket->Reset();
}

Status StreamParser::SetPosition(Ipp64u bytePos)
{
    PARSER_CHECK_INIT;
    Reset();
    return m_uiSourceSize ? m_pDataReader->SetPosition(IPP_MIN(bytePos, m_uiSourceSize)) : UMC_OK;
}

Ipp64u StreamParser::GetPosition(void)
{
    return m_pDataReader ? m_pDataReader->GetPosition() : 0;
}

Ipp64u StreamParser::GetSize(void)
{
    return m_pDataReader ? m_uiSourceSize : 0;
}

Status StreamParser::MoveToNextHeader()
{
    PARSER_CHECK_INIT;
    if (END_OF_STREAM == m_ParserState)
        return UMC_ERR_END_OF_STREAM;
    else if (HEADER == m_ParserState)
        return UMC_OK;
    Status umcRes = m_pDataReader->MovePosition(m_pPacket->iBufOffset + m_pPacket->uiSize);
    Reset();
    return umcRes;
}

Ipp64f StreamParser::GetDuration(void)
{
    return m_pDataReader ? m_dDuration : -1.0;
}

Ipp32s StreamParser::GetTrackByPid(Ipp32u uiPid)
{
    return GetTrackByPidOrCreateNew((Ipp32s)uiPid, NULL);
}

Ipp32s StreamParser::GetTrackByPidOrCreateNew(Ipp32s iPid, bool *pIsNew)
{
    Ipp32u i;
    for (i = 0; i < m_uiTracks; i++)
        if (m_pInfo[i]->m_PID == (Ipp32u)iPid)
            break;

    if (i < m_uiTracks)
        return (Ipp32s)i;
    else if (!pIsNew || m_uiTracks >= MAX_TRACK)
        return -1;

    *pIsNew = true;
    m_uiTracks;
    if (!m_pInfo[m_uiTracks])
        m_pInfo[m_uiTracks] = new Mpeg2TrackInfo;
    m_pInfo[m_uiTracks]->m_PID = iPid;
    m_uiTracks++;
    return m_uiTracks - 1;
}

void StreamParser::PacketToMediaData(FCSample &packet, MediaData &data)
{
    if (NULL == data.GetBufferPointer())
    {
        data.SetBufferPointer((Ipp8u *)1, packet.uiSize);
        data.SetDataSize(packet.uiSize);
    }
    else
    {
        data.SetBufferPointer((Ipp8u *)data.GetBufferPointer(), packet.uiSize);
        data.SetDataSize(packet.uiSize);
    }

    data.SetTime(packet.dPTS, packet.dDTS);
    if (DynamicCast<SplMediaData>(&data))
        ((SplMediaData *)&data)->SetAbsPos(packet.uiAbsPos);
}

Status ParseInitialObjectDescriptor(Mpeg2TsPmt &pmt, Ipp8u *pParam, Ipp32s buflen);
Status Mpeg2PesParser::ParsePmtInfo(Mpeg2TsPmt &pmt)
{
    Ipp8u *pPtr = NULL;
    Ipp32u uiTag, uiLen;
    if (pmt.pProgInfo && pmt.uiProgInfoLen)
    {
        DescriptorNavigator descrNav(pmt.pProgInfo, pmt.uiProgInfoLen);
        while (NULL != (pPtr = descrNav.GetNextDescriptor(&uiTag, &uiLen)))
        {
            if (DESC_IOD == uiTag && uiLen > 2)
                ParseInitialObjectDescriptor(pmt, pPtr + 2, uiLen - 2);
        }
    }

    Ipp32u i;
    for (i = 0; i < pmt.uiESs; i++)
    {
        bool bIsNew = false;
        Ipp32s iTrack = GetTrackByPidOrCreateNew(pmt.pESs[i].uiPid, &bIsNew);
        if (iTrack < 0 || !bIsNew)
            continue;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -