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

📄 umc_frame_constructor.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                if (!m_bEndOfStream)
                    return UMC_ERR_NOT_ENOUGH_DATA;

                ippsZero_8u(&m_pBuf[m_lLastBytePos], 4);
                m_lLastBytePos += 4;
                m_lCurPos = m_lLastBytePos;
            }

            // Frame found, check type and playback rate
            if (IsSampleComplyWithTmPolicy(m_CurFrame, m_dRate))
            {
                m_CurFrame.uiSize = m_lCurPos - m_CurFrame.iBufOffset;
                m_CurFrame.CopyTo(frame[0], m_pBuf);
                // prepare for next frame
                m_CurFrame.dPTS = m_CurFrame.dDTS = -1.0;
                m_CurFrame.iBufOffset = m_lCurPos;
                bFound = true;
            }
            else
            {
                CutInterval(m_PrevSample, m_LastSample, m_pBuf, m_CurFrame.iBufOffset, m_lCurPos, m_lLastBytePos);
                m_lLastBytePos -= m_lCurPos - m_CurFrame.iBufOffset;
                m_lCurPos = m_CurFrame.iBufOffset;

                m_CurFrame.dPTS = m_CurFrame.dDTS = -1.0;
                m_CurFrame.iBufOffset = m_lCurPos;
            }

            // start finding next frame
            m_bFrameBegFound = false;
            m_bPicSCFound = false;
        }
    }

    return UMC_OK;
}

Status Mpeg4FrameConstructor::GetFrame(SplMediaData *frame)
{
    Status umcRes;
    Ipp8u *buf = m_pBuf;
    bool bFrameFound = false;

    // initialization loop
    while (!m_bSeqSCFound)
    {
        while (m_lCurPos < m_lLastBytePos - 3 && !IS_CODE_INT(&buf[m_lCurPos], 0x00, 0x2F) && !IS_CODE(&buf[m_lCurPos], 0xb0))
            m_lCurPos++;
        if (m_lCurPos >= m_lLastBytePos - 3)
            return m_bEndOfStream ? UMC_ERR_END_OF_STREAM : UMC_ERR_SYNC;

        m_CurFrame.iBufOffset = m_lCurPos;
        AssignAbsPos(m_CurFrame.iBufOffset);

        Ipp32s offset = 0;
        while (m_lCurPos + offset < m_lLastBytePos - 3 && !IS_CODE(&m_pBuf[m_lCurPos + offset], 0xb6))
            offset++;
        if (m_lCurPos + offset >= m_lLastBytePos - 5)
            return m_bEndOfStream ? UMC_ERR_END_OF_STREAM : UMC_ERR_NOT_ENOUGH_DATA;

        umcRes = ParseVideoObjectLayer(&m_pBuf[m_lCurPos], -1, m_bInfoFilled ? NULL : m_pInfo);
        if (UMC_OK == umcRes)
        {
            m_bInfoFilled = true;
            m_bSeqSCFound = true;
            m_CurFrame.SetFrameType((buf[m_lCurPos + offset + 4] >> 6) + 1);
            AssignTimeStamps(m_lCurPos + offset);
            m_lCurPos += offset + 4;
        }
        else
        {
            m_lCurPos++;
        }
    }

    while (!bFrameFound)
    {
        while ((m_lCurPos < m_lLastBytePos - 3) && !IS_CODE(&buf[m_lCurPos + 0], 0xb6))
            m_lCurPos++;

        if (m_lCurPos >= m_lLastBytePos - 4)
        {
            if (!m_bEndOfStream)
                return UMC_ERR_NOT_ENOUGH_DATA;
            if (m_lCurPos >= m_lLastBytePos)
                return UMC_ERR_END_OF_STREAM;
            m_lCurPos = m_lLastBytePos;
        }

        //frame found, check type and playback rate
        if (IsSampleComplyWithTmPolicy(m_CurFrame, m_dRate))
        {
            m_CurFrame.uiSize = m_lCurPos - m_CurFrame.iBufOffset;
            m_CurFrame.CopyTo(frame[0], m_pBuf);
            bFrameFound = true;
        }

        m_CurFrame.iBufOffset = m_lCurPos;
        m_CurFrame.SetFrameType((buf[m_lCurPos + 4] >> 6) + 1);
        AssignTimeStamps(m_CurFrame.iBufOffset);
        AssignAbsPos(m_CurFrame.iBufOffset);
        m_lCurPos += 4;
    }

    return UMC_OK;
}

