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

📄 umc_linear_buffer.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    if (NULL == m_pbFree)
        return UMC_ERR_NOT_INITIALIZED;

    // when no data is given
    if (0 == in->GetDataSize())
        return UMC_OK;

    // get free size
    if (m_pbFree + m_lFreeSize >= m_pbBuffer + m_lBufferSize)
        lFreeSize = m_pbBuffer + m_lBufferSize - m_pbFree;
    else
        lFreeSize = m_lFreeSize;

    // check free size
    if ((lFreeSize < m_lInputSize) ||
        (NULL == m_pFreeSampleInfo))
        return UMC_ERR_NOT_ENOUGH_BUFFER;

    // check used data
    if (in->GetDataSize() > lFreeSize)
        return UMC_ERR_FAILED;

    // get new sample info
    pTemp = m_pFreeSampleInfo;
    m_pFreeSampleInfo = m_pFreeSampleInfo->m_pNext;

    //
    // fill sample info
    //

    // handle data gaps
    if ((m_pSamples) || (in->GetTime() > m_Dummy.m_dTime))
        pTemp->m_dTime = in->GetTime();
    else
        pTemp->m_dTime = m_Dummy.m_dTime;
    pTemp->m_lBufferSize =
    pTemp->m_lDataSize = in->GetDataSize();
    pTemp->m_pNext = NULL;

    // add sample to end of queue
    if (m_pSamples)
    {
        SampleInfo *pWork = m_pSamples;

        while (pWork->m_pNext)
            pWork = pWork->m_pNext;

        pWork->m_pNext = pTemp;
    }
    else
        m_pSamples = pTemp;

    // update variable(s)
    m_pbFree += pTemp->m_lBufferSize;
    if (m_pbBuffer + m_lBufferSize == m_pbFree)
        m_pbFree = m_pbBuffer;
    m_lFreeSize -= pTemp->m_lBufferSize;
    m_lUsedSize += pTemp->m_lBufferSize;
    return UMC_OK;

} // Status LinearBuffer::UnLockInputBuffer(MediaData* in, Status StreamStatus)

Status LinearBuffer::LockOutputBuffer(MediaData* out)
{
    AutomaticMutex guard(m_synchro);
    size_t lUsedSize;

    // check error(s)
    if (NULL == out)
        return UMC_ERR_NULL_PTR;
    if (NULL == m_pbUsed)
        return UMC_ERR_NOT_INITIALIZED;

    // when END OF STREAM
    if (m_bEndOfStream)
    {
        // time to exit
        if ((m_bQuit) || (0 == m_lUsedSize - m_lDummySize))
        {
            // add sample info(s) to list of free sample info(s)
            if (m_pFreeSampleInfo)
            {
                SampleInfo *pTemp = m_pFreeSampleInfo;

                while (pTemp->m_pNext)
                    pTemp = pTemp->m_pNext;

                pTemp->m_pNext = m_pSamples;
                m_pSamples = NULL;
            }
            else
            {
                m_pFreeSampleInfo = m_pSamples;
                m_pSamples = NULL;
            }

            // reset variables
            m_pbFree = m_pbBuffer;
            m_lFreeSize = m_lBufferSize;
            m_pbUsed = m_pbBuffer;
            m_lUsedSize = 0;
            m_lDummySize = 0;

            return UMC_ERR_END_OF_STREAM;
        }
        // set the last "lock output" request
        else
            m_bQuit = true;
    }

    // when used pointer is wrapped around
    if (m_pbBuffer + m_lBufferSize == m_pbUsed)
        m_pbUsed = m_pbBuffer;

    // when used space at end is small (move it to beginning)
    if ((m_pbUsed + m_lUsedSize >= m_pbBuffer + m_lBufferSize) &&
        (m_pbBuffer + m_lBufferSize < m_pbUsed + m_lOutputSize + m_lDummySize))
    {
        size_t lBytesAtEnd;

        lBytesAtEnd = m_pbBuffer + m_lBufferSize - m_pbUsed - m_lDummySize;
        // copy remain byte(s) before the buffer
        memcpy(m_pbBuffer - lBytesAtEnd, m_pbUsed, lBytesAtEnd);
        // update variable(s)
        m_pbUsed = m_pbBuffer - lBytesAtEnd;
        m_lFreeSize += lBytesAtEnd + m_lDummySize;
        m_lUsedSize -= m_lDummySize;
        m_lDummySize = 0;
        // remove dummy bytes from sample info
        {
            SampleInfo *pTemp = m_pSamples;

            while (pTemp)
            {
                if (pTemp->m_lBufferSize != pTemp->m_lDataSize)
                {
                    pTemp->m_lBufferSize = pTemp->m_lDataSize;
                    break;
                }
                pTemp = pTemp->m_pNext;
            }
        }
    }

    // get used size
    if (m_pbUsed >= m_pbBuffer + (m_lBufferSize - m_lUsedSize))
        lUsedSize = m_pbBuffer + m_lBufferSize - m_pbUsed - m_lDummySize;
    else
        lUsedSize = m_lUsedSize;

    // check used size
    if ((lUsedSize < m_lOutputSize) && (false == m_bEndOfStream))
        return UMC_ERR_NOT_ENOUGH_DATA;

    // set used pointer
    out->SetBufferPointer(m_pbUsed, lUsedSize);
    out->SetDataSize(lUsedSize);
    out->SetTime(m_pSamples->m_dTime);
    return UMC_OK;

} // Status LinearBuffer::LockOutputBuffer(MediaData* out)

