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

📄 umc_demuxer.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    {
        if (rCheckPoint.uiPos >= gap.uiPos)
            rCheckPoint.dTime -= gap.dTime;
        err = m_ListOfGaps.Next(gap);
    }

    if (m_dPrevValidSystemTime < 0.0)
    {
        m_dPrevValidSystemTime = rCheckPoint.dTime;
        return isNewGapDetected;
    }

    // check for negative (even small ones) and positive jumps (only big)
    if (rCheckPoint.dTime < m_dPrevValidSystemTime - 1.0 || rCheckPoint.dTime > m_dPrevValidSystemTime + 10.0)
    { // new gap is found
        vm_debug_trace2(VM_DEBUG_WARNING, VM_STRING("TimeStampCorrector: discontinuity detected at pos=%d, gap=%.3f\n"), (Ipp32s)rCheckPoint.uiPos, rCheckPoint.dTime - m_dPrevValidSystemTime);
        gap.uiPos = rCheckPoint.uiPos;
        gap.dTime = rCheckPoint.dTime - m_dPrevValidSystemTime;
        m_ListOfGaps.Add(gap);
        rCheckPoint.dTime -= gap.dTime;
        isNewGapDetected = true;
    }

    m_dPrevValidSystemTime = rCheckPoint.dTime;
    return isNewGapDetected;
}

Status TimeStampCorrector::GetSystemTimeUpTo(CheckPoint &rCheckPoint, Ipp64u upToPos, bool *pIsGapDetectHere)
{
    if (!m_pParser)
        return UMC_ERR_NOT_INITIALIZED;

    CheckPoint checkPoint;
    Status umcRes = m_pParser->GetSystemTime(checkPoint, upToPos);
    if (UMC_OK != umcRes)
        return umcRes;

    if(CorrectTime(checkPoint) && pIsGapDetectHere)
        pIsGapDetectHere[0] = true;

    rCheckPoint = checkPoint;
    return UMC_OK;
}

Status TimeStampCorrector::GetSystemTime(CheckPoint &rCheckPoint, bool *pIsGapDetectHere)
{
    return GetSystemTimeUpTo(rCheckPoint, (Ipp64u)-1, pIsGapDetectHere);
}

Segmentator::Segmentator(void)
{
    m_pParser = NULL;
    m_pVFC = NULL;
    m_uiTrack = 0;
    m_iSegFrames = 0;
    m_uiSegStart = 0;
    m_uiSegEnd = 0;
    m_uiSegSize = 200000;
    m_bEndOfStream = false;
    m_bLastSegment = false;
    m_bNewSegment = true;
}

void Segmentator::RestartSegmentation(StreamParser *pParser, Ipp32u uiTrack, VideoFrameConstructor *pVFC)
{
    m_pParser = pParser;
    m_uiTrack = uiTrack;
    m_pVFC = pVFC;
    m_iSegFrames = 0;
    m_uiSegEnd = pParser->GetPosition();
    m_uiSegStart = m_uiSegEnd - IPP_MIN(m_uiSegSize, m_uiSegEnd);
    m_bEndOfStream = false;
    m_bLastSegment = false;
    m_bNewSegment = true;
}

void Segmentator::AdditionalJump(Ipp32s iJumpSize)
{
    if (!m_bNewSegment)
        return; // additional jumps are not allowed when current segment is not finished

    if (iJumpSize < (Ipp32s)m_uiSegSize)
        return; // jump is smaller that current segment size

    if ((Ipp64u)iJumpSize >= m_uiSegEnd)
        m_bEndOfStream = true;

    m_uiSegEnd -= IPP_MIN(iJumpSize, m_uiSegEnd);
    m_uiSegStart -= IPP_MIN(iJumpSize, m_uiSegStart);
}