Status H261FrameConstructor::GetFrame(SplMediaData *frame)
{
    Status umcRes;
    Ipp8u *buf = m_pBuf;
    bool bFrameFound = false;

    while (!m_bSeqSCFound)
    {
        while ((m_lCurPos < m_lLastBytePos - 2) &&
                (buf[m_lCurPos + 0] != 0 ||
                 buf[m_lCurPos + 1] != 1 ||
                (buf[m_lCurPos + 2] & 0xf0) != 0))
            m_lCurPos++;

        umcRes = ParseHeader(&m_pBuf[m_lCurPos], m_lLastBytePos - m_lCurPos, m_bInfoFilled ? NULL : m_pInfo);
        if (UMC_ERR_INVALID_STREAM == umcRes)
        {
            m_lCurPos += 1;
            continue;
        }
        else if (UMC_ERR_NOT_ENOUGH_DATA == umcRes)
            return m_bEndOfStream ? UMC_ERR_END_OF_STREAM : UMC_ERR_SYNC;

        m_bSeqSCFound = true;
        m_CurFrame.iBufOffset = m_lCurPos;
        m_CurFrame.SetFrameType(NONE_PICTURE);
        AssignTimeStamps(m_CurFrame.iBufOffset);
        AssignAbsPos(m_CurFrame.iBufOffset);
        m_lCurPos += 3;
    }

    while (!bFrameFound)
    {
        while ((m_lCurPos < m_lLastBytePos - 2) &&
                (buf[m_lCurPos + 0] != 0 ||
                 buf[m_lCurPos + 1] != 1 ||
                (buf[m_lCurPos + 2] & 0xf0) != 0))
            m_lCurPos++;

        if (m_lCurPos + 3 >= m_lLastBytePos)
        {
            if (!m_bEndOfStream)
                return UMC_ERR_NOT_ENOUGH_DATA;
            if (m_lCurPos >= m_lLastBytePos)
                return UMC_ERR_END_OF_STREAM;
            m_lCurPos = m_lLastBytePos;
        }

        // found frame
        m_CurFrame.uiSize = m_lCurPos - m_CurFrame.iBufOffset;
        m_CurFrame.CopyTo(frame[0], m_pBuf);
        bFrameFound = true;

        // next frame
        m_CurFrame.iBufOffset = m_lCurPos;
        m_CurFrame.SetFrameType(NONE_PICTURE);
        AssignTimeStamps(m_CurFrame.iBufOffset);
        AssignAbsPos(m_CurFrame.iBufOffset);
        m_lCurPos += 3;
    }

    return UMC_OK;
}