Status LinearBuffer::UnLockOutputBuffer(MediaData* out)
{
    AutomaticMutex guard(m_synchro);
    size_t lUsedSize, lToSkip;
    SampleInfo *pTemp;
    bool bSingleMemoryPiece = true;

    // check error(s)
    if (NULL == out)
        return UMC_ERR_NULL_PTR;
    if (NULL == m_pbUsed)
        return UMC_ERR_NOT_INITIALIZED;

    // drop the "last lock output" event,
    // because data was used
    if (m_bEndOfStream)
        m_bQuit = false;

    // when 0 bytes to unlock
    if (0 == (out->GetBufferSize() - out->GetDataSize()))
        return UMC_OK;

    // get used size
    if (m_pbUsed >= m_pbBuffer + (m_lBufferSize - m_lUsedSize))
        lUsedSize = m_pbBuffer + m_lBufferSize - m_pbUsed - m_lDummySize;
    else
        lUsedSize = m_lUsedSize;

    // check used size
    if ((lUsedSize < m_lOutputSize) && (false == m_bEndOfStream))
        return UMC_ERR_NOT_ENOUGH_BUFFER;

    // check used data
    lToSkip = out->GetBufferSize() - out->GetDataSize();
    if (lToSkip > lUsedSize)
        return UMC_ERR_FAILED;

    // skip data
    while (lToSkip)
    {
        size_t lFreeSizeInc;

        pTemp = m_pSamples;

        // when skipped data is placed before the buffer
        if (m_pbUsed < m_pbBuffer)
        {
            if (lToSkip < pTemp->m_lDataSize)
                lFreeSizeInc = 0;
            else
                lFreeSizeInc = IPP_MAX(m_pbUsed + pTemp->m_lBufferSize - m_pbBuffer, 0);
        }
        // when skipped data is placed in middle of buffer
        else
        {
            if (lToSkip < pTemp->m_lDataSize)
                lFreeSizeInc = lToSkip;
            else
                lFreeSizeInc = pTemp->m_lBufferSize;
        }

        // when data to skip is smaller then the current data potion
        if (lToSkip < pTemp->m_lDataSize)
        {
            // update timestamp. We keep the timestamp only for the first
            // frame in memory piece.
            if (bSingleMemoryPiece)
                pTemp->m_dTime = -1.0;

            m_pbUsed += lToSkip;
            m_lUsedSize -= lToSkip;
            m_lFreeSize += lFreeSizeInc;
            pTemp->m_lBufferSize -= lToSkip;
            pTemp->m_lDataSize -= lToSkip;

            lToSkip = 0;
        }
        // when data to skip is greater then the current data potion
        else
        {
            if (pTemp->m_lBufferSize != pTemp->m_lDataSize)
                m_lDummySize = 0;

            m_pbUsed += pTemp->m_lBufferSize;
            m_lUsedSize -= pTemp->m_lBufferSize;
            m_lFreeSize += lFreeSizeInc;
            lToSkip -= pTemp->m_lDataSize;

            // update sample queue(s)
            m_pSamples = m_pSamples->m_pNext;
            pTemp->m_pNext = m_pFreeSampleInfo;
            m_pFreeSampleInfo = pTemp;
            pTemp = m_pSamples;

            // we skip several memory pieces
            bSingleMemoryPiece = false;
        }
    }
    return UMC_OK;

} // Status LinearBuffer::UnLockOutputBuffer(MediaData* out)

Status LinearBuffer::Stop(void)
{
    return UMC_OK;

} // Status LinearBuffer::Stop(void)

Status LinearBuffer::Reset(void)
{
    AutomaticMutex guard(m_synchro);

    // reset variables
    m_pbFree = m_pbBuffer;
    m_lFreeSize = m_lBufferSize;
    m_pbUsed = m_pbBuffer;
    m_lUsedSize = 0;

    // move all samples to the free list
    while (m_pSamples)
    {
        SampleInfo *pTemp = m_pSamples;
        m_pSamples = m_pSamples->m_pNext;
        pTemp->m_pNext = m_pFreeSampleInfo;
        m_pFreeSampleInfo = pTemp;
    }

    m_bEndOfStream = false;
    m_bQuit = false;

    return UMC_OK;

} // Status LinearBuffer::Reset(void)

} // namespace UMC

⌨️ 快捷键说明

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