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

📄 umc_linear_buffer.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*
//
//              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) 2003-2007 Intel Corporation. All Rights Reserved.
//
//
*/

#include "umc_linear_buffer.h"
#include "umc_automatic_mutex.h"

namespace UMC
{

enum
{
    ALIGN_VALUE                 = 128
};

MediaBuffer *CreateLinearBuffer(void)
{
    return new LinearBuffer();

} // MediaBuffer *CreateLinearBuffer(void)

LinearBuffer::LinearBuffer(void)
{
    // reset variables
    m_pbAllocatedBuffer = NULL;
    m_midAllocatedBuffer = MID_INVALID;
    m_lAllocatedBufferSize = 0;
    m_pbBuffer = NULL;
    m_lBufferSize = 0;
    m_pbFree = NULL;
    m_lFreeSize = 0;
    m_pbUsed = NULL;
    m_lUsedSize = 0;
    m_lDummySize = 0;
    m_pSamples = NULL;
    m_pFreeSampleInfo = NULL;

    m_bEndOfStream = false;
    m_bQuit = false;

    // reset mutex
    vm_mutex_set_invalid(&m_synchro);

    // reset time of dummy sample
    memset(&m_Dummy, 0, sizeof(m_Dummy));
    m_Dummy.m_dTime = -1.0;

} // LinearBuffer::LinearBuffer(void)

LinearBuffer::~LinearBuffer(void)
{
    Close();

    // destroy mutex
    if (1 == vm_mutex_is_valid(&m_synchro))
        vm_mutex_destroy(&m_synchro);

} // LinearBuffer::~LinearBuffer(void)

Status LinearBuffer::Close(void)
{
    // stop all waiting(s)
    // actually, this method does nothing
    Stop();

    // delete buffer
    if (m_pbAllocatedBuffer)
        m_pMemoryAllocator->Unlock(m_midAllocatedBuffer);
    if (MID_INVALID != m_midAllocatedBuffer)
        m_pMemoryAllocator->Free(m_midAllocatedBuffer);
    m_midAllocatedBuffer = MID_INVALID;

    // delete sample list
    while (m_pSamples)
    {
        SampleInfo *pTemp = m_pSamples;
        m_pSamples = m_pSamples->m_pNext;
        delete pTemp;
    }

    // delete free sample list
    while (m_pFreeSampleInfo)
    {
        SampleInfo *pTemp = m_pFreeSampleInfo;
        m_pFreeSampleInfo = m_pFreeSampleInfo->m_pNext;
        delete pTemp;
    }

    // reset variables
    m_pbAllocatedBuffer = NULL;
    m_lAllocatedBufferSize = 0;
    m_pbBuffer = NULL;
    m_lBufferSize = 0;
    m_pbFree = NULL;
    m_lFreeSize = 0;
    m_pbUsed = NULL;
    m_lUsedSize = 0;
    m_lDummySize = 0;
    m_pSamples = NULL;
    m_pFreeSampleInfo = NULL;

    m_bEndOfStream = false;
    m_bQuit = false;

    // reset time of dummy sample
    m_Dummy.m_dTime = -1.0;

    // call the parent's method
    MediaBuffer::Close();

    return UMC_OK;

} // Status LinearBuffer::Close(void)

Status LinearBuffer::Init(MediaReceiverParams *init)
{
    size_t lAllocate, lMaxSampleSize;
    Ipp32u l, lFramesNumber;
    MediaBufferParams *pParams = DynamicCast<MediaBufferParams> (init);
    Status umcRes;

    // check error(s)
    if (NULL == pParams)
        return UMC_ERR_NULL_PTR;

    if ((0 == pParams->m_numberOfFrames) ||
        (0 == pParams->m_prefInputBufferSize) ||
        (0 == pParams->m_prefOutputBufferSize))
        return UMC_ERR_INIT;

    // release the object before initialization
    Close();

    // call the parent's method
    umcRes = MediaBuffer::Init(init);
    if (UMC_OK != umcRes)
        return umcRes;

    m_Params = *pParams;

    // init mutex
    if (0 == vm_mutex_is_valid(&m_synchro))
    {
        if (VM_OK != vm_mutex_init(&m_synchro))
            return UMC_ERR_INIT;
    }

    // allocate buffer (one more)
    lMaxSampleSize = IPP_MAX(pParams->m_prefInputBufferSize, pParams->m_prefOutputBufferSize);
    lAllocate = lMaxSampleSize * (IPP_MAX(pParams->m_numberOfFrames, 3) + 1);
    if (UMC_OK != m_pMemoryAllocator->Alloc(&m_midAllocatedBuffer, lAllocate + ALIGN_VALUE, UMC_ALLOC_PERSISTENT, 16))
        return UMC_ERR_ALLOC;
    m_pbAllocatedBuffer = (Ipp8u *) m_pMemoryAllocator->Lock(m_midAllocatedBuffer);
    if (NULL == m_pbAllocatedBuffer)
        return UMC_ERR_ALLOC;
    m_lAllocatedBufferSize = lAllocate + ALIGN_VALUE;

    // align buffer & reserve one sample
    m_pbBuffer = align_pointer<Ipp8u *> (m_pbAllocatedBuffer + lMaxSampleSize, ALIGN_VALUE);
    m_lBufferSize = lAllocate - lMaxSampleSize;

    m_pbFree = m_pbBuffer;
    m_lFreeSize = m_lBufferSize;
    m_pbUsed = m_pbBuffer;
    m_lUsedSize = 0;

    // allocate sample info
    lFramesNumber = (IPP_MAX(pParams->m_prefInputBufferSize, pParams->m_prefOutputBufferSize) *
                    pParams->m_numberOfFrames) /
                    IPP_MIN(pParams->m_prefInputBufferSize, pParams->m_prefOutputBufferSize);
    for (l = 0; l < lFramesNumber; l++)
    {
        SampleInfo *pTemp;

        pTemp = new SampleInfo();
        if (NULL == pTemp)
            return UMC_ERR_ALLOC;

        pTemp->m_pNext = m_pFreeSampleInfo;
        m_pFreeSampleInfo = pTemp;
    }

    // save preferended size(s)
    m_lInputSize = pParams->m_prefInputBufferSize;
    m_lOutputSize = pParams->m_prefOutputBufferSize;

    return UMC_OK;

} // Status LinearBuffer::Init(MediaReceiverParams *init)

Status LinearBuffer::LockInputBuffer(MediaData* in)
{
    AutomaticMutex guard(m_synchro);
    size_t lFreeSize;
    bool bAtEnd = false;

    // check error(s)
    if (NULL == in)
        return UMC_ERR_NULL_PTR;
    if (NULL == m_pbFree)
        return UMC_ERR_NOT_INITIALIZED;

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

    // check free size
    if (lFreeSize < m_lInputSize)
    {
        if (false == bAtEnd)
            return UMC_ERR_NOT_ENOUGH_BUFFER;
        // free space at end is too small
        else
        {
            // when used data is present,
            // concatenate dummy bytes to last sample info
            if (m_pSamples)
            {
                SampleInfo *pTemp;

                // find last sample info
                pTemp = m_pSamples;
                while (pTemp->m_pNext)
                    pTemp = pTemp->m_pNext;
                pTemp->m_lBufferSize += lFreeSize;

                // update variable(s)
                m_pbFree = m_pbBuffer;
                m_lFreeSize -= lFreeSize;
                m_lDummySize = lFreeSize;
                m_lUsedSize += lFreeSize;

                // need to Unlock to avoid double locking of
                // the mutex
                guard.Unlock();
                // and call again to lock space at the
                // beginning of the buffer
                return LockInputBuffer(in);
            }
            // when there is no used data,
            // simply move pointer(s)
            else
            {
                m_pbFree = m_pbBuffer;
                m_pbUsed = m_pbBuffer;
                lFreeSize = m_lFreeSize;
            }
        }
    }

    // check free sample info
    if (NULL == m_pFreeSampleInfo)
    {
        // when needed - allocate one more
        if (m_lUsedSize - m_lDummySize < m_lOutputSize)
        {
            m_pFreeSampleInfo = new SampleInfo();
            if (m_pFreeSampleInfo)
                m_pFreeSampleInfo->m_pNext = NULL;
            else
                return UMC_ERR_NOT_ENOUGH_BUFFER;
        }
        else
            return UMC_ERR_NOT_ENOUGH_BUFFER;
    }

    // set free pointer
    in->SetBufferPointer(m_pbFree, lFreeSize);
    in->SetDataSize(0);
    return UMC_OK;

} // Status LinearBuffer::LockInputBuffer(MediaData* in)

Status LinearBuffer::UnLockInputBuffer(MediaData* in, Status StreamStatus)
{
    AutomaticMutex guard(m_synchro);
    size_t lFreeSize;
    SampleInfo *pTemp;

    // check END OF STREAM
    if (UMC_OK != StreamStatus)
        m_bEndOfStream = true;

    // check error(s)
    if (NULL == in)
        return UMC_ERR_NULL_PTR;

⌨️ 快捷键说明

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