📄 umc_avs_splitter_buffer.cpp
字号:
/*
//
// 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 + -