Status H263FrameConstructor::GetFrame(SplMediaData *frame)
{
    Status umcRes;
    Ipp8u *buf = m_pBuf;
    bool bFrameFound = false;

    while (!m_bSeqSCFound)
    {
        while ((m_lCurPos < m_lLastBytePos - 2) &&
                (buf[m_lCurPos + 0] != 0 ||
                 buf[m_lCurPos + 1] != 0 ||
                (buf[m_lCurPos + 2] & 0xfc) != 0x80))
            m_lCurPos++;

        umcRes = ParseHeader(&m_pBuf[m_lCurPos], m_lLastBytePos - m_lCurPos, m_bInfoFilled ? NULL : m_pInfo);
        if (UMC_ERR_INVALID_STREAM == umcRes)
        {
            m_lCurPos += 1;
            continue;
        }
        else if (UMC_ERR_NOT_ENOUGH_DATA == umcRes)
            return m_bEndOfStream ? UMC_ERR_END_OF_STREAM : UMC_ERR_SYNC;

        m_bSeqSCFound = true;
        m_CurFrame.iBufOffset = m_lCurPos;
        m_CurFrame.SetFrameType(NONE_PICTURE);
        AssignTimeStamps(m_CurFrame.iBufOffset);
        AssignAbsPos(m_CurFrame.iBufOffset);
        m_lCurPos += 3;
    }

    while (!bFrameFound)
    {
        while ((m_lCurPos < m_lLastBytePos - 2) &&
                (buf[m_lCurPos + 0] != 0 ||
                 buf[m_lCurPos + 1] != 0 ||
                (buf[m_lCurPos + 2] & 0xfc) != 0x80))
            m_lCurPos++;

        if (m_lCurPos + 3 >= m_lLastBytePos)
        {
            if (!m_bEndOfStream)
                return UMC_ERR_NOT_ENOUGH_DATA;
            if (m_lCurPos >= m_lLastBytePos)
                return UMC_ERR_END_OF_STREAM;
            m_lCurPos = m_lLastBytePos;
        }

        // found frame
        m_CurFrame.uiSize = m_lCurPos - m_CurFrame.iBufOffset;
        m_CurFrame.CopyTo(frame[0], m_pBuf);
        bFrameFound = true;

        // next frame
        m_CurFrame.iBufOffset = m_lCurPos;
        m_CurFrame.SetFrameType(NONE_PICTURE);
        AssignTimeStamps(m_CurFrame.iBufOffset);
        AssignAbsPos(m_CurFrame.iBufOffset);
        m_lCurPos += 3;
    }

    return UMC_OK;
}

Status H264FrameConstructor::Init(MediaReceiverParams *pInit)
{
    m_h264Headers.bOneOfNALRefIdcEqualTo0 = false;
    m_h264Headers.bOneOfNALUnitTypeEqualTo5 = false;
    m_h264Headers.iShCount = 0;
    m_bFirstVLCNALUnitDetected = false;
    m_bIsCorrupted = false;
    return VideoFrameConstructor::Init(pInit);
}

Status H264FrameConstructor::Reset(void)
{
    m_bSeqSCFound = false;
    m_bFirstVLCNALUnitDetected = false;
    m_h264Headers.bOneOfNALRefIdcEqualTo0 = false;
    m_h264Headers.bOneOfNALUnitTypeEqualTo5 = false;
    m_h264Headers.iShCount = 0;
    m_bIsCorrupted = false;
    return VideoFrameConstructor::Reset();
}

Status H264FrameConstructor::SoftReset(void)
{
    m_bSeqSCFound = false;
    m_bFirstVLCNALUnitDetected = false;
    m_h264Headers.bOneOfNALRefIdcEqualTo0 = false;
    m_h264Headers.bOneOfNALUnitTypeEqualTo5 = false;
    m_h264Headers.iShCount = 0;
    m_bIsCorrupted = false;
    return VideoFrameConstructor::SoftReset();
}

