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

📄 umc_avs_splitter_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) 2007 Intel Corporation. All Rights Reserved.
//
//
*/

#include "umc_defs.h"
#if defined(UMC_ENABLE_AVS_SPLITTER)

#include "umc_avs_splitter_buffer.h"
#include "umc_automatic_mutex.h"
#include "umc_media_data_ex.h"
#include "vm_debug.h"

namespace UMC
{

enum
{
    DEFAULT_NUMBER_OF_SAMPLE    = 9,
    MIN_WRITE_PORTION           = 64 * 1024,
    EXTRA_MEMORY                = 1024,
    ALIGN_VALUE                 = 128
};

enum
{
    LAST_SLICE_START_CODE       = 0x0af,
    VIDEO_SEQUENCE_START_CODE   = 0x0b0,
    VIDEO_SEQUENCE_END_CODE     = 0x0b1,
    USER_DATA_START_CODE        = 0x0b2,
    I_PICTURE_START_CODE        = 0x0b3,
    EXTENSION_START_CODE        = 0x0b5,
    BP_PICTURE_START_CODE       = 0x0b6,
    VIDEO_EDIT_CODE             = 0x0b7,
    FIRST_SYSTEM_START_CODE     = 0x0b9
};

AVSSampleBuffer::AVSSampleBuffer(void)
{
    m_pbBuffer = NULL;
    m_nBufferSize = 0;
    m_nInputSize = 0;

    m_pbSample = NULL;
    m_pbSampleEnd = NULL;

    m_iNumberOfStartCodes = 0;

    m_bFoundSequenceHeader = false;

} // AVSSampleBuffer::AVSSampleBuffer(void)

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

} // AVSSampleBuffer::~AVSSampleBuffer(void)

Status AVSSampleBuffer::Close(void)
{
    // release object's resources
    if (m_pbBuffer)
    {
        ippsFree(m_pbBuffer);
    }

    m_pbBuffer = NULL;
    m_nBufferSize = 0;
    m_nInputSize = 0;

    m_pbSample = NULL;
    m_pbSampleEnd = NULL;

    m_iNumberOfStartCodes = 0;

    m_bFoundSequenceHeader = false;

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

    return UMC_OK;

} // Status AVSSampleBuffer::Close(void)

Status AVSSampleBuffer::Init(MediaReceiverParams *init)
{
    MediaBufferParams *pParams = DynamicCast<MediaBufferParams> (init);
    Status umcRes;

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

    // release the object before the initialization
    Close();

    // check parameter(s) & generate the default
    if ((0 == pParams->m_numberOfFrames) ||
        (0 == pParams->m_prefInputBufferSize) ||
        (0 == pParams->m_prefOutputBufferSize))
    {
        m_nInputSize = MIN_WRITE_PORTION;

        m_bufferParams.m_numberOfFrames = DEFAULT_NUMBER_OF_SAMPLE;
        m_bufferParams.m_prefInputBufferSize = MIN_WRITE_PORTION * 2;
        m_bufferParams.m_prefOutputBufferSize = MIN_WRITE_PORTION * 2;
        m_bufferParams.m_pMemoryAllocator = pParams->m_pMemoryAllocator;
    }
    else
    {
        m_bufferParams = *pParams;

        m_nInputSize = pParams->m_prefInputBufferSize;

        m_bufferParams.m_prefInputBufferSize *= 2;
    }

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

    //
    // do specific initializations here
    //

    // initialize start code array
    umcRes = m_startCodes.Init();
    if (UMC_OK != umcRes)
        return umcRes;

    // allocate buffer for the being collected sample
    m_nBufferSize = m_nInputSize * 2;
    m_pbBuffer = ippsMalloc_8u((int) (m_nBufferSize + EXTRA_MEMORY));
    if (NULL == m_pbBuffer)
        return UMC_ERR_ALLOC;
    m_pbSample = m_pbBuffer;
    m_pbSampleEnd = m_pbBuffer;

    // initialize the main buffer
    umcRes = m_mainBuffer.Init(&m_bufferParams);
    if (UMC_OK != umcRes)
        return UMC_OK;

    return UMC_OK;

} // Status AVSSampleBuffer::Init(MediaReceiverParams *pParams)