Status Segmentator::PullSegment(SplMediaData *pData)
{
    Status umcRes = UMC_OK;
    Ipp32u curTrack;
    Ipp64u uiCurChunkPos;
    SplMediaData chunk;
    SplMediaData *pChunk;
    bool bEndOfSegment = false;

    // we are at the beginning of the stream, last segment was pulled previously
    if (m_bEndOfStream)
        return UMC_ERR_END_OF_STREAM;

    if (m_bNewSegment)
    {
        // go to start of next segment
        m_pParser->SetPosition(m_uiSegStart);
        m_bNewSegment = false;
    }

    chunk.SetBufferPointer((Ipp8u *)1, 0);

    for (; !bEndOfSegment;)
    {
        // find next packet from video track
        umcRes = CheckPacketFromTrack(&chunk);
        if (UMC_OK != umcRes && UMC_ERR_END_OF_STREAM != umcRes)
            return umcRes;

        // save position of last chunk
        uiCurChunkPos = (UMC_OK == umcRes) ? chunk.GetAbsPos() : m_uiSegEnd;
        if (uiCurChunkPos >= m_uiSegEnd && (!m_pVFC->IsFrameStartFound() || UMC_ERR_END_OF_STREAM == umcRes))
        { // end of segment
            break;
        }

        // order space for chunk in FC's buffer
        umcRes = m_pVFC->LockInputBuffer(&chunk);
        if (UMC_OK != umcRes)
            return umcRes;

        // copy chunk from parser to FC's buffer
        umcRes = m_pParser->GetNextData(&chunk, &curTrack);

        // parse received chunk
        pChunk = &chunk;
        for (; UMC_OK == umcRes;)
        {
            umcRes = m_pVFC->PreUnLockInputBuffer(pChunk);
            pChunk = NULL;
            if (UMC_OK == umcRes)
            {
                m_pVFC->GetLastFrame(pData);
                m_iSegFrames += 1;
                if (1 == m_iSegFrames)
                { // update bottom boundary of segment using position of first sample
                    m_pVFC->GetLastFrame(pData);
                    m_uiSegStart = pData->GetAbsPos();
                }
                if (uiCurChunkPos >= m_uiSegEnd)
                {
                    bEndOfSegment = true;
                    break; // end of segment
                }
            }
        }
    }

    // update segment boundaries
    if (m_iSegFrames > 0 || m_pVFC->IsFrameStartFound())
    { // current segment size is enough
        m_uiSegEnd = m_uiSegStart;
        m_uiSegStart -= IPP_MIN(m_uiSegStart, m_uiSegSize);
    }
    else
    { // current segment size is too small
        m_uiSegStart -= IPP_MIN(m_uiSegStart, m_uiSegSize);
        m_uiSegSize *= 2;
    }

    m_bNewSegment = true;
    if (0 == m_uiSegStart)
    {
        m_bEndOfStream = m_bLastSegment;
        m_bLastSegment = true;
    }

    // at least one frame was found?
    umcRes = m_iSegFrames > 0 ? UMC_OK : UMC_ERR_NOT_ENOUGH_DATA;
    m_iSegFrames = 0;

    // clean up remained bytes
    m_pVFC->GetLastFrame(pData);
    m_pVFC->SoftReset();
    return umcRes;
}

Status Segmentator::CheckPacketFromTrack(SplMediaData *pData)
{
    Ipp32u curTrack;
    for (;;)
    {
        Status umcRes = m_pParser->CheckNextData(pData, &curTrack);
        if (UMC_OK != umcRes || curTrack == m_uiTrack)
            return umcRes;
        if (curTrack != m_uiTrack)
            umcRes = m_pParser->MoveToNextHeader();
    }
}