Status H264FrameConstructor::GetFrame(SplMediaData *frame)
{
    Ipp8u *buf = m_pBuf;
    bool bAccessUnitDetected = false;
    Ipp8u uiNALUnitType = 0;
    Ipp8u uiNALRefIdc = 0;
    Ipp32s iNOfZeroes = 0;
    FrameType curSliceType = NONE_PICTURE;

    while (!bAccessUnitDetected)
    {
        // this loop finds next NAL unit
        iNOfZeroes = 0;
        for (; m_lCurPos + 3 < m_lLastBytePos; m_lCurPos++)
        {
            if (0 == buf[m_lCurPos] && 0 == buf[m_lCurPos + 1])
            { // two zeroes found
                // skip and count other zeroes
                for (iNOfZeroes = 2; m_lCurPos + iNOfZeroes + 1 < m_lLastBytePos; iNOfZeroes++)
                    if (0 != buf[m_lCurPos + iNOfZeroes])
                        break;

                // 'one' follows more than two 'zero' is the NAL unit start code
                if (m_lCurPos + iNOfZeroes + 1 < m_lLastBytePos && 1 == buf[m_lCurPos + iNOfZeroes])
                    break;

                iNOfZeroes = 0;
            }
        }

        if (iNOfZeroes > 3)
        {
            m_lCurPos += iNOfZeroes - 3;
            iNOfZeroes -= iNOfZeroes - 3;
        }

        if (iNOfZeroes < 2)
        { // no NAL unit was found
            if (!m_bSeqSCFound && 0 == m_uiTotalFrames)
            {
                m_CurFrame.iBufOffset = m_lFirstBytePos = m_lCurPos;
            }

            if (!m_bEndOfStream) // just not enough data
                return UMC_ERR_NOT_ENOUGH_DATA;
            else if (m_bIsFinalizeSequenceSent) // EOS received and last frame returned
                return UMC_ERR_END_OF_STREAM;

            // add 4 bytes to the end of last frame
            ippsZero_8u(&m_pBuf[m_lLastBytePos], 4);
            m_lLastBytePos += 4;
            m_lCurPos = m_lLastBytePos;
            uiNALUnitType = 0;
            bAccessUnitDetected = true;
            m_bIsFinalizeSequenceSent = true;
        }
        else
        {
            uiNALRefIdc = (buf[m_lCurPos + iNOfZeroes + 1] >> 5) & 0x03;
            uiNALUnitType = buf[m_lCurPos + iNOfZeroes + 1] & 0x1f;
        }

        if (NALU_SPS == uiNALUnitType)
        {
            Ipp32s iSPSsize;
            for (iSPSsize = iNOfZeroes; m_lCurPos + iSPSsize + 2 < m_lLastBytePos; iSPSsize++)
                if (buf[m_lCurPos + iSPSsize + 0] == 0 &&
                    buf[m_lCurPos + iSPSsize + 1] == 0 &&
                    buf[m_lCurPos + iSPSsize + 2] == 1)
                    break;

            if (m_lCurPos + iSPSsize + 2 >= m_lLastBytePos)
                return m_bEndOfStream ? UMC_ERR_END_OF_STREAM : UMC_ERR_NOT_ENOUGH_DATA;

            ParseSequenceParameterSet(&m_pBuf[m_lCurPos], -1, &m_h264Headers, m_bInfoFilled ? NULL : m_pInfo);
            if (!m_bSeqSCFound)
            {
                m_CurFrame.iBufOffset = m_lCurPos;
                AssignAbsPos(m_CurFrame.iBufOffset);
            }

            if (m_bFirstVLCNALUnitDetected)
            { // SPS unit is from next AU, current AU is completed
                bAccessUnitDetected = true;
                m_bFirstVLCNALUnitDetected = false;
                if (MAX_NUM_PPS_PARSETS == m_h264Headers.m_PrevSH.pic_parameter_set_id)
                    m_bIsCorrupted = true;
            }

            m_bSeqSCFound = true;

        }
        else if (m_bSeqSCFound)
        {
            if (NALU_PPS == uiNALUnitType)
            {
                if (m_lCurPos + 3 + 16 >= m_lLastBytePos)
                    return m_bEndOfStream ? UMC_ERR_END_OF_STREAM : UMC_ERR_NOT_ENOUGH_DATA;

                ParsePictureParameterSet(&m_pBuf[m_lCurPos], -1, &m_h264Headers);
                m_bPicSCFound = true;

                if (m_bFirstVLCNALUnitDetected)
                { // PPS unit is from next AU, current AU is completed
                    bAccessUnitDetected = true;
                    m_bFirstVLCNALUnitDetected = false;
                    if (MAX_NUM_PPS_PARSETS == m_h264Headers.m_PrevSH.pic_parameter_set_id)
                        m_bIsCorrupted = true;
                }

            }
            else if (NALU_SEI == uiNALUnitType)
            {
                if (m_bFirstVLCNALUnitDetected)
                { // SEI unit is from next A

⌨️ 快捷键说明

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