Status AVSSampleBuffer::LockInputBuffer(MediaData *pDst)
{
    size_t nFreeSize;
    Status umcRes;

    // check error(s)
    if (NULL == pDst)
        return UMC_ERR_NULL_PTR;
    if (NULL == m_pbBuffer)
        return UMC_ERR_NOT_INITIALIZED;

    // move collected sample
    // into the main buffer
    umcRes = MoveCollectedSample(UMC_OK);
    if (UMC_OK != umcRes)
        return umcRes;

    // compute free size in the temporal buffer
    nFreeSize = m_nBufferSize - (m_pbSampleEnd - m_pbSample);

    // we have filled the whole temporal buffer,
    // but a sample has not been collected.
    // we need to enlarge the temporal buffer
    if (m_nInputSize > nFreeSize)
    {
        size_t nSize = m_nBufferSize * 2;
        Ipp8u *pbTemp;

        // allocate a new buffer
        pbTemp = ippsMalloc_8u((int) (nSize + EXTRA_MEMORY));
        if (NULL == pbTemp)
            return UMC_ERR_ALLOC;

        // copy there existing data and exchange the pointers
        memcpy(pbTemp, m_pbSample, m_pbSampleEnd - m_pbSample);
        m_pbSampleEnd = pbTemp + (m_pbSampleEnd - m_pbSample);
        m_pbSample = pbTemp;
        ippsFree(m_pbBuffer);
        m_pbBuffer = pbTemp;
        m_nBufferSize = nSize;
    }

    // reserve space in the main buffer (maximum possible sample)
    {
        size_t nMaxSampleSize;

        nMaxSampleSize = (m_pbSampleEnd - m_pbSample) +
                         sizeof(Ipp32u) * (m_iNumberOfStartCodes * 2 + 2);

        umcRes = m_mainBuffer.LockInputBuffer(pDst, nMaxSampleSize);
        if (UMC_OK != umcRes)
            return umcRes;
    }

    // set the destination pointer
    pDst->SetBufferPointer(m_pbSampleEnd, m_nInputSize);

    return UMC_OK;

} // Status AVSSampleBuffer::LockInputBuffer(MediaData *pDst)

Status AVSSampleBuffer::UnLockInputBuffer(MediaData *pDst, Status StreamStatus)
{
    size_t nFreeSize;
    size_t nDataSize;

    // check error(s)
    if (NULL == pDst)
        return UMC_ERR_NULL_PTR;
    if (NULL == m_pbBuffer)
        return UMC_ERR_NOT_INITIALIZED;

    // get free size
    nFreeSize = m_nBufferSize - (m_pbSampleEnd - m_pbSample);
    if (pDst->GetDataSize() > nFreeSize)
        return UMC_ERR_NOT_ENOUGH_BUFFER;

    // add 'video sequence end' code
    if ((UMC_OK != StreamStatus) &&
        (m_iNumberOfStartCodes) &&
        (VIDEO_SEQUENCE_END_CODE != m_startCodes[m_iNumberOfStartCodes - 1].m_startCode))
    {
        Ipp8u *pbTmp = m_pbSampleEnd + pDst->GetDataSize();

        pbTmp[0] = 0;
        pbTmp[1] = 0;
        pbTmp[2] = 1;
        pbTmp[3] = VIDEO_SEQUENCE_END_CODE;

        nDataSize = pDst->GetDataSize() + sizeof(Ipp32u);
    }
    else
    {
        nDataSize = pDst->GetDataSize();
    }

    // process all start codes
    CollectStartCodes((Ipp32s) nDataSize);

    // this is the only case when we move collected sample
    // into the main buffer in this function
    if (UMC_OK != StreamStatus)
        MoveCollectedSample(StreamStatus);

    return UMC_OK;

} // Status AVSSampleBuffer::UnLockInputBuffer(MediaData *pDst, Status StreamStatus)

Status AVSSampleBuffer::LockOutputBuffer(MediaData *pSrc)
{
    MediaDataEx *pSrcEx;
    Status umcRes;
    Ipp32u *pCodes;

    // check error(s)
    if (NULL == pSrc)
        return UMC_ERR_NULL_PTR;
    if (NULL == m_pbBuffer)
        return UMC_ERR_NOT_INITIALIZED;

    // lock the space in the main buffer
    umcRes = m_mainBuffer.LockOutputBuffer(&m_latestSample);
    if (UMC_OK != umcRes)
        return umcRes;

    // set pointer to start codes
    pCodes = (Ipp32u *) (((Ipp8u *) m_latestSample.GetDataPointer()) + m_latestSample.GetDataSize());

    // set destination media data
    pSrc->SetBufferPointer((Ipp8u *) m_latestSample.GetBufferPointer(), pCodes[-1]);
    pSrc->SetDataSize(pCodes[-1]);

    // try to cast to the extended type
    pSrcEx = DynamicCast<MediaDataEx> (pSrc);
    // fill start codes info
    if (pSrcEx)
    {
        /* DEBUG: need to develop */
    }

    return UMC_OK;

} // Status AVSSampleBuffer::LockOutputBuffer(MediaData *pSrc)

Status AVSSampleBuffer::UnLockOutputBuffer(MediaData *pSrc)
{
    // check error(s)
    if (NULL == pSrc)
        return UMC_ERR_NULL_PTR;
    if (NULL == m_pbBuffer)
        return UMC_ERR_NOT_INITIALIZED;

    // need to update start codes array
    if (pSrc->GetDataSize())
    {
        if (pSrc->GetBufferSize() != pSrc->GetDataSize())
        {
            /* DEBUG: need to update start codes */
        }
    }
    else
    {
        m_latestSample.MoveDataPointer((Ipp32s) m_latestSample.GetDataSize());
    }

⌨️ 快捷键说明

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