SystemStreamType DetectSystem(DataReader* pDataReader)
{
    Status umcRes = UMC_OK;
    Ipp8u byteCode;
    Ipp32u longCode;

    if (!pDataReader)
        return UNDEF_STREAM;

    umcRes = pDataReader->Check8u(&byteCode, 0);
    if (UMC_OK != umcRes)
        return UNDEF_STREAM;

    umcRes = pDataReader->Check32u(&longCode, 0);
    if (UMC_OK != umcRes)
        return UNDEF_STREAM;

    if (longCode == 'RIFF') // RIFF
    {
        umcRes = pDataReader->Check32u(&longCode, 8);
        if (UMC_OK != umcRes)
            return UNDEF_STREAM;
        if (longCode == 'AVI ')
            return AVI_STREAM;
        else
            return WAVE_STREAM;
    }

    //search some MPEG2 PS start code, it can start from bunch of zeros before
    if (0 == longCode)
    {
        Ipp32s offset = 1;
        while (0 == longCode)
        {
            umcRes = pDataReader->Check32u(&longCode, offset);
            if (UMC_OK != umcRes)
                return UNDEF_STREAM;
            offset++;
        }

        umcRes = pDataReader->Check32u(&longCode, offset);
        if (UMC_OK != umcRes)
            return UNDEF_STREAM;

        if ((longCode & 0x0000fff0) == 0x0000fff0)
            return MPEGx_PURE_AUDIO_STREAM;
    }

    if (ID_TS_SYNC == byteCode) //check if transport stream, 0x47 is sync byte for it
        return MPEG2_TRANSPORT_STREAM;
    else if ((0x100 | ID_PS_PACK) == longCode || 0x000001BC == (longCode & 0xFFFFFFFC)) //check if program stream
        return MPEG2_PROGRAMM_STREAM;
    else if ((longCode >= 0x000001C0) && (longCode <= 0x000001DF))  //check if PES audio stream,
        return MPEG2_PES_PACKETS_STREAM;
    else if ((longCode >= 0x000001E0) && (longCode <= 0x000001EF))  //check if PES video stream,
        return MPEG2_PES_PACKETS_STREAM;
    else if (SC_MPEG2_SEQ == longCode) //check if MPEG2 Sequence or Picture start code
        return MPEG2_PURE_VIDEO_STREAM;
    else if (SC_MPEG2_PIC == (longCode & (~0xff))) //check if MPEG2 Sequence or Picture start code
    {
        if (7 == (longCode & 0x1f))
            return H264_PURE_VIDEO_STREAM;

        // create MPEG4FC to assure that stream is actually mpeg4 video
        Ipp32u uiSize = 32 * 1024;
        Mpeg4FrameConstructor fc;
        FrameConstructorParams fcPar;
        fcPar.m_lBufferSize = uiSize;
        fcPar.m_nOfFrames = 1;
        umcRes = fc.Init(&fcPar);
        if (UMC_OK != umcRes)
            return UNDEF_STREAM;

        // get buffer
        MediaData data;
        data.SetBufferPointer((Ipp8u *)1, uiSize);
        data.SetDataSize(uiSize);
        umcRes = fc.LockInputBuffer(&data);
        if (UMC_OK != umcRes)
            return UNDEF_STREAM;

        // read data to buffer
        umcRes = pDataReader->CheckData(data.GetDataPointer(), &uiSize, 0);
        if (UMC_ERR_END_OF_STREAM == umcRes && uiSize > 0)
            umcRes = UMC_OK;
        if (UMC_OK != umcRes)
            return UNDEF_STREAM;

        data.SetDataSize(uiSize);
        fc.UnLockInputBuffer(&data);
        if (TRACK_MPEG4V == fc.GetInfo()->m_Type)
            return MPEG4_PURE_VIDEO_STREAM;
    }
    else if ((longCode & 0xfffffc00) == 0x00008000) //check if H.263 pure video
        return H263_PURE_VIDEO_STREAM;
    else if ((longCode & 0xfffff000) == 0x00010000) //check if H.261 pure video
        return H261_PURE_VIDEO_STREAM;
    else if ((longCode & 0x1f) == 7 || (longCode == 0x00000001)) //check if H.264 pure video
        return H264_PURE_VIDEO_STREAM;
    else if ((longCode & 0xffe00000) == 0xffe00000 || (longCode & 0xffffff00) == 0x49443300 || (longCode == 0))
    {
        //skip ID3 header
        if ((longCode & 0xffffff00) == 0x49443300)
        {
            Ipp8u byte;
            Ipp32s id3size = 0;
            pDataReader->Get8u(&byte); // 'I'
            pDataReader->Get8u(&byte); // 'D'
            pDataReader->Get8u(&byte); // '3'
            pDataReader->Get8u(&byte); // major version != 0xFF
            pDataReader->Get8u(&byte); // revision number != 0xFF
            pDataReader->Get8u(&byte); // flags (only 3 first bits are used)
            pDataReader->Get8u(&byte); // 21...27 bits of size < 0x80
            id3size |= byte << 21;
            pDataReader->Get8u(&byte); // 14...20 bits of size < 0x80
            id3size |= byte << 14;
            pDataReader->Get8u(&byte); // 07...13 bits of size < 0x80
            id3size |= byte << 7;
            pDataReader->Get8u(&byte); // 00...06 bits of size < 0x80
            id3size |= byte;
            pDataReader->MovePosition(id3size);
        }

        return MPEGx_PURE_AUDIO_STREAM;
    }
    else if ((longCode >> 16) == SC_AC3) //check if AC3 audio stream
        return MPEGx_PURE_AUDIO_STREAM;

    umcRes = pDataReader->Check8u(&byteCode,4);
    if (UMC_OK != umcRes)
        return UNDEF_STREAM;

    if (0x47 == byteCode)
    {
        umcRes = pDataReader->Check8u(&byteCode,196);
        if (UMC_OK != umcRes)
            return UNDEF_STREAM;
        if (0x47 == byteCode)
            return MPEG2_TRANSPORT_STREAM_TTS;
    }

    // look over 3kb for MPEG2 system stream start codes
    Ipp32s i;
    for (i = 0; i < 3 * 1024; i++)
    {
        umcRes = pDataReader->Check32u(&longCode, i);
        if (UMC_OK != umcRes)
            return UNDEF_STREAM;
        if ((0x100 | ID_PS_PACK) == longCode || 0x000001BC == (longCode & 0xFFFFFFFC))
            return MPEG2_PROGRAMM_STREAM;

        umcRes = pDataReader->Check8u(&byteCode, i);
        if (UMC_OK != umcRes)
            return UNDEF_STREAM;

        if (ID_TS_SYNC == byteCode)
        {
            umcRes = pDataReader->Check8u(&byteCode, i + 188);
            if (UMC_OK != umcRes)
                return UNDEF_STREAM;

            if (ID_TS_SYNC == byteCode)
            {
                umcRes = pDataReader->Check8u(&byteCode, i + 2 * 188);
                if (UMC_OK != umcRes)
                    return UNDEF_STREAM;
                if (ID_TS_SYNC == byteCode)
                    return MPEG2_TRANSPORT_STREAM;
            }

            umcRes = pDataReader->Check8u(&byteCode, i + 192);
            if (UMC_OK != umcRes)
                return UNDEF_STREAM;

            if (ID_TS_SYNC == byteCode)
            {
                umcRes = pDataReader->Check8u(&byteCode, i + 2 * 192);
                if (UMC_OK != umcRes)
                    return UNDEF_STREAM;

                if (ID_TS_SYNC == byteCode)
                    return MPEG2_TRANSPORT_STREAM_TTS;
            }
        }
    }

    return UNDEF_STREAM;
}

} //namespace UMC

⌨️ 快捷键说明

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