You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
3522 lines
113 KiB
3522 lines
113 KiB
//-----------------------------------------------------------------------------
|
|
// COPYRIGHT (C) 2020 CHIPS&MEDIA INC. ALL RIGHTS RESERVED
|
|
//
|
|
// This file is distributed under BSD 3 clause and LGPL2.1 (dual license)
|
|
// SPDX License Identifier: BSD-3-Clause
|
|
// SPDX License Identifier: LGPL-2.1-only
|
|
//
|
|
// The entire notice above must be reproduced on all authorized copies.
|
|
//
|
|
// Description :
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#include "vpuapi.h"
|
|
#include "vpuapifunc.h"
|
|
#include "product.h"
|
|
#include "wave5_regdefine.h"
|
|
|
|
#define W5_RET_DEC_DISPLAY_SIZE (W5_REG_BASE + 0x01D8) // [FIX ME] delete ? or not?
|
|
|
|
#define INVALID_CORE_INDEX_RETURN_ERROR(_coreIdx) \
|
|
if (_coreIdx >= MAX_NUM_VPU_CORE) \
|
|
return -1;
|
|
|
|
static const Uint16* s_pusBitCode[MAX_NUM_VPU_CORE] = {NULL,};
|
|
static int s_bitCodeSize[MAX_NUM_VPU_CORE] = {0,};
|
|
|
|
Uint32 __VPU_BUSY_TIMEOUT = VPU_BUSY_CHECK_TIMEOUT;
|
|
|
|
static RetCode CheckDecInstanceValidity(CodecInst* pCodecInst)
|
|
{
|
|
RetCode ret;
|
|
|
|
if (pCodecInst == NULL)
|
|
return RETCODE_INVALID_HANDLE;
|
|
|
|
ret = CheckInstanceValidity(pCodecInst);
|
|
if (ret != RETCODE_SUCCESS) {
|
|
return RETCODE_INVALID_HANDLE;
|
|
}
|
|
if (!pCodecInst->inUse) {
|
|
return RETCODE_INVALID_HANDLE;
|
|
}
|
|
|
|
return ProductVpuDecCheckCapability(pCodecInst);
|
|
}
|
|
|
|
Int32 VPU_IsInit(Uint32 coreIdx)
|
|
{
|
|
Int32 pc;
|
|
|
|
INVALID_CORE_INDEX_RETURN_ERROR(coreIdx);
|
|
|
|
pc = ProductVpuIsInit(coreIdx);
|
|
|
|
return pc;
|
|
}
|
|
|
|
Int32 VPU_WaitInterrupt(Uint32 coreIdx, int timeout)
|
|
{
|
|
Int32 ret;
|
|
CodecInst* instance;
|
|
|
|
INVALID_CORE_INDEX_RETURN_ERROR(coreIdx);
|
|
|
|
if ((instance=GetPendingInst(coreIdx)) != NULL) {
|
|
ret = ProductVpuWaitInterrupt(instance, timeout);
|
|
}
|
|
else {
|
|
ret = -1;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
Int32 VPU_WaitInterruptEx(VpuHandle handle, int timeout)
|
|
{
|
|
Int32 ret;
|
|
CodecInst *pCodecInst;
|
|
|
|
pCodecInst = handle;
|
|
|
|
INVALID_CORE_INDEX_RETURN_ERROR(pCodecInst->coreIdx);
|
|
|
|
ret = ProductVpuWaitInterrupt(pCodecInst, timeout);
|
|
|
|
return ret;
|
|
}
|
|
|
|
void VPU_ClearInterrupt(Uint32 coreIdx)
|
|
{
|
|
/* clear all interrupt flags */
|
|
ProductVpuClearInterrupt(coreIdx, 0xffff);
|
|
}
|
|
|
|
void VPU_ClearInterruptEx(VpuHandle handle, Int32 intrFlag)
|
|
{
|
|
CodecInst *pCodecInst;
|
|
|
|
pCodecInst = handle;
|
|
|
|
ProductVpuClearInterrupt(pCodecInst->coreIdx, intrFlag);
|
|
}
|
|
|
|
|
|
|
|
int VPU_GetFrameBufSize(VpuHandle handle, int coreIdx, int stride, int height, int mapType, int format, int interleave, DRAMConfig *pDramCfg)
|
|
{
|
|
int productId;
|
|
CodecInst *pCodecInst;
|
|
|
|
pCodecInst = handle;
|
|
UNREFERENCED_PARAMETER(interleave); /*!<< for backward compatiblity */
|
|
|
|
if (coreIdx < 0 || coreIdx >= MAX_NUM_VPU_CORE)
|
|
return -1;
|
|
|
|
productId = ProductVpuGetId(coreIdx);
|
|
|
|
return ProductCalculateFrameBufSize(pCodecInst, productId, stride, height, (TiledMapType)mapType, (FrameBufferFormat)format, (BOOL)interleave, pDramCfg);
|
|
}
|
|
|
|
|
|
int VPU_GetProductId(int coreIdx)
|
|
{
|
|
Int32 productId;
|
|
|
|
INVALID_CORE_INDEX_RETURN_ERROR(coreIdx);
|
|
|
|
if ((productId=ProductVpuGetId(coreIdx)) != PRODUCT_ID_NONE) {
|
|
return productId;
|
|
}
|
|
|
|
if (vdi_init(coreIdx) < 0)
|
|
return -1;
|
|
|
|
EnterLock(coreIdx);
|
|
if (ProductVpuScan(coreIdx) == FALSE)
|
|
productId = -1;
|
|
else
|
|
productId = ProductVpuGetId(coreIdx);
|
|
LeaveLock((coreIdx));
|
|
|
|
vdi_release(coreIdx);
|
|
|
|
return productId;
|
|
}
|
|
|
|
int VPU_GetOpenInstanceNum(Uint32 coreIdx)
|
|
{
|
|
INVALID_CORE_INDEX_RETURN_ERROR(coreIdx);
|
|
|
|
return vdi_get_instance_num(coreIdx);
|
|
}
|
|
|
|
static RetCode InitializeVPU(Uint32 coreIdx, const Uint16* code, Uint32 size)
|
|
{
|
|
RetCode ret;
|
|
|
|
if (vdi_init(coreIdx) < 0)
|
|
return RETCODE_FAILURE;
|
|
|
|
EnterLock(coreIdx);
|
|
|
|
if (vdi_get_instance_num(coreIdx) > 0) {
|
|
if (ProductVpuScan(coreIdx) == 0) {
|
|
LeaveLock(coreIdx);
|
|
return RETCODE_NOT_FOUND_VPU_DEVICE;
|
|
}
|
|
}
|
|
|
|
ProductVpuReInit(coreIdx, (void *)code, size);
|
|
|
|
InitCodecInstancePool(coreIdx);
|
|
|
|
ret = ProductVpuReset(coreIdx, SW_RESET_ON_BOOT);
|
|
if (ret != RETCODE_SUCCESS) {
|
|
LeaveLock(coreIdx);
|
|
return ret;
|
|
}
|
|
|
|
#if defined(SUPPORT_SW_UART) || defined(SUPPORT_SW_UART_V2)
|
|
create_sw_uart_thread(coreIdx);
|
|
usleep(500*1000);
|
|
#endif
|
|
ret = ProductVpuInit(coreIdx, (void*)code, size);
|
|
if (ret != RETCODE_SUCCESS) {
|
|
LeaveLock(coreIdx);
|
|
return ret;
|
|
}
|
|
|
|
LeaveLock(coreIdx);
|
|
return RETCODE_SUCCESS;
|
|
}
|
|
|
|
RetCode VPU_Init(Uint32 coreIdx)
|
|
{
|
|
|
|
if (coreIdx >= MAX_NUM_VPU_CORE)
|
|
return RETCODE_INVALID_PARAM;
|
|
|
|
if (s_bitCodeSize[coreIdx] == 0)
|
|
return RETCODE_NOT_FOUND_BITCODE_PATH;
|
|
|
|
return InitializeVPU(coreIdx, s_pusBitCode[coreIdx], s_bitCodeSize[coreIdx]);
|
|
}
|
|
|
|
RetCode VPU_InitWithBitcode(Uint32 coreIdx, const Uint16* code, Uint32 size)
|
|
{
|
|
if (coreIdx >= MAX_NUM_VPU_CORE)
|
|
return RETCODE_INVALID_PARAM;
|
|
if (code == NULL || size == 0)
|
|
return RETCODE_INVALID_PARAM;
|
|
|
|
s_pusBitCode[coreIdx] = NULL;
|
|
s_pusBitCode[coreIdx] = (Uint16 *)osal_malloc((Int32)(size*sizeof(Uint16)));
|
|
if (!s_pusBitCode[coreIdx])
|
|
return RETCODE_INSUFFICIENT_RESOURCE;
|
|
osal_memcpy((void *)s_pusBitCode[coreIdx], (const void *)code, (Int32)(size*sizeof(Uint16)));
|
|
s_bitCodeSize[coreIdx] = size;
|
|
|
|
return InitializeVPU(coreIdx, code, size);
|
|
}
|
|
|
|
RetCode VPU_DeInit(Uint32 coreIdx)
|
|
{
|
|
int ret;
|
|
|
|
if (coreIdx >= MAX_NUM_VPU_CORE)
|
|
return RETCODE_INVALID_PARAM;
|
|
|
|
EnterLock(coreIdx);
|
|
if (s_pusBitCode[coreIdx]) {
|
|
osal_free((void *)s_pusBitCode[coreIdx]);
|
|
}
|
|
|
|
s_pusBitCode[coreIdx] = NULL;
|
|
s_bitCodeSize[coreIdx] = 0;
|
|
LeaveLock(coreIdx);
|
|
|
|
#if defined(SUPPORT_SW_UART) || defined(SUPPORT_SW_UART_V2)
|
|
destory_sw_uart_thread(coreIdx);
|
|
#endif
|
|
ret = vdi_release(coreIdx);
|
|
if (ret != 0)
|
|
return RETCODE_FAILURE;
|
|
|
|
return RETCODE_SUCCESS;
|
|
}
|
|
|
|
RetCode VPU_GetVersionInfo(Uint32 coreIdx, Uint32 *versionInfo, Uint32 *revision, Uint32 *productId)
|
|
{
|
|
RetCode ret;
|
|
|
|
if (coreIdx >= MAX_NUM_VPU_CORE)
|
|
return RETCODE_INVALID_PARAM;
|
|
|
|
EnterLock(coreIdx);
|
|
|
|
if (ProductVpuIsInit(coreIdx) == 0) {
|
|
LeaveLock(coreIdx);
|
|
return RETCODE_NOT_INITIALIZED;
|
|
}
|
|
|
|
if (GetPendingInst(coreIdx)) {
|
|
LeaveLock(coreIdx);
|
|
return RETCODE_FRAME_NOT_COMPLETE;
|
|
}
|
|
|
|
if (productId != NULL) {
|
|
*productId = ProductVpuGetId(coreIdx);
|
|
}
|
|
ret = ProductVpuGetVersion(coreIdx, versionInfo, revision);
|
|
|
|
LeaveLock(coreIdx);
|
|
|
|
return ret;
|
|
}
|
|
|
|
RetCode VPU_GetProductInfo(Uint32 coreIdx, VpuAttr *productInfo)
|
|
{
|
|
RetCode ret;
|
|
|
|
if (coreIdx >= MAX_NUM_VPU_CORE)
|
|
return RETCODE_INVALID_PARAM;
|
|
|
|
EnterLock(coreIdx);
|
|
|
|
if (ProductVpuIsInit(coreIdx) == 0) {
|
|
LeaveLock(coreIdx);
|
|
return RETCODE_NOT_INITIALIZED;
|
|
}
|
|
|
|
if (GetPendingInst(coreIdx)) {
|
|
LeaveLock(coreIdx);
|
|
return RETCODE_FRAME_NOT_COMPLETE;
|
|
}
|
|
productInfo->productId = ProductVpuGetId(coreIdx);
|
|
ret = ProductVpuGetProductInfo(coreIdx, productInfo);
|
|
|
|
LeaveLock(coreIdx);
|
|
|
|
return ret;
|
|
}
|
|
|
|
RetCode VPU_DecOpen(DecHandle* pHandle, DecOpenParam* pop)
|
|
{
|
|
CodecInst * pCodecInst = NULL;
|
|
DecInfo* pDecInfo = NULL;
|
|
RetCode ret = RETCODE_SUCCESS;
|
|
|
|
ret = ProductVpuDecCheckOpenParam(pop);
|
|
if (ret != RETCODE_SUCCESS)
|
|
return ret;
|
|
|
|
EnterLock(pop->coreIdx);
|
|
|
|
if (VPU_IsInit(pop->coreIdx) == 0) {
|
|
LeaveLock(pop->coreIdx);
|
|
return RETCODE_NOT_INITIALIZED;
|
|
}
|
|
|
|
ret = GetCodecInstance(pop->coreIdx, &pCodecInst);
|
|
if (ret != RETCODE_SUCCESS)
|
|
{
|
|
*pHandle = 0;
|
|
LeaveLock(pop->coreIdx);
|
|
return ret;
|
|
}
|
|
|
|
pCodecInst->isDecoder = TRUE;
|
|
*pHandle = pCodecInst;
|
|
pDecInfo = &pCodecInst->CodecInfo->decInfo;
|
|
osal_memcpy((void*)&pDecInfo->openParam, pop, sizeof(DecOpenParam));
|
|
|
|
if (pop->bitstreamFormat == STD_MPEG4) {
|
|
pCodecInst->codecMode = MP4_DEC;
|
|
pCodecInst->codecModeAux = MP4_AUX_MPEG4;
|
|
}
|
|
else if (pop->bitstreamFormat == STD_AVC) {
|
|
if (pCodecInst->productId == PRODUCT_ID_521 || pCodecInst->productId == PRODUCT_ID_511 || pCodecInst->productId == PRODUCT_ID_517) {
|
|
pCodecInst->codecMode = W_AVC_DEC;
|
|
}
|
|
else {
|
|
pCodecInst->codecMode = AVC_DEC;
|
|
pCodecInst->codecModeAux = pop->avcExtension;
|
|
}
|
|
}
|
|
else if (pop->bitstreamFormat == STD_VC1) {
|
|
pCodecInst->codecMode = VC1_DEC;
|
|
}
|
|
else if (pop->bitstreamFormat == STD_MPEG2) {
|
|
pCodecInst->codecMode = MP2_DEC;
|
|
}
|
|
else if (pop->bitstreamFormat == STD_H263) {
|
|
pCodecInst->codecMode = MP4_DEC;
|
|
pCodecInst->codecModeAux = MP4_AUX_MPEG4;
|
|
}
|
|
else if (pop->bitstreamFormat == STD_DIV3) {
|
|
pCodecInst->codecMode = DV3_DEC;
|
|
pCodecInst->codecModeAux = MP4_AUX_DIVX3;
|
|
}
|
|
else if (pop->bitstreamFormat == STD_RV) {
|
|
pCodecInst->codecMode = RV_DEC;
|
|
}
|
|
else if (pop->bitstreamFormat == STD_AVS) {
|
|
pCodecInst->codecMode = AVS_DEC;
|
|
}
|
|
else if (pop->bitstreamFormat == STD_THO) {
|
|
pCodecInst->codecMode = VPX_DEC;
|
|
pCodecInst->codecModeAux = VPX_AUX_THO;
|
|
}
|
|
else if (pop->bitstreamFormat == STD_VP3) {
|
|
pCodecInst->codecMode = VPX_DEC;
|
|
pCodecInst->codecModeAux = VPX_AUX_THO;
|
|
}
|
|
else if (pop->bitstreamFormat == STD_VP8) {
|
|
pCodecInst->codecMode = VPX_DEC;
|
|
pCodecInst->codecModeAux = VPX_AUX_VP8;
|
|
}
|
|
else if (pop->bitstreamFormat == STD_HEVC) {
|
|
pCodecInst->codecMode = W_HEVC_DEC;
|
|
}
|
|
else if (pop->bitstreamFormat == STD_VP9) {
|
|
pCodecInst->codecMode = W_VP9_DEC;
|
|
}
|
|
else if (pop->bitstreamFormat == STD_AVS2) {
|
|
pCodecInst->codecMode = W_AVS2_DEC;
|
|
}
|
|
else if (pop->bitstreamFormat == STD_SVAC) {
|
|
pCodecInst->codecMode = W_SVAC_DEC;
|
|
}
|
|
else if (pop->bitstreamFormat == STD_AV1) {
|
|
pCodecInst->codecMode = W_AV1_DEC;
|
|
}
|
|
else {
|
|
LeaveLock(pop->coreIdx);
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
|
|
pDecInfo->wtlEnable = pop->wtlEnable;
|
|
pDecInfo->wtlMode = pop->wtlMode;
|
|
if (!pDecInfo->wtlEnable)
|
|
pDecInfo->wtlMode = 0;
|
|
|
|
pDecInfo->streamWrPtr = pop->bitstreamBuffer;
|
|
pDecInfo->streamRdPtr = pop->bitstreamBuffer;
|
|
pDecInfo->frameDelay = -1;
|
|
pDecInfo->streamBufStartAddr = pop->bitstreamBuffer;
|
|
pDecInfo->streamBufSize = pop->bitstreamBufferSize;
|
|
pDecInfo->streamBufEndAddr = pop->bitstreamBuffer + pop->bitstreamBufferSize;
|
|
pDecInfo->reorderEnable = TRUE;
|
|
pDecInfo->mirrorDirection = MIRDIR_NONE;
|
|
pDecInfo->tempIdSelectMode = pop->tempIdSelectMode;
|
|
pDecInfo->targetSubLayerId = DECODE_ALL_TEMPORAL_LAYERS;
|
|
pDecInfo->relTargetLayerId = 0;
|
|
|
|
if ((ret=ProductVpuDecBuildUpOpenParam(pCodecInst, pop)) != RETCODE_SUCCESS) {
|
|
*pHandle = 0;
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
return ret;
|
|
}
|
|
|
|
if (vdi_open_instance(pCodecInst->coreIdx, pCodecInst->instIndex) < 0) {
|
|
return RETCODE_FAILURE;
|
|
}
|
|
pDecInfo->tiled2LinearEnable = pop->tiled2LinearEnable;
|
|
pDecInfo->tiled2LinearMode = pop->tiled2LinearMode;
|
|
if (!pDecInfo->tiled2LinearEnable)
|
|
pDecInfo->tiled2LinearMode = 0; //coda980 only
|
|
|
|
if (!pDecInfo->wtlEnable) //coda980, wave320, wave410 only
|
|
pDecInfo->wtlMode = 0;
|
|
|
|
osal_memset((void*)&pDecInfo->cacheConfig, 0x00, sizeof(MaverickCacheConfig));
|
|
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
|
|
return RETCODE_SUCCESS;
|
|
}
|
|
|
|
RetCode VPU_DecClose(DecHandle handle)
|
|
{
|
|
CodecInst * pCodecInst;
|
|
DecInfo * pDecInfo;
|
|
RetCode ret;
|
|
int i;
|
|
|
|
ret = CheckDecInstanceValidity(handle);
|
|
if (ret != RETCODE_SUCCESS) {
|
|
return ret;
|
|
}
|
|
|
|
pCodecInst = handle;
|
|
if (!pCodecInst) {
|
|
return RETCODE_INVALID_HANDLE;
|
|
}
|
|
pDecInfo = &pCodecInst->CodecInfo->decInfo;
|
|
|
|
EnterLock(pCodecInst->coreIdx);
|
|
|
|
if ((ret=ProductVpuDecFiniSeq(pCodecInst)) != RETCODE_SUCCESS) {
|
|
if (pCodecInst->loggingEnable)
|
|
vdi_log(pCodecInst->coreIdx, pCodecInst->instIndex, DEC_SEQ_END, 2);
|
|
|
|
if (ret == RETCODE_VPU_STILL_RUNNING) {
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
if (pCodecInst->loggingEnable)
|
|
vdi_log(pCodecInst->coreIdx, pCodecInst->instIndex, DEC_SEQ_END, 0);
|
|
|
|
if (pDecInfo->vbSlice.size)
|
|
vdi_free_dma_memory(pCodecInst->coreIdx, &pDecInfo->vbSlice, DEC_ETC, pCodecInst->instIndex);
|
|
|
|
if (pDecInfo->vbWork.size) {
|
|
vdi_free_dma_memory(pCodecInst->coreIdx, &pDecInfo->vbWork, DEC_WORK, pCodecInst->instIndex);
|
|
}
|
|
|
|
if (pDecInfo->vbFrame.size) {
|
|
if (pDecInfo->frameAllocExt == 0) {
|
|
vdi_free_dma_memory(pCodecInst->coreIdx, &pDecInfo->vbFrame, DEC_ETC, pCodecInst->instIndex);
|
|
}
|
|
}
|
|
for ( i=0 ; i<MAX_REG_FRAME; i++) {
|
|
if (pDecInfo->vbMV[i].size)
|
|
vdi_free_dma_memory(pCodecInst->coreIdx, &pDecInfo->vbMV[i], DEC_MV, pCodecInst->instIndex);
|
|
if (pDecInfo->vbFbcYTbl[i].size)
|
|
vdi_free_dma_memory(pCodecInst->coreIdx, &pDecInfo->vbFbcYTbl[i], DEC_FBCY_TBL, pCodecInst->instIndex);
|
|
if (pDecInfo->vbFbcCTbl[i].size)
|
|
vdi_free_dma_memory(pCodecInst->coreIdx, &pDecInfo->vbFbcCTbl[i], DEC_FBCC_TBL, pCodecInst->instIndex);
|
|
}
|
|
|
|
if (pDecInfo->vbPPU.size) {
|
|
if (pDecInfo->ppuAllocExt == 0)
|
|
vdi_free_dma_memory(pCodecInst->coreIdx, &pDecInfo->vbPPU, DEC_ETC, pCodecInst->instIndex);
|
|
}
|
|
|
|
if (pDecInfo->vbWTL.size)
|
|
vdi_free_dma_memory(pCodecInst->coreIdx, &pDecInfo->vbWTL, DEC_FB_LINEAR, pCodecInst->instIndex);
|
|
|
|
if (pDecInfo->vbUserData.size)
|
|
vdi_dettach_dma_memory(pCodecInst->coreIdx, &pDecInfo->vbUserData);
|
|
|
|
if (pDecInfo->vbReport.size)
|
|
vdi_free_dma_memory(pCodecInst->coreIdx, &pDecInfo->vbReport, DEC_ETC, pCodecInst->instIndex);
|
|
|
|
if (pDecInfo->vbTask.size)
|
|
vdi_free_dma_memory(pCodecInst->coreIdx, &pDecInfo->vbTask, DEC_TASK, pCodecInst->instIndex);
|
|
|
|
if (GetPendingInst(pCodecInst->coreIdx) == pCodecInst)
|
|
ClearPendingInst(pCodecInst->coreIdx);
|
|
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
|
|
FreeCodecInstance(pCodecInst);
|
|
|
|
return ret;
|
|
}
|
|
|
|
RetCode VPU_DecSetEscSeqInit(DecHandle handle, int escape)
|
|
{
|
|
CodecInst * pCodecInst;
|
|
DecInfo * pDecInfo;
|
|
RetCode ret;
|
|
|
|
ret = CheckDecInstanceValidity(handle);
|
|
if (ret != RETCODE_SUCCESS)
|
|
return ret;
|
|
|
|
pCodecInst = handle;
|
|
pDecInfo = &pCodecInst->CodecInfo->decInfo;
|
|
|
|
if (pDecInfo->openParam.bitstreamMode != BS_MODE_INTERRUPT)
|
|
return RETCODE_INVALID_PARAM;
|
|
|
|
pDecInfo->seqInitEscape = escape;
|
|
|
|
return RETCODE_SUCCESS;
|
|
}
|
|
|
|
RetCode VPU_DecGetInitialInfo(DecHandle handle, DecInitialInfo* info)
|
|
{
|
|
CodecInst* pCodecInst;
|
|
DecInfo* pDecInfo;
|
|
RetCode ret;
|
|
Int32 flags;
|
|
Uint32 interruptBit;
|
|
VpuAttr* pAttr;
|
|
|
|
if (PRODUCT_ID_W_SERIES(handle->productId)) {
|
|
if (handle->productId == PRODUCT_ID_511 || handle->productId == PRODUCT_ID_517 || handle->productId == PRODUCT_ID_521) {
|
|
interruptBit = INT_WAVE5_INIT_SEQ;
|
|
}
|
|
else
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
else {
|
|
/* CODA9xx */
|
|
interruptBit = INT_BIT_SEQ_INIT;
|
|
}
|
|
|
|
ret = CheckDecInstanceValidity(handle);
|
|
if (ret != RETCODE_SUCCESS)
|
|
return ret;
|
|
|
|
if (info == NULL)
|
|
return RETCODE_INVALID_PARAM;
|
|
|
|
pCodecInst = handle;
|
|
pDecInfo = &pCodecInst->CodecInfo->decInfo;
|
|
ret = ProductVpuDecCheckCapability(pCodecInst);
|
|
if (ret != RETCODE_SUCCESS)
|
|
return ret;
|
|
|
|
EnterLock(pCodecInst->coreIdx);
|
|
|
|
pAttr = &g_VpuCoreAttributes[pCodecInst->coreIdx];
|
|
|
|
if (GetPendingInst(pCodecInst->coreIdx)) {
|
|
/* The other instance is running */
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
return RETCODE_FRAME_NOT_COMPLETE;
|
|
}
|
|
|
|
if (DecBitstreamBufEmpty(pDecInfo)) {
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
return RETCODE_WRONG_CALL_SEQUENCE;
|
|
}
|
|
|
|
ret = ProductVpuDecInitSeq(handle);
|
|
if (ret != RETCODE_SUCCESS) {
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
return ret;
|
|
}
|
|
|
|
if (pAttr->supportCommandQueue == TRUE) {
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
}
|
|
|
|
flags = ProductVpuWaitInterrupt(pCodecInst, __VPU_BUSY_TIMEOUT);
|
|
|
|
if (pAttr->supportCommandQueue == TRUE) {
|
|
EnterLock(pCodecInst->coreIdx);
|
|
}
|
|
|
|
if (flags == -1) {
|
|
info->rdPtr = VpuReadReg(pCodecInst->coreIdx, pDecInfo->streamRdPtrRegAddr);
|
|
info->wrPtr = VpuReadReg(pCodecInst->coreIdx, pDecInfo->streamWrPtrRegAddr);
|
|
ret = RETCODE_VPU_RESPONSE_TIMEOUT;
|
|
}
|
|
else {
|
|
if (flags&(1<<interruptBit))
|
|
ProductVpuClearInterrupt(pCodecInst->coreIdx, (1<<interruptBit));
|
|
|
|
if (flags != (1<<interruptBit))
|
|
ret = RETCODE_FAILURE;
|
|
else
|
|
ret = ProductVpuDecGetSeqInfo(handle, info);
|
|
}
|
|
|
|
info->rdPtr = VpuReadReg(pCodecInst->coreIdx, pDecInfo->streamRdPtrRegAddr);
|
|
info->wrPtr = VpuReadReg(pCodecInst->coreIdx, pDecInfo->streamWrPtrRegAddr);
|
|
|
|
pDecInfo->initialInfo = *info;
|
|
if (ret == RETCODE_SUCCESS) {
|
|
pDecInfo->initialInfoObtained = 1;
|
|
}
|
|
|
|
SetPendingInst(pCodecInst->coreIdx, 0);
|
|
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
|
|
return ret;
|
|
}
|
|
|
|
RetCode VPU_DecIssueSeqInit(DecHandle handle)
|
|
{
|
|
CodecInst* pCodecInst;
|
|
RetCode ret;
|
|
VpuAttr* pAttr;
|
|
|
|
ret = CheckDecInstanceValidity(handle);
|
|
if (ret != RETCODE_SUCCESS)
|
|
return ret;
|
|
|
|
pCodecInst = handle;
|
|
|
|
EnterLock(pCodecInst->coreIdx);
|
|
|
|
pAttr = &g_VpuCoreAttributes[pCodecInst->coreIdx];
|
|
|
|
if (GetPendingInst(pCodecInst->coreIdx)) {
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
return RETCODE_FRAME_NOT_COMPLETE;
|
|
}
|
|
|
|
ret = ProductVpuDecInitSeq(handle);
|
|
if (ret == RETCODE_SUCCESS) {
|
|
SetPendingInst(pCodecInst->coreIdx, pCodecInst);
|
|
}
|
|
|
|
if (pAttr->supportCommandQueue == TRUE) {
|
|
SetPendingInst(pCodecInst->coreIdx, NULL);
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
RetCode VPU_DecCompleteSeqInit(DecHandle handle, DecInitialInfo * info)
|
|
{
|
|
CodecInst* pCodecInst;
|
|
DecInfo* pDecInfo;
|
|
RetCode ret;
|
|
VpuAttr* pAttr;
|
|
|
|
ret = CheckDecInstanceValidity(handle);
|
|
if (ret != RETCODE_SUCCESS) {
|
|
return ret;
|
|
}
|
|
|
|
if (info == 0) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
|
|
pCodecInst = handle;
|
|
pDecInfo = &pCodecInst->CodecInfo->decInfo;
|
|
|
|
pAttr = &g_VpuCoreAttributes[pCodecInst->coreIdx];
|
|
|
|
if (pAttr->supportCommandQueue == TRUE) {
|
|
EnterLock(pCodecInst->coreIdx);
|
|
}
|
|
else {
|
|
if (pCodecInst != GetPendingInst(pCodecInst->coreIdx)) {
|
|
SetPendingInst(pCodecInst->coreIdx, 0);
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
return RETCODE_WRONG_CALL_SEQUENCE;
|
|
}
|
|
}
|
|
|
|
ret = ProductVpuDecGetSeqInfo(handle, info);
|
|
if (ret == RETCODE_SUCCESS) {
|
|
pDecInfo->initialInfoObtained = 1;
|
|
}
|
|
|
|
info->rdPtr = ProductVpuDecGetRdPtr(pCodecInst);
|
|
info->wrPtr = pDecInfo->streamWrPtr;
|
|
|
|
pDecInfo->initialInfo = *info;
|
|
|
|
SetPendingInst(pCodecInst->coreIdx, NULL);
|
|
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
|
|
return ret;
|
|
}
|
|
|
|
static RetCode DecRegisterFrameBuffer(DecHandle handle, FrameBuffer *bufArray, int numFbsForDecoding, int numFbsForWTL, int stride, int height, int mapType)
|
|
{
|
|
CodecInst* pCodecInst;
|
|
DecInfo* pDecInfo;
|
|
Int32 i;
|
|
RetCode ret;
|
|
FrameBuffer* fb, nullFb;
|
|
vpu_buffer_t* vb;
|
|
FrameBufferFormat format = FORMAT_420;
|
|
Int32 totalNumOfFbs;
|
|
|
|
ret = CheckDecInstanceValidity(handle);
|
|
if (ret != RETCODE_SUCCESS)
|
|
return ret;
|
|
|
|
if (numFbsForDecoding > MAX_FRAMEBUFFER_COUNT || numFbsForWTL > MAX_FRAMEBUFFER_COUNT) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
|
|
osal_memset(&nullFb, 0x00, sizeof(FrameBuffer));
|
|
pCodecInst = handle;
|
|
pDecInfo = &pCodecInst->CodecInfo->decInfo;
|
|
pDecInfo->numFbsForDecoding = numFbsForDecoding;
|
|
pDecInfo->numFbsForWTL = numFbsForWTL;
|
|
pDecInfo->numFrameBuffers = numFbsForDecoding + numFbsForWTL;
|
|
pDecInfo->stride = stride;
|
|
if (pCodecInst->codecMode == VPX_DEC)
|
|
pDecInfo->frameBufferHeight = VPU_ALIGN64(height);
|
|
else if (pCodecInst->codecMode == W_VP9_DEC)
|
|
pDecInfo->frameBufferHeight = VPU_ALIGN64(height);
|
|
else
|
|
pDecInfo->frameBufferHeight = height;
|
|
pDecInfo->mapType = mapType;
|
|
pDecInfo->mapCfg.productId = pCodecInst->productId;
|
|
|
|
ret = ProductVpuDecCheckCapability(pCodecInst);
|
|
if (ret != RETCODE_SUCCESS)
|
|
return ret;
|
|
|
|
if (!pDecInfo->initialInfoObtained)
|
|
return RETCODE_WRONG_CALL_SEQUENCE;
|
|
|
|
if ( (stride < pDecInfo->initialInfo.picWidth) || (stride % 8 != 0) || (height<pDecInfo->initialInfo.picHeight) ) {
|
|
return RETCODE_INVALID_STRIDE;
|
|
}
|
|
|
|
EnterLock(pCodecInst->coreIdx);
|
|
if (GetPendingInst(pCodecInst->coreIdx)) {
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
return RETCODE_FRAME_NOT_COMPLETE;
|
|
}
|
|
|
|
/* clear frameBufPool */
|
|
for (i=0; i<(int)(sizeof(pDecInfo->frameBufPool)/sizeof(FrameBuffer)); i++) {
|
|
pDecInfo->frameBufPool[i] = nullFb;
|
|
}
|
|
|
|
/* LinearMap or TiledMap, compressed framebuffer inclusive. */
|
|
if (pDecInfo->initialInfo.lumaBitdepth > 8 || pDecInfo->initialInfo.chromaBitdepth > 8)
|
|
format = FORMAT_420_P10_16BIT_LSB;
|
|
|
|
totalNumOfFbs = numFbsForDecoding + numFbsForWTL;
|
|
|
|
if (pCodecInst->codecMode == W_SVAC_DEC && pDecInfo->initialInfo.spatialSvcEnable == TRUE)
|
|
totalNumOfFbs = numFbsForDecoding + numFbsForDecoding + numFbsForWTL; // (EL + BL + linear)
|
|
|
|
if (bufArray) {
|
|
for(i=0; i<totalNumOfFbs; i++)
|
|
pDecInfo->frameBufPool[i] = bufArray[i];
|
|
}
|
|
else {
|
|
vb = &pDecInfo->vbFrame;
|
|
fb = &pDecInfo->frameBufPool[0];
|
|
ret = ProductVpuAllocateFramebuffer(
|
|
(CodecInst*)handle, fb, (TiledMapType)mapType, numFbsForDecoding, stride, height, format,
|
|
pDecInfo->openParam.cbcrInterleave,
|
|
pDecInfo->openParam.nv21,
|
|
pDecInfo->openParam.frameEndian, vb, 0, FB_TYPE_CODEC);
|
|
if (ret != RETCODE_SUCCESS) {
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
return ret;
|
|
}
|
|
}
|
|
if (pCodecInst->productId != PRODUCT_ID_960) {
|
|
pDecInfo->mapCfg.tiledBaseAddr = pDecInfo->frameBufPool[0].bufY;
|
|
}
|
|
|
|
/* LinearMap */
|
|
if (pDecInfo->wtlEnable == TRUE || numFbsForWTL != 0) {
|
|
pDecInfo->stride = stride;
|
|
if (!bufArray) {
|
|
TiledMapType map;
|
|
map = pDecInfo->wtlMode==FF_FRAME ? LINEAR_FRAME_MAP : LINEAR_FIELD_MAP;
|
|
vb = &pDecInfo->vbWTL;
|
|
fb = &pDecInfo->frameBufPool[numFbsForDecoding];
|
|
|
|
ret = ProductVpuAllocateFramebuffer(
|
|
(CodecInst*)handle, fb, map, numFbsForWTL, stride, height,
|
|
pDecInfo->wtlFormat,
|
|
pDecInfo->openParam.cbcrInterleave,
|
|
pDecInfo->openParam.nv21,
|
|
pDecInfo->openParam.frameEndian, vb, 0, FB_TYPE_PPU);
|
|
|
|
if (ret != RETCODE_SUCCESS) {
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
return ret;
|
|
}
|
|
}
|
|
}
|
|
|
|
ret = ProductVpuRegisterFramebuffer(pCodecInst);
|
|
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
|
|
|
|
return ret;
|
|
}
|
|
|
|
RetCode VPU_DecRegisterFrameBuffer(DecHandle handle, FrameBuffer *bufArray, int num, int stride, int height, int mapType)
|
|
{
|
|
DecInfo* pDecInfo = &handle->CodecInfo->decInfo;
|
|
Uint32 numWTL = 0;
|
|
|
|
if (pDecInfo->wtlEnable == TRUE) numWTL = num;
|
|
return DecRegisterFrameBuffer(handle, bufArray, num, numWTL, stride, height, mapType);
|
|
}
|
|
|
|
RetCode VPU_DecRegisterFrameBufferEx(DecHandle handle, FrameBuffer *bufArray, int numOfDecFbs, int numOfDisplayFbs, int stride, int height, int mapType)
|
|
{
|
|
return DecRegisterFrameBuffer(handle, bufArray, numOfDecFbs, numOfDisplayFbs, stride, height, mapType);
|
|
}
|
|
|
|
RetCode VPU_DecGetFrameBuffer(DecHandle handle, int frameIdx, FrameBuffer* frameBuf)
|
|
{
|
|
CodecInst * pCodecInst;
|
|
DecInfo * pDecInfo;
|
|
RetCode ret;
|
|
|
|
ret = CheckDecInstanceValidity(handle);
|
|
if (ret != RETCODE_SUCCESS)
|
|
return ret;
|
|
|
|
if (frameBuf == 0)
|
|
return RETCODE_INVALID_PARAM;
|
|
|
|
pCodecInst = handle;
|
|
pDecInfo = &pCodecInst->CodecInfo->decInfo;
|
|
|
|
if (frameIdx < 0 || frameIdx >= pDecInfo->numFrameBuffers)
|
|
return RETCODE_INVALID_PARAM;
|
|
|
|
*frameBuf = pDecInfo->frameBufPool[frameIdx];
|
|
|
|
return RETCODE_SUCCESS;
|
|
}
|
|
|
|
RetCode VPU_DecUpdateFrameBuffer(
|
|
DecHandle handle,
|
|
FrameBuffer* fbcFb,
|
|
FrameBuffer* linearFb,
|
|
Int32 mvColIndex,
|
|
Int32 picWidth,
|
|
Int32 picHeight
|
|
)
|
|
{
|
|
if (handle == NULL) {
|
|
return RETCODE_INVALID_HANDLE;
|
|
}
|
|
|
|
return ProductVpuDecUpdateFrameBuffer((CodecInst*)handle, fbcFb, linearFb, mvColIndex, picWidth, picHeight);
|
|
}
|
|
|
|
RetCode VPU_DecGetBitstreamBuffer(DecHandle handle, PhysicalAddress* prdPtr, PhysicalAddress* pwrPtr, Uint32* size)
|
|
{
|
|
CodecInst* pCodecInst;
|
|
DecInfo* pDecInfo;
|
|
PhysicalAddress rdPtr;
|
|
PhysicalAddress wrPtr;
|
|
PhysicalAddress tempPtr;
|
|
int room;
|
|
Int32 coreIdx;
|
|
VpuAttr* pAttr;
|
|
|
|
coreIdx = handle->coreIdx;
|
|
pAttr = &g_VpuCoreAttributes[coreIdx];
|
|
pCodecInst = handle;
|
|
pDecInfo = &pCodecInst->CodecInfo->decInfo;
|
|
|
|
if (pAttr->supportCommandQueue == TRUE) {
|
|
EnterLock(pCodecInst->coreIdx);
|
|
rdPtr = ProductVpuDecGetRdPtr(pCodecInst);
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
}
|
|
else {
|
|
if (GetPendingInst(coreIdx) == pCodecInst) {
|
|
if (pCodecInst->codecMode == AVC_DEC && pCodecInst->codecModeAux == AVC_AUX_MVC) {
|
|
rdPtr = pDecInfo->streamRdPtr;
|
|
}
|
|
else {
|
|
rdPtr = VpuReadReg(coreIdx, pDecInfo->streamRdPtrRegAddr);
|
|
}
|
|
}
|
|
else {
|
|
rdPtr = pDecInfo->streamRdPtr;
|
|
}
|
|
}
|
|
|
|
wrPtr = pDecInfo->streamWrPtr;
|
|
|
|
pAttr = &g_VpuCoreAttributes[coreIdx];
|
|
|
|
tempPtr = rdPtr;
|
|
|
|
if (pDecInfo->openParam.bitstreamMode != BS_MODE_PIC_END) {
|
|
if (wrPtr < tempPtr) {
|
|
room = tempPtr - wrPtr - pAttr->bitstreamBufferMargin*2;
|
|
}
|
|
else {
|
|
room = (pDecInfo->streamBufEndAddr - wrPtr) + (tempPtr - pDecInfo->streamBufStartAddr) - pAttr->bitstreamBufferMargin*2;
|
|
}
|
|
room--;
|
|
}
|
|
else {
|
|
room = (pDecInfo->streamBufEndAddr - wrPtr);
|
|
}
|
|
|
|
if (prdPtr) *prdPtr = tempPtr;
|
|
if (pwrPtr) *pwrPtr = wrPtr;
|
|
if (size) *size = room;
|
|
|
|
return RETCODE_SUCCESS;
|
|
}
|
|
|
|
RetCode VPU_DecUpdateBitstreamBuffer(DecHandle handle, int size)
|
|
{
|
|
CodecInst* pCodecInst;
|
|
DecInfo* pDecInfo;
|
|
PhysicalAddress wrPtr;
|
|
PhysicalAddress rdPtr;
|
|
RetCode ret;
|
|
BOOL running;
|
|
VpuAttr* pAttr;
|
|
ret = CheckDecInstanceValidity(handle);
|
|
if (ret != RETCODE_SUCCESS)
|
|
return ret;
|
|
|
|
pCodecInst = handle;
|
|
if (!pCodecInst)
|
|
return RETCODE_INVALID_HANDLE;
|
|
pAttr = &g_VpuCoreAttributes[pCodecInst->coreIdx];
|
|
pDecInfo = &pCodecInst->CodecInfo->decInfo;
|
|
wrPtr = pDecInfo->streamWrPtr;
|
|
|
|
if (pAttr->supportCommandQueue == TRUE) {
|
|
running = FALSE;
|
|
}
|
|
else {
|
|
running = (BOOL)(GetPendingInst(pCodecInst->coreIdx) == pCodecInst);
|
|
}
|
|
|
|
if (size > 0) {
|
|
Uint32 room = 0;
|
|
|
|
if (running == TRUE)
|
|
rdPtr = VpuReadReg(pCodecInst->coreIdx, pDecInfo->streamRdPtrRegAddr);
|
|
else
|
|
rdPtr = pDecInfo->streamRdPtr;
|
|
|
|
if (wrPtr < rdPtr) {
|
|
if (rdPtr <= wrPtr + size) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
}
|
|
|
|
wrPtr += size;
|
|
|
|
if (pDecInfo->openParam.bitstreamMode != BS_MODE_PIC_END) {
|
|
if (wrPtr > pDecInfo->streamBufEndAddr) {
|
|
room = wrPtr - pDecInfo->streamBufEndAddr;
|
|
wrPtr = pDecInfo->streamBufStartAddr;
|
|
wrPtr += room;
|
|
}
|
|
else if (wrPtr == pDecInfo->streamBufEndAddr) {
|
|
wrPtr = pDecInfo->streamBufStartAddr;
|
|
}
|
|
}
|
|
|
|
pDecInfo->streamWrPtr = wrPtr;
|
|
pDecInfo->streamRdPtr = rdPtr;
|
|
|
|
if (running == TRUE) {
|
|
VpuWriteReg(pCodecInst->coreIdx, pDecInfo->streamWrPtrRegAddr, wrPtr);
|
|
}
|
|
}
|
|
|
|
if (running == FALSE) {
|
|
EnterLock(pCodecInst->coreIdx);
|
|
}
|
|
ret = ProductVpuDecSetBitstreamFlag(pCodecInst, running, size);
|
|
if (running == FALSE) {
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
RetCode VPU_HWReset(Uint32 coreIdx)
|
|
{
|
|
if (vdi_hw_reset(coreIdx) < 0 )
|
|
return RETCODE_FAILURE;
|
|
|
|
if (GetPendingInst(coreIdx))
|
|
{
|
|
SetPendingInst(coreIdx, 0);
|
|
LeaveLock(coreIdx); //if vpu is in a lock state. release the state;
|
|
}
|
|
return RETCODE_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
* VPU_SWReset
|
|
* IN
|
|
* forcedReset : 1 if there is no need to waiting for BUS transaction,
|
|
* 0 for otherwise
|
|
* OUT
|
|
* RetCode : RETCODE_FAILURE if failed to reset,
|
|
* RETCODE_SUCCESS for otherwise
|
|
*/
|
|
RetCode VPU_SWReset(Uint32 coreIdx, SWResetMode resetMode, void *pendingInst)
|
|
{
|
|
CodecInst *pCodecInst = (CodecInst *)pendingInst;
|
|
RetCode ret = RETCODE_SUCCESS;
|
|
VpuAttr* attr = &g_VpuCoreAttributes[coreIdx];
|
|
|
|
if (attr->supportCommandQueue == TRUE) {
|
|
if (pCodecInst && pCodecInst->loggingEnable) {
|
|
vdi_log(pCodecInst->coreIdx, pCodecInst->instIndex, 0x10000, 1);
|
|
}
|
|
|
|
EnterLock(coreIdx);
|
|
ret = ProductVpuReset(coreIdx, resetMode);
|
|
LeaveLock(coreIdx);
|
|
|
|
if (pCodecInst && pCodecInst->loggingEnable) {
|
|
vdi_log(pCodecInst->coreIdx, pCodecInst->instIndex, 0x10000, 0);
|
|
}
|
|
}
|
|
else {
|
|
if (pCodecInst) {
|
|
if (pCodecInst->loggingEnable) {
|
|
vdi_log(pCodecInst->coreIdx, pCodecInst->instIndex, (pCodecInst->productId == PRODUCT_ID_960 || pCodecInst->productId == PRODUCT_ID_980)?0x10:0x10000, 1);
|
|
}
|
|
}
|
|
else {
|
|
EnterLock(coreIdx);
|
|
}
|
|
|
|
ret = ProductVpuReset(coreIdx, resetMode);
|
|
|
|
if (pCodecInst) {
|
|
if (pCodecInst->loggingEnable) {
|
|
vdi_log(pCodecInst->coreIdx, pCodecInst->instIndex, (pCodecInst->productId == PRODUCT_ID_960 || pCodecInst->productId == PRODUCT_ID_980)?0x10:0x10000, 0);
|
|
}
|
|
SetPendingInst(pCodecInst->coreIdx, 0);
|
|
LeaveLock(coreIdx);
|
|
}
|
|
else {
|
|
LeaveLock(coreIdx);
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
//---- VPU_SLEEP/WAKE
|
|
RetCode VPU_SleepWake(Uint32 coreIdx, int iSleepWake)
|
|
{
|
|
RetCode ret;
|
|
|
|
EnterLock(coreIdx);
|
|
ret = ProductVpuSleepWake(coreIdx, iSleepWake, s_pusBitCode[coreIdx], s_bitCodeSize[coreIdx]);
|
|
LeaveLock(coreIdx);
|
|
|
|
return ret;
|
|
}
|
|
|
|
RetCode VPU_DecStartOneFrame(DecHandle handle, DecParam *param)
|
|
{
|
|
CodecInst* pCodecInst;
|
|
DecInfo* pDecInfo;
|
|
Uint32 val = 0;
|
|
RetCode ret = RETCODE_SUCCESS;
|
|
VpuAttr* pAttr = NULL;
|
|
|
|
ret = CheckDecInstanceValidity(handle);
|
|
if (ret != RETCODE_SUCCESS) {
|
|
return ret;
|
|
}
|
|
|
|
pCodecInst = (CodecInst*)handle;
|
|
pDecInfo = &pCodecInst->CodecInfo->decInfo;
|
|
|
|
if (pDecInfo->stride == 0) { // This means frame buffers have not been registered.
|
|
return RETCODE_WRONG_CALL_SEQUENCE;
|
|
}
|
|
|
|
pAttr = &g_VpuCoreAttributes[pCodecInst->coreIdx];
|
|
|
|
EnterLock(pCodecInst->coreIdx);
|
|
if (GetPendingInst(pCodecInst->coreIdx)) {
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
return RETCODE_FRAME_NOT_COMPLETE;
|
|
}
|
|
|
|
if (pAttr->supportCommandQueue == FALSE) {
|
|
EnterDispFlagLock(pCodecInst->coreIdx);
|
|
val = pDecInfo->frameDisplayFlag;
|
|
val |= pDecInfo->setDisplayIndexes;
|
|
val &= ~(Uint32)(pDecInfo->clearDisplayIndexes);
|
|
VpuWriteReg(pCodecInst->coreIdx, pDecInfo->frameDisplayFlagRegAddr, val);
|
|
pDecInfo->clearDisplayIndexes = 0;
|
|
pDecInfo->setDisplayIndexes = 0;
|
|
LeaveDispFlagLock(pCodecInst->coreIdx);
|
|
}
|
|
|
|
pDecInfo->frameStartPos = pDecInfo->streamRdPtr;
|
|
|
|
ret = ProductVpuDecode(pCodecInst, param);
|
|
|
|
if (pAttr->supportCommandQueue == TRUE) {
|
|
SetPendingInst(pCodecInst->coreIdx, NULL);
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
}
|
|
else {
|
|
SetPendingInst(pCodecInst->coreIdx, pCodecInst);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
RetCode VPU_DecGetOutputInfo(DecHandle handle, DecOutputInfo* info)
|
|
{
|
|
CodecInst* pCodecInst;
|
|
DecInfo* pDecInfo;
|
|
RetCode ret;
|
|
VpuRect rectInfo;
|
|
Uint32 val;
|
|
Int32 decodedIndex;
|
|
Int32 displayIndex;
|
|
Uint32 maxDecIndex;
|
|
VpuAttr* pAttr;
|
|
|
|
ret = CheckDecInstanceValidity(handle);
|
|
if (ret != RETCODE_SUCCESS) {
|
|
return ret;
|
|
}
|
|
|
|
if (info == 0) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
|
|
pCodecInst = handle;
|
|
pDecInfo = &pCodecInst->CodecInfo->decInfo;
|
|
pAttr = &g_VpuCoreAttributes[pCodecInst->coreIdx];
|
|
|
|
if (pAttr->supportCommandQueue == TRUE) {
|
|
EnterLock(pCodecInst->coreIdx);
|
|
}
|
|
else {
|
|
if (pCodecInst != GetPendingInst(pCodecInst->coreIdx)) {
|
|
SetPendingInst(pCodecInst->coreIdx, 0);
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
return RETCODE_WRONG_CALL_SEQUENCE;
|
|
}
|
|
}
|
|
|
|
osal_memset((void*)info, 0x00, sizeof(DecOutputInfo));
|
|
|
|
ret = ProductVpuDecGetResult(pCodecInst, info);
|
|
if (ret != RETCODE_SUCCESS) {
|
|
info->rdPtr = pDecInfo->streamRdPtr;
|
|
info->wrPtr = pDecInfo->streamWrPtr;
|
|
SetPendingInst(pCodecInst->coreIdx, 0);
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
return ret;
|
|
}
|
|
|
|
decodedIndex = info->indexFrameDecoded;
|
|
|
|
|
|
// Calculate display frame region
|
|
val = 0;
|
|
if (decodedIndex >= 0 && decodedIndex < MAX_GDI_IDX) {
|
|
//default value
|
|
rectInfo.left = 0;
|
|
rectInfo.right = info->decPicWidth;
|
|
rectInfo.top = 0;
|
|
rectInfo.bottom = info->decPicHeight;
|
|
|
|
if (pCodecInst->codecMode == W_HEVC_DEC || pCodecInst->codecMode == AVC_DEC || pCodecInst->codecMode == AVS_DEC)
|
|
rectInfo = pDecInfo->initialInfo.picCropRect;
|
|
|
|
if (pCodecInst->codecMode == W_HEVC_DEC)
|
|
pDecInfo->decOutInfo[decodedIndex].decodedPOC = info->decodedPOC;
|
|
|
|
if (pCodecInst->codecMode == W_AVS2_DEC)
|
|
pDecInfo->decOutInfo[decodedIndex].avs2Info.decodedPOI = info->avs2Info.decodedPOI;
|
|
|
|
info->rcDecoded.left = pDecInfo->decOutInfo[decodedIndex].rcDecoded.left = rectInfo.left;
|
|
info->rcDecoded.right = pDecInfo->decOutInfo[decodedIndex].rcDecoded.right = rectInfo.right;
|
|
info->rcDecoded.top = pDecInfo->decOutInfo[decodedIndex].rcDecoded.top = rectInfo.top;
|
|
info->rcDecoded.bottom = pDecInfo->decOutInfo[decodedIndex].rcDecoded.bottom = rectInfo.bottom;
|
|
}
|
|
else
|
|
{
|
|
info->rcDecoded.left = 0;
|
|
info->rcDecoded.right = info->decPicWidth;
|
|
info->rcDecoded.top = 0;
|
|
info->rcDecoded.bottom = info->decPicHeight;
|
|
}
|
|
|
|
displayIndex = info->indexFrameDisplay;
|
|
if (info->indexFrameDisplay >= 0 && info->indexFrameDisplay < MAX_GDI_IDX)
|
|
{
|
|
if (pCodecInst->codecMode == VC1_DEC) // vc1 rotates decoded frame buffer region. the other std rotated whole frame buffer region.
|
|
{
|
|
if (pDecInfo->rotationEnable && (pDecInfo->rotationAngle==90 || pDecInfo->rotationAngle==270))
|
|
{
|
|
info->rcDisplay.left = pDecInfo->decOutInfo[displayIndex].rcDecoded.top;
|
|
info->rcDisplay.right = pDecInfo->decOutInfo[displayIndex].rcDecoded.bottom;
|
|
info->rcDisplay.top = pDecInfo->decOutInfo[displayIndex].rcDecoded.left;
|
|
info->rcDisplay.bottom = pDecInfo->decOutInfo[displayIndex].rcDecoded.right;
|
|
}
|
|
else
|
|
{
|
|
info->rcDisplay.left = pDecInfo->decOutInfo[displayIndex].rcDecoded.left;
|
|
info->rcDisplay.right = pDecInfo->decOutInfo[displayIndex].rcDecoded.right;
|
|
info->rcDisplay.top = pDecInfo->decOutInfo[displayIndex].rcDecoded.top;
|
|
info->rcDisplay.bottom = pDecInfo->decOutInfo[displayIndex].rcDecoded.bottom;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (pDecInfo->rotationEnable)
|
|
{
|
|
switch(pDecInfo->rotationAngle)
|
|
{
|
|
case 90:
|
|
info->rcDisplay.left = pDecInfo->decOutInfo[displayIndex].rcDecoded.top;
|
|
info->rcDisplay.right = pDecInfo->decOutInfo[displayIndex].rcDecoded.bottom;
|
|
info->rcDisplay.top = pDecInfo->decOutInfo[displayIndex].decPicWidth - pDecInfo->decOutInfo[displayIndex].rcDecoded.right;
|
|
info->rcDisplay.bottom = pDecInfo->decOutInfo[displayIndex].decPicWidth - pDecInfo->decOutInfo[displayIndex].rcDecoded.left;
|
|
break;
|
|
case 270:
|
|
info->rcDisplay.left = pDecInfo->decOutInfo[displayIndex].decPicHeight - pDecInfo->decOutInfo[displayIndex].rcDecoded.bottom;
|
|
info->rcDisplay.right = pDecInfo->decOutInfo[displayIndex].decPicHeight - pDecInfo->decOutInfo[displayIndex].rcDecoded.top;
|
|
info->rcDisplay.top = pDecInfo->decOutInfo[displayIndex].rcDecoded.left;
|
|
info->rcDisplay.bottom = pDecInfo->decOutInfo[displayIndex].rcDecoded.right;
|
|
break;
|
|
case 180:
|
|
info->rcDisplay.left = pDecInfo->decOutInfo[displayIndex].rcDecoded.left;
|
|
info->rcDisplay.right = pDecInfo->decOutInfo[displayIndex].rcDecoded.right;
|
|
info->rcDisplay.top = pDecInfo->decOutInfo[displayIndex].decPicHeight - pDecInfo->decOutInfo[displayIndex].rcDecoded.bottom;
|
|
info->rcDisplay.bottom = pDecInfo->decOutInfo[displayIndex].decPicHeight - pDecInfo->decOutInfo[displayIndex].rcDecoded.top;
|
|
break;
|
|
default:
|
|
info->rcDisplay.left = pDecInfo->decOutInfo[displayIndex].rcDecoded.left;
|
|
info->rcDisplay.right = pDecInfo->decOutInfo[displayIndex].rcDecoded.right;
|
|
info->rcDisplay.top = pDecInfo->decOutInfo[displayIndex].rcDecoded.top;
|
|
info->rcDisplay.bottom = pDecInfo->decOutInfo[displayIndex].rcDecoded.bottom;
|
|
break;
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
info->rcDisplay.left = pDecInfo->decOutInfo[displayIndex].rcDecoded.left;
|
|
info->rcDisplay.right = pDecInfo->decOutInfo[displayIndex].rcDecoded.right;
|
|
info->rcDisplay.top = pDecInfo->decOutInfo[displayIndex].rcDecoded.top;
|
|
info->rcDisplay.bottom = pDecInfo->decOutInfo[displayIndex].rcDecoded.bottom;
|
|
}
|
|
|
|
if (pDecInfo->mirrorEnable) {
|
|
Uint32 temp;
|
|
Uint32 width = (pDecInfo->rotationAngle == 90 || pDecInfo->rotationAngle == 270) ? info->decPicHeight: info->decPicWidth;
|
|
Uint32 height = (pDecInfo->rotationAngle == 90 || pDecInfo->rotationAngle == 270) ? info->decPicWidth : info->decPicHeight;
|
|
if (pDecInfo->mirrorDirection & MIRDIR_VER) {
|
|
temp = info->rcDisplay.top;
|
|
info->rcDisplay.top = height - info->rcDisplay.bottom;
|
|
info->rcDisplay.bottom = height - temp;
|
|
}
|
|
if (pDecInfo->mirrorDirection & MIRDIR_HOR) {
|
|
temp = info->rcDisplay.left;
|
|
info->rcDisplay.left = width - info->rcDisplay.right;
|
|
info->rcDisplay.right = width - temp;
|
|
}
|
|
}
|
|
|
|
switch (pCodecInst->codecMode) {
|
|
case W_HEVC_DEC:
|
|
info->displayPOC = pDecInfo->decOutInfo[displayIndex].decodedPOC;
|
|
break;
|
|
case W_AVS2_DEC:
|
|
info->avs2Info.displayPOI = pDecInfo->decOutInfo[displayIndex].avs2Info.decodedPOI;
|
|
break;
|
|
case W_AVC_DEC:
|
|
if (TRUE == PRODUCT_ID_W_SERIES(pCodecInst->productId)) {
|
|
info->displayPOC = pDecInfo->decOutInfo[displayIndex].decodedPOC;
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (info->indexFrameDisplay == info->indexFrameDecoded)
|
|
{
|
|
info->dispPicWidth = info->decPicWidth;
|
|
info->dispPicHeight = info->decPicHeight;
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
When indexFrameDecoded < 0, and indexFrameDisplay >= 0
|
|
info->decPicWidth and info->decPicHeight are still valid
|
|
But those of pDecInfo->decOutInfo[displayIndex] are invalid in VP9
|
|
*/
|
|
info->dispPicWidth = pDecInfo->decOutInfo[displayIndex].decPicWidth;
|
|
info->dispPicHeight = pDecInfo->decOutInfo[displayIndex].decPicHeight;
|
|
}
|
|
|
|
if (pDecInfo->scalerEnable == TRUE) {
|
|
if ((pDecInfo->scaleWidth != 0) && (pDecInfo->scaleHeight != 0)) {
|
|
info->dispPicWidth = pDecInfo->scaleWidth;
|
|
info->dispPicHeight = pDecInfo->scaleHeight;
|
|
info->rcDisplay.right = pDecInfo->scaleWidth;
|
|
info->rcDisplay.bottom = pDecInfo->scaleHeight;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
info->rcDisplay.left = 0;
|
|
info->rcDisplay.right = 0;
|
|
info->rcDisplay.top = 0;
|
|
info->rcDisplay.bottom = 0;
|
|
|
|
if (pDecInfo->rotationEnable || pDecInfo->mirrorEnable || pDecInfo->tiled2LinearEnable || pDecInfo->deringEnable) {
|
|
info->dispPicWidth = info->decPicWidth;
|
|
info->dispPicHeight = info->decPicHeight;
|
|
}
|
|
else {
|
|
info->dispPicWidth = 0;
|
|
info->dispPicHeight = 0;
|
|
}
|
|
}
|
|
|
|
if ( (pCodecInst->codecMode == VC1_DEC ) && info->indexFrameDisplay != -3) {
|
|
if (pDecInfo->vc1BframeDisplayValid == 0) {
|
|
if (info->picType == 2)
|
|
info->indexFrameDisplay = -3;
|
|
else
|
|
pDecInfo->vc1BframeDisplayValid = 1;
|
|
}
|
|
}
|
|
|
|
pDecInfo->streamRdPtr = ProductVpuDecGetRdPtr(pCodecInst);
|
|
pDecInfo->frameDisplayFlag = VpuReadReg(pCodecInst->coreIdx, pDecInfo->frameDisplayFlagRegAddr);
|
|
if (pCodecInst->codecMode == W_VP9_DEC) {
|
|
pDecInfo->frameDisplayFlag &= 0xFFFF;
|
|
}
|
|
pDecInfo->frameEndPos = pDecInfo->streamRdPtr;
|
|
|
|
if (pDecInfo->frameEndPos < pDecInfo->frameStartPos)
|
|
info->consumedByte = pDecInfo->frameEndPos + pDecInfo->streamBufSize - pDecInfo->frameStartPos;
|
|
else
|
|
info->consumedByte = pDecInfo->frameEndPos - pDecInfo->frameStartPos;
|
|
|
|
if (pDecInfo->deringEnable || pDecInfo->mirrorEnable || pDecInfo->rotationEnable || pDecInfo->tiled2LinearEnable) {
|
|
info->dispFrame = pDecInfo->rotatorOutput;
|
|
info->dispFrame.stride = pDecInfo->rotatorStride;
|
|
}
|
|
else {
|
|
Int32 SvacSvcFlag = (pCodecInst->codecMode == W_SVAC_DEC && pDecInfo->initialInfo.spatialSvcEnable == TRUE);
|
|
val = (pDecInfo->openParam.wtlEnable == TRUE ? pDecInfo->numFbsForDecoding: 0); //fbOffset
|
|
if (SvacSvcFlag && pDecInfo->openParam.wtlEnable == TRUE)
|
|
val = pDecInfo->numFbsForDecoding*2;
|
|
|
|
maxDecIndex = (pDecInfo->numFbsForDecoding > pDecInfo->numFbsForWTL) ? (SvacSvcFlag ? pDecInfo->numFbsForDecoding*2 : pDecInfo->numFbsForDecoding) : pDecInfo->numFbsForWTL;
|
|
|
|
if (0 <= info->indexFrameDisplay && info->indexFrameDisplay < (int)maxDecIndex)
|
|
info->dispFrame = pDecInfo->frameBufPool[val+info->indexFrameDisplay];
|
|
}
|
|
|
|
info->rdPtr = pDecInfo->streamRdPtr;
|
|
info->wrPtr = pDecInfo->streamWrPtr;
|
|
info->frameDisplayFlag = pDecInfo->frameDisplayFlag;
|
|
|
|
info->sequenceNo = pDecInfo->initialInfo.sequenceNo;
|
|
if (decodedIndex >= 0 && decodedIndex < MAX_GDI_IDX) {
|
|
pDecInfo->decOutInfo[decodedIndex] = *info;
|
|
}
|
|
|
|
if (displayIndex >= 0 && displayIndex < MAX_GDI_IDX) {
|
|
info->numOfTotMBsInDisplay = pDecInfo->decOutInfo[displayIndex].numOfTotMBs;
|
|
info->numOfErrMBsInDisplay = pDecInfo->decOutInfo[displayIndex].numOfErrMBs;
|
|
info->dispFrame.sequenceNo = info->sequenceNo;
|
|
}
|
|
else {
|
|
info->numOfTotMBsInDisplay = 0;
|
|
info->numOfErrMBsInDisplay = 0;
|
|
}
|
|
|
|
if (info->sequenceChanged != 0) {
|
|
if (!(pCodecInst->productId == PRODUCT_ID_960 || pCodecInst->productId == PRODUCT_ID_980)) {
|
|
/* Update new sequence information */
|
|
osal_memcpy((void*)&pDecInfo->initialInfo, (void*)&pDecInfo->newSeqInfo, sizeof(DecInitialInfo));
|
|
}
|
|
if ((info->sequenceChanged & SEQ_CHANGE_INTER_RES_CHANGE) != SEQ_CHANGE_INTER_RES_CHANGE) {
|
|
pDecInfo->initialInfo.sequenceNo++;
|
|
}
|
|
}
|
|
|
|
SetPendingInst(pCodecInst->coreIdx, 0);
|
|
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
|
|
return RETCODE_SUCCESS;
|
|
}
|
|
|
|
RetCode VPU_DecFrameBufferFlush(DecHandle handle, DecOutputInfo* pRemainings, Uint32* retNum)
|
|
{
|
|
CodecInst* pCodecInst;
|
|
DecInfo* pDecInfo;
|
|
DecOutputInfo* pOut;
|
|
RetCode ret;
|
|
FramebufferIndex retIndex[MAX_GDI_IDX];
|
|
Uint32 retRemainings = 0;
|
|
Int32 i, index, val;
|
|
VpuAttr* pAttr = NULL;
|
|
|
|
ret = CheckDecInstanceValidity(handle);
|
|
if (ret != RETCODE_SUCCESS)
|
|
return ret;
|
|
|
|
pCodecInst = handle;
|
|
pDecInfo = &pCodecInst->CodecInfo->decInfo;
|
|
|
|
EnterLock(pCodecInst->coreIdx);
|
|
|
|
if (GetPendingInst(pCodecInst->coreIdx)) {
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
return RETCODE_FRAME_NOT_COMPLETE;
|
|
}
|
|
|
|
osal_memset((void*)retIndex, 0xff, sizeof(retIndex));
|
|
|
|
pAttr = &g_VpuCoreAttributes[pCodecInst->coreIdx];
|
|
if (pAttr->supportCommandQueue == FALSE) {
|
|
EnterDispFlagLock(pCodecInst->coreIdx);
|
|
val = pDecInfo->frameDisplayFlag;
|
|
val |= pDecInfo->setDisplayIndexes;
|
|
val &= ~(Uint32)(pDecInfo->clearDisplayIndexes);
|
|
VpuWriteReg(pCodecInst->coreIdx, pDecInfo->frameDisplayFlagRegAddr, val);
|
|
pDecInfo->clearDisplayIndexes = 0;
|
|
pDecInfo->setDisplayIndexes = 0;
|
|
LeaveDispFlagLock(pCodecInst->coreIdx);
|
|
}
|
|
|
|
if ((ret=ProductVpuDecFlush(pCodecInst, retIndex, MAX_GDI_IDX)) != RETCODE_SUCCESS) {
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
return ret;
|
|
}
|
|
|
|
if (pRemainings != NULL) {
|
|
for (i=0; i<MAX_GDI_IDX; i++) {
|
|
index = (pDecInfo->wtlEnable == TRUE) ? retIndex[i].tiledIndex : retIndex[i].linearIndex;
|
|
if (index < 0)
|
|
break;
|
|
pRemainings[i] = pDecInfo->decOutInfo[index];
|
|
pOut = &pRemainings[i];
|
|
pOut->indexFrameDisplay = pOut->indexFrameDecoded;
|
|
pOut->indexFrameDisplayForTiled = pOut->indexFrameDecodedForTiled;
|
|
if (pDecInfo->wtlEnable == TRUE)
|
|
pOut->dispFrame = pDecInfo->frameBufPool[pDecInfo->numFbsForDecoding+retIndex[i].linearIndex];
|
|
else
|
|
pOut->dispFrame = pDecInfo->frameBufPool[index];
|
|
|
|
pOut->dispFrame.sequenceNo = pOut->sequenceNo;
|
|
|
|
if (pCodecInst->codecMode == W_VP9_DEC || pCodecInst->codecMode == W_AVS2_DEC) {
|
|
Uint32 regVal;
|
|
if ((pDecInfo->scaleWidth == 0) || (pDecInfo->scaleHeight == 0)) {
|
|
regVal = VpuReadReg(pCodecInst->coreIdx, W5_RET_DEC_DISPLAY_SIZE);
|
|
pOut->dispPicWidth = regVal>>16;
|
|
pOut->dispPicHeight = regVal&0xffff;
|
|
}
|
|
else {
|
|
pOut->dispPicWidth = pDecInfo->scaleWidth;
|
|
pOut->dispPicHeight = pDecInfo->scaleHeight;
|
|
}
|
|
}
|
|
else {
|
|
pOut->dispPicWidth = pOut->decPicWidth;
|
|
pOut->dispPicHeight = pOut->decPicHeight;
|
|
}
|
|
|
|
|
|
if (pDecInfo->rotationEnable)
|
|
{
|
|
switch(pDecInfo->rotationAngle)
|
|
{
|
|
case 90:
|
|
pOut->rcDisplay.left = pDecInfo->decOutInfo[index].rcDecoded.top;
|
|
pOut->rcDisplay.right = pDecInfo->decOutInfo[index].rcDecoded.bottom;
|
|
pOut->rcDisplay.top = pOut->decPicWidth - pDecInfo->decOutInfo[index].rcDecoded.right;
|
|
pOut->rcDisplay.bottom = pOut->decPicWidth - pDecInfo->decOutInfo[index].rcDecoded.left;
|
|
break;
|
|
case 270:
|
|
pOut->rcDisplay.left = pOut->decPicHeight - pDecInfo->decOutInfo[index].rcDecoded.bottom;
|
|
pOut->rcDisplay.right = pOut->decPicHeight - pDecInfo->decOutInfo[index].rcDecoded.top;
|
|
pOut->rcDisplay.top = pDecInfo->decOutInfo[index].rcDecoded.left;
|
|
pOut->rcDisplay.bottom = pDecInfo->decOutInfo[index].rcDecoded.right;
|
|
break;
|
|
case 180:
|
|
pOut->rcDisplay.left = pDecInfo->decOutInfo[index].rcDecoded.left;
|
|
pOut->rcDisplay.right = pDecInfo->decOutInfo[index].rcDecoded.right;
|
|
pOut->rcDisplay.top = pOut->decPicHeight - pDecInfo->decOutInfo[index].rcDecoded.bottom;
|
|
pOut->rcDisplay.bottom = pOut->decPicHeight - pDecInfo->decOutInfo[index].rcDecoded.top;
|
|
break;
|
|
default:
|
|
pOut->rcDisplay.left = pDecInfo->decOutInfo[index].rcDecoded.left;
|
|
pOut->rcDisplay.right = pDecInfo->decOutInfo[index].rcDecoded.right;
|
|
pOut->rcDisplay.top = pDecInfo->decOutInfo[index].rcDecoded.top;
|
|
pOut->rcDisplay.bottom = pDecInfo->decOutInfo[index].rcDecoded.bottom;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pOut->rcDisplay.left = pDecInfo->decOutInfo[index].rcDecoded.left;
|
|
pOut->rcDisplay.right = pDecInfo->decOutInfo[index].rcDecoded.right;
|
|
pOut->rcDisplay.top = pDecInfo->decOutInfo[index].rcDecoded.top;
|
|
pOut->rcDisplay.bottom = pDecInfo->decOutInfo[index].rcDecoded.bottom;
|
|
}
|
|
retRemainings++;
|
|
}
|
|
}
|
|
|
|
if (retNum) *retNum = retRemainings;
|
|
|
|
if (pCodecInst->loggingEnable)
|
|
vdi_log(pCodecInst->coreIdx, pCodecInst->instIndex, DEC_BUF_FLUSH, 0);
|
|
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
|
|
return ret;
|
|
}
|
|
|
|
RetCode VPU_DecSetRdPtr(DecHandle handle, PhysicalAddress addr, int updateWrPtr)
|
|
{
|
|
CodecInst* pCodecInst;
|
|
CodecInst* pPendingInst;
|
|
DecInfo* pDecInfo;
|
|
VpuAttr* pAttr = NULL;
|
|
RetCode ret;
|
|
|
|
ret = CheckDecInstanceValidity(handle);
|
|
if (ret != RETCODE_SUCCESS) {
|
|
return ret;
|
|
}
|
|
|
|
pCodecInst = handle;
|
|
pDecInfo = &pCodecInst->CodecInfo->decInfo;
|
|
pPendingInst = GetPendingInst(pCodecInst->coreIdx);
|
|
pAttr = &g_VpuCoreAttributes[pCodecInst->coreIdx];
|
|
|
|
if (pAttr->supportCommandQueue == TRUE) {
|
|
EnterLock(pCodecInst->coreIdx);
|
|
ProductVpuDecSetRdPtr(pCodecInst, addr);
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
}
|
|
else {
|
|
if (pCodecInst == pPendingInst) {
|
|
VpuWriteReg(pCodecInst->coreIdx, pDecInfo->streamRdPtrRegAddr, addr);
|
|
}
|
|
else {
|
|
EnterLock(pCodecInst->coreIdx);
|
|
VpuWriteReg(pCodecInst->coreIdx, pDecInfo->streamRdPtrRegAddr, addr);
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
}
|
|
}
|
|
|
|
pDecInfo->streamRdPtr = addr;
|
|
if (updateWrPtr == TRUE) {
|
|
pDecInfo->streamWrPtr = addr;
|
|
}
|
|
|
|
return RETCODE_SUCCESS;
|
|
}
|
|
|
|
|
|
RetCode VPU_EncSetWrPtr(EncHandle handle, PhysicalAddress addr, int updateRdPtr)
|
|
{
|
|
CodecInst* pCodecInst;
|
|
CodecInst* pPendingInst;
|
|
EncInfo * pEncInfo;
|
|
RetCode ret;
|
|
|
|
ret = CheckEncInstanceValidity(handle);
|
|
if (ret != RETCODE_SUCCESS)
|
|
return ret;
|
|
pCodecInst = (CodecInst*)handle;
|
|
|
|
if (pCodecInst->productId == PRODUCT_ID_960 || pCodecInst->productId == PRODUCT_ID_980) {
|
|
return RETCODE_NOT_SUPPORTED_FEATURE;
|
|
}
|
|
|
|
pEncInfo = &handle->CodecInfo->encInfo;
|
|
pPendingInst = GetPendingInst(pCodecInst->coreIdx);
|
|
if (pCodecInst == pPendingInst) {
|
|
VpuWriteReg(pCodecInst->coreIdx, pEncInfo->streamWrPtrRegAddr, addr);
|
|
}
|
|
else {
|
|
EnterLock(pCodecInst->coreIdx);
|
|
VpuWriteReg(pCodecInst->coreIdx, pEncInfo->streamWrPtrRegAddr, addr);
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
}
|
|
pEncInfo->streamWrPtr = addr;
|
|
if (updateRdPtr)
|
|
pEncInfo->streamRdPtr = addr;
|
|
|
|
return RETCODE_SUCCESS;
|
|
}
|
|
|
|
RetCode VPU_DecClrDispFlag(DecHandle handle, int index)
|
|
{
|
|
CodecInst* pCodecInst;
|
|
DecInfo* pDecInfo;
|
|
RetCode ret = RETCODE_SUCCESS;
|
|
Int32 endIndex, SvacSvcFlag;
|
|
VpuAttr* pAttr = NULL;
|
|
BOOL supportCommandQueue;
|
|
|
|
ret = CheckDecInstanceValidity(handle);
|
|
if (ret != RETCODE_SUCCESS)
|
|
return ret;
|
|
|
|
pCodecInst = handle;
|
|
pDecInfo = &pCodecInst->CodecInfo->decInfo;
|
|
pAttr = &g_VpuCoreAttributes[pCodecInst->coreIdx];
|
|
|
|
SvacSvcFlag = (pCodecInst->codecMode == W_SVAC_DEC && pDecInfo->initialInfo.spatialSvcEnable == TRUE);
|
|
|
|
endIndex = (pDecInfo->openParam.wtlEnable == TRUE) ? pDecInfo->numFbsForWTL : (SvacSvcFlag == TRUE ? pDecInfo->numFbsForDecoding*2 : pDecInfo->numFbsForDecoding);
|
|
|
|
if ((index < 0) || (index > (endIndex - 1))) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
|
|
supportCommandQueue = (pAttr->supportCommandQueue == TRUE);
|
|
if (supportCommandQueue == TRUE) {
|
|
EnterLock(pCodecInst->coreIdx);
|
|
ret = ProductVpuDecClrDispFlag(pCodecInst, index);
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
}
|
|
else {
|
|
EnterDispFlagLock(pCodecInst->coreIdx);
|
|
pDecInfo->clearDisplayIndexes |= (1<<index);
|
|
LeaveDispFlagLock(pCodecInst->coreIdx);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
RetCode VPU_DecGiveCommand(DecHandle handle, CodecCommand cmd, void* param)
|
|
{
|
|
CodecInst* pCodecInst;
|
|
DecInfo* pDecInfo;
|
|
RetCode ret;
|
|
|
|
ret = CheckDecInstanceValidity(handle);
|
|
if (ret != RETCODE_SUCCESS)
|
|
return ret;
|
|
|
|
pCodecInst = handle;
|
|
pDecInfo = &pCodecInst->CodecInfo->decInfo;
|
|
switch (cmd)
|
|
{
|
|
case ENABLE_ROTATION :
|
|
{
|
|
if (pDecInfo->rotatorStride == 0) {
|
|
return RETCODE_ROTATOR_STRIDE_NOT_SET;
|
|
}
|
|
pDecInfo->rotationEnable = 1;
|
|
break;
|
|
}
|
|
|
|
case DISABLE_ROTATION :
|
|
{
|
|
pDecInfo->rotationEnable = 0;
|
|
break;
|
|
}
|
|
|
|
case ENABLE_MIRRORING :
|
|
{
|
|
if (pDecInfo->rotatorStride == 0) {
|
|
return RETCODE_ROTATOR_STRIDE_NOT_SET;
|
|
}
|
|
pDecInfo->mirrorEnable = 1;
|
|
break;
|
|
}
|
|
case DISABLE_MIRRORING :
|
|
{
|
|
pDecInfo->mirrorEnable = 0;
|
|
break;
|
|
}
|
|
case SET_MIRROR_DIRECTION :
|
|
{
|
|
|
|
MirrorDirection mirDir;
|
|
|
|
if (param == 0) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
mirDir = *(MirrorDirection *)param;
|
|
if ( !(mirDir == MIRDIR_NONE) && !(mirDir==MIRDIR_HOR) && !(mirDir==MIRDIR_VER) && !(mirDir==MIRDIR_HOR_VER)) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
pDecInfo->mirrorDirection = mirDir;
|
|
|
|
break;
|
|
}
|
|
case SET_ROTATION_ANGLE :
|
|
{
|
|
int angle;
|
|
|
|
if (param == 0) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
angle = *(int *)param;
|
|
if (angle != 0 && angle != 90 &&
|
|
angle != 180 && angle != 270) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
if (pDecInfo->rotatorStride != 0) {
|
|
if (angle == 90 || angle ==270) {
|
|
if (pDecInfo->initialInfo.picHeight > pDecInfo->rotatorStride) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
} else {
|
|
if (pDecInfo->initialInfo.picWidth > pDecInfo->rotatorStride) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
}
|
|
}
|
|
|
|
pDecInfo->rotationAngle = angle;
|
|
break;
|
|
}
|
|
case SET_ROTATOR_OUTPUT :
|
|
{
|
|
FrameBuffer *frame;
|
|
if (param == 0) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
frame = (FrameBuffer *)param;
|
|
|
|
pDecInfo->rotatorOutput = *frame;
|
|
pDecInfo->rotatorOutputValid = 1;
|
|
break;
|
|
}
|
|
|
|
case SET_ROTATOR_STRIDE :
|
|
{
|
|
int stride;
|
|
|
|
if (param == 0) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
stride = *(int *)param;
|
|
if (stride % 8 != 0 || stride == 0) {
|
|
return RETCODE_INVALID_STRIDE;
|
|
}
|
|
|
|
if (pDecInfo->rotationAngle == 90 || pDecInfo->rotationAngle == 270) {
|
|
if (pDecInfo->initialInfo.picHeight > stride) {
|
|
return RETCODE_INVALID_STRIDE;
|
|
}
|
|
} else {
|
|
if (pDecInfo->initialInfo.picWidth > stride) {
|
|
return RETCODE_INVALID_STRIDE;
|
|
}
|
|
}
|
|
|
|
pDecInfo->rotatorStride = stride;
|
|
break;
|
|
}
|
|
case DEC_SET_SPS_RBSP:
|
|
{
|
|
if (pCodecInst->codecMode != AVC_DEC) {
|
|
return RETCODE_INVALID_COMMAND;
|
|
}
|
|
if (param == 0) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
|
|
return SetParaSet(handle, 0, (DecParamSet *)param);
|
|
|
|
}
|
|
|
|
case DEC_SET_PPS_RBSP:
|
|
{
|
|
if (pCodecInst->codecMode != AVC_DEC) {
|
|
return RETCODE_INVALID_COMMAND;
|
|
}
|
|
if (param == 0) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
|
|
return SetParaSet(handle, 1, (DecParamSet *)param);
|
|
}
|
|
case ENABLE_DERING :
|
|
{
|
|
if (pDecInfo->rotatorStride == 0) {
|
|
return RETCODE_ROTATOR_STRIDE_NOT_SET;
|
|
}
|
|
pDecInfo->deringEnable = 1;
|
|
break;
|
|
}
|
|
|
|
case DISABLE_DERING :
|
|
{
|
|
pDecInfo->deringEnable = 0;
|
|
break;
|
|
}
|
|
case SET_SEC_AXI:
|
|
{
|
|
SecAxiUse secAxiUse;
|
|
|
|
if (param == 0) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
secAxiUse = *(SecAxiUse *)param;
|
|
if (handle->productId == PRODUCT_ID_511 || handle->productId == PRODUCT_ID_517 || handle->productId == PRODUCT_ID_521) {
|
|
pDecInfo->secAxiInfo.u.wave.useIpEnable = secAxiUse.u.wave.useIpEnable;
|
|
pDecInfo->secAxiInfo.u.wave.useLfRowEnable = secAxiUse.u.wave.useLfRowEnable;
|
|
pDecInfo->secAxiInfo.u.wave.useBitEnable = secAxiUse.u.wave.useBitEnable;
|
|
pDecInfo->secAxiInfo.u.wave.useSclEnable = secAxiUse.u.wave.useSclEnable;
|
|
}
|
|
else {
|
|
pDecInfo->secAxiInfo.u.coda9.useBitEnable = secAxiUse.u.coda9.useBitEnable;
|
|
pDecInfo->secAxiInfo.u.coda9.useIpEnable = secAxiUse.u.coda9.useIpEnable;
|
|
pDecInfo->secAxiInfo.u.coda9.useDbkYEnable = secAxiUse.u.coda9.useDbkYEnable;
|
|
pDecInfo->secAxiInfo.u.coda9.useDbkCEnable = secAxiUse.u.coda9.useDbkCEnable;
|
|
pDecInfo->secAxiInfo.u.coda9.useOvlEnable = secAxiUse.u.coda9.useOvlEnable;
|
|
pDecInfo->secAxiInfo.u.coda9.useBtpEnable = secAxiUse.u.coda9.useBtpEnable;
|
|
}
|
|
|
|
break;
|
|
}
|
|
case ENABLE_REP_USERDATA:
|
|
{
|
|
if (!pDecInfo->userDataBufAddr) {
|
|
return RETCODE_USERDATA_BUF_NOT_SET;
|
|
}
|
|
if (pDecInfo->userDataBufSize == 0) {
|
|
return RETCODE_USERDATA_BUF_NOT_SET;
|
|
}
|
|
switch (pCodecInst->productId) {
|
|
case PRODUCT_ID_521:
|
|
case PRODUCT_ID_511:
|
|
case PRODUCT_ID_517:
|
|
if (!param)
|
|
return RETCODE_INVALID_PARAM;
|
|
pDecInfo->userDataEnable = *(Uint32*)param;
|
|
break;
|
|
case PRODUCT_ID_960:
|
|
case PRODUCT_ID_980:
|
|
pDecInfo->userDataEnable = TRUE;
|
|
break;
|
|
default:
|
|
VLOG(INFO, "%s(ENABLE_REP_DATA) invalid productId(%d)\n", __FUNCTION__, pCodecInst->productId);
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
break;
|
|
}
|
|
case DISABLE_REP_USERDATA:
|
|
{
|
|
pDecInfo->userDataEnable = 0;
|
|
break;
|
|
}
|
|
case SET_ADDR_REP_USERDATA:
|
|
{
|
|
PhysicalAddress userDataBufAddr;
|
|
|
|
if (param == 0) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
userDataBufAddr = *(PhysicalAddress *)param;
|
|
if (userDataBufAddr % 8 != 0 || userDataBufAddr == 0) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
|
|
pDecInfo->userDataBufAddr = userDataBufAddr;
|
|
break;
|
|
}
|
|
case SET_VIRT_ADDR_REP_USERDATA:
|
|
{
|
|
unsigned long userDataVirtAddr;
|
|
|
|
if (param == 0) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
|
|
if (!pDecInfo->userDataBufAddr) {
|
|
return RETCODE_USERDATA_BUF_NOT_SET;
|
|
}
|
|
if (pDecInfo->userDataBufSize == 0) {
|
|
return RETCODE_USERDATA_BUF_NOT_SET;
|
|
}
|
|
|
|
userDataVirtAddr = *(unsigned long *)param;
|
|
if (!userDataVirtAddr) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
|
|
pDecInfo->vbUserData.phys_addr = pDecInfo->userDataBufAddr;
|
|
pDecInfo->vbUserData.size = pDecInfo->userDataBufSize;
|
|
pDecInfo->vbUserData.virt_addr = (unsigned long)userDataVirtAddr;
|
|
if (vdi_attach_dma_memory(pCodecInst->coreIdx, &pDecInfo->vbUserData) != 0) {
|
|
return RETCODE_INSUFFICIENT_RESOURCE;
|
|
}
|
|
break;
|
|
}
|
|
case SET_SIZE_REP_USERDATA:
|
|
{
|
|
PhysicalAddress userDataBufSize;
|
|
|
|
if (param == 0) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
userDataBufSize = *(PhysicalAddress *)param;
|
|
|
|
pDecInfo->userDataBufSize = userDataBufSize;
|
|
break;
|
|
}
|
|
|
|
case SET_USERDATA_REPORT_MODE:
|
|
{
|
|
int userDataMode;
|
|
|
|
userDataMode = *(int *)param;
|
|
if (userDataMode != 1 && userDataMode != 0) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
pDecInfo->userDataReportMode = userDataMode;
|
|
break;
|
|
}
|
|
case SET_CACHE_CONFIG:
|
|
{
|
|
MaverickCacheConfig *mcCacheConfig;
|
|
if (param == 0) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
mcCacheConfig = (MaverickCacheConfig *)param;
|
|
pDecInfo->cacheConfig = *mcCacheConfig;
|
|
}
|
|
break;
|
|
case SET_LOW_DELAY_CONFIG:
|
|
{
|
|
LowDelayInfo *lowDelayInfo;
|
|
if (param == 0) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
if (pCodecInst->productId != PRODUCT_ID_980) {
|
|
return RETCODE_NOT_SUPPORTED_FEATURE;
|
|
}
|
|
lowDelayInfo = (LowDelayInfo *)param;
|
|
|
|
if (lowDelayInfo->lowDelayEn) {
|
|
if ( (pCodecInst->codecMode != AVC_DEC) ||
|
|
pDecInfo->rotationEnable ||
|
|
pDecInfo->mirrorEnable ||
|
|
pDecInfo->tiled2LinearEnable ||
|
|
pDecInfo->deringEnable) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
}
|
|
|
|
pDecInfo->lowDelayInfo.lowDelayEn = lowDelayInfo->lowDelayEn;
|
|
pDecInfo->lowDelayInfo.numRows = lowDelayInfo->numRows;
|
|
}
|
|
break;
|
|
|
|
case DEC_SET_FRAME_DELAY:
|
|
{
|
|
pDecInfo->frameDelay = *(int *)param;
|
|
break;
|
|
}
|
|
case DEC_ENABLE_REORDER:
|
|
{
|
|
if((handle->productId == PRODUCT_ID_980) || (handle->productId == PRODUCT_ID_960) || (handle->productId == PRODUCT_ID_950))
|
|
{
|
|
if (pDecInfo->initialInfoObtained) {
|
|
return RETCODE_WRONG_CALL_SEQUENCE;
|
|
}
|
|
}
|
|
|
|
pDecInfo->reorderEnable = TRUE;
|
|
break;
|
|
}
|
|
case DEC_DISABLE_REORDER:
|
|
{
|
|
if((handle->productId == PRODUCT_ID_980) || (handle->productId == PRODUCT_ID_960) || (handle->productId == PRODUCT_ID_950))
|
|
{
|
|
if (pDecInfo->initialInfoObtained) {
|
|
return RETCODE_WRONG_CALL_SEQUENCE;
|
|
}
|
|
|
|
if(pCodecInst->codecMode != AVC_DEC && pCodecInst->codecMode != VC1_DEC && pCodecInst->codecMode != AVS_DEC) {
|
|
return RETCODE_INVALID_COMMAND;
|
|
}
|
|
}
|
|
|
|
pDecInfo->reorderEnable = FALSE;
|
|
break;
|
|
}
|
|
case DEC_SET_AVC_ERROR_CONCEAL_MODE:
|
|
{
|
|
if(pCodecInst->codecMode != AVC_DEC) {
|
|
return RETCODE_INVALID_COMMAND;
|
|
}
|
|
|
|
pDecInfo->avcErrorConcealMode = *(int *)param;
|
|
break;
|
|
}
|
|
case DEC_FREE_FRAME_BUFFER:
|
|
{
|
|
int i;
|
|
if (pDecInfo->vbSlice.size)
|
|
vdi_free_dma_memory(pCodecInst->coreIdx, &pDecInfo->vbSlice, DEC_ETC, pCodecInst->instIndex);
|
|
|
|
if (pDecInfo->vbFrame.size){
|
|
if (pDecInfo->frameAllocExt == 0)
|
|
vdi_free_dma_memory(pCodecInst->coreIdx, &pDecInfo->vbFrame, DEC_ETC, pCodecInst->instIndex);
|
|
}
|
|
for (i=0 ; i<MAX_REG_FRAME; i++) {
|
|
if (pDecInfo->vbFbcYTbl[i].size)
|
|
vdi_free_dma_memory(pCodecInst->coreIdx, &pDecInfo->vbFbcYTbl[i], DEC_FBCY_TBL, pCodecInst->instIndex);
|
|
|
|
if (pDecInfo->vbFbcCTbl[i].size)
|
|
vdi_free_dma_memory(pCodecInst->coreIdx, &pDecInfo->vbFbcCTbl[i], DEC_FBCC_TBL, pCodecInst->instIndex);
|
|
|
|
if (pDecInfo->vbMV[i].size)
|
|
vdi_free_dma_memory(pCodecInst->coreIdx, &pDecInfo->vbMV[i], DEC_MV, pCodecInst->instIndex);
|
|
}
|
|
|
|
if (pDecInfo->vbPPU.size) {
|
|
if (pDecInfo->ppuAllocExt == 0)
|
|
vdi_free_dma_memory(pCodecInst->coreIdx, &pDecInfo->vbPPU, DEC_ETC, pCodecInst->instIndex);
|
|
}
|
|
|
|
if (pDecInfo->wtlEnable) {
|
|
if (pDecInfo->vbWTL.size)
|
|
vdi_free_dma_memory(pCodecInst->coreIdx, &pDecInfo->vbWTL, DEC_FB_LINEAR, pCodecInst->instIndex);
|
|
}
|
|
break;
|
|
}
|
|
case DEC_GET_FRAMEBUF_INFO:
|
|
{
|
|
DecGetFramebufInfo* fbInfo = (DecGetFramebufInfo*)param;
|
|
Uint32 i;
|
|
fbInfo->vbFrame = pDecInfo->vbFrame;
|
|
fbInfo->vbWTL = pDecInfo->vbWTL;
|
|
for (i=0 ; i<MAX_REG_FRAME; i++)
|
|
{
|
|
fbInfo->vbFbcYTbl[i] = pDecInfo->vbFbcYTbl[i];
|
|
fbInfo->vbFbcCTbl[i] = pDecInfo->vbFbcCTbl[i];
|
|
fbInfo->vbMvCol[i] = pDecInfo->vbMV[i];
|
|
}
|
|
|
|
for (i=0; i<MAX_GDI_IDX*2; i++) {
|
|
fbInfo->framebufPool[i] = pDecInfo->frameBufPool[i];
|
|
}
|
|
fbInfo->vbTask = pDecInfo->vbTask;
|
|
}
|
|
break;
|
|
case DEC_RESET_FRAMEBUF_INFO:
|
|
{
|
|
int i;
|
|
|
|
pDecInfo->vbFrame.base = 0;
|
|
pDecInfo->vbFrame.phys_addr = 0;
|
|
pDecInfo->vbFrame.virt_addr = 0;
|
|
pDecInfo->vbFrame.size = 0;
|
|
pDecInfo->vbWTL.base = 0;
|
|
pDecInfo->vbWTL.phys_addr = 0;
|
|
pDecInfo->vbWTL.virt_addr = 0;
|
|
pDecInfo->vbWTL.size = 0;
|
|
for (i=0 ; i<MAX_REG_FRAME; i++)
|
|
{
|
|
pDecInfo->vbFbcYTbl[i].base = 0;
|
|
pDecInfo->vbFbcYTbl[i].phys_addr = 0;
|
|
pDecInfo->vbFbcYTbl[i].virt_addr = 0;
|
|
pDecInfo->vbFbcYTbl[i].size = 0;
|
|
pDecInfo->vbFbcCTbl[i].base = 0;
|
|
pDecInfo->vbFbcCTbl[i].phys_addr = 0;
|
|
pDecInfo->vbFbcCTbl[i].virt_addr = 0;
|
|
pDecInfo->vbFbcCTbl[i].size = 0;
|
|
pDecInfo->vbMV[i].base = 0;
|
|
pDecInfo->vbMV[i].phys_addr = 0;
|
|
pDecInfo->vbMV[i].virt_addr = 0;
|
|
pDecInfo->vbMV[i].size = 0;
|
|
}
|
|
|
|
pDecInfo->frameDisplayFlag = 0;
|
|
pDecInfo->setDisplayIndexes = 0;
|
|
pDecInfo->clearDisplayIndexes = 0;
|
|
break;
|
|
}
|
|
case DEC_GET_QUEUE_STATUS:
|
|
{
|
|
QueueStatusInfo* queueInfo = (QueueStatusInfo*)param;
|
|
queueInfo->instanceQueueCount = pDecInfo->instanceQueueCount;
|
|
queueInfo->reportQueueCount = pDecInfo->reportQueueCount;
|
|
break;
|
|
}
|
|
|
|
|
|
case ENABLE_DEC_THUMBNAIL_MODE:
|
|
{
|
|
pDecInfo->thumbnailMode = 1;
|
|
break;
|
|
}
|
|
case DEC_GET_SEQ_INFO:
|
|
{
|
|
DecInitialInfo* seqInfo = (DecInitialInfo*)param;
|
|
*seqInfo = pDecInfo->initialInfo;
|
|
break;
|
|
}
|
|
case DEC_GET_FIELD_PIC_TYPE:
|
|
{
|
|
return RETCODE_FAILURE;
|
|
}
|
|
case DEC_GET_DISPLAY_OUTPUT_INFO:
|
|
{
|
|
DecOutputInfo *pDecOutInfo = (DecOutputInfo *)param;
|
|
*pDecOutInfo = pDecInfo->decOutInfo[pDecOutInfo->indexFrameDisplay];
|
|
break;
|
|
}
|
|
case GET_TILEDMAP_CONFIG:
|
|
{
|
|
TiledMapConfig *pMapCfg = (TiledMapConfig *)param;
|
|
if (!pMapCfg) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
if (!pDecInfo->stride) {
|
|
return RETCODE_WRONG_CALL_SEQUENCE;
|
|
|
|
}
|
|
*pMapCfg = pDecInfo->mapCfg;
|
|
break;
|
|
}
|
|
case SET_DRAM_CONFIG:
|
|
{
|
|
DRAMConfig *cfg = (DRAMConfig *)param;
|
|
|
|
if (!cfg) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
|
|
pDecInfo->dramCfg = *cfg;
|
|
break;
|
|
}
|
|
case GET_DRAM_CONFIG:
|
|
{
|
|
DRAMConfig *cfg = (DRAMConfig *)param;
|
|
|
|
if (!cfg) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
|
|
*cfg = pDecInfo->dramCfg;
|
|
|
|
break;
|
|
}
|
|
case GET_LOW_DELAY_OUTPUT:
|
|
{
|
|
DecOutputInfo *lowDelayOutput;
|
|
if (param == 0) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
|
|
if (!pDecInfo->lowDelayInfo.lowDelayEn || pCodecInst->codecMode != AVC_DEC) {
|
|
return RETCODE_INVALID_COMMAND;
|
|
}
|
|
|
|
if (pCodecInst != GetPendingInst(pCodecInst->coreIdx)) {
|
|
return RETCODE_WRONG_CALL_SEQUENCE;
|
|
}
|
|
|
|
lowDelayOutput = (DecOutputInfo *)param;
|
|
|
|
GetLowDelayOutput(pCodecInst, lowDelayOutput);
|
|
}
|
|
break;
|
|
case ENABLE_LOGGING:
|
|
{
|
|
pCodecInst->loggingEnable = 1;
|
|
}
|
|
break;
|
|
case DISABLE_LOGGING:
|
|
{
|
|
pCodecInst->loggingEnable = 0;
|
|
}
|
|
break;
|
|
case DEC_SET_SEQ_CHANGE_MASK:
|
|
if (PRODUCT_ID_NOT_W_SERIES(pCodecInst->productId))
|
|
return RETCODE_INVALID_PARAM;
|
|
pDecInfo->seqChangeMask = *(int*)param;
|
|
break;
|
|
case DEC_SET_WTL_FRAME_FORMAT:
|
|
pDecInfo->wtlFormat = *(FrameBufferFormat*)param;
|
|
break;
|
|
case DEC_SET_DISPLAY_FLAG:
|
|
{
|
|
Int32 index;
|
|
VpuAttr* pAttr = &g_VpuCoreAttributes[pCodecInst->coreIdx];
|
|
BOOL supportCommandQueue = FALSE;
|
|
|
|
if (param == 0) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
|
|
index = *(Int32 *)param;
|
|
|
|
supportCommandQueue = (pAttr->supportCommandQueue == TRUE);
|
|
if (supportCommandQueue == TRUE) {
|
|
EnterLock(pCodecInst->coreIdx);
|
|
ProductVpuDecSetDispFlag(pCodecInst, index);
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
}
|
|
else {
|
|
EnterDispFlagLock(pCodecInst->coreIdx);
|
|
pDecInfo->setDisplayIndexes |= (1<<index);
|
|
LeaveDispFlagLock(pCodecInst->coreIdx);
|
|
}
|
|
|
|
}
|
|
break;
|
|
case DEC_GET_SCALER_INFO:
|
|
{
|
|
ScalerInfo* scalerInfo = (ScalerInfo*)param;
|
|
if (scalerInfo == NULL) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
scalerInfo->enScaler = pDecInfo->scalerEnable;
|
|
scalerInfo->scaleWidth = pDecInfo->scaleWidth;
|
|
scalerInfo->scaleHeight = pDecInfo->scaleHeight;
|
|
}
|
|
break;
|
|
case DEC_SET_SCALER_INFO:
|
|
{
|
|
ScalerInfo* scalerInfo = (ScalerInfo*)param;
|
|
|
|
if (!pDecInfo->initialInfoObtained) {
|
|
return RETCODE_WRONG_CALL_SEQUENCE;
|
|
}
|
|
|
|
if (scalerInfo == NULL) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
|
|
pDecInfo->scalerEnable = scalerInfo->enScaler;
|
|
if (scalerInfo->enScaler == TRUE) {
|
|
VpuAttr* pAttr = &g_VpuCoreAttributes[pCodecInst->coreIdx];
|
|
Uint32 scalerStep = (pAttr->support2AlignScaler == TRUE) ? 2 : 8;
|
|
// minW = Ceil8(picWidth/8), minH = Ceil8(picHeight/8)
|
|
Uint32 minScaleWidth = VPU_ALIGN8(pDecInfo->initialInfo.picWidth>>3);
|
|
Uint32 minScaleHeight = VPU_ALIGN8(pDecInfo->initialInfo.picHeight>>3);
|
|
|
|
if (minScaleWidth == 0) minScaleWidth = 8;
|
|
if (minScaleHeight == 0) minScaleHeight = 8;
|
|
|
|
if (scalerInfo->scaleWidth < minScaleWidth || scalerInfo->scaleHeight < minScaleHeight) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
|
|
if (scalerInfo->scaleWidth > 0 || scalerInfo->scaleHeight > 0) {
|
|
if ((scalerInfo->scaleWidth % scalerStep) || scalerInfo->scaleWidth > (Uint32)(VPU_ALIGN8(pDecInfo->initialInfo.picWidth))) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
|
|
if ((scalerInfo->scaleHeight % scalerStep) || scalerInfo->scaleHeight > (Uint32)(VPU_ALIGN8(pDecInfo->initialInfo.picHeight))) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
pDecInfo->scaleWidth = scalerInfo->scaleWidth;
|
|
pDecInfo->scaleHeight = scalerInfo->scaleHeight;
|
|
pDecInfo->scalerEnable = scalerInfo->enScaler;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case DEC_SET_TARGET_TEMPORAL_ID:
|
|
if (param == NULL) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
if (pDecInfo->tempIdSelectMode == FALSE)
|
|
pDecInfo->targetSubLayerId = *(Uint32*)param;
|
|
else
|
|
pDecInfo->relTargetLayerId = *(Uint32*)param;
|
|
break;
|
|
case DEC_SET_TEMPORAL_ID_MODE:
|
|
if (param == NULL) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
pDecInfo->tempIdSelectMode = *(Uint32*)param;
|
|
break;
|
|
case DEC_SET_BWB_CUR_FRAME_IDX:
|
|
pDecInfo->chBwbFrameIdx = *(Uint32*)param;
|
|
break;
|
|
case DEC_SET_FBC_CUR_FRAME_IDX:
|
|
pDecInfo->chFbcFrameIdx = *(Uint32*)param;
|
|
break;
|
|
case DEC_SET_INTER_RES_INFO_ON:
|
|
pDecInfo->interResChange = 1;
|
|
break;
|
|
case DEC_SET_INTER_RES_INFO_OFF:
|
|
pDecInfo->interResChange = 0;
|
|
break;
|
|
case DEC_FREE_FBC_TABLE_BUFFER:
|
|
{
|
|
Uint32 fbcCurFrameIdx = *(Uint32*)param;
|
|
if(pDecInfo->vbFbcYTbl[fbcCurFrameIdx].size > 0) {
|
|
vdi_free_dma_memory(pCodecInst->coreIdx, &pDecInfo->vbFbcYTbl[fbcCurFrameIdx], DEC_FBCY_TBL, pCodecInst->instIndex);
|
|
pDecInfo->vbFbcYTbl[fbcCurFrameIdx].size = 0;
|
|
}
|
|
if(pDecInfo->vbFbcCTbl[fbcCurFrameIdx].size > 0) {
|
|
vdi_free_dma_memory(pCodecInst->coreIdx, &pDecInfo->vbFbcCTbl[fbcCurFrameIdx], DEC_FBCC_TBL, pCodecInst->instIndex);
|
|
pDecInfo->vbFbcCTbl[fbcCurFrameIdx].size = 0;
|
|
}
|
|
}
|
|
break;
|
|
case DEC_FREE_MV_BUFFER:
|
|
{
|
|
Uint32 fbcCurFrameIdx = *(Uint32*)param;
|
|
if(pDecInfo->vbMV[fbcCurFrameIdx].size > 0) {
|
|
vdi_free_dma_memory(pCodecInst->coreIdx, &pDecInfo->vbMV[fbcCurFrameIdx], DEC_MV, pCodecInst->instIndex);
|
|
pDecInfo->vbMV[fbcCurFrameIdx].size = 0;
|
|
}
|
|
}
|
|
break;
|
|
case DEC_ALLOC_MV_BUFFER:
|
|
{
|
|
Uint32 fbcCurFrameIdx = *(Uint32*)param;
|
|
Uint32 size;
|
|
size = WAVE5_DEC_VP9_MVCOL_BUF_SIZE(pDecInfo->initialInfo.picWidth, pDecInfo->initialInfo.picHeight);
|
|
pDecInfo->vbMV[fbcCurFrameIdx].phys_addr = 0;
|
|
pDecInfo->vbMV[fbcCurFrameIdx].size = ((size+4095)&~4095)+4096; /* 4096 is a margin */
|
|
if (vdi_allocate_dma_memory(pCodecInst->coreIdx, &pDecInfo->vbMV[fbcCurFrameIdx], DEC_MV, pCodecInst->instIndex) < 0)
|
|
return RETCODE_INSUFFICIENT_RESOURCE;
|
|
}
|
|
break;
|
|
case DEC_ALLOC_FBC_Y_TABLE_BUFFER:
|
|
{
|
|
Uint32 fbcCurFrameIdx = *(Uint32*)param;
|
|
Uint32 size;
|
|
size = WAVE5_FBC_LUMA_TABLE_SIZE(VPU_ALIGN64(pDecInfo->initialInfo.picWidth), VPU_ALIGN64(pDecInfo->initialInfo.picHeight));
|
|
size = VPU_ALIGN16(size);
|
|
pDecInfo->vbFbcYTbl[fbcCurFrameIdx].phys_addr = 0;
|
|
pDecInfo->vbFbcYTbl[fbcCurFrameIdx].size = ((size+4095)&~4095)+4096;
|
|
if (vdi_allocate_dma_memory(pCodecInst->coreIdx, &pDecInfo->vbFbcYTbl[fbcCurFrameIdx], DEC_FBCY_TBL, pCodecInst->instIndex) < 0)
|
|
return RETCODE_INSUFFICIENT_RESOURCE;
|
|
}
|
|
break;
|
|
case DEC_ALLOC_FBC_C_TABLE_BUFFER:
|
|
{
|
|
Uint32 fbcCurFrameIdx = *(Uint32*)param;
|
|
Uint32 size;
|
|
size = WAVE5_FBC_CHROMA_TABLE_SIZE(VPU_ALIGN64(pDecInfo->initialInfo.picWidth), VPU_ALIGN64(pDecInfo->initialInfo.picHeight));
|
|
size = VPU_ALIGN16(size);
|
|
pDecInfo->vbFbcCTbl[fbcCurFrameIdx].phys_addr = 0;
|
|
pDecInfo->vbFbcCTbl[fbcCurFrameIdx].size = ((size+4095)&~4095)+4096;
|
|
if (vdi_allocate_dma_memory(pCodecInst->coreIdx, &pDecInfo->vbFbcCTbl[fbcCurFrameIdx], DEC_FBCC_TBL, pCodecInst->instIndex) < 0)
|
|
return RETCODE_INSUFFICIENT_RESOURCE;
|
|
}
|
|
break;
|
|
case GET_BANDWIDTH_REPORT:
|
|
EnterLock(pCodecInst->coreIdx);
|
|
ret = ProductVpuGetBandwidth(pCodecInst, (VPUBWData*)param);
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
break;
|
|
case SET_CYCLE_PER_TICK:
|
|
{
|
|
pDecInfo->cyclePerTick = *(Uint32 *)param;
|
|
}
|
|
break;
|
|
case GET_DEBUG_INFORM:
|
|
EnterLock(pCodecInst->coreIdx);
|
|
ret = ProductVpuGetDebugInfo(pCodecInst, (VPUDebugInfo*)param);
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
break;
|
|
default:
|
|
return RETCODE_INVALID_COMMAND;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
RetCode VPU_DecAllocateFrameBuffer(DecHandle handle, FrameBufferAllocInfo info, FrameBuffer *frameBuffer)
|
|
{
|
|
CodecInst* pCodecInst;
|
|
DecInfo* pDecInfo;
|
|
RetCode ret;
|
|
Uint32 gdiIndex;
|
|
|
|
ret = CheckDecInstanceValidity(handle);
|
|
if (ret != RETCODE_SUCCESS)
|
|
return ret;
|
|
|
|
pCodecInst = handle;
|
|
pDecInfo = &pCodecInst->CodecInfo->decInfo;
|
|
|
|
if (!frameBuffer) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
|
|
if (info.type == FB_TYPE_PPU) {
|
|
if (pDecInfo->numFrameBuffers == 0)
|
|
return RETCODE_WRONG_CALL_SEQUENCE;
|
|
if (frameBuffer[0].updateFbInfo == TRUE) {
|
|
pDecInfo->ppuAllocExt = TRUE;
|
|
}
|
|
pDecInfo->ppuAllocExt = frameBuffer[0].updateFbInfo;
|
|
gdiIndex = pDecInfo->numFbsForDecoding;
|
|
ret = ProductVpuAllocateFramebuffer(
|
|
pCodecInst, frameBuffer, (TiledMapType)info.mapType, (Int32)info.num,
|
|
info.stride, info.height, info.format, info.cbcrInterleave, info.nv21, info.endian, &pDecInfo->vbPPU, gdiIndex, FB_TYPE_PPU);
|
|
}
|
|
else if (info.type == FB_TYPE_CODEC) {
|
|
gdiIndex = 0;
|
|
if (frameBuffer[0].updateFbInfo == TRUE) {
|
|
pDecInfo->frameAllocExt = TRUE;
|
|
}
|
|
ret = ProductVpuAllocateFramebuffer(
|
|
pCodecInst, frameBuffer, (TiledMapType)info.mapType, (Int32)info.num,
|
|
info.stride, info.height, info.format, info.cbcrInterleave, info.nv21, info.endian, &pDecInfo->vbFrame, gdiIndex, (FramebufferAllocType)info.type);
|
|
|
|
pDecInfo->mapCfg.tiledBaseAddr = pDecInfo->vbFrame.phys_addr;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
RetCode VPU_EncOpen(EncHandle* pHandle, EncOpenParam * pop)
|
|
{
|
|
CodecInst* pCodecInst = NULL;
|
|
EncInfo* pEncInfo = NULL;
|
|
RetCode ret = RETCODE_SUCCESS;
|
|
|
|
if ((ret=ProductVpuEncCheckOpenParam(pop)) != RETCODE_SUCCESS)
|
|
return ret;
|
|
|
|
EnterLock(pop->coreIdx);
|
|
|
|
if (VPU_IsInit(pop->coreIdx) == 0) {
|
|
LeaveLock(pop->coreIdx);
|
|
return RETCODE_NOT_INITIALIZED;
|
|
}
|
|
|
|
ret = GetCodecInstance(pop->coreIdx, &pCodecInst);
|
|
if (ret == RETCODE_FAILURE) {
|
|
*pHandle = 0;
|
|
LeaveLock(pop->coreIdx);
|
|
return RETCODE_FAILURE;
|
|
}
|
|
|
|
pCodecInst->isDecoder = FALSE;
|
|
*pHandle = pCodecInst;
|
|
pEncInfo = &pCodecInst->CodecInfo->encInfo;
|
|
|
|
pEncInfo->openParam = *pop;
|
|
|
|
if ((ret=ProductVpuEncBuildUpOpenParam(pCodecInst, pop)) != RETCODE_SUCCESS) {
|
|
*pHandle = 0;
|
|
}
|
|
if (vdi_open_instance(pCodecInst->coreIdx, pCodecInst->instIndex) < 0) {
|
|
return RETCODE_FAILURE;
|
|
}
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
|
|
return ret;
|
|
}
|
|
|
|
RetCode VPU_EncClose(EncHandle handle)
|
|
{
|
|
CodecInst* pCodecInst;
|
|
EncInfo* pEncInfo;
|
|
RetCode ret;
|
|
|
|
ret = CheckEncInstanceValidity(handle);
|
|
if (ret != RETCODE_SUCCESS) {
|
|
return ret;
|
|
}
|
|
|
|
pCodecInst = handle;
|
|
pEncInfo = &pCodecInst->CodecInfo->encInfo;
|
|
|
|
EnterLock(pCodecInst->coreIdx);
|
|
|
|
if ((ret=ProductVpuEncFiniSeq(pCodecInst)) != RETCODE_SUCCESS) {
|
|
if (pCodecInst->loggingEnable)
|
|
vdi_log(pCodecInst->coreIdx, pCodecInst->instIndex, ENC_SEQ_END, 2);
|
|
|
|
if (ret == RETCODE_VPU_STILL_RUNNING) {
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
if (pCodecInst->loggingEnable)
|
|
vdi_log(pCodecInst->coreIdx, pCodecInst->instIndex, ENC_SEQ_END, 0);
|
|
|
|
if (pEncInfo->vbScratch.size) {
|
|
vdi_free_dma_memory(pCodecInst->coreIdx, &pEncInfo->vbScratch, ENC_ETC, pCodecInst->instIndex);
|
|
}
|
|
|
|
if (pEncInfo->vbWork.size) {
|
|
vdi_free_dma_memory(pCodecInst->coreIdx, &pEncInfo->vbWork, ENC_WORK, pCodecInst->instIndex);
|
|
}
|
|
|
|
if (pEncInfo->vbFrame.size) {
|
|
if (pEncInfo->frameAllocExt == 0)
|
|
vdi_free_dma_memory(pCodecInst->coreIdx, &pEncInfo->vbFrame, ENC_ETC, pCodecInst->instIndex);
|
|
}
|
|
|
|
if (pCodecInst->codecMode == W_HEVC_ENC || pCodecInst->codecMode == W_SVAC_ENC || pCodecInst->codecMode == W_AVC_ENC) {
|
|
if (pEncInfo->vbSubSamBuf.size)
|
|
vdi_free_dma_memory(pCodecInst->coreIdx, &pEncInfo->vbSubSamBuf, ENC_SUBSAMBUF, pCodecInst->instIndex);
|
|
|
|
if (pEncInfo->vbMV.size)
|
|
vdi_free_dma_memory(pCodecInst->coreIdx, &pEncInfo->vbMV, ENC_MV, pCodecInst->instIndex);
|
|
|
|
if (pEncInfo->vbFbcYTbl.size)
|
|
vdi_free_dma_memory(pCodecInst->coreIdx, &pEncInfo->vbFbcYTbl, ENC_FBCY_TBL, pCodecInst->instIndex);
|
|
|
|
if (pEncInfo->vbFbcCTbl.size)
|
|
vdi_free_dma_memory(pCodecInst->coreIdx, &pEncInfo->vbFbcCTbl, ENC_FBCC_TBL, pCodecInst->instIndex);
|
|
}
|
|
|
|
if (pEncInfo->vbPPU.size) {
|
|
if (pEncInfo->ppuAllocExt == 0)
|
|
vdi_free_dma_memory(pCodecInst->coreIdx, &pEncInfo->vbPPU, ENC_ETC, pCodecInst->instIndex);
|
|
}
|
|
if (pEncInfo->vbSubSampFrame.size)
|
|
vdi_free_dma_memory(pCodecInst->coreIdx, &pEncInfo->vbSubSampFrame, ENC_ETC, pCodecInst->instIndex);
|
|
if (pEncInfo->vbMvcSubSampFrame.size)
|
|
vdi_free_dma_memory(pCodecInst->coreIdx, &pEncInfo->vbMvcSubSampFrame, ENC_ETC, pCodecInst->instIndex);
|
|
|
|
if (pEncInfo->vbTask.size)
|
|
vdi_free_dma_memory(pCodecInst->coreIdx, &pEncInfo->vbTask, ENC_TASK, pCodecInst->instIndex);
|
|
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
|
|
FreeCodecInstance(pCodecInst);
|
|
|
|
return ret;
|
|
}
|
|
|
|
RetCode VPU_EncGetInitialInfo(EncHandle handle, EncInitialInfo * info)
|
|
{
|
|
CodecInst* pCodecInst;
|
|
EncInfo* pEncInfo;
|
|
RetCode ret;
|
|
|
|
ret = CheckEncInstanceValidity(handle);
|
|
if (ret != RETCODE_SUCCESS)
|
|
return ret;
|
|
|
|
if (info == 0) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
|
|
pCodecInst = handle;
|
|
pEncInfo = &pCodecInst->CodecInfo->encInfo;
|
|
|
|
EnterLock(pCodecInst->coreIdx);
|
|
|
|
if (GetPendingInst(pCodecInst->coreIdx)) {
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
return RETCODE_FRAME_NOT_COMPLETE;
|
|
}
|
|
|
|
if ((ret=ProductVpuEncSetup(pCodecInst)) != RETCODE_SUCCESS) {
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
return ret;
|
|
}
|
|
|
|
if (pCodecInst->codecMode == AVC_ENC && pCodecInst->codecModeAux == AVC_AUX_MVC)
|
|
info->minFrameBufferCount = 3; // reconstructed frame + 2 reference frame
|
|
else if(pCodecInst->codecMode == W_HEVC_ENC || pCodecInst->codecMode == W_SVAC_ENC || pCodecInst->codecMode == W_AVC_ENC) {
|
|
info->minFrameBufferCount = pEncInfo->initialInfo.minFrameBufferCount;
|
|
info->minSrcFrameCount = pEncInfo->initialInfo.minSrcFrameCount;
|
|
}
|
|
else
|
|
info->minFrameBufferCount = 2; // reconstructed frame + reference frame
|
|
|
|
pEncInfo->initialInfo = *info;
|
|
pEncInfo->initialInfoObtained = TRUE;
|
|
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
|
|
return RETCODE_SUCCESS;
|
|
}
|
|
|
|
RetCode VPU_EncRegisterFrameBuffer(EncHandle handle, FrameBuffer* bufArray, int num, int stride, int height, TiledMapType mapType)
|
|
{
|
|
CodecInst* pCodecInst;
|
|
EncInfo* pEncInfo;
|
|
Int32 i;
|
|
RetCode ret;
|
|
EncOpenParam* openParam;
|
|
FrameBuffer* fb;
|
|
|
|
ret = CheckEncInstanceValidity(handle);
|
|
// FIXME temp
|
|
if (ret != RETCODE_SUCCESS)
|
|
return ret;
|
|
|
|
pCodecInst = handle;
|
|
pEncInfo = &pCodecInst->CodecInfo->encInfo;
|
|
openParam = &pEncInfo->openParam;
|
|
|
|
if (pEncInfo->stride)
|
|
return RETCODE_CALLED_BEFORE;
|
|
|
|
if (!pEncInfo->initialInfoObtained)
|
|
return RETCODE_WRONG_CALL_SEQUENCE;
|
|
|
|
if (num < pEncInfo->initialInfo.minFrameBufferCount)
|
|
return RETCODE_INSUFFICIENT_FRAME_BUFFERS;
|
|
|
|
if (stride == 0 || (stride % 8 != 0) || stride < 0)
|
|
return RETCODE_INVALID_STRIDE;
|
|
|
|
if (height == 0 || height < 0)
|
|
return RETCODE_INVALID_PARAM;
|
|
|
|
EnterLock(pCodecInst->coreIdx);
|
|
|
|
if (GetPendingInst(pCodecInst->coreIdx)) {
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
return RETCODE_FRAME_NOT_COMPLETE;
|
|
}
|
|
|
|
pEncInfo->numFrameBuffers = num;
|
|
pEncInfo->stride = stride;
|
|
pEncInfo->frameBufferHeight = height;
|
|
pEncInfo->mapType = mapType;
|
|
pEncInfo->mapCfg.productId = pCodecInst->productId;
|
|
|
|
if (bufArray) {
|
|
for(i=0; i<num; i++) {
|
|
pEncInfo->frameBufPool[i] = bufArray[i];
|
|
}
|
|
|
|
if (openParam->EncStdParam.waveParam.svcEnable == TRUE) {
|
|
for(i=num; i<num*2; i++) {
|
|
pEncInfo->frameBufPool[i] = bufArray[i];
|
|
}
|
|
}
|
|
}
|
|
|
|
if (pEncInfo->frameAllocExt == FALSE) {
|
|
fb = pEncInfo->frameBufPool;
|
|
if (bufArray) {
|
|
if (bufArray[0].bufCb == (PhysicalAddress)-1 && bufArray[0].bufCr == (PhysicalAddress)-1) {
|
|
Uint32 size;
|
|
pEncInfo->frameAllocExt = TRUE;
|
|
size = ProductCalculateFrameBufSize(pCodecInst, pCodecInst->productId, stride, height,
|
|
(TiledMapType)mapType, (FrameBufferFormat)openParam->srcFormat,
|
|
(BOOL)openParam->cbcrInterleave, NULL);
|
|
if (mapType == LINEAR_FRAME_MAP) {
|
|
pEncInfo->vbFrame.phys_addr = bufArray[0].bufY;
|
|
pEncInfo->vbFrame.size = size * num;
|
|
}
|
|
}
|
|
}
|
|
ret = ProductVpuAllocateFramebuffer(
|
|
pCodecInst, fb, (TiledMapType)mapType, num, stride, height, (FrameBufferFormat)openParam->srcFormat,
|
|
openParam->cbcrInterleave, FALSE, openParam->frameEndian, &pEncInfo->vbFrame, 0, FB_TYPE_CODEC);
|
|
if (ret != RETCODE_SUCCESS) {
|
|
SetPendingInst(pCodecInst->coreIdx, 0);
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
ret = ProductVpuRegisterFramebuffer(pCodecInst);
|
|
|
|
SetPendingInst(pCodecInst->coreIdx, 0);
|
|
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
RetCode VPU_EncGetBitstreamBuffer( EncHandle handle,
|
|
PhysicalAddress * prdPrt,
|
|
PhysicalAddress * pwrPtr,
|
|
int * size)
|
|
{
|
|
CodecInst * pCodecInst;
|
|
EncInfo * pEncInfo;
|
|
PhysicalAddress rdPtr;
|
|
PhysicalAddress wrPtr;
|
|
Uint32 room;
|
|
RetCode ret;
|
|
|
|
ret = CheckEncInstanceValidity(handle);
|
|
if (ret != RETCODE_SUCCESS)
|
|
return ret;
|
|
|
|
if ( prdPrt == 0 || pwrPtr == 0 || size == 0) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
|
|
pCodecInst = handle;
|
|
pEncInfo = &pCodecInst->CodecInfo->encInfo;
|
|
|
|
rdPtr = pEncInfo->streamRdPtr;
|
|
|
|
if (GetPendingInst(pCodecInst->coreIdx) == pCodecInst)
|
|
wrPtr = VpuReadReg(pCodecInst->coreIdx, pEncInfo->streamWrPtrRegAddr);
|
|
else {
|
|
if (handle->productId == PRODUCT_ID_521) {
|
|
EnterLock(pCodecInst->coreIdx);
|
|
ProductVpuEncGetRdWrPtr(pCodecInst, &rdPtr, &wrPtr);
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
}
|
|
else
|
|
wrPtr = pEncInfo->streamWrPtr;
|
|
}
|
|
|
|
if(pEncInfo->ringBufferEnable == 1 || pEncInfo->lineBufIntEn == 1) {
|
|
if (wrPtr >= rdPtr) {
|
|
room = wrPtr - rdPtr;
|
|
}
|
|
else {
|
|
room = (pEncInfo->streamBufEndAddr - rdPtr) + (wrPtr - pEncInfo->streamBufStartAddr);
|
|
}
|
|
}
|
|
else {
|
|
if(wrPtr >= rdPtr)
|
|
room = wrPtr - rdPtr;
|
|
else
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
|
|
*prdPrt = rdPtr;
|
|
*pwrPtr = wrPtr;
|
|
*size = room;
|
|
|
|
return RETCODE_SUCCESS;
|
|
}
|
|
|
|
RetCode VPU_EncUpdateBitstreamBuffer(
|
|
EncHandle handle,
|
|
int size)
|
|
{
|
|
CodecInst * pCodecInst;
|
|
EncInfo * pEncInfo;
|
|
PhysicalAddress wrPtr;
|
|
PhysicalAddress rdPtr;
|
|
RetCode ret;
|
|
int room = 0;
|
|
ret = CheckEncInstanceValidity(handle);
|
|
if (ret != RETCODE_SUCCESS)
|
|
return ret;
|
|
|
|
pCodecInst = handle;
|
|
pEncInfo = &pCodecInst->CodecInfo->encInfo;
|
|
|
|
rdPtr = pEncInfo->streamRdPtr;
|
|
|
|
if (GetPendingInst(pCodecInst->coreIdx) == pCodecInst)
|
|
wrPtr = VpuReadReg(pCodecInst->coreIdx, pEncInfo->streamWrPtrRegAddr);
|
|
else
|
|
wrPtr = pEncInfo->streamWrPtr;
|
|
|
|
if ( rdPtr < wrPtr ) {
|
|
if ( rdPtr + size > wrPtr ) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
}
|
|
|
|
if (PRODUCT_ID_NOT_W_SERIES(pCodecInst->productId)) {
|
|
//************** for CODA *********************/
|
|
if (pEncInfo->ringBufferEnable == TRUE || pEncInfo->lineBufIntEn == TRUE) {
|
|
rdPtr += size;
|
|
if (rdPtr > pEncInfo->streamBufEndAddr) {
|
|
if (pEncInfo->lineBufIntEn == TRUE) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
room = rdPtr - pEncInfo->streamBufEndAddr;
|
|
rdPtr = pEncInfo->streamBufStartAddr;
|
|
rdPtr += room;
|
|
}
|
|
if (rdPtr == pEncInfo->streamBufEndAddr)
|
|
rdPtr = pEncInfo->streamBufStartAddr;
|
|
}
|
|
else {
|
|
rdPtr = pEncInfo->streamBufStartAddr;
|
|
}
|
|
}
|
|
else {
|
|
//************** for WAVE5 *********************/
|
|
if (size > 0) {
|
|
if (pEncInfo->ringBufferEnable == TRUE) {
|
|
rdPtr += size;
|
|
if (pEncInfo->ringBufferWrapEnable == TRUE) {
|
|
//======== [case1]. ring=1 & wrap=1 ===================
|
|
|
|
if (rdPtr > pEncInfo->streamBufEndAddr) {
|
|
if (pEncInfo->lineBufIntEn == TRUE) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
room = rdPtr - pEncInfo->streamBufEndAddr;
|
|
rdPtr = pEncInfo->streamBufStartAddr;
|
|
rdPtr += room;
|
|
}
|
|
|
|
pEncInfo->streamRdPtr = rdPtr;
|
|
EnterLock(pCodecInst->coreIdx);
|
|
ProductVpuEncUpdateBitstreamBuffer(pCodecInst);
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
if (rdPtr == pEncInfo->streamBufEndAddr) {
|
|
//set EndAddr to FW and set StartAddr to API
|
|
rdPtr = pEncInfo->streamBufStartAddr; // wrap-around
|
|
}
|
|
}
|
|
else {
|
|
//========= [case2]. ring=1 & wrap=0 ===================
|
|
pEncInfo->streamRdPtr = rdPtr;
|
|
EnterLock(pCodecInst->coreIdx);
|
|
ProductVpuEncUpdateBitstreamBuffer(pCodecInst);
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
if (rdPtr == pEncInfo->streamBufEndAddr) {
|
|
//set EndAddr to FW and set StartAddr to API
|
|
rdPtr = pEncInfo->streamBufStartAddr; // start? end? [FIX ME]
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
//========= [case3]. Line buffer mode ===================
|
|
if (VPU_ALIGN16(wrPtr) >= pEncInfo->streamRdPtr + pEncInfo->streamBufSize) { // linebuffer full detected. already host read whole bistream in bitstreamBuffer.
|
|
EnterLock(pCodecInst->coreIdx);
|
|
ProductVpuEncUpdateBitstreamBuffer(pCodecInst);
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
//************ update new CPB buffer addr/size ***************/
|
|
if (size == UPDATE_NEW_BS_BUF) {
|
|
EnterLock(pCodecInst->coreIdx);
|
|
ProductVpuEncUpdateBitstreamBuffer(pCodecInst);
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
}
|
|
}
|
|
}
|
|
|
|
pEncInfo->streamRdPtr = rdPtr;
|
|
pEncInfo->streamWrPtr = wrPtr;
|
|
if (GetPendingInst(pCodecInst->coreIdx) == pCodecInst)
|
|
VpuWriteReg(pCodecInst->coreIdx, pEncInfo->streamRdPtrRegAddr, rdPtr);
|
|
|
|
if (pEncInfo->ringBufferEnable == FALSE && pEncInfo->lineBufIntEn == TRUE) {
|
|
pEncInfo->streamRdPtr = pEncInfo->streamBufStartAddr;
|
|
}
|
|
|
|
return RETCODE_SUCCESS;
|
|
}
|
|
|
|
RetCode VPU_EncStartOneFrame(
|
|
EncHandle handle,
|
|
EncParam * param
|
|
)
|
|
{
|
|
CodecInst* pCodecInst;
|
|
EncInfo* pEncInfo;
|
|
RetCode ret;
|
|
VpuAttr* pAttr = NULL;
|
|
vpu_instance_pool_t* vip;
|
|
|
|
ret = CheckEncInstanceValidity(handle);
|
|
if (ret != RETCODE_SUCCESS)
|
|
return ret;
|
|
|
|
pCodecInst = handle;
|
|
pEncInfo = &pCodecInst->CodecInfo->encInfo;
|
|
vip = (vpu_instance_pool_t *)vdi_get_instance_pool(pCodecInst->coreIdx);
|
|
if (!vip) {
|
|
return RETCODE_INVALID_HANDLE;
|
|
}
|
|
|
|
if (pEncInfo->stride == 0) { // This means frame buffers have not been registered.
|
|
return RETCODE_WRONG_CALL_SEQUENCE;
|
|
}
|
|
|
|
ret = CheckEncParam(handle, param);
|
|
if (ret != RETCODE_SUCCESS) {
|
|
return ret;
|
|
}
|
|
|
|
pAttr = &g_VpuCoreAttributes[pCodecInst->coreIdx];
|
|
|
|
EnterLock(pCodecInst->coreIdx);
|
|
|
|
pEncInfo->ptsMap[param->srcIdx] = (pEncInfo->openParam.enablePTS == TRUE) ? GetTimestamp(handle) : param->pts;
|
|
|
|
if (GetPendingInst(pCodecInst->coreIdx)) {
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
return RETCODE_FRAME_NOT_COMPLETE;
|
|
}
|
|
|
|
ret = ProductVpuEncode(pCodecInst, param);
|
|
|
|
if (pAttr->supportCommandQueue == TRUE) {
|
|
SetPendingInst(pCodecInst->coreIdx, NULL);
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
}
|
|
else {
|
|
SetPendingInst(pCodecInst->coreIdx, pCodecInst);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
RetCode VPU_EncGetOutputInfo(
|
|
EncHandle handle,
|
|
EncOutputInfo* info
|
|
)
|
|
{
|
|
CodecInst* pCodecInst;
|
|
EncInfo* pEncInfo;
|
|
RetCode ret;
|
|
VpuAttr* pAttr;
|
|
|
|
ret = CheckEncInstanceValidity(handle);
|
|
if (ret != RETCODE_SUCCESS) {
|
|
return ret;
|
|
}
|
|
|
|
if (info == 0) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
|
|
pCodecInst = handle;
|
|
pEncInfo = &pCodecInst->CodecInfo->encInfo;
|
|
pAttr = &g_VpuCoreAttributes[pCodecInst->coreIdx];
|
|
|
|
if (pAttr->supportCommandQueue == TRUE) {
|
|
EnterLock(pCodecInst->coreIdx);
|
|
}
|
|
else {
|
|
if (pCodecInst != GetPendingInst(pCodecInst->coreIdx)) {
|
|
SetPendingInst(pCodecInst->coreIdx, 0);
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
return RETCODE_WRONG_CALL_SEQUENCE;
|
|
}
|
|
}
|
|
|
|
ret = ProductVpuEncGetResult(pCodecInst, info);
|
|
|
|
if (ret == RETCODE_SUCCESS) {
|
|
if (info->encSrcIdx >= 0 && info->reconFrameIndex >= 0 )
|
|
info->pts = pEncInfo->ptsMap[info->encSrcIdx];
|
|
}
|
|
else {
|
|
info->pts = 0LL;
|
|
}
|
|
|
|
SetPendingInst(pCodecInst->coreIdx, 0);
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
|
|
return ret;
|
|
}
|
|
|
|
RetCode VPU_EncGiveCommand(
|
|
EncHandle handle,
|
|
CodecCommand cmd,
|
|
void* param
|
|
)
|
|
{
|
|
CodecInst* pCodecInst;
|
|
EncInfo* pEncInfo;
|
|
RetCode ret;
|
|
|
|
ret = CheckEncInstanceValidity(handle);
|
|
if (ret != RETCODE_SUCCESS) {
|
|
return ret;
|
|
}
|
|
|
|
pCodecInst = handle;
|
|
pEncInfo = &pCodecInst->CodecInfo->encInfo;
|
|
switch (cmd)
|
|
{
|
|
case ENABLE_ROTATION :
|
|
{
|
|
pEncInfo->rotationEnable = 1;
|
|
}
|
|
break;
|
|
case DISABLE_ROTATION :
|
|
{
|
|
pEncInfo->rotationEnable = 0;
|
|
}
|
|
break;
|
|
case ENABLE_MIRRORING :
|
|
{
|
|
pEncInfo->mirrorEnable = 1;
|
|
}
|
|
break;
|
|
case DISABLE_MIRRORING :
|
|
{
|
|
pEncInfo->mirrorEnable = 0;
|
|
}
|
|
break;
|
|
case SET_MIRROR_DIRECTION :
|
|
{
|
|
MirrorDirection mirDir;
|
|
|
|
if (param == 0) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
mirDir = *(MirrorDirection *)param;
|
|
if ( !(mirDir == MIRDIR_NONE) && !(mirDir==MIRDIR_HOR) && !(mirDir==MIRDIR_VER) && !(mirDir==MIRDIR_HOR_VER)) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
pEncInfo->mirrorDirection = mirDir;
|
|
}
|
|
break;
|
|
case SET_ROTATION_ANGLE :
|
|
{
|
|
int angle;
|
|
|
|
if (param == 0) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
angle = *(int *)param;
|
|
if (angle != 0 && angle != 90 &&
|
|
angle != 180 && angle != 270) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
if (pEncInfo->initialInfoObtained && (angle == 90 || angle ==270)) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
pEncInfo->rotationAngle = angle;
|
|
}
|
|
break;
|
|
case SET_CACHE_CONFIG:
|
|
{
|
|
MaverickCacheConfig *mcCacheConfig;
|
|
if (param == 0) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
mcCacheConfig = (MaverickCacheConfig *)param;
|
|
pEncInfo->cacheConfig = *mcCacheConfig;
|
|
}
|
|
break;
|
|
case ENC_PUT_VIDEO_HEADER:
|
|
{
|
|
EncHeaderParam *encHeaderParam;
|
|
|
|
if (param == 0) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
encHeaderParam = (EncHeaderParam *)param;
|
|
if (pCodecInst->codecMode == MP4_ENC ) {
|
|
if (!( VOL_HEADER<=encHeaderParam->headerType && encHeaderParam->headerType <= VIS_HEADER)) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
}
|
|
else if (pCodecInst->codecMode == AVC_ENC) {
|
|
if (!( SPS_RBSP<=encHeaderParam->headerType && encHeaderParam->headerType <= PPS_RBSP_MVC)) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
}
|
|
else if (pCodecInst->codecMode == W_HEVC_ENC || pCodecInst->codecMode == W_SVAC_ENC || pCodecInst->codecMode == W_AVC_ENC) {
|
|
if (!( CODEOPT_ENC_VPS<=encHeaderParam->headerType && encHeaderParam->headerType <= (CODEOPT_ENC_VPS|CODEOPT_ENC_SPS|CODEOPT_ENC_PPS))) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
if (pEncInfo->ringBufferEnable == 0 ) {
|
|
if (encHeaderParam->buf % 16 || encHeaderParam->size == 0)
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
if (encHeaderParam->headerType & CODEOPT_ENC_VCL) // ENC_PUT_VIDEO_HEADER encode only non-vcl header.
|
|
return RETCODE_INVALID_PARAM;
|
|
|
|
}
|
|
else
|
|
return RETCODE_INVALID_PARAM;
|
|
|
|
if (pEncInfo->ringBufferEnable == 0 ) {
|
|
if (encHeaderParam->buf % 8 || encHeaderParam->size == 0) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
}
|
|
|
|
return ProductVpuEncGetHeader(pCodecInst, encHeaderParam);
|
|
}
|
|
case ENC_SET_PARAM:
|
|
{
|
|
if (param == 0) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
pEncInfo->openParam = *(EncOpenParam *)param;
|
|
|
|
if (pCodecInst->codecMode != AVC_ENC)
|
|
return RETCODE_INVALID_COMMAND;
|
|
|
|
ret = EncParaSet(handle, SPS_RBSP);
|
|
if (ret != RETCODE_SUCCESS)
|
|
return ret;
|
|
|
|
ret = EncParaSet(handle, PPS_RBSP);
|
|
if (ret != RETCODE_SUCCESS)
|
|
return ret;
|
|
return ret;
|
|
}
|
|
case ENC_SET_GOP_NUMBER:
|
|
{
|
|
ParamChange paramChange;
|
|
|
|
paramChange.paraEnable = ENC_CHANGE_PARAM_GOP_NUM;
|
|
paramChange.NewGopNum = *(int*)param;
|
|
|
|
if ((pCodecInst->codecMode != MP4_ENC) && (pCodecInst->codecMode != AVC_ENC))
|
|
return RETCODE_INVALID_COMMAND;
|
|
if (paramChange.NewGopNum < 0)
|
|
return RETCODE_INVALID_PARAM;
|
|
|
|
return ProductVpuEncChangeParam(pCodecInst, ¶mChange);
|
|
}
|
|
case ENC_SET_INTRA_QP:
|
|
{
|
|
ParamChange paramChange;
|
|
|
|
paramChange.paraEnable = ENC_CHANGE_PARAM_INTRA_QP;
|
|
paramChange.NewIntraQp = *(int*)param;
|
|
|
|
if ((pCodecInst->codecMode != MP4_ENC) && (pCodecInst->codecMode != AVC_ENC))
|
|
return RETCODE_INVALID_COMMAND;
|
|
if ((pCodecInst->codecMode == MP4_ENC) && (paramChange.NewIntraQp < 1 || paramChange.NewIntraQp > 31))
|
|
return RETCODE_INVALID_PARAM;
|
|
if ((pCodecInst->codecMode == AVC_ENC) && (paramChange.NewIntraQp < 0 || paramChange.NewIntraQp > 51))
|
|
return RETCODE_INVALID_PARAM;
|
|
|
|
return ProductVpuEncChangeParam(pCodecInst, ¶mChange);
|
|
}
|
|
case ENC_SET_BITRATE:
|
|
{
|
|
ParamChange paramChange;
|
|
|
|
paramChange.paraEnable = ENC_CHANGE_PARAM_BIT_RATE;
|
|
paramChange.NewBitrate = *(int*)param;
|
|
|
|
if ((pCodecInst->codecMode != MP4_ENC) && (pCodecInst->codecMode != AVC_ENC))
|
|
return RETCODE_INVALID_COMMAND;
|
|
if ((pCodecInst->codecMode == AVC_ENC) && (paramChange.NewBitrate < 0 || paramChange.NewBitrate > 32767))
|
|
return RETCODE_INVALID_PARAM;
|
|
if ((pCodecInst->codecMode == MP4_ENC) && (paramChange.NewBitrate < 0 || paramChange.NewBitrate > 32767))
|
|
return RETCODE_INVALID_PARAM;
|
|
|
|
return ProductVpuEncChangeParam(pCodecInst, ¶mChange);
|
|
}
|
|
case ENC_SET_FRAME_RATE:
|
|
{
|
|
ParamChange paramChange;
|
|
|
|
paramChange.paraEnable = ENC_CHANGE_PARAM_FRAME_RATE;
|
|
paramChange.NewFrameRate = *(int*)param;
|
|
|
|
if ((pCodecInst->codecMode != MP4_ENC) && (pCodecInst->codecMode != AVC_ENC))
|
|
return RETCODE_INVALID_COMMAND;
|
|
if (paramChange.NewFrameRate <= 0)
|
|
return RETCODE_INVALID_PARAM;
|
|
|
|
return ProductVpuEncChangeParam(pCodecInst, ¶mChange);
|
|
}
|
|
case ENC_SET_INTRA_MB_REFRESH_NUMBER:
|
|
{
|
|
ParamChange paramChange;
|
|
|
|
paramChange.paraEnable = ENC_CHANGE_PARAM_INTRA_REFRESH;
|
|
paramChange.NewIntraRefresh = *(int*)param;
|
|
|
|
return ProductVpuEncChangeParam(pCodecInst, ¶mChange);
|
|
}
|
|
case ENC_SET_SLICE_INFO:
|
|
{
|
|
EncSliceMode *pSliceMode = (EncSliceMode *)param;
|
|
|
|
if(pSliceMode->sliceMode<0 || pSliceMode->sliceMode>1)
|
|
{
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
if(pSliceMode->sliceSizeMode<0 || pSliceMode->sliceSizeMode>1)
|
|
{
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
SetSliceMode(handle, (EncSliceMode *)pSliceMode);
|
|
}
|
|
break;
|
|
case ENC_ENABLE_HEC:
|
|
{
|
|
if (pCodecInst->codecMode != MP4_ENC) {
|
|
return RETCODE_INVALID_COMMAND;
|
|
}
|
|
SetHecMode(handle, 1);
|
|
}
|
|
break;
|
|
case ENC_DISABLE_HEC:
|
|
{
|
|
if (pCodecInst->codecMode != MP4_ENC) {
|
|
return RETCODE_INVALID_COMMAND;
|
|
}
|
|
SetHecMode(handle, 0);
|
|
}
|
|
break;
|
|
case SET_SEC_AXI:
|
|
{
|
|
SecAxiUse secAxiUse;
|
|
|
|
if (param == 0) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
secAxiUse = *(SecAxiUse *)param;
|
|
if (handle->productId == PRODUCT_ID_521) {
|
|
pEncInfo->secAxiInfo.u.wave.useEncRdoEnable = secAxiUse.u.wave.useEncRdoEnable;
|
|
pEncInfo->secAxiInfo.u.wave.useEncLfEnable = secAxiUse.u.wave.useEncLfEnable;
|
|
}
|
|
else { // coda9 or coda7q or ...
|
|
pEncInfo->secAxiInfo.u.coda9.useBitEnable = secAxiUse.u.coda9.useBitEnable;
|
|
pEncInfo->secAxiInfo.u.coda9.useIpEnable = secAxiUse.u.coda9.useIpEnable;
|
|
pEncInfo->secAxiInfo.u.coda9.useDbkYEnable = secAxiUse.u.coda9.useDbkYEnable;
|
|
pEncInfo->secAxiInfo.u.coda9.useDbkCEnable = secAxiUse.u.coda9.useDbkCEnable;
|
|
pEncInfo->secAxiInfo.u.coda9.useOvlEnable = secAxiUse.u.coda9.useOvlEnable;
|
|
pEncInfo->secAxiInfo.u.coda9.useBtpEnable = secAxiUse.u.coda9.useBtpEnable;
|
|
}
|
|
}
|
|
break;
|
|
case ENC_CONFIG_SUB_FRAME_SYNC: // for CODA9
|
|
{
|
|
EncSubFrameSyncConfig *subFrameSyncConfig;
|
|
if (param == 0) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
subFrameSyncConfig = (EncSubFrameSyncConfig *)param;
|
|
pEncInfo->subFrameSyncConfig.subFrameSyncMode = subFrameSyncConfig->subFrameSyncMode;
|
|
pEncInfo->subFrameSyncConfig.subFrameSyncOn = subFrameSyncConfig->subFrameSyncOn;
|
|
pEncInfo->subFrameSyncConfig.sourceBufNumber = subFrameSyncConfig->sourceBufNumber;
|
|
pEncInfo->subFrameSyncConfig.sourceBufIndexBase = subFrameSyncConfig->sourceBufIndexBase;
|
|
pEncInfo->subFrameSyncConfig.curEncSourceIdx = subFrameSyncConfig->curEncSourceIdx;
|
|
|
|
}
|
|
break;
|
|
case ENC_SET_SUB_FRAME_SYNC:
|
|
EnterLock(pCodecInst->coreIdx);
|
|
ret = ProductVpuEncGiveCommand(pCodecInst, ENC_SET_SUB_FRAME_SYNC, param);
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
return ret;
|
|
case GET_TILEDMAP_CONFIG:
|
|
{
|
|
TiledMapConfig *pMapCfg = (TiledMapConfig *)param;
|
|
if (!pMapCfg) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
*pMapCfg = pEncInfo->mapCfg;
|
|
break;
|
|
}
|
|
case SET_DRAM_CONFIG:
|
|
{
|
|
DRAMConfig *cfg = (DRAMConfig *)param;
|
|
|
|
if (!cfg) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
|
|
pEncInfo->dramCfg = *cfg;
|
|
break;
|
|
}
|
|
case GET_DRAM_CONFIG:
|
|
{
|
|
DRAMConfig *cfg = (DRAMConfig *)param;
|
|
|
|
if (!cfg) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
|
|
*cfg = pEncInfo->dramCfg;
|
|
break;
|
|
}
|
|
case ENABLE_LOGGING:
|
|
{
|
|
pCodecInst->loggingEnable = 1;
|
|
}
|
|
break;
|
|
case DISABLE_LOGGING:
|
|
{
|
|
pCodecInst->loggingEnable = 0;
|
|
}
|
|
break;
|
|
case ENC_SET_PARA_CHANGE:
|
|
{
|
|
return ProductVpuEncChangeParam(pCodecInst, param);
|
|
}
|
|
case GET_BANDWIDTH_REPORT:
|
|
EnterLock(pCodecInst->coreIdx);
|
|
ret = ProductVpuGetBandwidth(pCodecInst, (VPUBWData*)param);
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
return ret;
|
|
case ENC_SET_SEI_NAL_DATA:
|
|
{
|
|
HevcSEIDataEnc* option = (HevcSEIDataEnc*)param;
|
|
pEncInfo->prefixSeiNalEnable = option->prefixSeiNalEnable;
|
|
pEncInfo->prefixSeiDataSize = option->prefixSeiDataSize;
|
|
pEncInfo->prefixSeiNalAddr = option->prefixSeiNalAddr;
|
|
|
|
pEncInfo->suffixSeiNalEnable = option->suffixSeiNalEnable;
|
|
pEncInfo->suffixSeiDataSize = option->suffixSeiDataSize;
|
|
pEncInfo->suffixSeiNalAddr = option->suffixSeiNalAddr;
|
|
}
|
|
break;
|
|
case ENC_GET_QUEUE_STATUS:
|
|
{
|
|
QueueStatusInfo* queueInfo = (QueueStatusInfo*)param;
|
|
queueInfo->instanceQueueCount = pEncInfo->instanceQueueCount;
|
|
queueInfo->reportQueueCount = pEncInfo->reportQueueCount;
|
|
break;
|
|
}
|
|
case ENC_WRPTR_SEL:
|
|
{
|
|
pEncInfo->encWrPtrSel = *(int *)param;
|
|
}
|
|
break;
|
|
case SET_CYCLE_PER_TICK:
|
|
{
|
|
pEncInfo->cyclePerTick = *(Uint32 *)param;
|
|
}
|
|
break;
|
|
case ENC_GET_SRC_BUF_FLAG:
|
|
EnterLock(pCodecInst->coreIdx);
|
|
ret = ProductVpuEncGetSrcBufFlag(pCodecInst, (Uint32*)param);
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
return ret;
|
|
case GET_DEBUG_INFORM:
|
|
EnterLock(pCodecInst->coreIdx);
|
|
ret = ProductVpuGetDebugInfo(pCodecInst, (VPUDebugInfo*)param);
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
return ret;
|
|
default:
|
|
return RETCODE_INVALID_COMMAND;
|
|
}
|
|
return RETCODE_SUCCESS;
|
|
}
|
|
|
|
RetCode VPU_EncAllocateFrameBuffer(EncHandle handle, FrameBufferAllocInfo info, FrameBuffer *frameBuffer)
|
|
{
|
|
CodecInst* pCodecInst;
|
|
EncInfo* pEncInfo;
|
|
RetCode ret;
|
|
int gdiIndex;
|
|
|
|
ret = CheckEncInstanceValidity(handle);
|
|
if (ret != RETCODE_SUCCESS)
|
|
return ret;
|
|
|
|
pCodecInst = handle;
|
|
pEncInfo = &pCodecInst->CodecInfo->encInfo;
|
|
|
|
if (!frameBuffer) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
if (info.num == 0 || info.num < 0) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
if (info.stride == 0 || info.stride < 0) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
if (info.height == 0 || info.height < 0) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
|
|
if (info.type == FB_TYPE_PPU) {
|
|
if (pEncInfo->numFrameBuffers == 0) {
|
|
return RETCODE_WRONG_CALL_SEQUENCE;
|
|
}
|
|
pEncInfo->ppuAllocExt = frameBuffer[0].updateFbInfo;
|
|
gdiIndex = pEncInfo->numFrameBuffers;
|
|
ret = ProductVpuAllocateFramebuffer(pCodecInst, frameBuffer, (TiledMapType)info.mapType, (Int32)info.num,
|
|
info.stride, info.height, info.format, info.cbcrInterleave, info.nv21,
|
|
info.endian, &pEncInfo->vbPPU, gdiIndex, (FramebufferAllocType)info.type);
|
|
}
|
|
else if (info.type == FB_TYPE_CODEC) {
|
|
gdiIndex = 0;
|
|
pEncInfo->frameAllocExt = frameBuffer[0].updateFbInfo;
|
|
ret = ProductVpuAllocateFramebuffer(
|
|
pCodecInst, frameBuffer, (TiledMapType)info.mapType, (Int32)info.num,
|
|
info.stride, info.height, info.format, info.cbcrInterleave, FALSE, info.endian, &pEncInfo->vbFrame, gdiIndex, (FramebufferAllocType)info.type);
|
|
}
|
|
else {
|
|
ret = RETCODE_INVALID_PARAM;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
RetCode VPU_EncIssueSeqInit(EncHandle handle)
|
|
{
|
|
CodecInst* pCodecInst;
|
|
RetCode ret;
|
|
VpuAttr* pAttr;
|
|
|
|
ret = CheckEncInstanceValidity(handle);
|
|
if (ret != RETCODE_SUCCESS)
|
|
return ret;
|
|
|
|
pCodecInst = handle;
|
|
|
|
EnterLock(pCodecInst->coreIdx);
|
|
|
|
pAttr = &g_VpuCoreAttributes[pCodecInst->coreIdx];
|
|
|
|
if (GetPendingInst(pCodecInst->coreIdx)) {
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
return RETCODE_FRAME_NOT_COMPLETE;
|
|
}
|
|
|
|
ret = ProductVpuEncInitSeq(handle);
|
|
if (ret == RETCODE_SUCCESS) {
|
|
SetPendingInst(pCodecInst->coreIdx, pCodecInst);
|
|
}
|
|
|
|
if (pAttr->supportCommandQueue == TRUE) {
|
|
SetPendingInst(pCodecInst->coreIdx, NULL);
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
RetCode VPU_EncCompleteSeqInit(EncHandle handle, EncInitialInfo * info)
|
|
{
|
|
CodecInst* pCodecInst;
|
|
EncInfo* pEncInfo;
|
|
RetCode ret;
|
|
VpuAttr* pAttr;
|
|
|
|
ret = CheckEncInstanceValidity(handle);
|
|
if (ret != RETCODE_SUCCESS) {
|
|
return ret;
|
|
}
|
|
|
|
if (info == 0) {
|
|
return RETCODE_INVALID_PARAM;
|
|
}
|
|
|
|
pCodecInst = handle;
|
|
pEncInfo = &pCodecInst->CodecInfo->encInfo;
|
|
|
|
pAttr = &g_VpuCoreAttributes[pCodecInst->coreIdx];
|
|
|
|
if (pAttr->supportCommandQueue == TRUE) {
|
|
EnterLock(pCodecInst->coreIdx);
|
|
}
|
|
else {
|
|
if (pCodecInst != GetPendingInst(pCodecInst->coreIdx)) {
|
|
SetPendingInst(pCodecInst->coreIdx, 0);
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
return RETCODE_WRONG_CALL_SEQUENCE;
|
|
}
|
|
}
|
|
|
|
ret = ProductVpuEncGetSeqInfo(handle, info);
|
|
if (ret == RETCODE_SUCCESS) {
|
|
pEncInfo->initialInfoObtained = 1;
|
|
}
|
|
|
|
pEncInfo->initialInfo = *info;
|
|
|
|
SetPendingInst(pCodecInst->coreIdx, NULL);
|
|
|
|
LeaveLock(pCodecInst->coreIdx);
|
|
|
|
return ret;
|
|
}
|
|
|
|
|