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.
4261 lines
179 KiB
4261 lines
179 KiB
|
7 months ago
|
//-----------------------------------------------------------------------------
|
||
|
|
// 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 "wave5.h"
|
||
|
|
#include "wave5_regdefine.h"
|
||
|
|
#include <stdio.h>
|
||
|
|
#include <string.h>
|
||
|
|
|
||
|
|
Uint32 Wave5VpuIsInit(Uint32 coreIdx)
|
||
|
|
{
|
||
|
|
Uint32 pc;
|
||
|
|
|
||
|
|
pc = (Uint32)VpuReadReg(coreIdx, W5_VCPU_CUR_PC);
|
||
|
|
|
||
|
|
return pc;
|
||
|
|
}
|
||
|
|
|
||
|
|
Int32 Wave5VpuIsBusy(Uint32 coreIdx)
|
||
|
|
{
|
||
|
|
return VpuReadReg(coreIdx, W5_VPU_BUSY_STATUS);
|
||
|
|
}
|
||
|
|
|
||
|
|
Int32 WaveVpuGetProductId(Uint32 coreIdx)
|
||
|
|
{
|
||
|
|
Uint32 productId = PRODUCT_ID_NONE;
|
||
|
|
Uint32 val;
|
||
|
|
|
||
|
|
if (coreIdx >= MAX_NUM_VPU_CORE)
|
||
|
|
return PRODUCT_ID_NONE;
|
||
|
|
|
||
|
|
val = VpuReadReg(coreIdx, W5_PRODUCT_NUMBER);
|
||
|
|
|
||
|
|
switch (val) {
|
||
|
|
case WAVE521_CODE: productId = PRODUCT_ID_521; break;
|
||
|
|
case WAVE521C_CODE: productId = PRODUCT_ID_521; break;
|
||
|
|
case WAVE511_CODE: productId = PRODUCT_ID_511; break;
|
||
|
|
case WAVE521C_DUAL_CODE: productId = PRODUCT_ID_521; break;
|
||
|
|
case WAVE517_CODE: productId = PRODUCT_ID_517; break;
|
||
|
|
case WAVE537_CODE: productId = PRODUCT_ID_517; break;
|
||
|
|
case WAVE521E1_CODE: productId = PRODUCT_ID_521; break;
|
||
|
|
default:
|
||
|
|
VLOG(ERR, "Check productId(%x)\n", val);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
return productId;
|
||
|
|
}
|
||
|
|
|
||
|
|
void Wave5BitIssueCommand(CodecInst* instance, Uint32 cmd)
|
||
|
|
{
|
||
|
|
Uint32 instanceIndex = 0;
|
||
|
|
Uint32 codecMode = 0;
|
||
|
|
Uint32 coreIdx;
|
||
|
|
|
||
|
|
if (instance == NULL) {
|
||
|
|
return ;
|
||
|
|
}
|
||
|
|
|
||
|
|
instanceIndex = instance->instIndex;
|
||
|
|
codecMode = instance->codecMode;
|
||
|
|
coreIdx = instance->coreIdx;
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_INSTANCE_INFO, (codecMode<<16)|(instanceIndex&0xffff));
|
||
|
|
VpuWriteReg(coreIdx, W5_VPU_BUSY_STATUS, 1);
|
||
|
|
VpuWriteReg(coreIdx, W5_COMMAND, cmd);
|
||
|
|
|
||
|
|
if ((instance != NULL && instance->loggingEnable))
|
||
|
|
vdi_log(coreIdx, instanceIndex, cmd, 1);
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_VPU_HOST_INT_REQ, 1);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
static RetCode SendQuery(CodecInst* instance, QUERY_OPT queryOpt)
|
||
|
|
{
|
||
|
|
// Send QUERY cmd
|
||
|
|
VpuWriteReg(instance->coreIdx, W5_QUERY_OPTION, queryOpt);
|
||
|
|
VpuWriteReg(instance->coreIdx, W5_VPU_BUSY_STATUS, 1);
|
||
|
|
Wave5BitIssueCommand(instance, W5_QUERY);
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
if (vdi_wait_vpu_busy(instance->coreIdx, __VPU_BUSY_TIMEOUT, W5_VPU_BUSY_STATUS) == -1) {
|
||
|
|
if (instance->loggingEnable)
|
||
|
|
vdi_log(instance->coreIdx, instance->instIndex, W5_QUERY, 2);
|
||
|
|
return RETCODE_VPU_RESPONSE_TIMEOUT;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (VpuReadReg(instance->coreIdx, W5_RET_SUCCESS) == FALSE)
|
||
|
|
return RETCODE_FAILURE;
|
||
|
|
|
||
|
|
return RETCODE_SUCCESS;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
RetCode Wave5VpuEncGiveCommand(CodecInst *pCodecInst, CodecCommand cmd, void *param)
|
||
|
|
{
|
||
|
|
RetCode ret = RETCODE_SUCCESS;
|
||
|
|
|
||
|
|
if (param == NULL)
|
||
|
|
return RETCODE_INVALID_PARAM;
|
||
|
|
|
||
|
|
switch (cmd) {
|
||
|
|
case ENC_SET_SUB_FRAME_SYNC:
|
||
|
|
{
|
||
|
|
EncSubFrameSyncState* pSubFrameSyncState = (EncSubFrameSyncState*)param;
|
||
|
|
if (pCodecInst->productId != PRODUCT_ID_521)
|
||
|
|
return RETCODE_INVALID_COMMAND;
|
||
|
|
|
||
|
|
VpuWriteReg(pCodecInst->coreIdx, W5_ENC_PIC_SUB_FRAME_SYNC_IF, (pSubFrameSyncState->ipuCurFrameIndex<<17) | ((pSubFrameSyncState->ipuNewFrame&0x01)<<16) | (pSubFrameSyncState->ipuEndOfRow));
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
ret = RETCODE_NOT_SUPPORTED_FEATURE;
|
||
|
|
}
|
||
|
|
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
static RetCode SetupWave5Properties(Uint32 coreIdx)
|
||
|
|
{
|
||
|
|
VpuAttr* pAttr = &g_VpuCoreAttributes[coreIdx];
|
||
|
|
Uint32 regVal;
|
||
|
|
Uint8* str;
|
||
|
|
RetCode ret = RETCODE_SUCCESS;
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_QUERY_OPTION, GET_VPU_INFO);
|
||
|
|
VpuWriteReg(coreIdx, W5_VPU_BUSY_STATUS, 1);
|
||
|
|
VpuWriteReg(coreIdx, W5_COMMAND, W5_QUERY);
|
||
|
|
VpuWriteReg(coreIdx, W5_VPU_HOST_INT_REQ, 1);
|
||
|
|
|
||
|
|
|
||
|
|
if (vdi_wait_vpu_busy(coreIdx, __VPU_BUSY_TIMEOUT, W5_VPU_BUSY_STATUS) == -1) {
|
||
|
|
return RETCODE_VPU_RESPONSE_TIMEOUT;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (VpuReadReg(coreIdx, W5_RET_SUCCESS) == FALSE) {
|
||
|
|
ret = RETCODE_QUERY_FAILURE;
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
regVal = VpuReadReg(coreIdx, W5_RET_PRODUCT_NAME);
|
||
|
|
str = (Uint8*)®Val;
|
||
|
|
pAttr->productName[0] = str[3];
|
||
|
|
pAttr->productName[1] = str[2];
|
||
|
|
pAttr->productName[2] = str[1];
|
||
|
|
pAttr->productName[3] = str[0];
|
||
|
|
pAttr->productName[4] = 0;
|
||
|
|
|
||
|
|
pAttr->productId = WaveVpuGetProductId(coreIdx);
|
||
|
|
pAttr->productVersion = VpuReadReg(coreIdx, W5_RET_PRODUCT_VERSION);
|
||
|
|
pAttr->fwVersion = VpuReadReg(coreIdx, W5_RET_FW_VERSION);
|
||
|
|
pAttr->customerId = VpuReadReg(coreIdx, W5_RET_CUSTOMER_ID);
|
||
|
|
pAttr->hwConfigDef0 = VpuReadReg(coreIdx, W5_RET_STD_DEF0);
|
||
|
|
pAttr->hwConfigDef1 = VpuReadReg(coreIdx, W5_RET_STD_DEF1);
|
||
|
|
pAttr->hwConfigFeature = VpuReadReg(coreIdx, W5_RET_CONF_FEATURE);
|
||
|
|
pAttr->hwConfigDate = VpuReadReg(coreIdx, W5_RET_CONF_DATE);
|
||
|
|
pAttr->hwConfigRev = VpuReadReg(coreIdx, W5_RET_CONF_REVISION);
|
||
|
|
pAttr->hwConfigType = VpuReadReg(coreIdx, W5_RET_CONF_TYPE);
|
||
|
|
|
||
|
|
pAttr->supportHEVC10bitEnc = (pAttr->hwConfigFeature>>3)&1;
|
||
|
|
if ( pAttr->hwConfigRev > 167455 ) {//20190321
|
||
|
|
pAttr->supportAVC10bitEnc = (pAttr->hwConfigFeature>>11)&1;
|
||
|
|
} else {
|
||
|
|
pAttr->supportAVC10bitEnc = pAttr->supportHEVC10bitEnc;
|
||
|
|
}
|
||
|
|
pAttr->supportGDIHW = TRUE;
|
||
|
|
|
||
|
|
pAttr->supportDecoders = 0;
|
||
|
|
pAttr->supportEncoders = 0;
|
||
|
|
if (pAttr->productId == PRODUCT_ID_521) {
|
||
|
|
pAttr->supportDecoders = (((pAttr->hwConfigDef1>>3)&0x01) << STD_AVC);
|
||
|
|
pAttr->supportDecoders |= (((pAttr->hwConfigDef1>>2)&0x01) << STD_HEVC);
|
||
|
|
pAttr->supportEncoders = (((pAttr->hwConfigDef1>>1)&0x01) << STD_AVC);
|
||
|
|
pAttr->supportEncoders |= (((pAttr->hwConfigDef1>>0)&0x01) << STD_HEVC);
|
||
|
|
pAttr->supportDualCore = (BOOL)((pAttr->hwConfigDef1 >> 26) & 0x01);
|
||
|
|
if (pAttr->supportDualCore || (pAttr->hwConfigRev < 206116)) {
|
||
|
|
pAttr->supportDecoders = (1 << STD_AVC);
|
||
|
|
pAttr->supportDecoders |= (1 << STD_HEVC);
|
||
|
|
pAttr->supportEncoders = (1 << STD_AVC);
|
||
|
|
pAttr->supportEncoders |= (1 << STD_HEVC);
|
||
|
|
}
|
||
|
|
pAttr->support2AlignScaler = (BOOL)((pAttr->hwConfigDef0 >> 7) & 0x01);
|
||
|
|
}
|
||
|
|
if (pAttr->productId == PRODUCT_ID_511) {
|
||
|
|
pAttr->supportDecoders = (1 << STD_HEVC);
|
||
|
|
pAttr->supportDecoders |= (1 << STD_AVC);
|
||
|
|
pAttr->support2AlignScaler = (BOOL)((pAttr->hwConfigDef0>>23)&0x01);
|
||
|
|
}
|
||
|
|
if (pAttr->productId == PRODUCT_ID_517) {
|
||
|
|
pAttr->supportDecoders = (((pAttr->hwConfigDef1>>4)&0x01) << STD_AV1);
|
||
|
|
pAttr->supportDecoders |= (((pAttr->hwConfigDef1>>3)&0x01) << STD_AVS2);
|
||
|
|
pAttr->supportDecoders |= (((pAttr->hwConfigDef1>>2)&0x01) << STD_AVC);
|
||
|
|
pAttr->supportDecoders |= (((pAttr->hwConfigDef1>>1)&0x01) << STD_VP9);
|
||
|
|
pAttr->supportDecoders |= (((pAttr->hwConfigDef1>>0)&0x01) << STD_HEVC);
|
||
|
|
pAttr->support2AlignScaler = (BOOL)((pAttr->hwConfigDef0>>7)&0x01);
|
||
|
|
}
|
||
|
|
|
||
|
|
pAttr->supportBackbone = (BOOL)((pAttr->hwConfigDef0>>16)&0x01);
|
||
|
|
pAttr->supportVcpuBackbone = (BOOL)((pAttr->hwConfigDef0>>28)&0x01);
|
||
|
|
pAttr->supportVcoreBackbone = (BOOL)((pAttr->hwConfigDef0>>22)&0x01);
|
||
|
|
pAttr->supportCommandQueue = TRUE;
|
||
|
|
pAttr->supportFBCBWOptimization = (BOOL)((pAttr->hwConfigDef1>>15)&0x01);
|
||
|
|
pAttr->supportNewTimer = (BOOL)((pAttr->hwConfigDef1>>27)&0x01);
|
||
|
|
pAttr->supportWTL = TRUE;
|
||
|
|
pAttr->supportDualCore = (BOOL)((pAttr->hwConfigDef1>>26)&0x01);
|
||
|
|
pAttr->supportUserQMatrix = (BOOL)((pAttr->hwConfigDef1>>11)&0x01);
|
||
|
|
pAttr->supportWeightedPrediction = (BOOL)((pAttr->hwConfigDef1>>10)&0x01);
|
||
|
|
pAttr->supportRDOQ = (BOOL)((pAttr->hwConfigDef1>>9)&0x01);
|
||
|
|
pAttr->supportAdaptiveRounding = (BOOL)((pAttr->hwConfigDef1>>8)&0x01);
|
||
|
|
pAttr->supportTiled2Linear = FALSE;
|
||
|
|
pAttr->supportMapTypes = FALSE;
|
||
|
|
pAttr->support128bitBus = TRUE;
|
||
|
|
pAttr->supportThumbnailMode = TRUE;
|
||
|
|
pAttr->supportEndianMask = (Uint32)((1<<VDI_LITTLE_ENDIAN) | (1<<VDI_BIG_ENDIAN) | (1<<VDI_32BIT_LITTLE_ENDIAN) | (1<<VDI_32BIT_BIG_ENDIAN) | (0xffffUL<<16));
|
||
|
|
pAttr->supportBitstreamMode = (1<<BS_MODE_INTERRUPT) | (1<<BS_MODE_PIC_END);
|
||
|
|
pAttr->framebufferCacheType = FramebufCacheNone;
|
||
|
|
pAttr->bitstreamBufferMargin = 0;
|
||
|
|
pAttr->maxNumVcores = MAX_NUM_VCORE;
|
||
|
|
pAttr->numberOfMemProtectRgns = 10;
|
||
|
|
}
|
||
|
|
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
RetCode Wave5VpuGetVersion(Uint32 coreIdx, Uint32* versionInfo, Uint32* revision)
|
||
|
|
{
|
||
|
|
Uint32 regVal;
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_QUERY_OPTION, GET_VPU_INFO);
|
||
|
|
VpuWriteReg(coreIdx, W5_VPU_BUSY_STATUS, 1);
|
||
|
|
VpuWriteReg(coreIdx, W5_COMMAND, W5_QUERY);
|
||
|
|
VpuWriteReg(coreIdx, W5_VPU_HOST_INT_REQ, 1);
|
||
|
|
|
||
|
|
|
||
|
|
if (vdi_wait_vpu_busy(coreIdx, __VPU_BUSY_TIMEOUT, W5_VPU_BUSY_STATUS) == -1) {
|
||
|
|
VLOG(ERR, "Wave5VpuGetVersion timeout\n");
|
||
|
|
return RETCODE_VPU_RESPONSE_TIMEOUT;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (VpuReadReg(coreIdx, W5_RET_SUCCESS) == FALSE) {
|
||
|
|
VLOG(ERR, "Wave5VpuGetVersion FALSE\n");
|
||
|
|
return RETCODE_QUERY_FAILURE;
|
||
|
|
}
|
||
|
|
|
||
|
|
regVal = VpuReadReg(coreIdx, W5_RET_FW_VERSION);
|
||
|
|
if (versionInfo != NULL) {
|
||
|
|
*versionInfo = 0;
|
||
|
|
}
|
||
|
|
if (revision != NULL) {
|
||
|
|
*revision = regVal;
|
||
|
|
}
|
||
|
|
|
||
|
|
return RETCODE_SUCCESS;
|
||
|
|
}
|
||
|
|
|
||
|
|
RetCode Wave5VpuInit(Uint32 coreIdx, void* firmware, Uint32 size)
|
||
|
|
{
|
||
|
|
vpu_buffer_t vb;
|
||
|
|
PhysicalAddress codeBase, tempBase;
|
||
|
|
Uint32 codeSize, tempSize;
|
||
|
|
Uint32 regVal, remapSize;
|
||
|
|
// Uint32 get_version_info;
|
||
|
|
Uint32 i;
|
||
|
|
Uint32 hwOption = 0;
|
||
|
|
RetCode ret = RETCODE_SUCCESS;
|
||
|
|
|
||
|
|
vdi_get_common_memory(coreIdx, &vb);
|
||
|
|
|
||
|
|
codeBase = vb.phys_addr;
|
||
|
|
/* ALIGN TO 4KB */
|
||
|
|
codeSize = (WAVE5_MAX_CODE_BUF_SIZE&~0xfff);
|
||
|
|
if (codeSize < size*2) {
|
||
|
|
return RETCODE_INSUFFICIENT_RESOURCE;
|
||
|
|
}
|
||
|
|
|
||
|
|
tempBase = vb.phys_addr + WAVE5_TEMPBUF_OFFSET;
|
||
|
|
tempSize = WAVE5_TEMPBUF_SIZE;
|
||
|
|
|
||
|
|
// VLOG(INFO, "\nVPU INIT Start!!!\n");
|
||
|
|
VpuWriteMem(coreIdx, codeBase, (unsigned char*)firmware, size*2, VDI_128BIT_LITTLE_ENDIAN);
|
||
|
|
vdi_set_bit_firmware_to_pm(coreIdx, (Uint16*)firmware);
|
||
|
|
|
||
|
|
regVal = 0;
|
||
|
|
VpuWriteReg(coreIdx, W5_PO_CONF, regVal);
|
||
|
|
|
||
|
|
/* clear registers */
|
||
|
|
|
||
|
|
for (i=W5_CMD_REG_BASE; i<W5_CMD_REG_END; i+=4)
|
||
|
|
{
|
||
|
|
#if defined(SUPPORT_SW_UART) || defined(SUPPORT_SW_UART_V2)
|
||
|
|
if (i == W5_SW_UART_STATUS)
|
||
|
|
continue;
|
||
|
|
#endif
|
||
|
|
VpuWriteReg(coreIdx, i, 0x00);
|
||
|
|
}
|
||
|
|
|
||
|
|
/* remap page size 0*/
|
||
|
|
remapSize = (W5_REMAP_MAX_SIZE>>12) & 0x1ff;
|
||
|
|
regVal = 0x80000000 | (WAVE5_UPPER_PROC_AXI_ID<<20) | (0<<16) | (W5_REMAP_INDEX0<<12) | (1<<11) | remapSize;
|
||
|
|
VpuWriteReg(coreIdx, W5_VPU_REMAP_CTRL, regVal);
|
||
|
|
VpuWriteReg(coreIdx, W5_VPU_REMAP_VADDR, W5_REMAP_INDEX0*W5_REMAP_MAX_SIZE);
|
||
|
|
VpuWriteReg(coreIdx, W5_VPU_REMAP_PADDR, codeBase + W5_REMAP_INDEX0*W5_REMAP_MAX_SIZE);
|
||
|
|
|
||
|
|
/* remap page size 1*/
|
||
|
|
remapSize = (W5_REMAP_MAX_SIZE>>12) & 0x1ff;
|
||
|
|
regVal = 0x80000000 | (WAVE5_UPPER_PROC_AXI_ID<<20) | (0<<16) | (W5_REMAP_INDEX1<<12) | (1<<11) | remapSize;
|
||
|
|
VpuWriteReg(coreIdx, W5_VPU_REMAP_CTRL, regVal);
|
||
|
|
VpuWriteReg(coreIdx, W5_VPU_REMAP_VADDR, W5_REMAP_INDEX1*W5_REMAP_MAX_SIZE);
|
||
|
|
VpuWriteReg(coreIdx, W5_VPU_REMAP_PADDR, codeBase + W5_REMAP_INDEX1*W5_REMAP_MAX_SIZE);
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_ADDR_CODE_BASE, codeBase);
|
||
|
|
VpuWriteReg(coreIdx, W5_CODE_SIZE, codeSize);
|
||
|
|
VpuWriteReg(coreIdx, W5_CODE_PARAM, (WAVE5_UPPER_PROC_AXI_ID<<4) | 0);
|
||
|
|
VpuWriteReg(coreIdx, W5_ADDR_TEMP_BASE, tempBase);
|
||
|
|
VpuWriteReg(coreIdx, W5_TEMP_SIZE, tempSize);
|
||
|
|
|
||
|
|
#ifdef SUPPORT_QOS_PARAM
|
||
|
|
vdi_fio_write_register(coreIdx, W5_BACKBONE_QOS_PROC_R_CH_PRIOR, QOS_R_PRIOR);
|
||
|
|
vdi_fio_write_register(coreIdx, W5_BACKBONE_QOS_PROC_W_CH_PRIOR, QOS_W_PRIOR);
|
||
|
|
#endif
|
||
|
|
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_HW_OPTION, hwOption);
|
||
|
|
|
||
|
|
/* Interrupt */
|
||
|
|
// encoder
|
||
|
|
regVal = (1<<INT_WAVE5_ENC_SET_PARAM);
|
||
|
|
regVal |= (1<<INT_WAVE5_ENC_PIC);
|
||
|
|
regVal |= (1<<INT_WAVE5_BSBUF_FULL);
|
||
|
|
#ifdef SUPPORT_SOURCE_RELEASE_INTERRUPT
|
||
|
|
regVal |= (1<<INT_WAVE5_ENC_SRC_RELEASE);
|
||
|
|
#endif
|
||
|
|
// decoder
|
||
|
|
regVal |= (1<<INT_WAVE5_INIT_SEQ);
|
||
|
|
regVal |= (1<<INT_WAVE5_DEC_PIC);
|
||
|
|
regVal |= (1<<INT_WAVE5_BSBUF_EMPTY);
|
||
|
|
VpuWriteReg(coreIdx, W5_VPU_VINT_ENABLE, regVal);
|
||
|
|
|
||
|
|
regVal = VpuReadReg(coreIdx, W5_VPU_RET_VPU_CONFIG0);
|
||
|
|
if (((regVal>>16)&1) == 1) {
|
||
|
|
regVal = ((WAVE5_PROC_AXI_ID<<28) |
|
||
|
|
(WAVE5_PRP_AXI_ID<<24) |
|
||
|
|
(WAVE5_FBD_Y_AXI_ID<<20) |
|
||
|
|
(WAVE5_FBC_Y_AXI_ID<<16) |
|
||
|
|
(WAVE5_FBD_C_AXI_ID<<12) |
|
||
|
|
(WAVE5_FBC_C_AXI_ID<<8) |
|
||
|
|
(WAVE5_PRI_AXI_ID<<4) |
|
||
|
|
(WAVE5_SEC_AXI_ID<<0));
|
||
|
|
vdi_fio_write_register(coreIdx, W5_BACKBONE_PROG_AXI_ID, regVal);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (vdi_get_sram_memory(coreIdx, &vb) < 0) // get SRAM base/size
|
||
|
|
return RETCODE_INSUFFICIENT_RESOURCE;
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_ADDR_SEC_AXI, vb.phys_addr);
|
||
|
|
VpuWriteReg(coreIdx, W5_SEC_AXI_SIZE, vb.size);
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_VPU_BUSY_STATUS, 1);
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_COMMAND, W5_INIT_VPU);
|
||
|
|
VpuWriteReg(coreIdx, W5_VPU_REMAP_CORE_START, 1);
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
if (vdi_wait_vpu_busy(coreIdx, __VPU_BUSY_TIMEOUT, W5_VPU_BUSY_STATUS) == -1) {
|
||
|
|
VLOG(ERR, "VPU init(W5_VPU_REMAP_CORE_START) timeout\n");
|
||
|
|
return RETCODE_VPU_RESPONSE_TIMEOUT;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
regVal = VpuReadReg(coreIdx, W5_RET_SUCCESS);
|
||
|
|
if (regVal == 0) {
|
||
|
|
Uint32 reasonCode = VpuReadReg(coreIdx, W5_RET_FAIL_REASON);
|
||
|
|
VLOG(ERR, "VPU init(W5_RET_SUCCESS) failed(%d) REASON CODE(%08x)\n", regVal, reasonCode);
|
||
|
|
return RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
|
||
|
|
ret = SetupWave5Properties(coreIdx);
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
RetCode Wave5VpuBuildUpDecParam(CodecInst* instance, DecOpenParam* param)
|
||
|
|
{
|
||
|
|
RetCode ret = RETCODE_SUCCESS;
|
||
|
|
DecInfo* pDecInfo = VPU_HANDLE_TO_DECINFO(instance);
|
||
|
|
Uint32 bsEndian = 0;
|
||
|
|
vpu_buffer_t vb;
|
||
|
|
|
||
|
|
pDecInfo->streamRdPtrRegAddr = W5_RET_DEC_BS_RD_PTR;
|
||
|
|
pDecInfo->streamWrPtrRegAddr = W5_BS_WR_PTR;
|
||
|
|
pDecInfo->frameDisplayFlagRegAddr = W5_RET_DEC_DISP_IDC;
|
||
|
|
pDecInfo->currentPC = W5_VCPU_CUR_PC;
|
||
|
|
pDecInfo->busyFlagAddr = W5_VPU_BUSY_STATUS;
|
||
|
|
pDecInfo->scaleWidth = 0;
|
||
|
|
pDecInfo->scaleHeight = 0;
|
||
|
|
|
||
|
|
switch (param->bitstreamFormat) {
|
||
|
|
case STD_HEVC:
|
||
|
|
pDecInfo->seqChangeMask = SEQ_CHANGE_ENABLE_ALL_HEVC;
|
||
|
|
break;
|
||
|
|
case STD_VP9:
|
||
|
|
pDecInfo->seqChangeMask = SEQ_CHANGE_ENABLE_ALL_VP9;
|
||
|
|
break;
|
||
|
|
case STD_AVS2:
|
||
|
|
pDecInfo->seqChangeMask = SEQ_CHANGE_ENABLE_ALL_AVS2;
|
||
|
|
break;
|
||
|
|
case STD_AVC:
|
||
|
|
pDecInfo->seqChangeMask = SEQ_CHANGE_ENABLE_ALL_AVC;
|
||
|
|
break;
|
||
|
|
case STD_SVAC:
|
||
|
|
pDecInfo->seqChangeMask = SEQ_CHANGE_ENABLE_ALL_SVAC;
|
||
|
|
break;
|
||
|
|
case STD_AV1:
|
||
|
|
pDecInfo->seqChangeMask = SEQ_CHANGE_ENABLE_ALL_AV1;
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
return RETCODE_NOT_SUPPORTED_FEATURE;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (instance->productId == PRODUCT_ID_517) {
|
||
|
|
pDecInfo->vbWork.size = (Uint32)WAVE517_WORKBUF_SIZE;
|
||
|
|
}
|
||
|
|
else if (instance->productId == PRODUCT_ID_521) {
|
||
|
|
pDecInfo->vbWork.size = (Uint32)WAVE521DEC_WORKBUF_SIZE;
|
||
|
|
}
|
||
|
|
else if (instance->productId == PRODUCT_ID_511) {
|
||
|
|
pDecInfo->vbWork.size = (Uint32)WAVE521DEC_WORKBUF_SIZE;
|
||
|
|
}
|
||
|
|
|
||
|
|
// APIDPRINT("ALLOC MEM - WORK\n");
|
||
|
|
if (vdi_allocate_dma_memory(instance->coreIdx, &pDecInfo->vbWork, DEC_WORK, instance->instIndex) < 0) {
|
||
|
|
pDecInfo->vbWork.base = 0;
|
||
|
|
pDecInfo->vbWork.phys_addr = 0;
|
||
|
|
pDecInfo->vbWork.size = 0;
|
||
|
|
pDecInfo->vbWork.virt_addr = 0;
|
||
|
|
return RETCODE_INSUFFICIENT_RESOURCE;
|
||
|
|
}
|
||
|
|
|
||
|
|
VpuWriteReg(instance->coreIdx, W5_CMD_DEC_VCORE_INFO, 1);
|
||
|
|
|
||
|
|
vdi_get_common_memory(instance->coreIdx, &vb);
|
||
|
|
pDecInfo->vbTemp.phys_addr = vb.phys_addr + WAVE5_TEMPBUF_OFFSET;
|
||
|
|
pDecInfo->vbTemp.size = WAVE5_TEMPBUF_SIZE;
|
||
|
|
|
||
|
|
vdi_get_sram_memory(instance->coreIdx, &vb);
|
||
|
|
pDecInfo->secAxiInfo.bufBase = vb.phys_addr;
|
||
|
|
pDecInfo->secAxiInfo.bufSize = vb.size;
|
||
|
|
|
||
|
|
vdi_clear_memory(instance->coreIdx, pDecInfo->vbWork.phys_addr, pDecInfo->vbWork.size, 0);
|
||
|
|
|
||
|
|
VpuWriteReg(instance->coreIdx, W5_ADDR_WORK_BASE, pDecInfo->vbWork.phys_addr);
|
||
|
|
VpuWriteReg(instance->coreIdx, W5_WORK_SIZE, pDecInfo->vbWork.size);
|
||
|
|
|
||
|
|
VpuWriteReg(instance->coreIdx, W5_CMD_DEC_BS_START_ADDR, pDecInfo->streamBufStartAddr);
|
||
|
|
VpuWriteReg(instance->coreIdx, W5_CMD_DEC_BS_SIZE, pDecInfo->streamBufSize);
|
||
|
|
|
||
|
|
/* NOTE: When endian mode is 0, SDMA reads MSB first */
|
||
|
|
bsEndian = vdi_convert_endian(instance->coreIdx, param->streamEndian);
|
||
|
|
bsEndian = (~bsEndian&VDI_128BIT_ENDIAN_MASK);
|
||
|
|
VpuWriteReg(instance->coreIdx, W5_CMD_BS_PARAM, bsEndian);
|
||
|
|
|
||
|
|
VpuWriteReg(instance->coreIdx, W5_CMD_NUM_CQ_DEPTH_M1, (COMMAND_QUEUE_DEPTH-1));
|
||
|
|
VpuWriteReg(instance->coreIdx, W5_CMD_ERR_CONCEAL, (param->errorConcealUnit<<2) | (param->errorConcealMode));
|
||
|
|
|
||
|
|
Wave5BitIssueCommand(instance, W5_CREATE_INSTANCE);
|
||
|
|
|
||
|
|
|
||
|
|
if (vdi_wait_vpu_busy(instance->coreIdx, __VPU_BUSY_TIMEOUT, W5_VPU_BUSY_STATUS) == -1) { // Check QUEUE_DONE
|
||
|
|
if (instance->loggingEnable)
|
||
|
|
vdi_log(instance->coreIdx, instance->instIndex, W5_CREATE_INSTANCE, 2);
|
||
|
|
vdi_free_dma_memory(instance->coreIdx, &pDecInfo->vbWork, DEC_WORK, instance->instIndex);
|
||
|
|
return RETCODE_VPU_RESPONSE_TIMEOUT;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (VpuReadReg(instance->coreIdx, W5_RET_SUCCESS) == FALSE) { // FAILED for adding into VCPU QUEUE
|
||
|
|
vdi_free_dma_memory(instance->coreIdx, &pDecInfo->vbWork, DEC_WORK, instance->instIndex);
|
||
|
|
ret = RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
|
||
|
|
pDecInfo->productCode = VpuReadReg(instance->coreIdx, W5_PRODUCT_NUMBER);
|
||
|
|
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
RetCode Wave5VpuDecInitSeq(CodecInst* instance)
|
||
|
|
{
|
||
|
|
RetCode ret = RETCODE_SUCCESS;
|
||
|
|
DecInfo* pDecInfo;
|
||
|
|
Uint32 cmdOption = INIT_SEQ_NORMAL, bsOption;
|
||
|
|
Uint32 regVal;
|
||
|
|
|
||
|
|
if (instance == NULL)
|
||
|
|
return RETCODE_INVALID_PARAM;
|
||
|
|
|
||
|
|
pDecInfo = VPU_HANDLE_TO_DECINFO(instance);
|
||
|
|
if (pDecInfo->thumbnailMode)
|
||
|
|
cmdOption = INIT_SEQ_W_THUMBNAIL;
|
||
|
|
|
||
|
|
|
||
|
|
/* Set attributes of bitstream buffer controller */
|
||
|
|
bsOption = 0;
|
||
|
|
switch (pDecInfo->openParam.bitstreamMode) {
|
||
|
|
case BS_MODE_INTERRUPT:
|
||
|
|
if(pDecInfo->seqInitEscape == TRUE)
|
||
|
|
bsOption = BSOPTION_ENABLE_EXPLICIT_END;
|
||
|
|
break;
|
||
|
|
case BS_MODE_PIC_END:
|
||
|
|
bsOption = BSOPTION_ENABLE_EXPLICIT_END;
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
return RETCODE_INVALID_PARAM;
|
||
|
|
}
|
||
|
|
|
||
|
|
VpuWriteReg(instance->coreIdx, W5_BS_RD_PTR, pDecInfo->streamRdPtr);
|
||
|
|
VpuWriteReg(instance->coreIdx, W5_BS_WR_PTR, pDecInfo->streamWrPtr);
|
||
|
|
|
||
|
|
if (pDecInfo->streamEndflag == 1) {
|
||
|
|
bsOption = 3;
|
||
|
|
}
|
||
|
|
if (instance->codecMode == W_AV1_DEC) {
|
||
|
|
bsOption |= ((pDecInfo->openParam.av1Format) << 2);
|
||
|
|
}
|
||
|
|
VpuWriteReg(instance->coreIdx, W5_BS_OPTION, (1UL<<31) | bsOption);
|
||
|
|
|
||
|
|
VpuWriteReg(instance->coreIdx, W5_COMMAND_OPTION, cmdOption);
|
||
|
|
VpuWriteReg(instance->coreIdx, W5_CMD_DEC_USER_MASK, pDecInfo->userDataEnable);
|
||
|
|
|
||
|
|
Wave5BitIssueCommand(instance, W5_INIT_SEQ);
|
||
|
|
|
||
|
|
|
||
|
|
if (vdi_wait_vpu_busy(instance->coreIdx, __VPU_BUSY_TIMEOUT, W5_VPU_BUSY_STATUS) == -1) { // Check QUEUE_DONE
|
||
|
|
if (instance->loggingEnable)
|
||
|
|
vdi_log(instance->coreIdx, instance->instIndex, W5_INIT_SEQ, 2);
|
||
|
|
return RETCODE_VPU_RESPONSE_TIMEOUT;
|
||
|
|
}
|
||
|
|
|
||
|
|
regVal = VpuReadReg(instance->coreIdx, W5_RET_QUEUE_STATUS);
|
||
|
|
|
||
|
|
pDecInfo->instanceQueueCount = (regVal>>16)&0xff;
|
||
|
|
pDecInfo->reportQueueCount = (regVal & 0xffff);
|
||
|
|
|
||
|
|
if (VpuReadReg(instance->coreIdx, W5_RET_SUCCESS) == FALSE) { // FAILED for adding a command into VCPU QUEUE
|
||
|
|
regVal = VpuReadReg(instance->coreIdx, W5_RET_FAIL_REASON);
|
||
|
|
if (regVal != WAVE5_SYSERR_QUEUEING_FAIL)
|
||
|
|
VLOG(ERR, "FAIL_REASON = 0x%x\n", regVal);
|
||
|
|
|
||
|
|
if (regVal == WAVE5_SYSERR_QUEUEING_FAIL) {
|
||
|
|
regVal = VpuReadReg(instance->coreIdx, W5_RET_QUEUE_FAIL_REASON);
|
||
|
|
VLOG(ERR, "QUEUE_FAIL_REASON = 0x%x\n", regVal);
|
||
|
|
ret = RETCODE_QUEUEING_FAILURE;
|
||
|
|
}
|
||
|
|
else if (regVal == WAVE5_SYSERR_ACCESS_VIOLATION_HW)
|
||
|
|
ret = RETCODE_MEMORY_ACCESS_VIOLATION;
|
||
|
|
else if (regVal == WAVE5_SYSERR_WATCHDOG_TIMEOUT)
|
||
|
|
ret = RETCODE_VPU_RESPONSE_TIMEOUT;
|
||
|
|
else if (regVal == WAVE5_SYSERR_VLC_BUF_FULL)
|
||
|
|
ret = RETCODE_VLC_BUF_FULL;
|
||
|
|
else if (regVal == WAVE5_SYSERR_BUS_ERROR || regVal == WAVE5_SYSERR_DOUBLE_FAULT)
|
||
|
|
ret = RETCODE_VPU_BUS_ERROR;
|
||
|
|
else
|
||
|
|
ret = RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
static void GetDecSequenceResult(CodecInst* instance, DecInitialInfo* info)
|
||
|
|
{
|
||
|
|
DecInfo* pDecInfo = &instance->CodecInfo->decInfo;
|
||
|
|
Uint32 regVal;
|
||
|
|
Uint32 profileCompatibilityFlag;
|
||
|
|
Uint32 left, right, top, bottom;
|
||
|
|
Uint32 progressiveFlag, interlacedFlag, outputBitDepthMinus8;
|
||
|
|
PhysicalAddress retRdPtr;
|
||
|
|
|
||
|
|
if (Wave5VpuDecGetRdPtr(instance, &retRdPtr) == RETCODE_SUCCESS) {
|
||
|
|
pDecInfo->streamRdPtr = retRdPtr;
|
||
|
|
info->rdPtr = retRdPtr;
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
info->rdPtr = pDecInfo->streamRdPtr;
|
||
|
|
}
|
||
|
|
|
||
|
|
pDecInfo->frameDisplayFlag = VpuReadReg(instance->coreIdx, W5_RET_DEC_DISP_IDC);
|
||
|
|
|
||
|
|
regVal = VpuReadReg(instance->coreIdx, W5_RET_DEC_PIC_SIZE);
|
||
|
|
info->picWidth = ( (regVal >> 16) & 0xffff );
|
||
|
|
info->picHeight = ( regVal & 0xffff );
|
||
|
|
info->minFrameBufferCount = VpuReadReg(instance->coreIdx, W5_RET_DEC_NUM_REQUIRED_FB);
|
||
|
|
info->frameBufDelay = VpuReadReg(instance->coreIdx, W5_RET_DEC_NUM_REORDER_DELAY);
|
||
|
|
|
||
|
|
regVal = VpuReadReg(instance->coreIdx, W5_RET_DEC_CROP_LEFT_RIGHT);
|
||
|
|
left = (regVal >> 16) & 0xffff;
|
||
|
|
right = regVal & 0xffff;
|
||
|
|
regVal = VpuReadReg(instance->coreIdx, W5_RET_DEC_CROP_TOP_BOTTOM);
|
||
|
|
top = (regVal >> 16) & 0xffff;
|
||
|
|
bottom = regVal & 0xffff;
|
||
|
|
|
||
|
|
info->picCropRect.left = left;
|
||
|
|
info->picCropRect.right = info->picWidth - right;
|
||
|
|
info->picCropRect.top = top;
|
||
|
|
info->picCropRect.bottom = info->picHeight - bottom;
|
||
|
|
|
||
|
|
info->fRateNumerator = VpuReadReg(instance->coreIdx, W5_RET_DEC_FRAME_RATE_NR);
|
||
|
|
info->fRateDenominator = VpuReadReg(instance->coreIdx, W5_RET_DEC_FRAME_RATE_DR);
|
||
|
|
|
||
|
|
regVal = VpuReadReg(instance->coreIdx, W5_RET_DEC_COLOR_SAMPLE_INFO);
|
||
|
|
info->lumaBitdepth = (regVal>>0)&0x0f;
|
||
|
|
info->chromaBitdepth = (regVal>>4)&0x0f;
|
||
|
|
info->chromaFormatIDC = (regVal>>8)&0x0f;
|
||
|
|
info->aspectRateInfo = (regVal>>16)&0xff;
|
||
|
|
info->isExtSAR = (info->aspectRateInfo == 255 ? TRUE : FALSE);
|
||
|
|
if (info->isExtSAR == TRUE) {
|
||
|
|
info->aspectRateInfo = VpuReadReg(instance->coreIdx, W5_RET_DEC_ASPECT_RATIO); /* [0:15] - vertical size, [16:31] - horizontal size */
|
||
|
|
}
|
||
|
|
info->bitRate = VpuReadReg(instance->coreIdx, W5_RET_DEC_BIT_RATE);
|
||
|
|
|
||
|
|
regVal = VpuReadReg(instance->coreIdx, W5_RET_DEC_SUB_LAYER_INFO);
|
||
|
|
info->maxSubLayers = (regVal>>8)&0xff;
|
||
|
|
|
||
|
|
regVal = VpuReadReg(instance->coreIdx, W5_RET_DEC_SEQ_PARAM);
|
||
|
|
info->level = regVal&0xff;
|
||
|
|
interlacedFlag = (regVal>>10)&0x1;
|
||
|
|
progressiveFlag = (regVal>>11)&0x1;
|
||
|
|
profileCompatibilityFlag = (regVal>>12)&0xff;
|
||
|
|
info->profile = (regVal>>24)&0x1f;
|
||
|
|
info->tier = (regVal>>29)&0x01;
|
||
|
|
outputBitDepthMinus8 = (regVal>>30)&0x03;
|
||
|
|
|
||
|
|
if (instance->codecMode == W_HEVC_DEC) {
|
||
|
|
/* Guessing Profile */
|
||
|
|
if (info->profile == 0) {
|
||
|
|
if ((profileCompatibilityFlag&0x06) == 0x06) info->profile = HEVC_PROFILE_MAIN; /* Main profile */
|
||
|
|
else if ((profileCompatibilityFlag&0x04) == 0x04) info->profile = HEVC_PROFILE_MAIN10; /* Main10 profile */
|
||
|
|
else if ((profileCompatibilityFlag&0x08) == 0x08) info->profile = HEVC_PROFILE_STILLPICTURE; /* Main Still Picture profile */
|
||
|
|
else info->profile = HEVC_PROFILE_MAIN; /* For old version HM */
|
||
|
|
}
|
||
|
|
|
||
|
|
if (progressiveFlag == 1 && interlacedFlag == 0)
|
||
|
|
info->interlace = 0;
|
||
|
|
else
|
||
|
|
info->interlace = 1;
|
||
|
|
}
|
||
|
|
else if (instance->codecMode == W_AVS2_DEC) {
|
||
|
|
if ((info->lumaBitdepth == 10) && (outputBitDepthMinus8 == 2))
|
||
|
|
info->outputBitDepth = 10;
|
||
|
|
else
|
||
|
|
info->outputBitDepth = 8;
|
||
|
|
|
||
|
|
if (progressiveFlag == 1)
|
||
|
|
info->interlace = 0;
|
||
|
|
else
|
||
|
|
info->interlace = 1;
|
||
|
|
}
|
||
|
|
else if (instance->codecMode == W_AVC_DEC) {
|
||
|
|
info->profile = (regVal>>24)&0x7f;
|
||
|
|
info->interlace = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
info->vlcBufSize = VpuReadReg(instance->coreIdx, W5_RET_VLC_BUF_SIZE);
|
||
|
|
info->paramBufSize = VpuReadReg(instance->coreIdx, W5_RET_PARAM_BUF_SIZE);
|
||
|
|
pDecInfo->vlcBufSize = info->vlcBufSize;
|
||
|
|
pDecInfo->paramBufSize = info->paramBufSize;
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
RetCode Wave5VpuDecGetSeqInfo(CodecInst* instance, DecInitialInfo* info)
|
||
|
|
{
|
||
|
|
RetCode ret = RETCODE_SUCCESS;
|
||
|
|
Uint32 regVal, i;
|
||
|
|
DecInfo* pDecInfo;
|
||
|
|
|
||
|
|
pDecInfo = VPU_HANDLE_TO_DECINFO(instance);
|
||
|
|
|
||
|
|
VpuWriteReg(instance->coreIdx, W5_CMD_DEC_ADDR_REPORT_BASE, pDecInfo->userDataBufAddr);
|
||
|
|
VpuWriteReg(instance->coreIdx, W5_CMD_DEC_REPORT_SIZE, pDecInfo->userDataBufSize);
|
||
|
|
VpuWriteReg(instance->coreIdx, W5_CMD_DEC_REPORT_PARAM, VPU_USER_DATA_ENDIAN&VDI_128BIT_ENDIAN_MASK);
|
||
|
|
|
||
|
|
// Send QUERY cmd
|
||
|
|
ret = SendQuery(instance, GET_RESULT);
|
||
|
|
if (ret != RETCODE_SUCCESS) {
|
||
|
|
regVal = VpuReadReg(instance->coreIdx, W5_RET_FAIL_REASON);
|
||
|
|
if (regVal != WAVE5_SYSERR_QUEUEING_FAIL)
|
||
|
|
VLOG(ERR, "FAIL_REASON = 0x%x\n", regVal);
|
||
|
|
|
||
|
|
if (regVal == WAVE5_SYSERR_RESULT_NOT_READY)
|
||
|
|
return RETCODE_REPORT_NOT_READY;
|
||
|
|
else if (regVal == WAVE5_SYSERR_ACCESS_VIOLATION_HW)
|
||
|
|
return RETCODE_MEMORY_ACCESS_VIOLATION;
|
||
|
|
else if (regVal == WAVE5_SYSERR_WATCHDOG_TIMEOUT)
|
||
|
|
return RETCODE_VPU_RESPONSE_TIMEOUT;
|
||
|
|
else if (regVal == WAVE5_SYSERR_VLC_BUF_FULL)
|
||
|
|
return RETCODE_VLC_BUF_FULL;
|
||
|
|
else if (regVal == WAVE5_SYSERR_BUS_ERROR || regVal == WAVE5_SYSERR_DOUBLE_FAULT)
|
||
|
|
return RETCODE_VPU_BUS_ERROR;
|
||
|
|
else
|
||
|
|
return RETCODE_QUERY_FAILURE;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (instance->loggingEnable)
|
||
|
|
vdi_log(instance->coreIdx, instance->instIndex, W5_INIT_SEQ, 0);
|
||
|
|
|
||
|
|
regVal = VpuReadReg(instance->coreIdx, W5_RET_QUEUE_STATUS);
|
||
|
|
|
||
|
|
pDecInfo->instanceQueueCount = (regVal>>16)&0xff;
|
||
|
|
pDecInfo->reportQueueCount = (regVal & 0xffff);
|
||
|
|
|
||
|
|
if (VpuReadReg(instance->coreIdx, W5_RET_DEC_DECODING_SUCCESS) != 1) {
|
||
|
|
#ifdef SUPPORT_SW_UART
|
||
|
|
ret = RETCODE_FAILURE;
|
||
|
|
#else
|
||
|
|
info->seqInitErrReason = VpuReadReg(instance->coreIdx, W5_RET_DEC_ERR_INFO);
|
||
|
|
ret = RETCODE_FAILURE;
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
#ifdef SUPPORT_SW_UART
|
||
|
|
info->warnInfo = 0;
|
||
|
|
#else
|
||
|
|
info->warnInfo = VpuReadReg(instance->coreIdx, W5_RET_DEC_WARN_INFO);
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
// Get Sequence Info
|
||
|
|
info->userDataSize = 0;
|
||
|
|
info->userDataNum = 0;
|
||
|
|
info->userDataBufFull= 0;
|
||
|
|
info->userDataHeader = VpuReadReg(instance->coreIdx, W5_RET_DEC_USERDATA_IDC);
|
||
|
|
if (info->userDataHeader != 0) {
|
||
|
|
regVal = info->userDataHeader;
|
||
|
|
for (i=0; i<32; i++) {
|
||
|
|
if (i == 1) {
|
||
|
|
if (regVal & (1<<i))
|
||
|
|
info->userDataBufFull = 1;
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
if (regVal & (1<<i))
|
||
|
|
info->userDataNum++;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
info->userDataSize = pDecInfo->userDataBufSize;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (instance->codecMode == W_SVAC_DEC) {
|
||
|
|
regVal = VpuReadReg(instance->coreIdx, W5_RET_DEC_SUB_LAYER_INFO);
|
||
|
|
info->spatialSvcEnable = (regVal>>16)&0x1;
|
||
|
|
info->spatialSvcMode = (regVal>>17)&0x1;
|
||
|
|
}
|
||
|
|
GetDecSequenceResult(instance, info);
|
||
|
|
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
RetCode Wave5VpuDecRegisterFramebuffer(CodecInst* inst, FrameBuffer* fbArr, TiledMapType mapType, Uint32 count)
|
||
|
|
{
|
||
|
|
RetCode ret = RETCODE_SUCCESS;
|
||
|
|
DecInfo* pDecInfo = &inst->CodecInfo->decInfo;
|
||
|
|
Int32 q, j, i, remain, idx, svcBLbaseIdx;
|
||
|
|
Uint32 mvCount;
|
||
|
|
Uint32 k;
|
||
|
|
Int32 coreIdx, startNo, endNo;
|
||
|
|
Uint32 regVal, cbcrInterleave, nv21, picSize;
|
||
|
|
Uint32 endian, yuvFormat = 0;
|
||
|
|
Uint32 addrY, addrCb, addrCr;
|
||
|
|
Uint32 mvColSize, fbcYTblSize, fbcCTblSize;
|
||
|
|
vpu_buffer_t vbBuffer;
|
||
|
|
Uint32 stride;
|
||
|
|
Uint32 colorFormat = 0;
|
||
|
|
Uint32 axiID;
|
||
|
|
Uint32 initPicWidth = 0, initPicHeight = 0;
|
||
|
|
Uint32 scalerFlag = (mapType == LINEAR_FRAME_MAP) ? pDecInfo->scalerEnable : 0;
|
||
|
|
Uint32 pixelOrder=1;
|
||
|
|
Uint32 bwbFlag = (mapType == LINEAR_FRAME_MAP) ? 1 : 0;
|
||
|
|
|
||
|
|
|
||
|
|
coreIdx = inst->coreIdx;
|
||
|
|
axiID = pDecInfo->openParam.virtAxiID;
|
||
|
|
cbcrInterleave = pDecInfo->openParam.cbcrInterleave;
|
||
|
|
nv21 = pDecInfo->openParam.nv21;
|
||
|
|
mvColSize = fbcYTblSize = fbcCTblSize = 0;
|
||
|
|
|
||
|
|
initPicWidth = pDecInfo->initialInfo.picWidth;
|
||
|
|
initPicHeight = pDecInfo->initialInfo.picHeight;
|
||
|
|
|
||
|
|
if (inst->codecMode == W_SVAC_DEC && mapType == COMPRESSED_FRAME_MAP_SVAC_SVC_BL) {
|
||
|
|
initPicWidth = pDecInfo->initialInfo.picWidth>>1; // BL size is half as EL
|
||
|
|
initPicHeight = pDecInfo->initialInfo.picHeight>>1;
|
||
|
|
svcBLbaseIdx = count;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
svcBLbaseIdx = 0;
|
||
|
|
|
||
|
|
if (mapType >= COMPRESSED_FRAME_MAP) {
|
||
|
|
cbcrInterleave = 0;
|
||
|
|
nv21 = 0;
|
||
|
|
|
||
|
|
switch (inst->codecMode) {
|
||
|
|
case W_HEVC_DEC: mvColSize = WAVE5_DEC_HEVC_MVCOL_BUF_SIZE(initPicWidth, initPicHeight); break;
|
||
|
|
case W_VP9_DEC: mvColSize = WAVE5_DEC_VP9_MVCOL_BUF_SIZE(initPicWidth, initPicHeight); break;
|
||
|
|
case W_AVS2_DEC: mvColSize = WAVE5_DEC_AVS2_MVCOL_BUF_SIZE(initPicWidth, initPicHeight); break;
|
||
|
|
case W_SVAC_DEC: mvColSize = 0; break; // case of SVAC, mvColbuffer included in WorkBuffer due to sequence change.
|
||
|
|
case W_AVC_DEC: mvColSize = WAVE5_DEC_AVC_MVCOL_BUF_SIZE(initPicWidth, initPicHeight); break;
|
||
|
|
case W_AV1_DEC: mvColSize = WAVE5_DEC_AV1_MVCOL_BUF_SIZE(initPicWidth, initPicHeight); break;
|
||
|
|
default:
|
||
|
|
return RETCODE_NOT_SUPPORTED_FEATURE;
|
||
|
|
}
|
||
|
|
|
||
|
|
mvColSize = VPU_ALIGN16(mvColSize);
|
||
|
|
vbBuffer.phys_addr = 0;
|
||
|
|
if (inst->codecMode == W_HEVC_DEC || inst->codecMode == W_AVS2_DEC || inst->codecMode == W_VP9_DEC || inst->codecMode == W_AVC_DEC || inst->codecMode == W_AV1_DEC) {
|
||
|
|
vbBuffer.size = ((mvColSize+4095)&~4095)+4096; /* 4096 is a margin */
|
||
|
|
mvCount = count;
|
||
|
|
|
||
|
|
// APIDPRINT("ALLOC MEM - MV\n");
|
||
|
|
for (k=0 ; k<mvCount ; k++) {
|
||
|
|
if ( pDecInfo->vbMV[k].size == 0) {
|
||
|
|
if (vdi_allocate_dma_memory(inst->coreIdx, &vbBuffer, DEC_MV, inst->instIndex) < 0)
|
||
|
|
return RETCODE_INSUFFICIENT_RESOURCE;
|
||
|
|
pDecInfo->vbMV[k] = vbBuffer;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (pDecInfo->productCode == WAVE521C_DUAL_CODE) {
|
||
|
|
Uint32 bgs_width = (pDecInfo->initialInfo.lumaBitdepth >8 ? 256 : 512);
|
||
|
|
Uint32 ot_bg_width = 1024;
|
||
|
|
Uint32 frm_width = VPU_CEIL(initPicWidth, 16);
|
||
|
|
Uint32 frm_height = VPU_CEIL(initPicHeight, 16);
|
||
|
|
Uint32 comp_frm_width = VPU_CEIL(VPU_CEIL(frm_width , 16) + 16, 16); // valid_width = align(width, 16), comp_frm_width = align(valid_width+pad_x, 16)
|
||
|
|
Uint32 ot_frm_width = VPU_CEIL(comp_frm_width, ot_bg_width); // 1024 = offset table BG width
|
||
|
|
|
||
|
|
// sizeof_offset_table()
|
||
|
|
Uint32 ot_bg_height = 32;
|
||
|
|
Uint32 bgs_height = (1<<14) / bgs_width / (pDecInfo->initialInfo.lumaBitdepth >8 ? 2 : 1);
|
||
|
|
Uint32 comp_frm_height = VPU_CEIL(VPU_CEIL(frm_height, 4) + 4, bgs_height);
|
||
|
|
Uint32 ot_frm_height = VPU_CEIL(comp_frm_height, ot_bg_height);
|
||
|
|
fbcYTblSize = (ot_frm_width/16) * (ot_frm_height/4) *2;
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
switch (inst->codecMode) {
|
||
|
|
case W_HEVC_DEC: fbcYTblSize = WAVE5_FBC_LUMA_TABLE_SIZE(initPicWidth, initPicHeight); break;
|
||
|
|
case W_VP9_DEC: fbcYTblSize = WAVE5_FBC_LUMA_TABLE_SIZE(VPU_ALIGN64(initPicWidth), VPU_ALIGN64(initPicHeight)); break;
|
||
|
|
case W_AVS2_DEC: fbcYTblSize = WAVE5_FBC_LUMA_TABLE_SIZE(initPicWidth, initPicHeight); break;
|
||
|
|
case W_SVAC_DEC: fbcYTblSize = WAVE5_FBC_LUMA_TABLE_SIZE(VPU_ALIGN128(initPicWidth), VPU_ALIGN128(initPicHeight)); break;
|
||
|
|
case W_AVC_DEC: fbcYTblSize = WAVE5_FBC_LUMA_TABLE_SIZE(initPicWidth, initPicHeight); break;
|
||
|
|
case W_AV1_DEC: fbcYTblSize = WAVE5_FBC_LUMA_TABLE_SIZE(VPU_ALIGN16(initPicWidth), VPU_ALIGN8(initPicHeight)); break;
|
||
|
|
default:
|
||
|
|
return RETCODE_NOT_SUPPORTED_FEATURE;
|
||
|
|
}
|
||
|
|
fbcYTblSize = VPU_ALIGN16(fbcYTblSize);
|
||
|
|
}
|
||
|
|
|
||
|
|
vbBuffer.phys_addr = 0;
|
||
|
|
vbBuffer.size = ((fbcYTblSize+4095)&~4095)+4096;
|
||
|
|
// APIDPRINT("ALLOC MEM - FBC Y TBL\n");
|
||
|
|
for (k=0 ; k<count ; k++) {
|
||
|
|
if ( pDecInfo->vbFbcYTbl[k+svcBLbaseIdx].size == 0) {
|
||
|
|
if (vdi_allocate_dma_memory(inst->coreIdx, &vbBuffer, DEC_FBCY_TBL, inst->instIndex) < 0)
|
||
|
|
return RETCODE_INSUFFICIENT_RESOURCE;
|
||
|
|
pDecInfo->vbFbcYTbl[k+svcBLbaseIdx] = vbBuffer;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (pDecInfo->productCode == WAVE521C_DUAL_CODE) {
|
||
|
|
Uint32 bgs_width = (pDecInfo->initialInfo.chromaBitdepth >8 ? 256 : 512);
|
||
|
|
Uint32 ot_bg_width = 1024;
|
||
|
|
Uint32 frm_width = VPU_CEIL(initPicWidth, 16);
|
||
|
|
Uint32 frm_height = VPU_CEIL(initPicHeight, 16);
|
||
|
|
Uint32 comp_frm_width = VPU_CEIL(VPU_CEIL(frm_width/2 , 16) + 16, 16); // valid_width = align(width, 16), comp_frm_width = align(valid_width+pad_x, 16)
|
||
|
|
Uint32 ot_frm_width = VPU_CEIL(comp_frm_width, ot_bg_width); // 1024 = offset table BG width
|
||
|
|
|
||
|
|
// sizeof_offset_table()
|
||
|
|
Uint32 ot_bg_height = 32;
|
||
|
|
Uint32 bgs_height = (1<<14) / bgs_width / (pDecInfo->initialInfo.chromaBitdepth >8 ? 2 : 1);
|
||
|
|
Uint32 comp_frm_height = VPU_CEIL(VPU_CEIL(frm_height, 4) + 4, bgs_height);
|
||
|
|
Uint32 ot_frm_height = VPU_CEIL(comp_frm_height, ot_bg_height);
|
||
|
|
fbcCTblSize = (ot_frm_width/16) * (ot_frm_height/4) *2;
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
switch (inst->codecMode) {
|
||
|
|
case W_HEVC_DEC: fbcCTblSize = WAVE5_FBC_CHROMA_TABLE_SIZE(initPicWidth, initPicHeight); break;
|
||
|
|
case W_VP9_DEC: fbcCTblSize = WAVE5_FBC_CHROMA_TABLE_SIZE(VPU_ALIGN64(initPicWidth), VPU_ALIGN64(initPicHeight)); break;
|
||
|
|
case W_AVS2_DEC: fbcCTblSize = WAVE5_FBC_CHROMA_TABLE_SIZE(initPicWidth, initPicHeight); break;
|
||
|
|
case W_SVAC_DEC: fbcCTblSize = WAVE5_FBC_CHROMA_TABLE_SIZE(VPU_ALIGN64(initPicWidth), VPU_ALIGN64(initPicHeight)); break;
|
||
|
|
case W_AVC_DEC: fbcCTblSize = WAVE5_FBC_CHROMA_TABLE_SIZE(initPicWidth, initPicHeight); break;
|
||
|
|
case W_AV1_DEC: fbcCTblSize = WAVE5_FBC_CHROMA_TABLE_SIZE(VPU_ALIGN16(initPicWidth), VPU_ALIGN8(initPicHeight)); break;
|
||
|
|
default:
|
||
|
|
return RETCODE_NOT_SUPPORTED_FEATURE;
|
||
|
|
}
|
||
|
|
fbcCTblSize = VPU_ALIGN16(fbcCTblSize);
|
||
|
|
}
|
||
|
|
|
||
|
|
vbBuffer.phys_addr = 0;
|
||
|
|
vbBuffer.size = ((fbcCTblSize+4095)&~4095)+4096;
|
||
|
|
// APIDPRINT("ALLOC MEM - FBC C TBL\n");
|
||
|
|
for (k=0 ; k<count ; k++) {
|
||
|
|
if ( pDecInfo->vbFbcCTbl[k+svcBLbaseIdx].size == 0) {
|
||
|
|
if (vdi_allocate_dma_memory(inst->coreIdx, &vbBuffer, DEC_FBCC_TBL, inst->instIndex) < 0)
|
||
|
|
return RETCODE_INSUFFICIENT_RESOURCE;
|
||
|
|
pDecInfo->vbFbcCTbl[k+svcBLbaseIdx] = vbBuffer;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
picSize = (initPicWidth<<16)|(initPicHeight);
|
||
|
|
|
||
|
|
// Allocate TaskBuffer
|
||
|
|
vbBuffer.size = (Uint32)((pDecInfo->vlcBufSize * VLC_BUF_NUM) + (pDecInfo->paramBufSize * COMMAND_QUEUE_DEPTH));
|
||
|
|
vbBuffer.phys_addr = 0;
|
||
|
|
if (vdi_allocate_dma_memory(inst->coreIdx, &vbBuffer, DEC_TASK, inst->instIndex) < 0)
|
||
|
|
return RETCODE_INSUFFICIENT_RESOURCE;
|
||
|
|
|
||
|
|
pDecInfo->vbTask = vbBuffer;
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_SET_FB_ADDR_TASK_BUF, pDecInfo->vbTask.phys_addr);
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_SET_FB_TASK_BUF_SIZE, vbBuffer.size);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
picSize = (initPicWidth<<16)|(initPicHeight);
|
||
|
|
if (pDecInfo->scalerEnable == TRUE) {
|
||
|
|
picSize = (pDecInfo->scaleWidth << 16) | (pDecInfo->scaleHeight);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
endian = vdi_convert_endian(coreIdx, fbArr[0].endian);
|
||
|
|
VpuWriteReg(coreIdx, W5_PIC_SIZE, picSize);
|
||
|
|
|
||
|
|
yuvFormat = 0;
|
||
|
|
if (mapType == LINEAR_FRAME_MAP) {
|
||
|
|
BOOL justified = WTL_RIGHT_JUSTIFIED;
|
||
|
|
Uint32 formatNo = WTL_PIXEL_8BIT;
|
||
|
|
switch (pDecInfo->wtlFormat) {
|
||
|
|
case FORMAT_420_P10_16BIT_MSB:
|
||
|
|
case FORMAT_422_P10_16BIT_MSB:
|
||
|
|
justified = WTL_RIGHT_JUSTIFIED;
|
||
|
|
formatNo = WTL_PIXEL_16BIT;
|
||
|
|
break;
|
||
|
|
case FORMAT_420_P10_16BIT_LSB:
|
||
|
|
case FORMAT_422_P10_16BIT_LSB:
|
||
|
|
justified = WTL_LEFT_JUSTIFIED;
|
||
|
|
formatNo = WTL_PIXEL_16BIT;
|
||
|
|
break;
|
||
|
|
case FORMAT_420_P10_32BIT_MSB:
|
||
|
|
case FORMAT_422_P10_32BIT_MSB:
|
||
|
|
justified = WTL_RIGHT_JUSTIFIED;
|
||
|
|
formatNo = WTL_PIXEL_32BIT;
|
||
|
|
break;
|
||
|
|
case FORMAT_420_P10_32BIT_LSB:
|
||
|
|
case FORMAT_422_P10_32BIT_LSB:
|
||
|
|
justified = WTL_LEFT_JUSTIFIED;
|
||
|
|
formatNo = WTL_PIXEL_32BIT;
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
yuvFormat = justified<<2 | formatNo;
|
||
|
|
|
||
|
|
switch (pDecInfo->wtlFormat) {
|
||
|
|
case FORMAT_422:
|
||
|
|
case FORMAT_422_P10_16BIT_MSB:
|
||
|
|
case FORMAT_422_P10_16BIT_LSB:
|
||
|
|
case FORMAT_422_P10_32BIT_MSB:
|
||
|
|
case FORMAT_422_P10_32BIT_LSB:
|
||
|
|
colorFormat = 1;
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
colorFormat = 0;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
stride = fbArr[0].stride;
|
||
|
|
if (mapType >= COMPRESSED_FRAME_MAP) {
|
||
|
|
if ( pDecInfo->chFbcFrameIdx != -1 )
|
||
|
|
stride = fbArr[pDecInfo->chFbcFrameIdx].stride;
|
||
|
|
} else {
|
||
|
|
if ( pDecInfo->chBwbFrameIdx != -1 )
|
||
|
|
stride = fbArr[pDecInfo->chBwbFrameIdx].stride;
|
||
|
|
}
|
||
|
|
|
||
|
|
regVal =
|
||
|
|
(scalerFlag << 29) |
|
||
|
|
(bwbFlag << 28) |
|
||
|
|
(axiID << 24) |
|
||
|
|
(pixelOrder << 23) | /* PIXEL ORDER in 128bit. first pixel in low address */
|
||
|
|
(yuvFormat << 20) |
|
||
|
|
(colorFormat << 19) |
|
||
|
|
(nv21 << 17) |
|
||
|
|
(cbcrInterleave << 16) |
|
||
|
|
(stride);
|
||
|
|
VpuWriteReg(coreIdx, W5_COMMON_PIC_INFO, regVal); //// 0x008012c0
|
||
|
|
|
||
|
|
remain = count;
|
||
|
|
q = (remain+7)/8;
|
||
|
|
idx = 0;
|
||
|
|
for (j=0; j<q; j++) {
|
||
|
|
regVal = (endian<<16) | (j==q-1)<<4 | ((j==0)<<3);//lint !e514
|
||
|
|
regVal |= (pDecInfo->openParam.enableNonRefFbcWrite<<26);
|
||
|
|
regVal |= (pDecInfo->initialInfo.spatialSvcEnable == TRUE ) ? (mapType == COMPRESSED_FRAME_MAP_SVAC_SVC_BL ? 0 : 1<<27) : 0 ;
|
||
|
|
regVal |= (pDecInfo->initialInfo.spatialSvcEnable<<28);
|
||
|
|
VpuWriteReg(coreIdx, W5_SFB_OPTION, regVal);
|
||
|
|
startNo = j*8;
|
||
|
|
endNo = startNo + (remain>=8 ? 8 : remain) - 1;
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_SET_FB_NUM, (startNo<<8)|endNo);
|
||
|
|
|
||
|
|
for (i=0; i<8 && i<remain; i++) {
|
||
|
|
if (mapType == LINEAR_FRAME_MAP && pDecInfo->openParam.cbcrOrder == CBCR_ORDER_REVERSED) {
|
||
|
|
addrY = fbArr[i+startNo].bufY;
|
||
|
|
addrCb = fbArr[i+startNo].bufCr;
|
||
|
|
addrCr = fbArr[i+startNo].bufCb;
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
addrY = fbArr[i+startNo].bufY;
|
||
|
|
addrCb = fbArr[i+startNo].bufCb;
|
||
|
|
addrCr = fbArr[i+startNo].bufCr;
|
||
|
|
}
|
||
|
|
VpuWriteReg(coreIdx, W5_ADDR_LUMA_BASE0 + (i<<4), addrY);
|
||
|
|
VpuWriteReg(coreIdx, W5_ADDR_CB_BASE0 + (i<<4), addrCb);
|
||
|
|
APIDPRINT("REGISTER FB[%02d] Y(0x%08x), Cb(0x%08x) ", i, addrY, addrCb);
|
||
|
|
if (mapType >= COMPRESSED_FRAME_MAP) {
|
||
|
|
VpuWriteReg(coreIdx, W5_ADDR_FBC_Y_OFFSET0 + (i<<4), pDecInfo->vbFbcYTbl[idx+svcBLbaseIdx].phys_addr); /* Luma FBC offset table */
|
||
|
|
VpuWriteReg(coreIdx, W5_ADDR_FBC_C_OFFSET0 + (i<<4), pDecInfo->vbFbcCTbl[idx+svcBLbaseIdx].phys_addr); /* Chroma FBC offset table */
|
||
|
|
VpuWriteReg(coreIdx, W5_ADDR_MV_COL0 + (i<<2), pDecInfo->vbMV[idx+svcBLbaseIdx].phys_addr);
|
||
|
|
APIDPRINT("Yo(0x%08x) Co(0x%08x), Mv(0x%08x)\n",pDecInfo->vbFbcYTbl[idx].phys_addr, pDecInfo->vbFbcCTbl[idx].phys_addr, pDecInfo->vbMV[idx].phys_addr);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
VpuWriteReg(coreIdx, W5_ADDR_CR_BASE0 + (i<<4), addrCr);
|
||
|
|
VpuWriteReg(coreIdx, W5_ADDR_FBC_C_OFFSET0 + (i<<4), 0);
|
||
|
|
VpuWriteReg(coreIdx, W5_ADDR_MV_COL0 + (i<<2), 0);
|
||
|
|
APIDPRINT("Cr(0x%08x)\n", addrCr);
|
||
|
|
}
|
||
|
|
idx++;
|
||
|
|
}
|
||
|
|
remain -= i;
|
||
|
|
|
||
|
|
Wave5BitIssueCommand(inst, W5_SET_FB);
|
||
|
|
|
||
|
|
|
||
|
|
if (vdi_wait_vpu_busy(coreIdx, __VPU_BUSY_TIMEOUT, W5_VPU_BUSY_STATUS) == -1) {
|
||
|
|
return RETCODE_VPU_RESPONSE_TIMEOUT;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
regVal = VpuReadReg(coreIdx, W5_RET_SUCCESS);
|
||
|
|
if (regVal == 0) {
|
||
|
|
return RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
RetCode Wave5VpuDecUpdateFramebuffer(CodecInst* inst, FrameBuffer* fbcFb, FrameBuffer* linearFb, Int32 mvIndex, Int32 picWidth, Int32 picHeight)
|
||
|
|
{
|
||
|
|
RetCode ret = RETCODE_SUCCESS;
|
||
|
|
DecInfo* pDecInfo = &inst->CodecInfo->decInfo;
|
||
|
|
Int8 fbcIndex, linearIndex;
|
||
|
|
Uint32 coreIdx, regVal;
|
||
|
|
Uint32 mvColSize, fbcYTblSize, fbcCTblSize;
|
||
|
|
Uint32 linearStride, fbcStride;
|
||
|
|
vpu_buffer_t* pvbMv = NULL;
|
||
|
|
vpu_buffer_t* pvbFbcYOffset = NULL;
|
||
|
|
vpu_buffer_t* pvbFbcCOffset = NULL;
|
||
|
|
CodStd codec;
|
||
|
|
unsigned long fbcYoffsetAddr = 0;
|
||
|
|
unsigned long fbcCoffsetAddr = 0;
|
||
|
|
coreIdx = inst->coreIdx;
|
||
|
|
linearIndex = (Int8)((linearFb == NULL) ? -1 : linearFb->myIndex - pDecInfo->numFbsForDecoding);
|
||
|
|
fbcIndex = (Int8)((fbcFb == NULL) ? -1 : fbcFb->myIndex);
|
||
|
|
mvColSize = fbcYTblSize = fbcCTblSize = 0;
|
||
|
|
codec = pDecInfo->openParam.bitstreamFormat;
|
||
|
|
|
||
|
|
if (codec != STD_VP9) {
|
||
|
|
return RETCODE_NOT_SUPPORTED_FEATURE;
|
||
|
|
}
|
||
|
|
|
||
|
|
mvColSize = WAVE5_DEC_VP9_MVCOL_BUF_SIZE(picWidth, picHeight);
|
||
|
|
|
||
|
|
if ((fbcFb != NULL) && (fbcIndex >= 0)) {
|
||
|
|
pDecInfo->frameBufPool[fbcIndex] = *fbcFb;
|
||
|
|
}
|
||
|
|
if ((linearFb != NULL) && (linearIndex >= 0)) {
|
||
|
|
pDecInfo->frameBufPool[pDecInfo->numFbsForDecoding + linearIndex] = *linearFb;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (mvIndex >= 0) {
|
||
|
|
pvbMv = &pDecInfo->vbMV[mvIndex];
|
||
|
|
vdi_free_dma_memory(inst->coreIdx, pvbMv, DEC_MV, inst->instIndex);
|
||
|
|
pvbMv->size = ((mvColSize+4095)&~4095) + 4096;
|
||
|
|
if (vdi_allocate_dma_memory(inst->coreIdx, pvbMv, DEC_MV, inst->instIndex) < 0) {
|
||
|
|
return RETCODE_INSUFFICIENT_RESOURCE;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Reallocate FBC offset tables */
|
||
|
|
if (codec == STD_VP9) {
|
||
|
|
//VP9 Decoded size : 64 aligned.
|
||
|
|
fbcYTblSize = WAVE5_FBC_LUMA_TABLE_SIZE(VPU_ALIGN64(picWidth), VPU_ALIGN64(picHeight));
|
||
|
|
}
|
||
|
|
|
||
|
|
if (fbcIndex >= 0) {
|
||
|
|
pvbFbcYOffset = &pDecInfo->vbFbcYTbl[fbcIndex];
|
||
|
|
vdi_free_dma_memory(inst->coreIdx, pvbFbcYOffset, DEC_FBCY_TBL, inst->instIndex);
|
||
|
|
pvbFbcYOffset->phys_addr = 0;
|
||
|
|
pvbFbcYOffset->size = ((fbcYTblSize+4095)&~4095)+4096;
|
||
|
|
if (vdi_allocate_dma_memory(inst->coreIdx, pvbFbcYOffset, DEC_FBCY_TBL, inst->instIndex) < 0) {
|
||
|
|
return RETCODE_INSUFFICIENT_RESOURCE;
|
||
|
|
}
|
||
|
|
fbcYoffsetAddr = pvbFbcYOffset->phys_addr;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (codec == STD_VP9) {
|
||
|
|
fbcCTblSize = WAVE5_FBC_CHROMA_TABLE_SIZE(VPU_ALIGN64(picWidth), VPU_ALIGN64(picHeight));
|
||
|
|
}
|
||
|
|
|
||
|
|
if (fbcIndex >= 0) {
|
||
|
|
pvbFbcCOffset = &pDecInfo->vbFbcCTbl[fbcIndex];
|
||
|
|
vdi_free_dma_memory(inst->coreIdx, pvbFbcCOffset, DEC_FBCC_TBL, inst->instIndex);
|
||
|
|
pvbFbcCOffset->phys_addr = 0;
|
||
|
|
pvbFbcCOffset->size = ((fbcCTblSize+4095)&~4095)+4096;
|
||
|
|
if (vdi_allocate_dma_memory(inst->coreIdx, pvbFbcCOffset, DEC_FBCC_TBL, inst->instIndex) < 0) {
|
||
|
|
return RETCODE_INSUFFICIENT_RESOURCE;
|
||
|
|
}
|
||
|
|
fbcCoffsetAddr = pvbFbcCOffset->phys_addr;
|
||
|
|
}
|
||
|
|
|
||
|
|
linearStride = linearFb == NULL ? 0 : linearFb->stride;
|
||
|
|
fbcStride = fbcFb == NULL ? 0 : fbcFb->stride;
|
||
|
|
regVal = linearStride<<16 | fbcStride;
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_SET_FB_STRIDE, regVal);
|
||
|
|
|
||
|
|
regVal = (picWidth<<16) | picHeight;
|
||
|
|
if (pDecInfo->scalerEnable == TRUE) {
|
||
|
|
regVal = (pDecInfo->scaleWidth << 16) | (pDecInfo->scaleHeight);
|
||
|
|
}
|
||
|
|
VpuWriteReg(coreIdx, W5_PIC_SIZE, regVal);
|
||
|
|
|
||
|
|
VLOG(INFO, "fbcIndex(%d), linearIndex(%d), mvIndex(%d)\n", fbcIndex, linearIndex, mvIndex);
|
||
|
|
regVal = (mvIndex&0xff) << 16 | (linearIndex&0xff) << 8 | (fbcIndex&0xff);
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_SET_FB_INDEX, regVal);
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_ADDR_LUMA_BASE, linearFb == NULL ? 0 : linearFb->bufY);
|
||
|
|
VpuWriteReg(coreIdx, W5_ADDR_CB_BASE, linearFb == NULL ? 0 : linearFb->bufCb);
|
||
|
|
VpuWriteReg(coreIdx, W5_ADDR_CR_BASE, linearFb == NULL ? 0 : linearFb->bufCr);
|
||
|
|
VpuWriteReg(coreIdx, W5_ADDR_MV_COL, pvbMv == NULL ? 0 : pvbMv->phys_addr);
|
||
|
|
VpuWriteReg(coreIdx, W5_ADDR_FBC_Y_BASE, fbcFb == NULL ? 0 : fbcFb->bufY);
|
||
|
|
VpuWriteReg(coreIdx, W5_ADDR_FBC_C_BASE, fbcFb == NULL ? 0 : fbcFb->bufCb);
|
||
|
|
VpuWriteReg(coreIdx, W5_ADDR_FBC_Y_OFFSET, (unsigned int)fbcYoffsetAddr);
|
||
|
|
VpuWriteReg(coreIdx, W5_ADDR_FBC_C_OFFSET, (unsigned int)fbcCoffsetAddr);
|
||
|
|
VpuWriteReg(coreIdx, W5_SFB_OPTION, 1); /* UPDATE FRAMEBUFFER */
|
||
|
|
|
||
|
|
Wave5BitIssueCommand(inst, W5_SET_FB);
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
if (vdi_wait_vpu_busy(coreIdx, __VPU_BUSY_TIMEOUT, W5_VPU_BUSY_STATUS) == -1) {
|
||
|
|
return RETCODE_VPU_RESPONSE_TIMEOUT;
|
||
|
|
}
|
||
|
|
|
||
|
|
regVal = VpuReadReg(coreIdx, W5_RET_SUCCESS);
|
||
|
|
if (regVal == 0) {
|
||
|
|
return RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
RetCode Wave5VpuDecode(CodecInst* instance, DecParam* option)
|
||
|
|
{
|
||
|
|
DecInfo* pDecInfo = &instance->CodecInfo->decInfo;
|
||
|
|
DecOpenParam* pOpenParam = &pDecInfo->openParam;
|
||
|
|
Uint32 modeOption = DEC_PIC_NORMAL, bsOption, regVal;
|
||
|
|
Int32 forceLatency = -1;
|
||
|
|
|
||
|
|
if (pDecInfo->thumbnailMode) {
|
||
|
|
modeOption = DEC_PIC_W_THUMBNAIL;
|
||
|
|
}
|
||
|
|
else if (option->skipframeMode) {
|
||
|
|
switch (option->skipframeMode) {
|
||
|
|
case WAVE_SKIPMODE_NON_IRAP:
|
||
|
|
modeOption = SKIP_NON_IRAP;
|
||
|
|
forceLatency = 0;
|
||
|
|
break;
|
||
|
|
case WAVE_SKIPMODE_NON_REF:
|
||
|
|
modeOption = SKIP_NON_REF_PIC;
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
// skip off
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// set disable reorder
|
||
|
|
if (pDecInfo->reorderEnable == FALSE) {
|
||
|
|
forceLatency = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Set attributes of bitstream buffer controller */
|
||
|
|
bsOption = 0;
|
||
|
|
regVal = 0;
|
||
|
|
switch (pOpenParam->bitstreamMode) {
|
||
|
|
case BS_MODE_INTERRUPT:
|
||
|
|
bsOption = 0;
|
||
|
|
break;
|
||
|
|
case BS_MODE_PIC_END:
|
||
|
|
bsOption = BSOPTION_ENABLE_EXPLICIT_END;
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
return RETCODE_INVALID_PARAM;
|
||
|
|
}
|
||
|
|
|
||
|
|
VpuWriteReg(instance->coreIdx, W5_BS_RD_PTR, pDecInfo->streamRdPtr);
|
||
|
|
VpuWriteReg(instance->coreIdx, W5_BS_WR_PTR, pDecInfo->streamWrPtr);
|
||
|
|
if (pDecInfo->streamEndflag == 1) {
|
||
|
|
bsOption = 3; // (streamEndFlag<<1) | EXPLICIT_END
|
||
|
|
}
|
||
|
|
if (pOpenParam->bitstreamMode == BS_MODE_PIC_END) {
|
||
|
|
bsOption |= (1UL<<31);
|
||
|
|
}
|
||
|
|
if (instance->codecMode == W_AV1_DEC) {
|
||
|
|
bsOption |= ((pOpenParam->av1Format) << 2);
|
||
|
|
}
|
||
|
|
VpuWriteReg(instance->coreIdx, W5_BS_OPTION, bsOption);
|
||
|
|
|
||
|
|
/* Secondary AXI */
|
||
|
|
regVal = (pDecInfo->secAxiInfo.u.wave.useBitEnable<<0) |
|
||
|
|
(pDecInfo->secAxiInfo.u.wave.useIpEnable<<9) |
|
||
|
|
(pDecInfo->secAxiInfo.u.wave.useLfRowEnable<<15);
|
||
|
|
regVal |= (pDecInfo->secAxiInfo.u.wave.useSclEnable<<5);
|
||
|
|
VpuWriteReg(instance->coreIdx, W5_USE_SEC_AXI, regVal);
|
||
|
|
|
||
|
|
/* Set attributes of User buffer */
|
||
|
|
VpuWriteReg(instance->coreIdx, W5_CMD_DEC_USER_MASK, pDecInfo->userDataEnable);
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
if (pDecInfo->tempIdSelectMode == FALSE)
|
||
|
|
VpuWriteReg(instance->coreIdx, W5_CMD_DEC_TEMPORAL_ID_PLUS1, pDecInfo->tempIdSelectMode<<8 | (pDecInfo->targetSubLayerId+1));
|
||
|
|
else
|
||
|
|
VpuWriteReg(instance->coreIdx, W5_CMD_DEC_REL_TEMPORAL_ID, pDecInfo->tempIdSelectMode<<8 | (pDecInfo->relTargetLayerId+1));
|
||
|
|
|
||
|
|
VpuWriteReg(instance->coreIdx, W5_CMD_SEQ_CHANGE_ENABLE_FLAG, pDecInfo->seqChangeMask);
|
||
|
|
VpuWriteReg(instance->coreIdx, W5_CMD_DEC_FORCE_FB_LATENCY_PLUS1, forceLatency+1);
|
||
|
|
VpuWriteReg(instance->coreIdx, W5_COMMAND_OPTION, ((option->disableFilmGrain<<6) | (option->craAsBlaFlag<<5) | modeOption));
|
||
|
|
|
||
|
|
Wave5BitIssueCommand(instance, W5_DEC_PIC);
|
||
|
|
|
||
|
|
if (vdi_wait_vpu_busy(instance->coreIdx, __VPU_BUSY_TIMEOUT, W5_VPU_BUSY_STATUS) == -1) { // Check QUEUE_DONE
|
||
|
|
if (instance->loggingEnable)
|
||
|
|
vdi_log(instance->coreIdx, instance->instIndex, W5_DEC_PIC, 2);
|
||
|
|
return RETCODE_VPU_RESPONSE_TIMEOUT;
|
||
|
|
}
|
||
|
|
|
||
|
|
regVal = VpuReadReg(instance->coreIdx, W5_RET_QUEUE_STATUS);
|
||
|
|
|
||
|
|
pDecInfo->instanceQueueCount = (regVal>>16)&0xff;
|
||
|
|
pDecInfo->reportQueueCount = (regVal & 0xffff);
|
||
|
|
|
||
|
|
if (VpuReadReg(instance->coreIdx, W5_RET_SUCCESS) == FALSE) { // FAILED for adding a command into VCPU QUEUE
|
||
|
|
regVal = VpuReadReg(instance->coreIdx, W5_RET_FAIL_REASON);
|
||
|
|
if (regVal != WAVE5_SYSERR_QUEUEING_FAIL)
|
||
|
|
VLOG(ERR, "FAIL_REASON = 0x%x\n", regVal);
|
||
|
|
|
||
|
|
if (regVal == WAVE5_SYSERR_QUEUEING_FAIL) {
|
||
|
|
regVal = VpuReadReg(instance->coreIdx, W5_RET_QUEUE_FAIL_REASON);
|
||
|
|
VLOG(ERR, "QUEUE_FAIL_REASON = 0x%x\n", regVal);
|
||
|
|
return RETCODE_QUEUEING_FAILURE;
|
||
|
|
}
|
||
|
|
else if (regVal == WAVE5_SYSERR_ACCESS_VIOLATION_HW)
|
||
|
|
return RETCODE_MEMORY_ACCESS_VIOLATION;
|
||
|
|
else if (regVal == WAVE5_SYSERR_WATCHDOG_TIMEOUT)
|
||
|
|
return RETCODE_VPU_RESPONSE_TIMEOUT;
|
||
|
|
else if (regVal == WAVE5_SYSERR_VLC_BUF_FULL)
|
||
|
|
return RETCODE_VLC_BUF_FULL;
|
||
|
|
else if (regVal == WAVE5_SYSERR_BUS_ERROR || regVal == WAVE5_SYSERR_DOUBLE_FAULT)
|
||
|
|
return RETCODE_VPU_BUS_ERROR;
|
||
|
|
else
|
||
|
|
return RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
|
||
|
|
return RETCODE_SUCCESS;
|
||
|
|
}
|
||
|
|
|
||
|
|
RetCode Wave5VpuDecGetResult(CodecInst* instance, DecOutputInfo* result)
|
||
|
|
{
|
||
|
|
RetCode ret = RETCODE_SUCCESS;
|
||
|
|
Uint32 regVal, index, nalUnitType;
|
||
|
|
DecInfo* pDecInfo;
|
||
|
|
vpu_instance_pool_t* instancePool = NULL;
|
||
|
|
|
||
|
|
pDecInfo = VPU_HANDLE_TO_DECINFO(instance);
|
||
|
|
|
||
|
|
VpuWriteReg(instance->coreIdx, W5_CMD_DEC_ADDR_REPORT_BASE, pDecInfo->userDataBufAddr);
|
||
|
|
VpuWriteReg(instance->coreIdx, W5_CMD_DEC_REPORT_SIZE, pDecInfo->userDataBufSize);
|
||
|
|
VpuWriteReg(instance->coreIdx, W5_CMD_DEC_REPORT_PARAM, VPU_USER_DATA_ENDIAN&VDI_128BIT_ENDIAN_MASK);
|
||
|
|
|
||
|
|
// Send QUERY cmd
|
||
|
|
ret = SendQuery(instance, GET_RESULT);
|
||
|
|
|
||
|
|
if (ret != RETCODE_SUCCESS) {
|
||
|
|
regVal = VpuReadReg(instance->coreIdx, W5_RET_FAIL_REASON);
|
||
|
|
if (regVal != WAVE5_SYSERR_QUEUEING_FAIL)
|
||
|
|
VLOG(ERR, "FAIL_REASON = 0x%x\n", regVal);
|
||
|
|
|
||
|
|
if (regVal == WAVE5_SYSERR_RESULT_NOT_READY)
|
||
|
|
return RETCODE_REPORT_NOT_READY;
|
||
|
|
else if (regVal == WAVE5_SYSERR_ACCESS_VIOLATION_HW)
|
||
|
|
return RETCODE_MEMORY_ACCESS_VIOLATION;
|
||
|
|
else if (regVal == WAVE5_SYSERR_WATCHDOG_TIMEOUT)
|
||
|
|
return RETCODE_VPU_RESPONSE_TIMEOUT;
|
||
|
|
else if (regVal == WAVE5_SYSERR_VLC_BUF_FULL)
|
||
|
|
return RETCODE_VLC_BUF_FULL;
|
||
|
|
else if (regVal == WAVE5_SYSERR_BUS_ERROR || regVal == WAVE5_SYSERR_DOUBLE_FAULT)
|
||
|
|
return RETCODE_VPU_BUS_ERROR;
|
||
|
|
else
|
||
|
|
return RETCODE_QUERY_FAILURE;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (instance->loggingEnable)
|
||
|
|
vdi_log(instance->coreIdx, instance->instIndex, W5_DEC_PIC, 0);
|
||
|
|
|
||
|
|
regVal = VpuReadReg(instance->coreIdx, W5_RET_QUEUE_STATUS);
|
||
|
|
|
||
|
|
pDecInfo->instanceQueueCount = (regVal>>16)&0xff;
|
||
|
|
pDecInfo->reportQueueCount = (regVal & 0xffff);
|
||
|
|
|
||
|
|
result->decodingSuccess = VpuReadReg(instance->coreIdx, W5_RET_DEC_DECODING_SUCCESS);
|
||
|
|
#ifdef SUPPORT_SW_UART
|
||
|
|
#else
|
||
|
|
if (result->decodingSuccess == FALSE) {
|
||
|
|
result->errorReason = VpuReadReg(instance->coreIdx, W5_RET_DEC_ERR_INFO);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
result->warnInfo = VpuReadReg(instance->coreIdx, W5_RET_DEC_WARN_INFO);
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
|
result->decOutputExtData.userDataSize = 0;
|
||
|
|
result->decOutputExtData.userDataNum = 0;
|
||
|
|
result->decOutputExtData.userDataBufFull= 0;
|
||
|
|
result->decOutputExtData.userDataHeader = VpuReadReg(instance->coreIdx, W5_RET_DEC_USERDATA_IDC);
|
||
|
|
if (result->decOutputExtData.userDataHeader != 0) {
|
||
|
|
regVal = result->decOutputExtData.userDataHeader;
|
||
|
|
for (index=0; index<32; index++) {
|
||
|
|
if (index == 1) {
|
||
|
|
if (regVal & (1<<index))
|
||
|
|
result->decOutputExtData.userDataBufFull = 1;
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
if (regVal & (1<<index))
|
||
|
|
result->decOutputExtData.userDataNum++;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
result->decOutputExtData.userDataSize = pDecInfo->userDataBufSize;
|
||
|
|
}
|
||
|
|
|
||
|
|
regVal = VpuReadReg(instance->coreIdx, W5_RET_DEC_PIC_TYPE);
|
||
|
|
|
||
|
|
nalUnitType = (regVal & 0x3f0) >> 4;
|
||
|
|
result->nalType = nalUnitType;
|
||
|
|
|
||
|
|
if (instance->codecMode == W_VP9_DEC) {
|
||
|
|
if (regVal&0x01) result->picType = PIC_TYPE_I;
|
||
|
|
else if (regVal&0x02) result->picType = PIC_TYPE_P;
|
||
|
|
else if (regVal&0x04) result->picType = PIC_TYPE_REPEAT;
|
||
|
|
else result->picType = PIC_TYPE_MAX;
|
||
|
|
}
|
||
|
|
else if (instance->codecMode == W_HEVC_DEC) {
|
||
|
|
if (regVal&0x04) result->picType = PIC_TYPE_B;
|
||
|
|
else if (regVal&0x02) result->picType = PIC_TYPE_P;
|
||
|
|
else if (regVal&0x01) result->picType = PIC_TYPE_I;
|
||
|
|
else result->picType = PIC_TYPE_MAX;
|
||
|
|
if ((nalUnitType == 19 || nalUnitType == 20) && (result->picType == PIC_TYPE_I)) {
|
||
|
|
/* IDR_W_RADL, IDR_N_LP */
|
||
|
|
result->picType = PIC_TYPE_IDR;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else if (instance->codecMode == W_AVC_DEC) {
|
||
|
|
if (regVal&0x04) result->picType = PIC_TYPE_B;
|
||
|
|
else if (regVal&0x02) result->picType = PIC_TYPE_P;
|
||
|
|
else if (regVal&0x01) result->picType = PIC_TYPE_I;
|
||
|
|
else result->picType = PIC_TYPE_MAX;
|
||
|
|
if ((nalUnitType == 5) && (result->picType == PIC_TYPE_I)) {
|
||
|
|
/* IDR */
|
||
|
|
result->picType = PIC_TYPE_IDR;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else if (instance->codecMode == W_SVAC_DEC) {
|
||
|
|
if (regVal&0x01) result->picType = PIC_TYPE_KEY;
|
||
|
|
else if (regVal&0x02) result->picType = PIC_TYPE_INTER;
|
||
|
|
else result->picType = PIC_TYPE_MAX;
|
||
|
|
}
|
||
|
|
else if (instance->codecMode == W_AV1_DEC) {
|
||
|
|
switch (regVal & 0x07) {
|
||
|
|
case 0: result->picType = PIC_TYPE_KEY; break;
|
||
|
|
case 1: result->picType = PIC_TYPE_INTER; break;
|
||
|
|
case 2: result->picType = PIC_TYPE_AV1_INTRA; break;
|
||
|
|
case 3: result->picType = PIC_TYPE_AV1_SWITCH; break;
|
||
|
|
default:
|
||
|
|
result->picType = PIC_TYPE_MAX; break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else { // AVS2
|
||
|
|
switch(regVal&0x07) {
|
||
|
|
case 0: result->picType = PIC_TYPE_I; break;
|
||
|
|
case 1: result->picType = PIC_TYPE_P; break;
|
||
|
|
case 2: result->picType = PIC_TYPE_B; break;
|
||
|
|
case 3: result->picType = PIC_TYPE_AVS2_F; break;
|
||
|
|
case 4: result->picType = PIC_TYPE_AVS2_S; break;
|
||
|
|
case 5: result->picType = PIC_TYPE_AVS2_G; break;
|
||
|
|
case 6: result->picType = PIC_TYPE_AVS2_GB;break;
|
||
|
|
default:
|
||
|
|
result->picType = PIC_TYPE_MAX; break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
result->outputFlag = (regVal>>31)&0x1;
|
||
|
|
result->ctuSize = 16<<((regVal>>10)&0x3);
|
||
|
|
index = VpuReadReg(instance->coreIdx, W5_RET_DEC_DISPLAY_INDEX);
|
||
|
|
result->indexFrameDisplay = index;
|
||
|
|
result->indexFrameDisplayForTiled = index;
|
||
|
|
index = VpuReadReg(instance->coreIdx, W5_RET_DEC_DECODED_INDEX);
|
||
|
|
result->indexFrameDecoded = index;
|
||
|
|
result->indexFrameDecodedForTiled = index;
|
||
|
|
|
||
|
|
if (instance->codecMode == W_HEVC_DEC) {
|
||
|
|
result->decodedPOC = -1;
|
||
|
|
result->displayPOC = -1;
|
||
|
|
if (result->indexFrameDecoded >= 0 || result->indexFrameDecoded == DECODED_IDX_FLAG_SKIP)
|
||
|
|
result->decodedPOC = VpuReadReg(instance->coreIdx, W5_RET_DEC_PIC_POC);
|
||
|
|
regVal = VpuReadReg(instance->coreIdx, W5_RET_DEC_SUB_LAYER_INFO);
|
||
|
|
result->temporalId = regVal & 0xff;
|
||
|
|
}
|
||
|
|
else if (instance->codecMode == W_SVAC_DEC) {
|
||
|
|
regVal = VpuReadReg(instance->coreIdx, W5_RET_DEC_SUB_LAYER_INFO);
|
||
|
|
result->temporalId = regVal & 0xff;
|
||
|
|
result->svacInfo.spatialSvcFlag = (regVal >> 16) & 0x1;
|
||
|
|
result->svacInfo.spatialSvcMode = (regVal >> 17) & 0x1;
|
||
|
|
result->svacInfo.spatialSvcLayer= (regVal >> 18) & 0x1;
|
||
|
|
}
|
||
|
|
else if (instance->codecMode == W_AVS2_DEC) {
|
||
|
|
result->avs2Info.decodedPOI = -1;
|
||
|
|
result->avs2Info.displayPOI = -1;
|
||
|
|
if (result->indexFrameDecoded >= 0)
|
||
|
|
result->avs2Info.decodedPOI = VpuReadReg(instance->coreIdx, W5_RET_DEC_PIC_POC);
|
||
|
|
|
||
|
|
regVal = VpuReadReg(instance->coreIdx, W5_RET_DEC_SUB_LAYER_INFO);
|
||
|
|
result->temporalId = regVal & 0xff;
|
||
|
|
}
|
||
|
|
else if (instance->codecMode == W_AVC_DEC) {
|
||
|
|
result->decodedPOC = -1;
|
||
|
|
result->displayPOC = -1;
|
||
|
|
if (result->indexFrameDecoded >= 0 || result->indexFrameDecoded == DECODED_IDX_FLAG_SKIP)
|
||
|
|
result->decodedPOC = VpuReadReg(instance->coreIdx, W5_RET_DEC_PIC_POC);
|
||
|
|
regVal = VpuReadReg(instance->coreIdx, W5_RET_DEC_SUB_LAYER_INFO);
|
||
|
|
result->temporalId = regVal & 0xff;
|
||
|
|
}
|
||
|
|
else if (instance->codecMode == W_AV1_DEC) {
|
||
|
|
result->decodedPOC = -1;
|
||
|
|
result->displayPOC = -1;
|
||
|
|
if (result->indexFrameDecoded >= 0 || result->indexFrameDecoded == DECODED_IDX_FLAG_SKIP)
|
||
|
|
result->decodedPOC = VpuReadReg(instance->coreIdx, W5_RET_DEC_PIC_POC);
|
||
|
|
regVal = VpuReadReg(instance->coreIdx, W5_RET_DEC_SUB_LAYER_INFO);
|
||
|
|
result->temporalId = regVal & 0xff;
|
||
|
|
regVal = VpuReadReg(instance->coreIdx, W5_RET_DEC_PIC_PARAM);
|
||
|
|
result->av1Info.allowIntraBC = (regVal >> 0) & 0x1;
|
||
|
|
result->av1Info.allowScreenContentTools = (regVal >> 1) & 0x1;
|
||
|
|
}
|
||
|
|
|
||
|
|
result->sequenceChanged = VpuReadReg(instance->coreIdx, W5_RET_DEC_NOTIFICATION);
|
||
|
|
if (result->sequenceChanged & SEQ_CHANGE_INTER_RES_CHANGE)
|
||
|
|
result->indexInterFrameDecoded = VpuReadReg(instance->coreIdx, W5_RET_DEC_REALLOC_INDEX);
|
||
|
|
|
||
|
|
|
||
|
|
regVal = VpuReadReg(instance->coreIdx, W5_RET_DEC_PIC_SIZE);
|
||
|
|
result->decPicWidth = regVal>>16;
|
||
|
|
result->decPicHeight = regVal&0xffff;
|
||
|
|
|
||
|
|
if (result->sequenceChanged) {
|
||
|
|
osal_memcpy((void*)&pDecInfo->newSeqInfo, (void*)&pDecInfo->initialInfo, sizeof(DecInitialInfo));
|
||
|
|
GetDecSequenceResult(instance, &pDecInfo->newSeqInfo);
|
||
|
|
}
|
||
|
|
|
||
|
|
result->numOfErrMBs = VpuReadReg(instance->coreIdx, W5_RET_DEC_ERR_CTB_NUM)>>16;
|
||
|
|
result->numOfTotMBs = VpuReadReg(instance->coreIdx, W5_RET_DEC_ERR_CTB_NUM)&0xffff;
|
||
|
|
result->bytePosFrameStart = VpuReadReg(instance->coreIdx, W5_RET_DEC_AU_START_POS);
|
||
|
|
result->bytePosFrameEnd = VpuReadReg(instance->coreIdx, W5_RET_DEC_AU_END_POS);
|
||
|
|
|
||
|
|
regVal = VpuReadReg(instance->coreIdx, W5_RET_DEC_RECOVERY_POINT);
|
||
|
|
result->h265RpSei.recoveryPocCnt = regVal & 0xFFFF; // [15:0]
|
||
|
|
result->h265RpSei.exactMatchFlag = (regVal >> 16)&0x01; // [16]
|
||
|
|
result->h265RpSei.brokenLinkFlag = (regVal >> 17)&0x01; // [17]
|
||
|
|
result->h265RpSei.exist = (regVal >> 18)&0x01; // [18]
|
||
|
|
if(result->h265RpSei.exist == 0) {
|
||
|
|
result->h265RpSei.recoveryPocCnt = 0;
|
||
|
|
result->h265RpSei.exactMatchFlag = 0;
|
||
|
|
result->h265RpSei.brokenLinkFlag = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
result->decHostCmdTick = VpuReadReg(instance->coreIdx, W5_RET_DEC_HOST_CMD_TICK);
|
||
|
|
result->decSeekStartTick = VpuReadReg(instance->coreIdx, W5_RET_DEC_SEEK_START_TICK);
|
||
|
|
result->decSeekEndTick = VpuReadReg(instance->coreIdx, W5_RET_DEC_SEEK_END_TICK);
|
||
|
|
result->decParseStartTick = VpuReadReg(instance->coreIdx, W5_RET_DEC_PARSING_START_TICK);
|
||
|
|
result->decParseEndTick = VpuReadReg(instance->coreIdx, W5_RET_DEC_PARSING_END_TICK);
|
||
|
|
result->decDecodeStartTick = VpuReadReg(instance->coreIdx, W5_RET_DEC_DECODING_START_TICK);
|
||
|
|
result->decDecodeEndTick = VpuReadReg(instance->coreIdx, W5_RET_DEC_DECODING_ENC_TICK);
|
||
|
|
|
||
|
|
instancePool = vdi_get_instance_pool(instance->coreIdx);
|
||
|
|
if (instancePool) {
|
||
|
|
if (pDecInfo->firstCycleCheck == FALSE) {
|
||
|
|
result->frameCycle = (result->decDecodeEndTick - result->decHostCmdTick)*pDecInfo->cyclePerTick;
|
||
|
|
instancePool->lastPerformanceCycles = result->decDecodeEndTick;
|
||
|
|
pDecInfo->firstCycleCheck = TRUE;
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
if ( result->indexFrameDecodedForTiled != -1 ) {
|
||
|
|
result->frameCycle = (result->decDecodeEndTick - instancePool->lastPerformanceCycles)*pDecInfo->cyclePerTick;
|
||
|
|
instancePool->lastPerformanceCycles = result->decDecodeEndTick;
|
||
|
|
if (instancePool->lastPerformanceCycles < result->decHostCmdTick)
|
||
|
|
result->frameCycle = (result->decDecodeEndTick - result->decHostCmdTick);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
result->seekCycle = (result->decSeekEndTick - result->decSeekStartTick)*pDecInfo->cyclePerTick;
|
||
|
|
result->parseCycle = (result->decParseEndTick - result->decParseStartTick)*pDecInfo->cyclePerTick;
|
||
|
|
result->DecodedCycle = (result->decDecodeEndTick - result->decDecodeStartTick)*pDecInfo->cyclePerTick;
|
||
|
|
|
||
|
|
if (0 == pDecInfo->instanceQueueCount && 0 == pDecInfo->reportQueueCount) {
|
||
|
|
// No remaining command. Reset frame cycle.
|
||
|
|
pDecInfo->firstCycleCheck = FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (result->sequenceChanged && (instance->codecMode != W_VP9_DEC)) {
|
||
|
|
pDecInfo->scaleWidth = pDecInfo->newSeqInfo.picWidth;
|
||
|
|
pDecInfo->scaleHeight = pDecInfo->newSeqInfo.picHeight;
|
||
|
|
}
|
||
|
|
|
||
|
|
return RETCODE_SUCCESS;
|
||
|
|
}
|
||
|
|
|
||
|
|
RetCode Wave5VpuDecFlush(CodecInst* instance, FramebufferIndex* framebufferIndexes __attribute__((unused)), Uint32 size __attribute__((unused)))
|
||
|
|
{
|
||
|
|
RetCode ret = RETCODE_SUCCESS;
|
||
|
|
|
||
|
|
Wave5BitIssueCommand(instance, W5_FLUSH_INSTANCE);
|
||
|
|
|
||
|
|
|
||
|
|
if (vdi_wait_vpu_busy(instance->coreIdx, __VPU_BUSY_TIMEOUT, W5_VPU_BUSY_STATUS) == -1)
|
||
|
|
return RETCODE_VPU_RESPONSE_TIMEOUT;
|
||
|
|
|
||
|
|
if (VpuReadReg(instance->coreIdx, W5_RET_SUCCESS) == FALSE) {
|
||
|
|
Uint32 regVal;
|
||
|
|
regVal = VpuReadReg(instance->coreIdx, W5_RET_FAIL_REASON);
|
||
|
|
if (regVal != WAVE5_SYSERR_QUEUEING_FAIL)
|
||
|
|
VLOG(ERR, "FAIL_REASON = 0x%x\n", regVal);
|
||
|
|
|
||
|
|
if (regVal == WAVE5_SYSERR_VPU_STILL_RUNNING)
|
||
|
|
return RETCODE_VPU_STILL_RUNNING;
|
||
|
|
else if (regVal == WAVE5_SYSERR_ACCESS_VIOLATION_HW)
|
||
|
|
return RETCODE_MEMORY_ACCESS_VIOLATION;
|
||
|
|
else if (regVal == WAVE5_SYSERR_WATCHDOG_TIMEOUT)
|
||
|
|
return RETCODE_VPU_RESPONSE_TIMEOUT;
|
||
|
|
else if (regVal == WAVE5_SYSERR_VLC_BUF_FULL)
|
||
|
|
return RETCODE_VLC_BUF_FULL;
|
||
|
|
else if (regVal == WAVE5_SYSERR_BUS_ERROR || regVal == WAVE5_SYSERR_DOUBLE_FAULT)
|
||
|
|
return RETCODE_VPU_BUS_ERROR;
|
||
|
|
else
|
||
|
|
return RETCODE_QUERY_FAILURE;
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
DecInfo* pDecInfo = VPU_HANDLE_TO_DECINFO(instance);
|
||
|
|
pDecInfo->instanceQueueCount = 0;
|
||
|
|
pDecInfo->reportQueueCount = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
return ret;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
RetCode Wave5VpuReInit(Uint32 coreIdx, void* firmware, Uint32 size)
|
||
|
|
{
|
||
|
|
vpu_buffer_t vb;
|
||
|
|
PhysicalAddress codeBase, tempBase;
|
||
|
|
PhysicalAddress oldCodeBase, tempSize;
|
||
|
|
Uint32 codeSize;
|
||
|
|
Uint32 regVal, remapSize;
|
||
|
|
vdi_get_common_memory(coreIdx, &vb);
|
||
|
|
|
||
|
|
codeBase = vb.phys_addr;
|
||
|
|
/* ALIGN TO 4KB */
|
||
|
|
codeSize = (WAVE5_MAX_CODE_BUF_SIZE&~0xfff);
|
||
|
|
if (codeSize < size*2) {
|
||
|
|
return RETCODE_INSUFFICIENT_RESOURCE;
|
||
|
|
}
|
||
|
|
tempBase = vb.phys_addr + WAVE5_TEMPBUF_OFFSET;
|
||
|
|
tempSize = WAVE5_TEMPBUF_SIZE;
|
||
|
|
|
||
|
|
oldCodeBase = VpuReadReg(coreIdx, W5_VPU_REMAP_PADDR);
|
||
|
|
|
||
|
|
if (oldCodeBase != codeBase + W5_REMAP_INDEX1*W5_REMAP_MAX_SIZE) {
|
||
|
|
Uint32 hwOption = 0;
|
||
|
|
|
||
|
|
VpuWriteMem(coreIdx, codeBase, (unsigned char*)firmware, size*2, VDI_128BIT_LITTLE_ENDIAN);
|
||
|
|
vdi_set_bit_firmware_to_pm(coreIdx, (Uint16*)firmware);
|
||
|
|
|
||
|
|
regVal = 0;
|
||
|
|
VpuWriteReg(coreIdx, W5_PO_CONF, regVal);
|
||
|
|
|
||
|
|
Wave5VpuReset(coreIdx, SW_RESET_ON_BOOT);
|
||
|
|
|
||
|
|
/* remap page size 0*/
|
||
|
|
remapSize = (W5_REMAP_MAX_SIZE>>12) & 0x1ff;
|
||
|
|
regVal = 0x80000000 | (WAVE5_UPPER_PROC_AXI_ID<<20) | (0<<16) | (W5_REMAP_INDEX0<<12) | (1<<11) | remapSize;
|
||
|
|
VpuWriteReg(coreIdx, W5_VPU_REMAP_CTRL, regVal);
|
||
|
|
VpuWriteReg(coreIdx, W5_VPU_REMAP_VADDR, W5_REMAP_INDEX0*W5_REMAP_MAX_SIZE);
|
||
|
|
VpuWriteReg(coreIdx, W5_VPU_REMAP_PADDR, codeBase + W5_REMAP_INDEX0*W5_REMAP_MAX_SIZE);
|
||
|
|
|
||
|
|
/* remap page size 1*/
|
||
|
|
remapSize = (W5_REMAP_MAX_SIZE>>12) & 0x1ff;
|
||
|
|
regVal = 0x80000000 | (WAVE5_UPPER_PROC_AXI_ID<<20) | (0<<16) | (W5_REMAP_INDEX1<<12) | (1<<11) | remapSize;
|
||
|
|
VpuWriteReg(coreIdx, W5_VPU_REMAP_CTRL, regVal);
|
||
|
|
VpuWriteReg(coreIdx, W5_VPU_REMAP_VADDR, W5_REMAP_INDEX1*W5_REMAP_MAX_SIZE);
|
||
|
|
VpuWriteReg(coreIdx, W5_VPU_REMAP_PADDR, codeBase + W5_REMAP_INDEX1*W5_REMAP_MAX_SIZE);
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_ADDR_CODE_BASE, codeBase);
|
||
|
|
VpuWriteReg(coreIdx, W5_CODE_SIZE, codeSize);
|
||
|
|
VpuWriteReg(coreIdx, W5_CODE_PARAM, (WAVE5_UPPER_PROC_AXI_ID<<4) | 0);
|
||
|
|
VpuWriteReg(coreIdx, W5_ADDR_TEMP_BASE, tempBase);
|
||
|
|
VpuWriteReg(coreIdx, W5_TEMP_SIZE, tempSize);
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_HW_OPTION, hwOption);
|
||
|
|
|
||
|
|
/* Interrupt */
|
||
|
|
// encoder
|
||
|
|
regVal = (1<<INT_WAVE5_ENC_SET_PARAM);
|
||
|
|
regVal |= (1<<INT_WAVE5_ENC_PIC);
|
||
|
|
regVal |= (1<<INT_WAVE5_BSBUF_FULL);
|
||
|
|
#ifdef SUPPORT_SOURCE_RELEASE_INTERRUPT
|
||
|
|
regVal |= (1<<INT_WAVE5_ENC_SRC_RELEASE);
|
||
|
|
#endif
|
||
|
|
// decoder
|
||
|
|
regVal |= (1<<INT_WAVE5_INIT_SEQ);
|
||
|
|
regVal |= (1<<INT_WAVE5_DEC_PIC);
|
||
|
|
regVal |= (1<<INT_WAVE5_BSBUF_EMPTY);
|
||
|
|
VpuWriteReg(coreIdx, W5_VPU_VINT_ENABLE, regVal);
|
||
|
|
|
||
|
|
regVal = VpuReadReg(coreIdx, W5_VPU_RET_VPU_CONFIG0);
|
||
|
|
if (((regVal>>16)&1) == 1) {
|
||
|
|
regVal = ((WAVE5_PROC_AXI_ID<<28) |
|
||
|
|
(WAVE5_PRP_AXI_ID<<24) |
|
||
|
|
(WAVE5_FBD_Y_AXI_ID<<20) |
|
||
|
|
(WAVE5_FBC_Y_AXI_ID<<16) |
|
||
|
|
(WAVE5_FBD_C_AXI_ID<<12) |
|
||
|
|
(WAVE5_FBC_C_AXI_ID<<8) |
|
||
|
|
(WAVE5_PRI_AXI_ID<<4) |
|
||
|
|
(WAVE5_SEC_AXI_ID<<0));
|
||
|
|
vdi_fio_write_register(coreIdx, W5_BACKBONE_PROG_AXI_ID, regVal);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (vdi_get_sram_memory(coreIdx, &vb) < 0) // get SRAM base/size
|
||
|
|
return RETCODE_INSUFFICIENT_RESOURCE;
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_ADDR_SEC_AXI, vb.phys_addr);
|
||
|
|
VpuWriteReg(coreIdx, W5_SEC_AXI_SIZE, vb.size);
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_VPU_BUSY_STATUS, 1);
|
||
|
|
VpuWriteReg(coreIdx, W5_COMMAND, W5_INIT_VPU);
|
||
|
|
VpuWriteReg(coreIdx, W5_VPU_REMAP_CORE_START, 1);
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
if (vdi_wait_vpu_busy(coreIdx, __VPU_BUSY_TIMEOUT, W5_VPU_BUSY_STATUS) == -1) {
|
||
|
|
VLOG(ERR, "VPU reinit(W5_VPU_REMAP_CORE_START) timeout\n");
|
||
|
|
return RETCODE_VPU_RESPONSE_TIMEOUT;
|
||
|
|
}
|
||
|
|
|
||
|
|
regVal = VpuReadReg(coreIdx, W5_RET_SUCCESS);
|
||
|
|
if (regVal == 0) {
|
||
|
|
Uint32 reasonCode = VpuReadReg(coreIdx, W5_RET_FAIL_REASON);
|
||
|
|
VLOG(ERR, "VPU reinit(W5_RET_SUCCESS) failed(%d) REASON CODE(%08x)\n", regVal, reasonCode);
|
||
|
|
return RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
SetupWave5Properties(coreIdx);
|
||
|
|
return RETCODE_SUCCESS;
|
||
|
|
}
|
||
|
|
|
||
|
|
RetCode Wave5VpuSleepWake(Uint32 coreIdx, int iSleepWake, const Uint16* code __attribute__((unused)), Uint32 size)
|
||
|
|
{
|
||
|
|
Uint32 regVal;
|
||
|
|
vpu_buffer_t vb;
|
||
|
|
PhysicalAddress codeBase;
|
||
|
|
Uint32 codeSize;
|
||
|
|
Uint32 remapSize;
|
||
|
|
if(iSleepWake==1) //saves
|
||
|
|
{
|
||
|
|
|
||
|
|
if (vdi_wait_vpu_busy(coreIdx, __VPU_BUSY_TIMEOUT, W5_VPU_BUSY_STATUS) == -1)
|
||
|
|
return RETCODE_VPU_RESPONSE_TIMEOUT;
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_VPU_BUSY_STATUS, 1);
|
||
|
|
VpuWriteReg(coreIdx, W5_COMMAND, W5_SLEEP_VPU);
|
||
|
|
VpuWriteReg(coreIdx, W5_VPU_HOST_INT_REQ, 1);
|
||
|
|
|
||
|
|
|
||
|
|
if (vdi_wait_vpu_busy(coreIdx, __VPU_BUSY_TIMEOUT, W5_VPU_BUSY_STATUS) == -1)
|
||
|
|
return RETCODE_VPU_RESPONSE_TIMEOUT;
|
||
|
|
|
||
|
|
if (VpuReadReg(coreIdx, W5_RET_SUCCESS) == FALSE) {
|
||
|
|
Uint32 reason = VpuReadReg(coreIdx, W5_RET_FAIL_REASON);
|
||
|
|
APIDPRINT("SLEEP_VPU failed [0x%x]", reason);
|
||
|
|
|
||
|
|
if (reason == WAVE5_SYSERR_VPU_STILL_RUNNING)
|
||
|
|
return RETCODE_VPU_STILL_RUNNING;
|
||
|
|
else if (reason == WAVE5_SYSERR_BUS_ERROR || reason == WAVE5_SYSERR_DOUBLE_FAULT)
|
||
|
|
return RETCODE_VPU_BUS_ERROR;
|
||
|
|
else
|
||
|
|
return RETCODE_QUERY_FAILURE;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else //restore
|
||
|
|
{
|
||
|
|
Uint32 hwOption = 0;
|
||
|
|
|
||
|
|
vdi_get_common_memory(coreIdx, &vb);
|
||
|
|
|
||
|
|
codeBase = vb.phys_addr;
|
||
|
|
/* ALIGN TO 4KB */
|
||
|
|
codeSize = (WAVE5_MAX_CODE_BUF_SIZE&~0xfff);
|
||
|
|
if (codeSize < size*2) {
|
||
|
|
return RETCODE_INSUFFICIENT_RESOURCE;
|
||
|
|
}
|
||
|
|
|
||
|
|
regVal = 0;
|
||
|
|
VpuWriteReg(coreIdx, W5_PO_CONF, regVal);
|
||
|
|
|
||
|
|
/* remap page size 0*/
|
||
|
|
remapSize = (W5_REMAP_MAX_SIZE>>12) & 0x1ff;
|
||
|
|
regVal = 0x80000000 | (WAVE5_UPPER_PROC_AXI_ID<<20) | (0<<16) | (W5_REMAP_INDEX0<<12) | (1<<11) | remapSize;
|
||
|
|
VpuWriteReg(coreIdx, W5_VPU_REMAP_CTRL, regVal);
|
||
|
|
VpuWriteReg(coreIdx, W5_VPU_REMAP_VADDR, W5_REMAP_INDEX0*W5_REMAP_MAX_SIZE);
|
||
|
|
VpuWriteReg(coreIdx, W5_VPU_REMAP_PADDR, codeBase + W5_REMAP_INDEX0*W5_REMAP_MAX_SIZE);
|
||
|
|
|
||
|
|
/* remap page size 1*/
|
||
|
|
remapSize = (W5_REMAP_MAX_SIZE>>12) & 0x1ff;
|
||
|
|
regVal = 0x80000000 | (WAVE5_UPPER_PROC_AXI_ID<<20) | (0<<16) | (W5_REMAP_INDEX1<<12) | (1<<11) | remapSize;
|
||
|
|
VpuWriteReg(coreIdx, W5_VPU_REMAP_CTRL, regVal);
|
||
|
|
VpuWriteReg(coreIdx, W5_VPU_REMAP_VADDR, W5_REMAP_INDEX1*W5_REMAP_MAX_SIZE);
|
||
|
|
VpuWriteReg(coreIdx, W5_VPU_REMAP_PADDR, codeBase + W5_REMAP_INDEX1*W5_REMAP_MAX_SIZE);
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_ADDR_CODE_BASE, codeBase);
|
||
|
|
VpuWriteReg(coreIdx, W5_CODE_SIZE, codeSize);
|
||
|
|
VpuWriteReg(coreIdx, W5_CODE_PARAM, (WAVE5_UPPER_PROC_AXI_ID<<4) | 0);
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_HW_OPTION, hwOption);
|
||
|
|
|
||
|
|
/* Interrupt */
|
||
|
|
// encoder
|
||
|
|
regVal = (1<<INT_WAVE5_ENC_SET_PARAM);
|
||
|
|
regVal |= (1<<INT_WAVE5_ENC_PIC);
|
||
|
|
regVal |= (1<<INT_WAVE5_BSBUF_FULL);
|
||
|
|
#ifdef SUPPORT_SOURCE_RELEASE_INTERRUPT
|
||
|
|
regVal |= (1<<INT_WAVE5_ENC_SRC_RELEASE);
|
||
|
|
#endif
|
||
|
|
// decoder
|
||
|
|
regVal |= (1<<INT_WAVE5_INIT_SEQ);
|
||
|
|
regVal |= (1<<INT_WAVE5_DEC_PIC);
|
||
|
|
regVal |= (1<<INT_WAVE5_BSBUF_EMPTY);
|
||
|
|
VpuWriteReg(coreIdx, W5_VPU_VINT_ENABLE, regVal);
|
||
|
|
|
||
|
|
regVal = VpuReadReg(coreIdx, W5_VPU_RET_VPU_CONFIG0);
|
||
|
|
if (((regVal>>16)&1) == 1) {
|
||
|
|
regVal = ((WAVE5_PROC_AXI_ID<<28) |
|
||
|
|
(WAVE5_PRP_AXI_ID<<24) |
|
||
|
|
(WAVE5_FBD_Y_AXI_ID<<20) |
|
||
|
|
(WAVE5_FBC_Y_AXI_ID<<16) |
|
||
|
|
(WAVE5_FBD_C_AXI_ID<<12) |
|
||
|
|
(WAVE5_FBC_C_AXI_ID<<8) |
|
||
|
|
(WAVE5_PRI_AXI_ID<<4) |
|
||
|
|
(WAVE5_SEC_AXI_ID<<0));
|
||
|
|
vdi_fio_write_register(coreIdx, W5_BACKBONE_PROG_AXI_ID, regVal);
|
||
|
|
}
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_VPU_BUSY_STATUS, 1);
|
||
|
|
VpuWriteReg(coreIdx, W5_COMMAND, W5_WAKEUP_VPU);
|
||
|
|
VpuWriteReg(coreIdx, W5_VPU_REMAP_CORE_START, 1);
|
||
|
|
|
||
|
|
if (vdi_wait_vpu_busy(coreIdx, __VPU_BUSY_TIMEOUT, W5_VPU_BUSY_STATUS) == -1) {
|
||
|
|
VLOG(ERR, "VPU wakeup(W5_VPU_REMAP_CORE_START) timeout\n");
|
||
|
|
return RETCODE_VPU_RESPONSE_TIMEOUT;
|
||
|
|
}
|
||
|
|
|
||
|
|
regVal = VpuReadReg(coreIdx, W5_RET_SUCCESS);
|
||
|
|
if (regVal == 0) {
|
||
|
|
Uint32 reasonCode = VpuReadReg(coreIdx, W5_RET_FAIL_REASON);
|
||
|
|
VLOG(ERR, "VPU wakeup(W5_RET_SUCCESS) failed(%d) REASON CODE(%08x)\n", regVal, reasonCode);
|
||
|
|
return RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return RETCODE_SUCCESS;
|
||
|
|
}
|
||
|
|
|
||
|
|
RetCode Wave5VpuReset(Uint32 coreIdx, SWResetMode resetMode)
|
||
|
|
{
|
||
|
|
Uint32 val = 0;
|
||
|
|
RetCode ret = RETCODE_SUCCESS;
|
||
|
|
VpuAttr* pAttr = &g_VpuCoreAttributes[coreIdx];
|
||
|
|
#if defined(SUPPORT_SW_UART) || defined(SUPPORT_SW_UART_V2)
|
||
|
|
Uint32 regSwUartStatus;
|
||
|
|
#endif
|
||
|
|
// VPU doesn't send response. Force to set BUSY flag to 0.
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_VPU_BUSY_STATUS, 0);
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
if (resetMode == SW_RESET_SAFETY) {
|
||
|
|
if ((ret=Wave5VpuSleepWake(coreIdx, TRUE, NULL, 0)) != RETCODE_SUCCESS) {
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
val = VpuReadReg(coreIdx, W5_VPU_RET_VPU_CONFIG0);
|
||
|
|
if (((val>>16) & 0x1) == 0x01) {
|
||
|
|
pAttr->supportBackbone = TRUE;
|
||
|
|
}
|
||
|
|
if (((val>>22) & 0x1) == 0x01) {
|
||
|
|
pAttr->supportVcoreBackbone = TRUE;
|
||
|
|
}
|
||
|
|
if (((val>>28) & 0x1) == 0x01) {
|
||
|
|
pAttr->supportVcpuBackbone = TRUE;
|
||
|
|
}
|
||
|
|
|
||
|
|
val = VpuReadReg(coreIdx, W5_VPU_RET_VPU_CONFIG1);
|
||
|
|
if (((val>>26) & 0x1) == 0x01) {
|
||
|
|
pAttr->supportDualCore = TRUE;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Waiting for completion of bus transaction
|
||
|
|
if (pAttr->supportBackbone == TRUE) {
|
||
|
|
if (pAttr->supportDualCore == TRUE) {
|
||
|
|
// check CORE0
|
||
|
|
vdi_fio_write_register(coreIdx, W5_BACKBONE_BUS_CTRL_VCORE0, 0x7);
|
||
|
|
|
||
|
|
|
||
|
|
if (vdi_wait_bus_busy(coreIdx, __VPU_BUSY_TIMEOUT, W5_BACKBONE_BUS_STATUS_VCORE0) == -1) {
|
||
|
|
vdi_fio_write_register(coreIdx, W5_BACKBONE_BUS_CTRL_VCORE0, 0x00);
|
||
|
|
return RETCODE_VPU_RESPONSE_TIMEOUT;
|
||
|
|
}
|
||
|
|
|
||
|
|
// check CORE1
|
||
|
|
vdi_fio_write_register(coreIdx, W5_BACKBONE_BUS_CTRL_VCORE1, 0x7);
|
||
|
|
|
||
|
|
|
||
|
|
if (vdi_wait_bus_busy(coreIdx, __VPU_BUSY_TIMEOUT, W5_BACKBONE_BUS_STATUS_VCORE1) == -1) {
|
||
|
|
vdi_fio_write_register(coreIdx, W5_BACKBONE_BUS_CTRL_VCORE1, 0x00);
|
||
|
|
return RETCODE_VPU_RESPONSE_TIMEOUT;
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
if (pAttr->supportVcoreBackbone == TRUE) {
|
||
|
|
if (pAttr->supportVcpuBackbone == TRUE) {
|
||
|
|
// Step1 : disable request
|
||
|
|
vdi_fio_write_register(coreIdx, W5_BACKBONE_BUS_CTRL_VCPU, 0xFF);
|
||
|
|
|
||
|
|
// Step2 : Waiting for completion of bus transaction
|
||
|
|
if (vdi_wait_vcpu_bus_busy(coreIdx, __VPU_BUSY_TIMEOUT, W5_BACKBONE_BUS_STATUS_VCPU) == -1) {
|
||
|
|
vdi_fio_write_register(coreIdx, W5_BACKBONE_BUS_CTRL_VCPU, 0x00);
|
||
|
|
return RETCODE_VPU_RESPONSE_TIMEOUT;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
// Step1 : disable request
|
||
|
|
vdi_fio_write_register(coreIdx, W5_BACKBONE_BUS_CTRL_VCORE0, 0x7);
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
// Step2 : Waiting for completion of bus transaction
|
||
|
|
if (vdi_wait_bus_busy(coreIdx, __VPU_BUSY_TIMEOUT, W5_BACKBONE_BUS_STATUS_VCORE0) == -1) {
|
||
|
|
vdi_fio_write_register(coreIdx, W5_BACKBONE_BUS_CTRL_VCORE0, 0x00);
|
||
|
|
return RETCODE_VPU_RESPONSE_TIMEOUT;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
// Step1 : disable request
|
||
|
|
vdi_fio_write_register(coreIdx, W5_COMBINED_BACKBONE_BUS_CTRL, 0x7);
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
// Step2 : Waiting for completion of bus transaction
|
||
|
|
if (vdi_wait_bus_busy(coreIdx, __VPU_BUSY_TIMEOUT, W5_COMBINED_BACKBONE_BUS_STATUS) == -1) {
|
||
|
|
vdi_fio_write_register(coreIdx, W5_COMBINED_BACKBONE_BUS_CTRL, 0x00);
|
||
|
|
return RETCODE_VPU_RESPONSE_TIMEOUT;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
// Step1 : disable request
|
||
|
|
vdi_fio_write_register(coreIdx, W5_GDI_BUS_CTRL, 0x100);
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
// Step2 : Waiting for completion of bus transaction
|
||
|
|
if (vdi_wait_bus_busy(coreIdx, __VPU_BUSY_TIMEOUT, W5_GDI_BUS_STATUS) == -1) {
|
||
|
|
vdi_fio_write_register(coreIdx, W5_GDI_BUS_CTRL, 0x00);
|
||
|
|
return RETCODE_VPU_RESPONSE_TIMEOUT;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
switch (resetMode) {
|
||
|
|
case SW_RESET_ON_BOOT:
|
||
|
|
case SW_RESET_FORCE:
|
||
|
|
case SW_RESET_SAFETY:
|
||
|
|
val = W5_RST_BLOCK_ALL;
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
return RETCODE_INVALID_PARAM;
|
||
|
|
}
|
||
|
|
|
||
|
|
#if defined(SUPPORT_SW_UART) || defined(SUPPORT_SW_UART_V2)
|
||
|
|
regSwUartStatus = VpuReadReg(coreIdx, W5_SW_UART_STATUS);
|
||
|
|
#endif
|
||
|
|
if (val) {
|
||
|
|
VpuWriteReg(coreIdx, W5_VPU_RESET_REQ, val);
|
||
|
|
|
||
|
|
|
||
|
|
if (vdi_wait_vpu_busy(coreIdx, __VPU_BUSY_TIMEOUT, W5_VPU_RESET_STATUS) == -1) {
|
||
|
|
VpuWriteReg(coreIdx, W5_VPU_RESET_REQ, 0);
|
||
|
|
return RETCODE_VPU_RESPONSE_TIMEOUT;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_VPU_RESET_REQ, 0);
|
||
|
|
#if defined(SUPPORT_SW_UART) || defined(SUPPORT_SW_UART_V2)
|
||
|
|
VpuWriteReg(coreIdx, W5_SW_UART_STATUS, regSwUartStatus); // enable SW UART.
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
// Step3 : must clear GDI_BUS_CTRL after done SW_RESET
|
||
|
|
if (pAttr->supportBackbone == TRUE) {
|
||
|
|
if (pAttr->supportDualCore == TRUE) {
|
||
|
|
vdi_fio_write_register(coreIdx, W5_BACKBONE_BUS_CTRL_VCORE0, 0x00);
|
||
|
|
vdi_fio_write_register(coreIdx, W5_BACKBONE_BUS_CTRL_VCORE1, 0x00);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
if (pAttr->supportVcoreBackbone == TRUE) {
|
||
|
|
if (pAttr->supportVcpuBackbone == TRUE) {
|
||
|
|
vdi_fio_write_register(coreIdx, W5_BACKBONE_BUS_CTRL_VCPU, 0x00);
|
||
|
|
}
|
||
|
|
vdi_fio_write_register(coreIdx, W5_BACKBONE_BUS_CTRL_VCORE0, 0x00);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
vdi_fio_write_register(coreIdx, W5_COMBINED_BACKBONE_BUS_CTRL, 0x00);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
vdi_fio_write_register(coreIdx, W5_GDI_BUS_CTRL, 0x00);
|
||
|
|
}
|
||
|
|
if (resetMode == SW_RESET_SAFETY || resetMode == SW_RESET_FORCE ) {
|
||
|
|
ret = Wave5VpuSleepWake(coreIdx, FALSE, NULL, 0);
|
||
|
|
}
|
||
|
|
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
RetCode Wave5VpuDecFiniSeq(CodecInst* instance)
|
||
|
|
{
|
||
|
|
RetCode ret = RETCODE_SUCCESS;
|
||
|
|
|
||
|
|
Wave5BitIssueCommand(instance, W5_DESTROY_INSTANCE);
|
||
|
|
|
||
|
|
|
||
|
|
if (vdi_wait_vpu_busy(instance->coreIdx, __VPU_BUSY_TIMEOUT, W5_VPU_BUSY_STATUS) == -1)
|
||
|
|
return RETCODE_VPU_RESPONSE_TIMEOUT;
|
||
|
|
|
||
|
|
if (VpuReadReg(instance->coreIdx, W5_RET_SUCCESS) == FALSE) {
|
||
|
|
Uint32 regVal;
|
||
|
|
regVal = VpuReadReg(instance->coreIdx, W5_RET_FAIL_REASON);
|
||
|
|
if (regVal != WAVE5_SYSERR_QUEUEING_FAIL && regVal != WAVE5_SYSERR_VPU_STILL_RUNNING)
|
||
|
|
VLOG(ERR, "FAIL_REASON = 0x%x\n", regVal);
|
||
|
|
|
||
|
|
if (regVal == WAVE5_SYSERR_VPU_STILL_RUNNING)
|
||
|
|
ret = RETCODE_VPU_STILL_RUNNING;
|
||
|
|
else if (regVal == WAVE5_SYSERR_ACCESS_VIOLATION_HW)
|
||
|
|
ret = RETCODE_MEMORY_ACCESS_VIOLATION;
|
||
|
|
else if (regVal == WAVE5_SYSERR_WATCHDOG_TIMEOUT)
|
||
|
|
ret = RETCODE_VPU_RESPONSE_TIMEOUT;
|
||
|
|
else if (regVal == WAVE5_SYSERR_VLC_BUF_FULL)
|
||
|
|
ret = RETCODE_VLC_BUF_FULL;
|
||
|
|
else if (regVal == WAVE5_SYSERR_BUS_ERROR || regVal == WAVE5_SYSERR_DOUBLE_FAULT)
|
||
|
|
ret = RETCODE_VPU_BUS_ERROR;
|
||
|
|
else
|
||
|
|
ret = RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
RetCode Wave5VpuDecSetBitstreamFlag(CodecInst* instance, BOOL running __attribute__((unused)), BOOL eos, BOOL explictEnd)
|
||
|
|
{
|
||
|
|
DecInfo* pDecInfo = &instance->CodecInfo->decInfo;
|
||
|
|
BitStreamMode bsMode = (BitStreamMode)pDecInfo->openParam.bitstreamMode;
|
||
|
|
pDecInfo->streamEndflag = (eos == 1) ? TRUE : FALSE;
|
||
|
|
|
||
|
|
if (bsMode == BS_MODE_INTERRUPT) {
|
||
|
|
if (pDecInfo->streamEndflag == TRUE) explictEnd = TRUE;
|
||
|
|
|
||
|
|
VpuWriteReg(instance->coreIdx, W5_BS_OPTION, (pDecInfo->streamEndflag<<1) | explictEnd);
|
||
|
|
VpuWriteReg(instance->coreIdx, W5_BS_WR_PTR, pDecInfo->streamWrPtr);
|
||
|
|
|
||
|
|
Wave5BitIssueCommand(instance, W5_UPDATE_BS);
|
||
|
|
|
||
|
|
|
||
|
|
if (vdi_wait_vpu_busy(instance->coreIdx, __VPU_BUSY_TIMEOUT, W5_VPU_BUSY_STATUS) == -1) {
|
||
|
|
return RETCODE_VPU_RESPONSE_TIMEOUT;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (VpuReadReg(instance->coreIdx, W5_RET_SUCCESS) == 0) {
|
||
|
|
return RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return RETCODE_SUCCESS;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
RetCode Wave5DecClrDispFlag(CodecInst* instance, Uint32 index)
|
||
|
|
{
|
||
|
|
RetCode ret = RETCODE_SUCCESS;
|
||
|
|
DecInfo * pDecInfo;
|
||
|
|
pDecInfo = &instance->CodecInfo->decInfo;
|
||
|
|
|
||
|
|
VpuWriteReg(instance->coreIdx, W5_CMD_DEC_CLR_DISP_IDC, (1<<index));
|
||
|
|
VpuWriteReg(instance->coreIdx, W5_CMD_DEC_SET_DISP_IDC, 0);
|
||
|
|
ret = SendQuery(instance, UPDATE_DISP_FLAG);
|
||
|
|
|
||
|
|
if (ret != RETCODE_SUCCESS) {
|
||
|
|
VLOG(ERR, "Wave5DecClrDispFlag QUERY FAILURE\n");
|
||
|
|
return RETCODE_QUERY_FAILURE;
|
||
|
|
}
|
||
|
|
|
||
|
|
pDecInfo->frameDisplayFlag = VpuReadReg(instance->coreIdx, pDecInfo->frameDisplayFlagRegAddr);
|
||
|
|
|
||
|
|
return RETCODE_SUCCESS;
|
||
|
|
}
|
||
|
|
|
||
|
|
RetCode Wave5DecSetDispFlag(CodecInst* instance, Uint32 index)
|
||
|
|
{
|
||
|
|
RetCode ret = RETCODE_SUCCESS;
|
||
|
|
|
||
|
|
VpuWriteReg(instance->coreIdx, W5_CMD_DEC_CLR_DISP_IDC, 0);
|
||
|
|
VpuWriteReg(instance->coreIdx, W5_CMD_DEC_SET_DISP_IDC, (1<<index));
|
||
|
|
ret = SendQuery(instance, UPDATE_DISP_FLAG);
|
||
|
|
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
Int32 Wave5VpuWaitInterrupt(CodecInst* instance, Int32 timeout, BOOL pending __attribute__((unused)))
|
||
|
|
{
|
||
|
|
Int32 reason = -1;
|
||
|
|
#ifdef SUPPORT_MULTI_INST_INTR
|
||
|
|
#else
|
||
|
|
Int32 remain_intr = -1; // to set VPU_VINT_REASON for remain interrupt.
|
||
|
|
Int32 ownInt = 0;
|
||
|
|
Uint32 regVal;
|
||
|
|
#ifdef SUPPORT_SOURCE_RELEASE_INTERRUPT
|
||
|
|
Uint32 IntrMask = ((1 << INT_WAVE5_BSBUF_EMPTY) | (1 << INT_WAVE5_DEC_PIC) | (1 << INT_WAVE5_INIT_SEQ) | (1 << INT_WAVE5_ENC_SET_PARAM) | (1 << INT_WAVE5_ENC_SRC_RELEASE));
|
||
|
|
#else
|
||
|
|
Uint32 IntrMask = ((1 << INT_WAVE5_BSBUF_EMPTY) | (1 << INT_WAVE5_DEC_PIC) | (1 << INT_WAVE5_INIT_SEQ) | (1 << INT_WAVE5_ENC_SET_PARAM));
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#endif /* SUPPORT_MULTI_INST_INTR */
|
||
|
|
#ifdef SUPPORT_MULTI_INST_INTR
|
||
|
|
// check an interrupt for my instance during timeout
|
||
|
|
reason = vdi_wait_interrupt(instance->coreIdx, instance->instIndex, timeout);
|
||
|
|
#else
|
||
|
|
|
||
|
|
EnterLock(instance->coreIdx);
|
||
|
|
|
||
|
|
// check one interrupt for current instance even if the number of interrupt triggered more than one.
|
||
|
|
if ((reason = vdi_wait_interrupt(instance->coreIdx, timeout)) > 0) {
|
||
|
|
|
||
|
|
remain_intr = reason;
|
||
|
|
|
||
|
|
if (reason & (1 << INT_WAVE5_BSBUF_EMPTY)) {
|
||
|
|
regVal = VpuReadReg(instance->coreIdx, W5_RET_BS_EMPTY_INST);
|
||
|
|
if (regVal & (1 << instance->instIndex)) {
|
||
|
|
ownInt = 1;
|
||
|
|
reason = (1 << INT_WAVE5_BSBUF_EMPTY);
|
||
|
|
remain_intr &= ~(Uint32)reason;
|
||
|
|
|
||
|
|
regVal = regVal & ~(1UL << instance->instIndex);
|
||
|
|
VpuWriteReg(instance->coreIdx, W5_RET_BS_EMPTY_INST, regVal);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (reason & (1 << INT_WAVE5_INIT_SEQ)) {
|
||
|
|
regVal = VpuReadReg(instance->coreIdx, W5_RET_SEQ_DONE_INSTANCE_INFO);
|
||
|
|
if (regVal & (1 << instance->instIndex)) {
|
||
|
|
ownInt = 1;
|
||
|
|
reason = (1 << INT_WAVE5_INIT_SEQ);
|
||
|
|
remain_intr &= ~(Uint32)reason;
|
||
|
|
|
||
|
|
regVal = regVal & ~(1UL << instance->instIndex);
|
||
|
|
VpuWriteReg(instance->coreIdx, W5_RET_SEQ_DONE_INSTANCE_INFO, regVal);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (reason & (1 << INT_WAVE5_DEC_PIC)) {
|
||
|
|
regVal = VpuReadReg(instance->coreIdx, W5_RET_QUEUE_CMD_DONE_INST);
|
||
|
|
if (regVal & (1 << instance->instIndex)) {
|
||
|
|
ownInt = 1;
|
||
|
|
reason = (1 << INT_WAVE5_DEC_PIC);
|
||
|
|
remain_intr &= ~(Uint32)reason;
|
||
|
|
regVal = regVal & ~(1UL << instance->instIndex);
|
||
|
|
VpuWriteReg(instance->coreIdx, W5_RET_QUEUE_CMD_DONE_INST, regVal);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (reason & (1 << INT_WAVE5_ENC_SET_PARAM)) {
|
||
|
|
regVal = VpuReadReg(instance->coreIdx, W5_RET_SEQ_DONE_INSTANCE_INFO);
|
||
|
|
if (regVal & (1 << instance->instIndex)) {
|
||
|
|
ownInt = 1;
|
||
|
|
reason = (1 << INT_WAVE5_ENC_SET_PARAM);
|
||
|
|
remain_intr &= ~(Uint32)reason;
|
||
|
|
|
||
|
|
regVal = regVal & ~(1UL << instance->instIndex);
|
||
|
|
VpuWriteReg(instance->coreIdx, W5_RET_SEQ_DONE_INSTANCE_INFO, regVal);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
#ifdef SUPPORT_SOURCE_RELEASE_INTERRUPT
|
||
|
|
if (reason & (1 << INT_WAVE5_ENC_SRC_RELEASE)) {
|
||
|
|
regVal = VpuReadReg(instance->coreIdx, W5_RET_RELEASED_SRC_INSTANCE);
|
||
|
|
if (regVal & (1 << instance->instIndex)) {
|
||
|
|
ownInt = 1;
|
||
|
|
reason = (1 << INT_WAVE5_ENC_SRC_RELEASE);
|
||
|
|
remain_intr &= ~(Uint32)reason;
|
||
|
|
|
||
|
|
regVal = regVal & ~(1UL << instance->instIndex);
|
||
|
|
VpuWriteReg(instance->coreIdx, W5_RET_RELEASED_SRC_INSTANCE, regVal);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
|
// when interrupt is not for empty, dec_pic, init_seq.
|
||
|
|
if (reason & ~IntrMask) {
|
||
|
|
regVal = VpuReadReg(instance->coreIdx, W5_RET_SEQ_DONE_INSTANCE_INFO)&0xFF;
|
||
|
|
if (regVal == instance->instIndex) {
|
||
|
|
ownInt = 1;
|
||
|
|
reason = (reason & ~IntrMask);
|
||
|
|
remain_intr &= ~(Uint32)reason;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// set remain interrupt flag to trigger interrupt next time.
|
||
|
|
VpuWriteReg(instance->coreIdx, W5_VPU_VINT_REASON, remain_intr);
|
||
|
|
|
||
|
|
// if there was no interrupt for current instance id, reason should be -1.
|
||
|
|
if (!ownInt)
|
||
|
|
reason = -1;
|
||
|
|
}
|
||
|
|
LeaveLock(instance->coreIdx);
|
||
|
|
#endif
|
||
|
|
return reason;
|
||
|
|
}
|
||
|
|
|
||
|
|
RetCode Wave5VpuClearInterrupt(Uint32 coreIdx, Uint32 flags)
|
||
|
|
{
|
||
|
|
Uint32 interruptReason;
|
||
|
|
|
||
|
|
interruptReason = VpuReadReg(coreIdx, W5_VPU_VINT_REASON_USR);
|
||
|
|
interruptReason &= ~flags;
|
||
|
|
VpuWriteReg(coreIdx, W5_VPU_VINT_REASON_USR, interruptReason);
|
||
|
|
|
||
|
|
return RETCODE_SUCCESS;
|
||
|
|
}
|
||
|
|
|
||
|
|
RetCode Wave5VpuDecGetRdPtr(CodecInst* instance, PhysicalAddress *rdPtr)
|
||
|
|
{
|
||
|
|
RetCode ret = RETCODE_SUCCESS;
|
||
|
|
|
||
|
|
ret = SendQuery(instance, GET_BS_RD_PTR);
|
||
|
|
|
||
|
|
if (ret != RETCODE_SUCCESS)
|
||
|
|
return RETCODE_QUERY_FAILURE;
|
||
|
|
|
||
|
|
*rdPtr = VpuReadReg(instance->coreIdx, W5_RET_QUERY_DEC_BS_RD_PTR);
|
||
|
|
|
||
|
|
return RETCODE_SUCCESS;
|
||
|
|
}
|
||
|
|
|
||
|
|
RetCode Wave5VpuDecSetRdPtr(CodecInst* instance, PhysicalAddress rdPtr)
|
||
|
|
{
|
||
|
|
RetCode ret = RETCODE_SUCCESS;
|
||
|
|
|
||
|
|
VpuWriteReg(instance->coreIdx, W5_RET_QUERY_DEC_SET_BS_RD_PTR, rdPtr);
|
||
|
|
|
||
|
|
ret = SendQuery(instance, SET_BS_RD_PTR);
|
||
|
|
|
||
|
|
if (ret != RETCODE_SUCCESS)
|
||
|
|
return RETCODE_QUERY_FAILURE;
|
||
|
|
|
||
|
|
return RETCODE_SUCCESS;
|
||
|
|
}
|
||
|
|
|
||
|
|
RetCode Wave5VpuGetBwReport(CodecInst* instance, VPUBWData* bwMon)
|
||
|
|
{
|
||
|
|
RetCode ret = RETCODE_SUCCESS;
|
||
|
|
Int32 coreIdx = instance->coreIdx;
|
||
|
|
Uint32 multiNum = (bwMon->bwMode == 0) ? 16 : 1;
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_BW_OPTION, (bwMon->bwMode << 4) | (bwMon->burstLengthIdx));
|
||
|
|
|
||
|
|
ret = SendQuery(instance, GET_BW_REPORT);
|
||
|
|
if (ret != RETCODE_SUCCESS) {
|
||
|
|
if (VpuReadReg(coreIdx, W5_RET_FAIL_REASON) == WAVE5_SYSERR_RESULT_NOT_READY)
|
||
|
|
return RETCODE_REPORT_NOT_READY;
|
||
|
|
else
|
||
|
|
return RETCODE_QUERY_FAILURE;
|
||
|
|
}
|
||
|
|
|
||
|
|
bwMon->prpBwRead = VpuReadReg(coreIdx, RET_QUERY_BW_PRP_AXI_READ) * multiNum;
|
||
|
|
bwMon->prpBwWrite = VpuReadReg(coreIdx, RET_QUERY_BW_PRP_AXI_WRITE) * multiNum;
|
||
|
|
bwMon->fbdYRead = VpuReadReg(coreIdx, RET_QUERY_BW_FBD_Y_AXI_READ) * multiNum;
|
||
|
|
bwMon->fbcYWrite = VpuReadReg(coreIdx, RET_QUERY_BW_FBC_Y_AXI_WRITE) * multiNum;
|
||
|
|
bwMon->fbdCRead = VpuReadReg(coreIdx, RET_QUERY_BW_FBD_C_AXI_READ) * multiNum;
|
||
|
|
bwMon->fbcCWrite = VpuReadReg(coreIdx, RET_QUERY_BW_FBC_C_AXI_WRITE) * multiNum;
|
||
|
|
bwMon->priBwRead = VpuReadReg(coreIdx, RET_QUERY_BW_PRI_AXI_READ) * multiNum;
|
||
|
|
bwMon->priBwWrite = VpuReadReg(coreIdx, RET_QUERY_BW_PRI_AXI_WRITE) * multiNum;
|
||
|
|
bwMon->secBwRead = VpuReadReg(coreIdx, RET_QUERY_BW_SEC_AXI_READ) * multiNum;
|
||
|
|
bwMon->secBwWrite = VpuReadReg(coreIdx, RET_QUERY_BW_SEC_AXI_WRITE) * multiNum;
|
||
|
|
bwMon->procBwRead = VpuReadReg(coreIdx, RET_QUERY_BW_PROC_AXI_READ) * multiNum;
|
||
|
|
bwMon->procBwWrite = VpuReadReg(coreIdx, RET_QUERY_BW_PROC_AXI_WRITE) * multiNum;
|
||
|
|
bwMon->bwbBwWrite = VpuReadReg(coreIdx, RET_QUERY_BW_BWB_AXI_WRITE) * multiNum;
|
||
|
|
|
||
|
|
return RETCODE_SUCCESS;
|
||
|
|
}
|
||
|
|
|
||
|
|
RetCode Wave5VpuGetDebugInfo(CodecInst* instance, VPUDebugInfo* info)
|
||
|
|
{
|
||
|
|
RetCode ret = RETCODE_SUCCESS;
|
||
|
|
Int32 coreIdx;
|
||
|
|
int i;
|
||
|
|
int idx;
|
||
|
|
|
||
|
|
coreIdx = instance->coreIdx;
|
||
|
|
|
||
|
|
ret = SendQuery(instance, GET_DEBUG_INFO);
|
||
|
|
if (ret != RETCODE_SUCCESS) {
|
||
|
|
return RETCODE_QUERY_FAILURE;
|
||
|
|
}
|
||
|
|
|
||
|
|
idx = 0;
|
||
|
|
for (i=0; i < 0x40*4; i=i+4)
|
||
|
|
{
|
||
|
|
info->regs[idx] = VpuReadReg(coreIdx, 0x100 + i);
|
||
|
|
idx++;
|
||
|
|
}
|
||
|
|
|
||
|
|
return RETCODE_SUCCESS;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/* ENCODER functions */
|
||
|
|
/************************************************************************/
|
||
|
|
RetCode Wave5VpuEncUpdateBS(CodecInst* instance)
|
||
|
|
{
|
||
|
|
EncInfo* pEncInfo;
|
||
|
|
Int32 coreIdx;
|
||
|
|
Uint32 regVal = 0, bsEndian;
|
||
|
|
EncOpenParam* pOpenParam;
|
||
|
|
|
||
|
|
pEncInfo = VPU_HANDLE_TO_ENCINFO(instance);
|
||
|
|
pOpenParam = &pEncInfo->openParam;
|
||
|
|
coreIdx = instance->coreIdx;
|
||
|
|
|
||
|
|
regVal = vdi_convert_endian(coreIdx, pOpenParam->streamEndian);
|
||
|
|
bsEndian = (~regVal&VDI_128BIT_ENDIAN_MASK);
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_BS_START_ADDR, pEncInfo->streamRdPtr);
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_BS_SIZE, pEncInfo->streamBufSize);
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_BS_OPTION, (pEncInfo->lineBufIntEn<<6) | bsEndian);
|
||
|
|
|
||
|
|
Wave5BitIssueCommand(instance, W5_UPDATE_BS);
|
||
|
|
|
||
|
|
|
||
|
|
if (vdi_wait_vpu_busy(instance->coreIdx, __VPU_BUSY_TIMEOUT, W5_VPU_BUSY_STATUS) == -1) {
|
||
|
|
return RETCODE_VPU_RESPONSE_TIMEOUT;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (VpuReadReg(instance->coreIdx, W5_RET_SUCCESS) == 0) {
|
||
|
|
return RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
|
||
|
|
return RETCODE_SUCCESS;
|
||
|
|
}
|
||
|
|
|
||
|
|
RetCode Wave5VpuEncGetRdWrPtr(CodecInst* instance, PhysicalAddress *rdPtr, PhysicalAddress *wrPtr)
|
||
|
|
{
|
||
|
|
EncInfo* pEncInfo = VPU_HANDLE_TO_ENCINFO(instance);
|
||
|
|
RetCode ret = RETCODE_SUCCESS;
|
||
|
|
|
||
|
|
VpuWriteReg(instance->coreIdx, W5_CMD_ENC_REASON_SEL, pEncInfo->encWrPtrSel);
|
||
|
|
|
||
|
|
ret = SendQuery(instance, GET_BS_WR_PTR);
|
||
|
|
|
||
|
|
if (ret != RETCODE_SUCCESS)
|
||
|
|
return RETCODE_QUERY_FAILURE;
|
||
|
|
|
||
|
|
*rdPtr = VpuReadReg(instance->coreIdx, W5_RET_ENC_RD_PTR);
|
||
|
|
*wrPtr = VpuReadReg(instance->coreIdx, W5_RET_ENC_WR_PTR);
|
||
|
|
|
||
|
|
return RETCODE_SUCCESS;
|
||
|
|
}
|
||
|
|
|
||
|
|
RetCode Wave5VpuBuildUpEncParam(CodecInst* instance, EncOpenParam* param)
|
||
|
|
{
|
||
|
|
RetCode ret = RETCODE_SUCCESS;
|
||
|
|
EncInfo* pEncInfo = VPU_HANDLE_TO_ENCINFO(instance);
|
||
|
|
Uint32 regVal = 0;
|
||
|
|
vpu_buffer_t vb;
|
||
|
|
Uint32 bsEndian;
|
||
|
|
|
||
|
|
pEncInfo->streamRdPtrRegAddr = W5_RET_ENC_RD_PTR;
|
||
|
|
pEncInfo->streamWrPtrRegAddr = W5_RET_ENC_WR_PTR;
|
||
|
|
pEncInfo->currentPC = W5_VCPU_CUR_PC;
|
||
|
|
pEncInfo->busyFlagAddr = W5_VPU_BUSY_STATUS;
|
||
|
|
|
||
|
|
if (param->bitstreamFormat == STD_HEVC)
|
||
|
|
instance->codecMode = W_HEVC_ENC;
|
||
|
|
else if (param->bitstreamFormat == STD_SVAC)
|
||
|
|
instance->codecMode = W_SVAC_ENC;
|
||
|
|
else if (param->bitstreamFormat == STD_AVC)
|
||
|
|
instance->codecMode = W_AVC_ENC;
|
||
|
|
|
||
|
|
|
||
|
|
vdi_get_common_memory(instance->coreIdx, &vb);
|
||
|
|
pEncInfo->vbTemp.base = vb.phys_addr + WAVE5_TEMPBUF_OFFSET;
|
||
|
|
pEncInfo->vbTemp.phys_addr = (PhysicalAddress)pEncInfo->vbTemp.base;
|
||
|
|
pEncInfo->vbTemp.virt_addr = pEncInfo->vbTemp.base;
|
||
|
|
pEncInfo->vbTemp.size = WAVE5_TEMPBUF_SIZE;
|
||
|
|
|
||
|
|
vdi_get_sram_memory(instance->coreIdx, &vb);
|
||
|
|
pEncInfo->secAxiInfo.bufBase = vb.phys_addr;
|
||
|
|
pEncInfo->secAxiInfo.bufSize = vb.size;
|
||
|
|
|
||
|
|
if (instance->productId == PRODUCT_ID_521)
|
||
|
|
pEncInfo->vbWork.size = WAVE521ENC_WORKBUF_SIZE;
|
||
|
|
|
||
|
|
if (vdi_allocate_dma_memory(instance->coreIdx, &pEncInfo->vbWork, ENC_WORK, instance->instIndex) < 0) {
|
||
|
|
pEncInfo->vbWork.base = 0;
|
||
|
|
pEncInfo->vbWork.phys_addr = 0;
|
||
|
|
pEncInfo->vbWork.size = 0;
|
||
|
|
pEncInfo->vbWork.virt_addr = 0;
|
||
|
|
return RETCODE_INSUFFICIENT_RESOURCE;
|
||
|
|
}
|
||
|
|
|
||
|
|
vdi_clear_memory(instance->coreIdx, pEncInfo->vbWork.phys_addr, pEncInfo->vbWork.size, 0);
|
||
|
|
|
||
|
|
VpuWriteReg(instance->coreIdx, W5_ADDR_WORK_BASE, pEncInfo->vbWork.phys_addr);
|
||
|
|
VpuWriteReg(instance->coreIdx, W5_WORK_SIZE, pEncInfo->vbWork.size);
|
||
|
|
|
||
|
|
regVal = vdi_convert_endian(instance->coreIdx, param->streamEndian);
|
||
|
|
bsEndian = (~regVal&VDI_128BIT_ENDIAN_MASK);
|
||
|
|
|
||
|
|
regVal = (param->lineBufIntEn<<6) | bsEndian;
|
||
|
|
VpuWriteReg(instance->coreIdx, W5_CMD_BS_PARAM, regVal);
|
||
|
|
VpuWriteReg(instance->coreIdx, W5_CMD_NUM_CQ_DEPTH_M1, (COMMAND_QUEUE_DEPTH-1));
|
||
|
|
|
||
|
|
regVal = 0;
|
||
|
|
#ifdef SUPPORT_SOURCE_RELEASE_INTERRUPT
|
||
|
|
regVal |= (param->srcReleaseIntEnable<<2);
|
||
|
|
#endif
|
||
|
|
if (instance->productId == PRODUCT_ID_521)
|
||
|
|
regVal |= (param->subFrameSyncEnable | param->subFrameSyncMode<<1);
|
||
|
|
VpuWriteReg(instance->coreIdx, W5_CMD_ENC_SRC_OPTIONS, regVal);
|
||
|
|
|
||
|
|
VpuWriteReg(instance->coreIdx, W5_CMD_ENC_VCORE_INFO, 1);
|
||
|
|
|
||
|
|
Wave5BitIssueCommand(instance, W5_CREATE_INSTANCE);
|
||
|
|
|
||
|
|
|
||
|
|
if (vdi_wait_vpu_busy(instance->coreIdx, __VPU_BUSY_TIMEOUT, W5_VPU_BUSY_STATUS) == -1) { // Check QUEUE_DONE
|
||
|
|
if (instance->loggingEnable)
|
||
|
|
vdi_log(instance->coreIdx, instance->instIndex, W5_CREATE_INSTANCE, 2);
|
||
|
|
vdi_free_dma_memory(instance->coreIdx, &pEncInfo->vbWork, ENC_WORK, instance->instIndex);
|
||
|
|
return RETCODE_VPU_RESPONSE_TIMEOUT;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (VpuReadReg(instance->coreIdx, W5_RET_SUCCESS) == FALSE) { // FAILED for adding into VCPU QUEUE
|
||
|
|
vdi_free_dma_memory(instance->coreIdx, &pEncInfo->vbWork, ENC_WORK, instance->instIndex);
|
||
|
|
regVal = VpuReadReg(instance->coreIdx, W5_RET_FAIL_REASON);
|
||
|
|
if (regVal != WAVE5_SYSERR_QUEUEING_FAIL)
|
||
|
|
VLOG(ERR, "FAIL_REASON = 0x%x\n", regVal);
|
||
|
|
if (regVal == 2)
|
||
|
|
ret = RETCODE_INVALID_SFS_INSTANCE;
|
||
|
|
else if (regVal == WAVE5_SYSERR_WATCHDOG_TIMEOUT)
|
||
|
|
ret = RETCODE_VPU_RESPONSE_TIMEOUT;
|
||
|
|
else if (regVal == WAVE5_SYSERR_BUS_ERROR || regVal == WAVE5_SYSERR_DOUBLE_FAULT)
|
||
|
|
ret = RETCODE_VPU_BUS_ERROR;
|
||
|
|
else
|
||
|
|
ret = RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
|
||
|
|
pEncInfo->subFrameSyncConfig.subFrameSyncMode = param->subFrameSyncMode;
|
||
|
|
pEncInfo->subFrameSyncConfig.subFrameSyncOn = param->subFrameSyncEnable;
|
||
|
|
pEncInfo->prefixSeiDataSize = 0;
|
||
|
|
pEncInfo->prefixSeiNalEnable = 0;
|
||
|
|
pEncInfo->prefixSeiNalAddr = 0;
|
||
|
|
pEncInfo->suffixSeiDataSize = 0;
|
||
|
|
pEncInfo->suffixSeiNalEnable = 0;
|
||
|
|
pEncInfo->suffixSeiNalAddr = 0;
|
||
|
|
pEncInfo->streamRdPtr = param->bitstreamBuffer;
|
||
|
|
pEncInfo->streamWrPtr = param->bitstreamBuffer;
|
||
|
|
pEncInfo->lineBufIntEn = param->lineBufIntEn;
|
||
|
|
pEncInfo->streamBufStartAddr = param->bitstreamBuffer;
|
||
|
|
pEncInfo->streamBufSize = param->bitstreamBufferSize;
|
||
|
|
pEncInfo->streamBufEndAddr = param->bitstreamBuffer + param->bitstreamBufferSize;
|
||
|
|
pEncInfo->stride = 0;
|
||
|
|
pEncInfo->vbFrame.size = 0;
|
||
|
|
pEncInfo->vbPPU.size = 0;
|
||
|
|
pEncInfo->frameAllocExt = 0;
|
||
|
|
pEncInfo->ppuAllocExt = 0;
|
||
|
|
pEncInfo->initialInfoObtained = 0;
|
||
|
|
pEncInfo->productCode = VpuReadReg(instance->coreIdx, W5_PRODUCT_NUMBER);
|
||
|
|
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
RetCode Wave5VpuEncInitSeq(CodecInst* instance)
|
||
|
|
{
|
||
|
|
Int32 coreIdx;
|
||
|
|
Uint32 regVal = 0, rotMirMode;
|
||
|
|
EncInfo* pEncInfo;
|
||
|
|
EncOpenParam* pOpenParam;
|
||
|
|
EncWaveParam* pParam;
|
||
|
|
coreIdx = instance->coreIdx;
|
||
|
|
pEncInfo = &instance->CodecInfo->encInfo;
|
||
|
|
pOpenParam = &pEncInfo->openParam;
|
||
|
|
pParam = &pOpenParam->EncStdParam.waveParam;
|
||
|
|
|
||
|
|
/*==============================================*/
|
||
|
|
/* OPT_CUSTOM_GOP */
|
||
|
|
/*==============================================*/
|
||
|
|
/*
|
||
|
|
* SET_PARAM + CUSTOM_GOP
|
||
|
|
* only when gopPresetIdx == custom_gop, custom_gop related registers should be set
|
||
|
|
*/
|
||
|
|
if (pParam->gopPresetIdx == PRESET_IDX_CUSTOM_GOP) {
|
||
|
|
int i=0, j = 0;
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_CUSTOM_GOP_PARAM, pParam->gopParam.customGopSize);
|
||
|
|
for (i=0 ; i<pParam->gopParam.customGopSize; i++) {
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_CUSTOM_GOP_PIC_PARAM_0 + (i*4), (pParam->gopParam.picParam[i].picType<<0) |
|
||
|
|
(pParam->gopParam.picParam[i].pocOffset<<2) |
|
||
|
|
(pParam->gopParam.picParam[i].picQp<<6) |
|
||
|
|
(pParam->gopParam.picParam[i].useMultiRefP<<13) |
|
||
|
|
((pParam->gopParam.picParam[i].refPocL0&0x1F)<<14) |
|
||
|
|
((pParam->gopParam.picParam[i].refPocL1&0x1F)<<19) |
|
||
|
|
(pParam->gopParam.picParam[i].temporalId<<24));
|
||
|
|
}
|
||
|
|
|
||
|
|
for (j = i; j < MAX_GOP_NUM; j++) {
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_CUSTOM_GOP_PIC_PARAM_0 + (j*4), 0);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (pParam->gopPresetIdx == PRESET_IDX_CUSTOM_GOP) {
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_SET_PARAM_OPTION, OPT_CUSTOM_GOP);
|
||
|
|
Wave5BitIssueCommand(instance, W5_ENC_SET_PARAM);
|
||
|
|
|
||
|
|
if (vdi_wait_vpu_busy(coreIdx, __VPU_BUSY_TIMEOUT, W5_VPU_BUSY_STATUS) == -1) {
|
||
|
|
if (instance->loggingEnable)
|
||
|
|
vdi_log(coreIdx, instance->instIndex, W5_ENC_SET_PARAM, 2);
|
||
|
|
return RETCODE_VPU_RESPONSE_TIMEOUT;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/*======================================================================*/
|
||
|
|
/* OPT_COMMON */
|
||
|
|
/* : the last SET_PARAM command should be called with OPT_COMMON */
|
||
|
|
/*======================================================================*/
|
||
|
|
rotMirMode = 0;
|
||
|
|
/* CMD_ENC_ROT_MODE :
|
||
|
|
* | hor_mir | ver_mir | rot_angle | rot_en |
|
||
|
|
* [4] [3] [2:1] [0]
|
||
|
|
*/
|
||
|
|
if (pEncInfo->rotationEnable == TRUE) {
|
||
|
|
switch (pEncInfo->rotationAngle) {
|
||
|
|
case 0: rotMirMode |= 0x0; break;
|
||
|
|
case 90: rotMirMode |= 0x3; break;
|
||
|
|
case 180: rotMirMode |= 0x5; break;
|
||
|
|
case 270: rotMirMode |= 0x7; break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (pEncInfo->mirrorEnable == TRUE) {
|
||
|
|
switch (pEncInfo->mirrorDirection) {
|
||
|
|
case MIRDIR_NONE: rotMirMode |= 0x0; break;
|
||
|
|
case MIRDIR_VER: rotMirMode |= 0x9; break;
|
||
|
|
case MIRDIR_HOR: rotMirMode |= 0x11; break;
|
||
|
|
case MIRDIR_HOR_VER: rotMirMode |= 0x19; break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
SetEncCropInfo(instance->codecMode, pParam, rotMirMode, pOpenParam->picWidth, pOpenParam->picHeight);
|
||
|
|
|
||
|
|
/* SET_PARAM + COMMON */
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_SET_PARAM_OPTION, OPT_COMMON);
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_SRC_SIZE, pOpenParam->picHeight<<16 | pOpenParam->picWidth);
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_CUSTOM_MAP_ENDIAN, VDI_LITTLE_ENDIAN);
|
||
|
|
|
||
|
|
|
||
|
|
if (instance->codecMode == W_SVAC_ENC) {
|
||
|
|
regVal = (pParam->profile<<0) |
|
||
|
|
(pParam->level<<3) |
|
||
|
|
(pParam->internalBitDepth<<14) |
|
||
|
|
(pParam->useLongTerm<<21) |
|
||
|
|
(pParam->saoEnable<<24) |
|
||
|
|
(pParam->svcEnable<<28) |
|
||
|
|
(pParam->svcMode<<29);
|
||
|
|
}
|
||
|
|
else if (instance->codecMode == W_AVC_ENC) {
|
||
|
|
regVal = (pParam->profile<<0) |
|
||
|
|
(pParam->level<<3) |
|
||
|
|
(pParam->internalBitDepth<<14) |
|
||
|
|
(pParam->useLongTerm<<21);
|
||
|
|
if (pParam->scalingListEnable == 2) {
|
||
|
|
regVal |= (1<<22) | (1<<23); // [23]=USE_DEFAULT_SCALING_LIST
|
||
|
|
} else { // 0 or 1
|
||
|
|
regVal |= (pParam->scalingListEnable<<22);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else { // HEVC enc
|
||
|
|
regVal = (pParam->profile<<0) |
|
||
|
|
(pParam->level<<3) |
|
||
|
|
(pParam->tier<<12) |
|
||
|
|
(pParam->internalBitDepth<<14) |
|
||
|
|
(pParam->useLongTerm<<21) |
|
||
|
|
(pParam->tmvpEnable<<23) |
|
||
|
|
(pParam->saoEnable<<24) |
|
||
|
|
(pParam->skipIntraTrans<<25) |
|
||
|
|
(pParam->strongIntraSmoothEnable<<27) |
|
||
|
|
(pParam->enStillPicture<<30);
|
||
|
|
if (pParam->scalingListEnable == 2) {
|
||
|
|
regVal |= (1<<22) | (1UL<<31); // [31]=USE_DEFAULT_SCALING_LIST
|
||
|
|
} else {
|
||
|
|
regVal |= (pParam->scalingListEnable<<22);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_SPS_PARAM, regVal);
|
||
|
|
|
||
|
|
if (instance->codecMode == W_SVAC_ENC) {
|
||
|
|
regVal = (pParam->disableDeblk<<5) |
|
||
|
|
((pParam->chromaDcQpOffset&0x1F)<<14) |
|
||
|
|
((pParam->chromaAcQpOffset&0x1F)<<19) |
|
||
|
|
((pParam->lumaDcQpOffset&0x1F)<<24);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
regVal = (pParam->losslessEnable) |
|
||
|
|
(pParam->constIntraPredFlag<<1) |
|
||
|
|
(pParam->lfCrossSliceBoundaryEnable<<2) |
|
||
|
|
((pParam->weightPredEnable&1)<<3) |
|
||
|
|
(pParam->wppEnable<<4) |
|
||
|
|
(pParam->disableDeblk<<5) |
|
||
|
|
((pParam->betaOffsetDiv2&0xF)<<6) |
|
||
|
|
((pParam->tcOffsetDiv2&0xF)<<10) |
|
||
|
|
((pParam->chromaCbQpOffset&0x1F)<<14) |
|
||
|
|
((pParam->chromaCrQpOffset&0x1F)<<19) |
|
||
|
|
(pParam->transform8x8Enable<<29) |
|
||
|
|
(pParam->entropyCodingMode<<30);
|
||
|
|
}
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_PPS_PARAM, regVal);
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_GOP_PARAM, pParam->gopPresetIdx);
|
||
|
|
|
||
|
|
if (instance->codecMode == W_AVC_ENC) {
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_INTRA_PARAM, (pParam->intraQP<<0) | ((pParam->intraPeriod&0x7ff)<<6) | ((pParam->avcIdrPeriod&0x7ff)<<17) | ((pParam->forcedIdrHeaderEnable&3)<<28));
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_INTRA_PARAM, (pParam->decodingRefreshType<<0) | (pParam->intraQP<<3) | (pParam->forcedIdrHeaderEnable<<9) | (pParam->intraPeriod<<16));
|
||
|
|
}
|
||
|
|
|
||
|
|
regVal = (pParam->useRecommendEncParam) |
|
||
|
|
(pParam->rdoSkip<<2) |
|
||
|
|
(pParam->lambdaScalingEnable<<3) |
|
||
|
|
(pParam->coefClearDisable<<4) |
|
||
|
|
(pParam->cuSizeMode<<5) |
|
||
|
|
(pParam->intraNxNEnable<<8) |
|
||
|
|
(pParam->maxNumMerge<<18) |
|
||
|
|
(pParam->customMDEnable<<20) |
|
||
|
|
(pParam->customLambdaEnable<<21) |
|
||
|
|
(pParam->monochromeEnable<<22);
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_RDO_PARAM, regVal);
|
||
|
|
|
||
|
|
if (instance->codecMode == W_AVC_ENC) {
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_INTRA_REFRESH, pParam->intraMbRefreshArg<<16 | pParam->intraMbRefreshMode);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_INTRA_REFRESH, pParam->intraRefreshArg<<16 | pParam->intraRefreshMode);
|
||
|
|
}
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_RC_FRAME_RATE, pOpenParam->frameRateInfo);
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_RC_TARGET_RATE, pOpenParam->bitRate);
|
||
|
|
|
||
|
|
if (instance->codecMode == W_AVC_ENC) {
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_RC_PARAM, (pOpenParam->rcEnable<<0) |
|
||
|
|
(pParam->mbLevelRcEnable<<1) |
|
||
|
|
(pParam->hvsQPEnable<<2) |
|
||
|
|
(pParam->hvsQpScale<<4) |
|
||
|
|
(pParam->bitAllocMode<<8) |
|
||
|
|
(pParam->roiEnable<<13) |
|
||
|
|
((pParam->initialRcQp&0x3F)<<14) |
|
||
|
|
(pOpenParam->vbvBufferSize<<20));
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_RC_PARAM, (pOpenParam->rcEnable<<0) |
|
||
|
|
(pParam->cuLevelRCEnable<<1) |
|
||
|
|
(pParam->hvsQPEnable<<2) |
|
||
|
|
(pParam->hvsQpScale<<4) |
|
||
|
|
(pParam->bitAllocMode<<8) |
|
||
|
|
(pParam->roiEnable<<13) |
|
||
|
|
((pParam->initialRcQp&0x3F)<<14) |
|
||
|
|
(pOpenParam->vbvBufferSize<<20));
|
||
|
|
}
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_RC_WEIGHT_PARAM, pParam->rcWeightBuf<<8 | pParam->rcWeightParam);
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_RC_MIN_MAX_QP, (pParam->minQpI<<0) |
|
||
|
|
(pParam->maxQpI<<6) |
|
||
|
|
(pParam->hvsMaxDeltaQp<<12));
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_RC_INTER_MIN_MAX_QP, (pParam->minQpP << 0) |
|
||
|
|
(pParam->maxQpP << 6) |
|
||
|
|
(pParam->minQpB << 12) |
|
||
|
|
(pParam->maxQpB << 18));
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_RC_BIT_RATIO_LAYER_0_3, (pParam->fixedBitRatio[0]<<0) |
|
||
|
|
(pParam->fixedBitRatio[1]<<8) |
|
||
|
|
(pParam->fixedBitRatio[2]<<16) |
|
||
|
|
(pParam->fixedBitRatio[3]<<24));
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_RC_BIT_RATIO_LAYER_4_7, (pParam->fixedBitRatio[4]<<0) |
|
||
|
|
(pParam->fixedBitRatio[5]<<8) |
|
||
|
|
(pParam->fixedBitRatio[6]<<16) |
|
||
|
|
(pParam->fixedBitRatio[7]<<24));
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_ROT_PARAM, rotMirMode);
|
||
|
|
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_BG_PARAM, (pParam->bgDetectEnable) |
|
||
|
|
(pParam->bgThrDiff<<1) |
|
||
|
|
(pParam->bgThrMeanDiff<<10) |
|
||
|
|
(pParam->bgLambdaQp<<18) |
|
||
|
|
((pParam->bgDeltaQp&0x1F)<<24) |
|
||
|
|
(instance->codecMode == W_AVC_ENC ? pParam->s2fmeDisable<<29 : 0));
|
||
|
|
|
||
|
|
|
||
|
|
if (instance->codecMode == W_HEVC_ENC || instance->codecMode == W_AVC_ENC) {
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_CUSTOM_LAMBDA_ADDR, pParam->customLambdaAddr);
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_CONF_WIN_TOP_BOT, pParam->confWinBot<<16 | pParam->confWinTop);
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_CONF_WIN_LEFT_RIGHT, pParam->confWinRight<<16 | pParam->confWinLeft);
|
||
|
|
|
||
|
|
if (instance->codecMode == W_AVC_ENC) {
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_INDEPENDENT_SLICE, pParam->avcSliceArg<<16 | pParam->avcSliceMode);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_INDEPENDENT_SLICE, pParam->independSliceModeArg<<16 | pParam->independSliceMode);
|
||
|
|
}
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_USER_SCALING_LIST_ADDR, pParam->userScalingListAddr);
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_NUM_UNITS_IN_TICK, pParam->numUnitsInTick);
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_TIME_SCALE, pParam->timeScale);
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_NUM_TICKS_POC_DIFF_ONE, pParam->numTicksPocDiffOne);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (instance->codecMode == W_HEVC_ENC) {
|
||
|
|
// SVAC encoder can't configure below parameters
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_CUSTOM_MD_PU04, (pParam->pu04DeltaRate&0xFF) |
|
||
|
|
((pParam->pu04IntraPlanarDeltaRate&0xFF)<<8) |
|
||
|
|
((pParam->pu04IntraDcDeltaRate&0xFF)<<16) |
|
||
|
|
((pParam->pu04IntraAngleDeltaRate&0xFF)<<24));
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_CUSTOM_MD_PU08, (pParam->pu08DeltaRate&0xFF) |
|
||
|
|
((pParam->pu08IntraPlanarDeltaRate&0xFF)<<8) |
|
||
|
|
((pParam->pu08IntraDcDeltaRate&0xFF)<<16) |
|
||
|
|
((pParam->pu08IntraAngleDeltaRate&0xFF)<<24));
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_CUSTOM_MD_PU16, (pParam->pu16DeltaRate&0xFF) |
|
||
|
|
((pParam->pu16IntraPlanarDeltaRate&0xFF)<<8) |
|
||
|
|
((pParam->pu16IntraDcDeltaRate&0xFF)<<16) |
|
||
|
|
((pParam->pu16IntraAngleDeltaRate&0xFF)<<24));
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_CUSTOM_MD_PU32, (pParam->pu32DeltaRate&0xFF) |
|
||
|
|
((pParam->pu32IntraPlanarDeltaRate&0xFF)<<8) |
|
||
|
|
((pParam->pu32IntraDcDeltaRate&0xFF)<<16) |
|
||
|
|
((pParam->pu32IntraAngleDeltaRate&0xFF)<<24));
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_CUSTOM_MD_CU08, (pParam->cu08IntraDeltaRate&0xFF) |
|
||
|
|
((pParam->cu08InterDeltaRate&0xFF)<<8) |
|
||
|
|
((pParam->cu08MergeDeltaRate&0xFF)<<16));
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_CUSTOM_MD_CU16, (pParam->cu16IntraDeltaRate&0xFF) |
|
||
|
|
((pParam->cu16InterDeltaRate&0xFF)<<8) |
|
||
|
|
((pParam->cu16MergeDeltaRate&0xFF)<<16));
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_CUSTOM_MD_CU32, (pParam->cu32IntraDeltaRate&0xFF) |
|
||
|
|
((pParam->cu32InterDeltaRate&0xFF)<<8) |
|
||
|
|
((pParam->cu32MergeDeltaRate&0xFF)<<16));
|
||
|
|
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_DEPENDENT_SLICE, pParam->dependSliceModeArg<<16 | pParam->dependSliceMode);
|
||
|
|
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_NR_PARAM, (pParam->nrYEnable<<0) |
|
||
|
|
(pParam->nrCbEnable<<1) |
|
||
|
|
(pParam->nrCrEnable<<2) |
|
||
|
|
(pParam->nrNoiseEstEnable<<3)|
|
||
|
|
(pParam->nrNoiseSigmaY<<4) |
|
||
|
|
(pParam->nrNoiseSigmaCb<<12) |
|
||
|
|
(pParam->nrNoiseSigmaCr<<20));
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_NR_WEIGHT, (pParam->nrIntraWeightY<<0) |
|
||
|
|
(pParam->nrIntraWeightCb<<5) |
|
||
|
|
(pParam->nrIntraWeightCr<<10)|
|
||
|
|
(pParam->nrInterWeightY<<15) |
|
||
|
|
(pParam->nrInterWeightCb<<20)|
|
||
|
|
(pParam->nrInterWeightCr<<25));
|
||
|
|
|
||
|
|
}
|
||
|
|
if (pEncInfo->openParam.encodeVuiRbsp || pEncInfo->openParam.encodeHrdRbspInVPS) {
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_VUI_HRD_PARAM, (pEncInfo->openParam.hrdRbspDataSize<<18) |
|
||
|
|
(pEncInfo->openParam.vuiRbspDataSize<<4) |
|
||
|
|
(pEncInfo->openParam.encodeHrdRbspInVPS<<2) |
|
||
|
|
(pEncInfo->openParam.encodeVuiRbsp));
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_VUI_RBSP_ADDR, pEncInfo->openParam.vuiRbspDataAddr);
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_HRD_RBSP_ADDR, pEncInfo->openParam.hrdRbspDataAddr);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_VUI_HRD_PARAM, 0);
|
||
|
|
}
|
||
|
|
|
||
|
|
Wave5BitIssueCommand(instance, W5_ENC_SET_PARAM);
|
||
|
|
|
||
|
|
if (vdi_wait_vpu_busy(coreIdx, __VPU_BUSY_TIMEOUT, W5_VPU_BUSY_STATUS) == -1) {
|
||
|
|
if (instance->loggingEnable)
|
||
|
|
vdi_log(coreIdx, instance->instIndex, W5_ENC_SET_PARAM, 2);
|
||
|
|
return RETCODE_VPU_RESPONSE_TIMEOUT;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (VpuReadReg(coreIdx, W5_RET_SUCCESS) == 0) {
|
||
|
|
regVal = VpuReadReg(instance->coreIdx, W5_RET_FAIL_REASON);
|
||
|
|
if (regVal != WAVE5_SYSERR_QUEUEING_FAIL)
|
||
|
|
VLOG(ERR, "FAIL_REASON = 0x%x\n", regVal);
|
||
|
|
|
||
|
|
if (regVal == WAVE5_SYSERR_QUEUEING_FAIL) {
|
||
|
|
regVal = VpuReadReg(instance->coreIdx, W5_RET_QUEUE_FAIL_REASON);
|
||
|
|
VLOG(ERR, "QUEUE_FAIL_REASON = 0x%x\n", regVal);
|
||
|
|
return RETCODE_QUEUEING_FAILURE;
|
||
|
|
}
|
||
|
|
else if (regVal == WAVE5_SYSERR_ACCESS_VIOLATION_HW)
|
||
|
|
return RETCODE_MEMORY_ACCESS_VIOLATION;
|
||
|
|
else if (regVal == WAVE5_SYSERR_WATCHDOG_TIMEOUT)
|
||
|
|
return RETCODE_VPU_RESPONSE_TIMEOUT;
|
||
|
|
else if (regVal == WAVE5_SYSERR_BUS_ERROR || regVal == WAVE5_SYSERR_DOUBLE_FAULT)
|
||
|
|
return RETCODE_VPU_BUS_ERROR;
|
||
|
|
else
|
||
|
|
return RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
|
||
|
|
return RETCODE_SUCCESS;
|
||
|
|
}
|
||
|
|
|
||
|
|
RetCode Wave5VpuEncGetSeqInfo(CodecInst* instance, EncInitialInfo* info)
|
||
|
|
{
|
||
|
|
RetCode ret = RETCODE_SUCCESS;
|
||
|
|
Uint32 regVal;
|
||
|
|
EncInfo* pEncInfo;
|
||
|
|
|
||
|
|
pEncInfo = VPU_HANDLE_TO_ENCINFO(instance);
|
||
|
|
|
||
|
|
// Send QUERY cmd
|
||
|
|
ret = SendQuery(instance, GET_RESULT);
|
||
|
|
if (ret != RETCODE_SUCCESS) {
|
||
|
|
regVal = VpuReadReg(instance->coreIdx, W5_RET_FAIL_REASON);
|
||
|
|
if (regVal != WAVE5_SYSERR_QUEUEING_FAIL)
|
||
|
|
VLOG(ERR, "FAIL_REASON = 0x%x\n", regVal);
|
||
|
|
|
||
|
|
if (regVal == WAVE5_SYSERR_RESULT_NOT_READY)
|
||
|
|
return RETCODE_REPORT_NOT_READY;
|
||
|
|
else if(regVal == WAVE5_SYSERR_ACCESS_VIOLATION_HW)
|
||
|
|
return RETCODE_MEMORY_ACCESS_VIOLATION;
|
||
|
|
else if (regVal == WAVE5_SYSERR_WATCHDOG_TIMEOUT)
|
||
|
|
return RETCODE_VPU_RESPONSE_TIMEOUT;
|
||
|
|
else if (regVal == WAVE5_SYSERR_BUS_ERROR || regVal == WAVE5_SYSERR_DOUBLE_FAULT)
|
||
|
|
return RETCODE_VPU_BUS_ERROR;
|
||
|
|
else
|
||
|
|
return RETCODE_QUERY_FAILURE;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (instance->loggingEnable)
|
||
|
|
vdi_log(instance->coreIdx, instance->instIndex, W5_INIT_SEQ, 0);
|
||
|
|
|
||
|
|
regVal = VpuReadReg(instance->coreIdx, W5_RET_QUEUE_STATUS);
|
||
|
|
|
||
|
|
pEncInfo->instanceQueueCount = (regVal>>16)&0xff;
|
||
|
|
pEncInfo->reportQueueCount = (regVal & 0xffff);
|
||
|
|
|
||
|
|
if (VpuReadReg(instance->coreIdx, W5_RET_ENC_ENCODING_SUCCESS) != 1) {
|
||
|
|
info->seqInitErrReason = VpuReadReg(instance->coreIdx, W5_RET_ENC_ERR_INFO);
|
||
|
|
ret = RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
info->warnInfo = VpuReadReg(instance->coreIdx, W5_RET_ENC_WARN_INFO);
|
||
|
|
}
|
||
|
|
|
||
|
|
info->minFrameBufferCount = VpuReadReg(instance->coreIdx, W5_RET_ENC_NUM_REQUIRED_FB);
|
||
|
|
info->minSrcFrameCount = VpuReadReg(instance->coreIdx, W5_RET_ENC_MIN_SRC_BUF_NUM);
|
||
|
|
info->maxLatencyPictures = VpuReadReg(instance->coreIdx, W5_RET_ENC_PIC_MAX_LATENCY_PICTURES);
|
||
|
|
info->vlcBufSize = VpuReadReg(instance->coreIdx, W5_RET_VLC_BUF_SIZE);
|
||
|
|
info->paramBufSize = VpuReadReg(instance->coreIdx, W5_RET_PARAM_BUF_SIZE);
|
||
|
|
pEncInfo->vlcBufSize = info->vlcBufSize;
|
||
|
|
pEncInfo->paramBufSize = info->paramBufSize;
|
||
|
|
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
RetCode Wave5VpuEncRegisterFramebuffer(CodecInst* inst, FrameBuffer* fbArr, TiledMapType mapType, Uint32 count)
|
||
|
|
{
|
||
|
|
RetCode ret = RETCODE_SUCCESS;
|
||
|
|
Int32 q, j, i, remain, idx, coreIdx, startNo, endNo, stride;
|
||
|
|
Uint32 regVal=0, picSize=0, mvColSize, fbcYTblSize, fbcCTblSize, subSampledSize=0;
|
||
|
|
Uint32 endian, nv21=0, cbcrInterleave = 0, lumaStride, chromaStride, bufHeight = 0, bufWidth = 0;
|
||
|
|
Uint32 svacMvColSize0 = 0, svacMvColSize1 = 0;
|
||
|
|
vpu_buffer_t vbMV;
|
||
|
|
vpu_buffer_t vbFbcYTbl;
|
||
|
|
vpu_buffer_t vbFbcCTbl;
|
||
|
|
vpu_buffer_t vbSubSamBuf;
|
||
|
|
vpu_buffer_t vbTask;
|
||
|
|
|
||
|
|
memset(&vbMV , 0, sizeof(vpu_buffer_t));
|
||
|
|
memset(&vbFbcYTbl , 0, sizeof(vpu_buffer_t));
|
||
|
|
memset(&vbFbcCTbl , 0, sizeof(vpu_buffer_t));
|
||
|
|
memset(&vbSubSamBuf , 0, sizeof(vpu_buffer_t));
|
||
|
|
memset(&vbTask , 0, sizeof(vpu_buffer_t));
|
||
|
|
|
||
|
|
EncOpenParam* pOpenParam;
|
||
|
|
EncInfo* pEncInfo = &inst->CodecInfo->encInfo;
|
||
|
|
|
||
|
|
pOpenParam = &pEncInfo->openParam;
|
||
|
|
coreIdx = inst->coreIdx;
|
||
|
|
mvColSize = fbcYTblSize = fbcCTblSize = 0;
|
||
|
|
stride = pEncInfo->stride;
|
||
|
|
|
||
|
|
if (inst->codecMode == W_AVC_ENC) {
|
||
|
|
bufWidth = VPU_ALIGN16(pOpenParam->picWidth);
|
||
|
|
bufHeight = VPU_ALIGN16(pOpenParam->picHeight);
|
||
|
|
|
||
|
|
if ((pEncInfo->rotationAngle != 0 || pEncInfo->mirrorDirection != 0) && !(pEncInfo->rotationAngle == 180 && pEncInfo->mirrorDirection == MIRDIR_HOR_VER)) {
|
||
|
|
bufWidth = VPU_ALIGN16(pOpenParam->picWidth);
|
||
|
|
bufHeight = VPU_ALIGN16(pOpenParam->picHeight);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (pEncInfo->rotationAngle == 90 || pEncInfo->rotationAngle == 270) {
|
||
|
|
bufWidth = VPU_ALIGN16(pOpenParam->picHeight);
|
||
|
|
bufHeight = VPU_ALIGN16(pOpenParam->picWidth);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
bufWidth = VPU_ALIGN8(pOpenParam->picWidth);
|
||
|
|
bufHeight = VPU_ALIGN8(pOpenParam->picHeight);
|
||
|
|
|
||
|
|
if ((pEncInfo->rotationAngle != 0 || pEncInfo->mirrorDirection != 0) && !(pEncInfo->rotationAngle == 180 && pEncInfo->mirrorDirection == MIRDIR_HOR_VER)) {
|
||
|
|
bufWidth = VPU_ALIGN32(pOpenParam->picWidth);
|
||
|
|
bufHeight = VPU_ALIGN32(pOpenParam->picHeight);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (pEncInfo->rotationAngle == 90 || pEncInfo->rotationAngle == 270) {
|
||
|
|
bufWidth = VPU_ALIGN32(pOpenParam->picHeight);
|
||
|
|
bufHeight = VPU_ALIGN32(pOpenParam->picWidth);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (mapType == COMPRESSED_FRAME_MAP_SVAC_SVC_BL) {
|
||
|
|
bufWidth = pOpenParam->picWidthBL;
|
||
|
|
bufHeight = pOpenParam->picHeightBL;
|
||
|
|
}
|
||
|
|
|
||
|
|
svacMvColSize0 = WAVE5_ENC_SVAC_MVCOL_0_BUF_SIZE(bufWidth, bufHeight);
|
||
|
|
svacMvColSize1 = WAVE5_ENC_SVAC_MVCOL_1_BUF_SIZE(bufWidth, bufHeight);
|
||
|
|
|
||
|
|
picSize = (bufWidth<<16) | bufHeight;
|
||
|
|
|
||
|
|
if (inst->codecMode == W_SVAC_ENC) {
|
||
|
|
mvColSize = svacMvColSize0 + svacMvColSize1;
|
||
|
|
vbMV.phys_addr = 0;
|
||
|
|
vbMV.size = ((mvColSize+4095)&~4095)+4096; /* 4096 is a margin */
|
||
|
|
}
|
||
|
|
else if (inst->codecMode == W_HEVC_ENC) {
|
||
|
|
mvColSize = WAVE5_ENC_HEVC_MVCOL_BUF_SIZE(bufWidth, bufHeight);
|
||
|
|
mvColSize = VPU_ALIGN16(mvColSize);
|
||
|
|
vbMV.phys_addr = 0;
|
||
|
|
vbMV.size = ((mvColSize*count+4095)&~4095)+4096; /* 4096 is a margin */
|
||
|
|
}
|
||
|
|
else if (inst->codecMode == W_AVC_ENC) {
|
||
|
|
mvColSize = WAVE5_ENC_AVC_MVCOL_BUF_SIZE(bufWidth, bufHeight);
|
||
|
|
vbMV.phys_addr = 0;
|
||
|
|
vbMV.size = ((mvColSize*count+4095)&~4095)+4096; /* 4096 is a margin */
|
||
|
|
}
|
||
|
|
|
||
|
|
if (vdi_allocate_dma_memory(inst->coreIdx, &vbMV, ENC_MV, inst->instIndex) < 0)
|
||
|
|
return RETCODE_INSUFFICIENT_RESOURCE;
|
||
|
|
|
||
|
|
if (mapType == COMPRESSED_FRAME_MAP_SVAC_SVC_BL)
|
||
|
|
pEncInfo->vbMVBL = vbMV;
|
||
|
|
else
|
||
|
|
pEncInfo->vbMV = vbMV;
|
||
|
|
|
||
|
|
if (pEncInfo->productCode == WAVE521C_DUAL_CODE) {
|
||
|
|
Uint32 bgs_width, ot_bg_width, comp_frm_width, ot_frm_width, ot_bg_height, bgs_height, comp_frm_height, ot_frm_height;
|
||
|
|
Uint32 frm_width, frm_height;
|
||
|
|
Uint32 dualWidth = bufWidth;
|
||
|
|
Uint32 dualHeight = bufHeight;
|
||
|
|
bgs_width = (pOpenParam->EncStdParam.waveParam.internalBitDepth >8 ? 256 : 512);
|
||
|
|
|
||
|
|
if (inst->codecMode == W_AVC_ENC)
|
||
|
|
ot_bg_width = 1024;
|
||
|
|
else // if (inst->codecMode == W_HEVC_ENC)
|
||
|
|
ot_bg_width = 512;
|
||
|
|
|
||
|
|
frm_width = VPU_CEIL(dualWidth, 16);
|
||
|
|
frm_height = VPU_CEIL(dualHeight, 16);
|
||
|
|
comp_frm_width = VPU_CEIL(VPU_CEIL(frm_width , 16) + 16, 16); // valid_width = align(width, 16), comp_frm_width = align(valid_width+pad_x, 16)
|
||
|
|
ot_frm_width = VPU_CEIL(comp_frm_width, ot_bg_width); // 1024 = offset table BG width
|
||
|
|
|
||
|
|
// sizeof_offset_table()
|
||
|
|
ot_bg_height = 32;
|
||
|
|
bgs_height = (1<<14) / bgs_width / (pOpenParam->EncStdParam.waveParam.internalBitDepth>8 ? 2 : 1);
|
||
|
|
comp_frm_height = VPU_CEIL(VPU_CEIL(frm_height, 4) + 4, bgs_height);
|
||
|
|
ot_frm_height = VPU_CEIL(comp_frm_height, ot_bg_height);
|
||
|
|
fbcYTblSize = (ot_frm_width/16) * (ot_frm_height/4) *2;
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
fbcYTblSize = WAVE5_FBC_LUMA_TABLE_SIZE(bufWidth, bufHeight);
|
||
|
|
fbcYTblSize = VPU_ALIGN16(fbcYTblSize);
|
||
|
|
}
|
||
|
|
|
||
|
|
vbFbcYTbl.phys_addr = 0;
|
||
|
|
vbFbcYTbl.size = ((fbcYTblSize*count+4095)&~4095)+4096;
|
||
|
|
if (vdi_allocate_dma_memory(inst->coreIdx, &vbFbcYTbl, ENC_FBCY_TBL, inst->instIndex) < 0)
|
||
|
|
return RETCODE_INSUFFICIENT_RESOURCE;
|
||
|
|
|
||
|
|
if (mapType == COMPRESSED_FRAME_MAP_SVAC_SVC_BL)
|
||
|
|
pEncInfo->vbFbcYTblBL = vbFbcYTbl;
|
||
|
|
else
|
||
|
|
pEncInfo->vbFbcYTbl = vbFbcYTbl;
|
||
|
|
|
||
|
|
if (pEncInfo->productCode == WAVE521C_DUAL_CODE) {
|
||
|
|
Uint32 bgs_width, ot_bg_width, comp_frm_width, ot_frm_width, ot_bg_height, bgs_height, comp_frm_height, ot_frm_height;
|
||
|
|
Uint32 frm_width, frm_height;
|
||
|
|
Uint32 dualWidth = bufWidth;
|
||
|
|
Uint32 dualHeight = bufHeight;
|
||
|
|
bgs_width = (pOpenParam->EncStdParam.waveParam.internalBitDepth >8 ? 256 : 512);
|
||
|
|
|
||
|
|
if (inst->codecMode == W_AVC_ENC)
|
||
|
|
ot_bg_width = 1024;
|
||
|
|
else // if (inst->codecMode == W_HEVC_ENC)
|
||
|
|
ot_bg_width = 512;
|
||
|
|
|
||
|
|
frm_width = VPU_CEIL(dualWidth, 16);
|
||
|
|
frm_height = VPU_CEIL(dualHeight, 16);
|
||
|
|
comp_frm_width = VPU_CEIL(VPU_CEIL(frm_width/2 , 16) + 16, 16); // valid_width = align(width, 16), comp_frm_width = align(valid_width+pad_x, 16)
|
||
|
|
ot_frm_width = VPU_CEIL(comp_frm_width, ot_bg_width); // 1024 = offset table BG width
|
||
|
|
|
||
|
|
// sizeof_offset_table()
|
||
|
|
ot_bg_height = 32;
|
||
|
|
bgs_height = (1<<14) / bgs_width / (pOpenParam->EncStdParam.waveParam.internalBitDepth>8 ? 2 : 1);
|
||
|
|
comp_frm_height = VPU_CEIL(VPU_CEIL(frm_height, 4) + 4, bgs_height);
|
||
|
|
ot_frm_height = VPU_CEIL(comp_frm_height, ot_bg_height);
|
||
|
|
fbcCTblSize = (ot_frm_width/16) * (ot_frm_height/4) *2;
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
fbcCTblSize = WAVE5_FBC_CHROMA_TABLE_SIZE(bufWidth, bufHeight);
|
||
|
|
fbcCTblSize = VPU_ALIGN16(fbcCTblSize);
|
||
|
|
}
|
||
|
|
|
||
|
|
vbFbcCTbl.phys_addr = 0;
|
||
|
|
vbFbcCTbl.size = ((fbcCTblSize*count+4095)&~4095)+4096;
|
||
|
|
if (vdi_allocate_dma_memory(inst->coreIdx, &vbFbcCTbl, ENC_FBCC_TBL, inst->instIndex) < 0)
|
||
|
|
return RETCODE_INSUFFICIENT_RESOURCE;
|
||
|
|
|
||
|
|
if (mapType == COMPRESSED_FRAME_MAP_SVAC_SVC_BL)
|
||
|
|
pEncInfo->vbFbcCTblBL = vbFbcCTbl;
|
||
|
|
else
|
||
|
|
pEncInfo->vbFbcCTbl = vbFbcCTbl;
|
||
|
|
|
||
|
|
if (pOpenParam->bitstreamFormat == STD_AVC) {
|
||
|
|
subSampledSize = WAVE5_SUBSAMPLED_ONE_SIZE_AVC(bufWidth, bufHeight);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
subSampledSize = WAVE5_SUBSAMPLED_ONE_SIZE(bufWidth, bufHeight);
|
||
|
|
}
|
||
|
|
vbSubSamBuf.size = ((subSampledSize*count+4095)&~4095)+4096;
|
||
|
|
vbSubSamBuf.phys_addr = 0;
|
||
|
|
if (vdi_allocate_dma_memory(coreIdx, &vbSubSamBuf, ENC_SUBSAMBUF, inst->instIndex) < 0)
|
||
|
|
return RETCODE_INSUFFICIENT_RESOURCE;
|
||
|
|
if (mapType == COMPRESSED_FRAME_MAP_SVAC_SVC_BL)
|
||
|
|
pEncInfo->vbSubSamBufBL = vbSubSamBuf;
|
||
|
|
else
|
||
|
|
pEncInfo->vbSubSamBuf = vbSubSamBuf;
|
||
|
|
|
||
|
|
vbTask.size = (Uint32)((pEncInfo->vlcBufSize * VLC_BUF_NUM) + (pEncInfo->paramBufSize * COMMAND_QUEUE_DEPTH));
|
||
|
|
vbTask.phys_addr = 0;
|
||
|
|
if (pEncInfo->vbTask.size == 0) {
|
||
|
|
if (vdi_allocate_dma_memory(coreIdx, &vbTask, ENC_TASK, inst->instIndex) < 0)
|
||
|
|
return RETCODE_INSUFFICIENT_RESOURCE;
|
||
|
|
|
||
|
|
pEncInfo->vbTask = vbTask;
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_SET_FB_ADDR_TASK_BUF, pEncInfo->vbTask.phys_addr);
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_SET_FB_TASK_BUF_SIZE, vbTask.size);
|
||
|
|
}
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_ADDR_SUB_SAMPLED_FB_BASE, vbSubSamBuf.phys_addr); // set sub-sampled buffer base addr
|
||
|
|
VpuWriteReg(coreIdx, W5_SUB_SAMPLED_ONE_FB_SIZE, subSampledSize); // set sub-sampled buffer size for one frame
|
||
|
|
|
||
|
|
endian = vdi_convert_endian(coreIdx, fbArr[0].endian);
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_PIC_SIZE, picSize);
|
||
|
|
|
||
|
|
|
||
|
|
// set stride of Luma/Chroma for compressed buffer
|
||
|
|
if ((pEncInfo->rotationAngle != 0 || pEncInfo->mirrorDirection != 0) && !(pEncInfo->rotationAngle == 180 && pEncInfo->mirrorDirection == MIRDIR_HOR_VER)){
|
||
|
|
lumaStride = VPU_ALIGN16(bufWidth)*(pOpenParam->EncStdParam.waveParam.internalBitDepth >8 ? 5 : 4);
|
||
|
|
lumaStride = VPU_ALIGN32(lumaStride);
|
||
|
|
chromaStride = VPU_ALIGN16(bufWidth/2)*(pOpenParam->EncStdParam.waveParam.internalBitDepth >8 ? 5 : 4);
|
||
|
|
chromaStride = VPU_ALIGN32(chromaStride);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
if (mapType == COMPRESSED_FRAME_MAP_SVAC_SVC_BL) {
|
||
|
|
lumaStride = VPU_ALIGN16(pOpenParam->picWidthBL)*(pOpenParam->EncStdParam.waveParam.internalBitDepth >8 ? 5 : 4);
|
||
|
|
lumaStride = VPU_ALIGN32(lumaStride);
|
||
|
|
chromaStride = VPU_ALIGN16(pOpenParam->picWidthBL/2)*(pOpenParam->EncStdParam.waveParam.internalBitDepth >8 ? 5 : 4);
|
||
|
|
chromaStride = VPU_ALIGN32(chromaStride);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
lumaStride = VPU_ALIGN16(pOpenParam->picWidth)*(pOpenParam->EncStdParam.waveParam.internalBitDepth >8 ? 5 : 4);
|
||
|
|
lumaStride = VPU_ALIGN32(lumaStride);
|
||
|
|
chromaStride = VPU_ALIGN16(pOpenParam->picWidth/2)*(pOpenParam->EncStdParam.waveParam.internalBitDepth >8 ? 5 : 4);
|
||
|
|
chromaStride = VPU_ALIGN32(chromaStride);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_FBC_STRIDE, lumaStride<<16 | chromaStride);
|
||
|
|
|
||
|
|
cbcrInterleave = pOpenParam->cbcrInterleave;
|
||
|
|
|
||
|
|
if (mapType == COMPRESSED_FRAME_MAP_SVAC_SVC_BL) {
|
||
|
|
stride = VPU_ALIGN32(VPU_ALIGN32(VPU_ALIGN16(pOpenParam->picWidthBL)*5)/4);
|
||
|
|
}
|
||
|
|
regVal = (nv21 << 29) |
|
||
|
|
(cbcrInterleave << 16) |
|
||
|
|
(stride);
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_COMMON_PIC_INFO, regVal);
|
||
|
|
|
||
|
|
|
||
|
|
remain = count;
|
||
|
|
q = (remain+7)/8;
|
||
|
|
idx = 0;
|
||
|
|
for (j=0; j<q; j++) {
|
||
|
|
regVal = (endian<<16) | (j==q-1)<<4 | ((j==0)<<3);//lint !e514
|
||
|
|
regVal |= (pOpenParam->EncStdParam.waveParam.svcEnable == TRUE) ? (mapType == COMPRESSED_FRAME_MAP_SVAC_SVC_BL ? 0 : 1 << 27) : 0; // 0 = BL, 1 = EL
|
||
|
|
regVal |= (pOpenParam->enableNonRefFbcWrite<< 26);
|
||
|
|
VpuWriteReg(coreIdx, W5_SFB_OPTION, regVal);
|
||
|
|
startNo = j*8;
|
||
|
|
endNo = startNo + (remain>=8 ? 8 : remain) - 1;
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_SET_FB_NUM, (startNo<<8)|endNo);
|
||
|
|
|
||
|
|
for (i=0; i<8 && i<remain; i++) {
|
||
|
|
VpuWriteReg(coreIdx, W5_ADDR_LUMA_BASE0 + (i<<4), fbArr[i+startNo].bufY);
|
||
|
|
VpuWriteReg(coreIdx, W5_ADDR_CB_BASE0 + (i<<4), fbArr[i+startNo].bufCb);
|
||
|
|
APIDPRINT("REGISTER FB[%02d] Y(0x%08x), Cb(0x%08x) ", i, fbArr[i+startNo].bufY, fbArr[i+startNo].bufCb);
|
||
|
|
VpuWriteReg(coreIdx, W5_ADDR_FBC_Y_OFFSET0 + (i<<4), vbFbcYTbl.phys_addr+idx*fbcYTblSize); /* Luma FBC offset table */
|
||
|
|
VpuWriteReg(coreIdx, W5_ADDR_FBC_C_OFFSET0 + (i<<4), vbFbcCTbl.phys_addr+idx*fbcCTblSize); /* Chroma FBC offset table */
|
||
|
|
|
||
|
|
if (inst->codecMode == W_SVAC_ENC) {
|
||
|
|
if (idx == 0) { // SVAC encoder needs only 2 mv-col buffers. (COL0 = for RDO, COL1 = for MVP)
|
||
|
|
VpuWriteReg(coreIdx, W5_ADDR_MV_COL0, vbMV.phys_addr);
|
||
|
|
VpuWriteReg(coreIdx, W5_ADDR_MV_COL1, vbMV.phys_addr + svacMvColSize0);
|
||
|
|
APIDPRINT("Yo(0x%08x) Co(0x%08x), Mv(0x%08x), Mv1(0x%8x)\n", vbFbcYTbl.phys_addr, vbFbcCTbl.phys_addr, vbMV.phys_addr, vbMV.phys_addr + svacMvColSize0);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
APIDPRINT("Yo(0x%08x) Co(0x%08x)\n", vbFbcYTbl.phys_addr+idx*fbcYTblSize, vbFbcCTbl.phys_addr+idx*fbcCTblSize);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
VpuWriteReg(coreIdx, W5_ADDR_MV_COL0 + (i<<2), vbMV.phys_addr+idx*mvColSize);
|
||
|
|
APIDPRINT("Yo(0x%08x) Co(0x%08x), Mv(0x%08x)\n",vbFbcYTbl.phys_addr+idx*fbcYTblSize, vbFbcCTbl.phys_addr+idx*fbcCTblSize, vbMV.phys_addr+idx*mvColSize);
|
||
|
|
}
|
||
|
|
idx++;
|
||
|
|
}
|
||
|
|
remain -= i;
|
||
|
|
|
||
|
|
Wave5BitIssueCommand(inst, W5_SET_FB);
|
||
|
|
|
||
|
|
if (vdi_wait_vpu_busy(coreIdx, __VPU_BUSY_TIMEOUT, W5_VPU_BUSY_STATUS) == -1) {
|
||
|
|
return RETCODE_VPU_RESPONSE_TIMEOUT;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
regVal = VpuReadReg(coreIdx, W5_RET_SUCCESS);
|
||
|
|
if (regVal == 0) {
|
||
|
|
return RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
RetCode Wave5VpuEncode(CodecInst* instance, EncParam* option)
|
||
|
|
{
|
||
|
|
Int32 coreIdx, srcFrameFormat;
|
||
|
|
Uint32 regVal = 0, bsEndian;
|
||
|
|
Uint32 srcStrideC = 0;
|
||
|
|
EncInfo* pEncInfo;
|
||
|
|
FrameBuffer* pSrcFrame;
|
||
|
|
EncOpenParam* pOpenParam;
|
||
|
|
BOOL justified = WTL_RIGHT_JUSTIFIED;
|
||
|
|
Uint32 formatNo = WTL_PIXEL_8BIT;
|
||
|
|
|
||
|
|
coreIdx = instance->coreIdx;
|
||
|
|
pEncInfo = VPU_HANDLE_TO_ENCINFO(instance);
|
||
|
|
pOpenParam = &pEncInfo->openParam;
|
||
|
|
pSrcFrame = option->sourceFrame;
|
||
|
|
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_BS_START_ADDR, option->picStreamBufferAddr);
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_BS_SIZE, option->picStreamBufferSize);
|
||
|
|
pEncInfo->streamBufStartAddr = option->picStreamBufferAddr;
|
||
|
|
pEncInfo->streamBufSize = option->picStreamBufferSize;
|
||
|
|
pEncInfo->streamBufEndAddr = option->picStreamBufferAddr + option->picStreamBufferSize;
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_PIC_SRC_AXI_SEL, DEFAULT_SRC_AXI);
|
||
|
|
/* Secondary AXI */
|
||
|
|
regVal = (pEncInfo->secAxiInfo.u.wave.useEncRdoEnable << 11) | (pEncInfo->secAxiInfo.u.wave.useEncLfEnable << 15);
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_PIC_USE_SEC_AXI, regVal);
|
||
|
|
|
||
|
|
regVal = 0;
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_PIC_REPORT_PARAM, regVal);
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_PIC_REPORT_ENDIAN, VDI_128BIT_LITTLE_ENDIAN);
|
||
|
|
|
||
|
|
if (option->codeOption.implicitHeaderEncode == 1) {
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_PIC_CODE_OPTION, CODEOPT_ENC_HEADER_IMPLICIT | CODEOPT_ENC_VCL | // implicitly encode a header(headers) for generating bitstream. (to encode a header only, use ENC_PUT_VIDEO_HEADER for GiveCommand)
|
||
|
|
(option->codeOption.encodeAUD<<5) |
|
||
|
|
(option->codeOption.encodeEOS<<6) |
|
||
|
|
(option->codeOption.encodeEOB<<7));
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_PIC_CODE_OPTION, (option->codeOption.implicitHeaderEncode<<0) |
|
||
|
|
(option->codeOption.encodeVCL<<1) |
|
||
|
|
(option->codeOption.encodeVPS<<2) |
|
||
|
|
(option->codeOption.encodeSPS<<3) |
|
||
|
|
(option->codeOption.encodePPS<<4) |
|
||
|
|
(option->codeOption.encodeAUD<<5) |
|
||
|
|
(option->codeOption.encodeEOS<<6) |
|
||
|
|
(option->codeOption.encodeEOB<<7));
|
||
|
|
}
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_PIC_PIC_PARAM, (option->skipPicture<<0) |
|
||
|
|
(option->forcePicQpEnable<<1) |
|
||
|
|
(option->forcePicQpI<<2) |
|
||
|
|
(option->forcePicQpP<<8) |
|
||
|
|
(option->forcePicQpB<<14) |
|
||
|
|
(option->forcePicTypeEnable<<20) |
|
||
|
|
(option->forcePicType<<21) |
|
||
|
|
(option->forceAllCtuCoefDropEnable<<24) |
|
||
|
|
(option->svcLayerFlag<<25));
|
||
|
|
|
||
|
|
|
||
|
|
if (option->srcEndFlag == 1)
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_PIC_SRC_PIC_IDX, 0xFFFFFFFF); // no more source image.
|
||
|
|
else
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_PIC_SRC_PIC_IDX, option->srcIdx);
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_PIC_SRC_ADDR_Y, pSrcFrame->bufY);
|
||
|
|
if (pOpenParam->cbcrOrder == CBCR_ORDER_NORMAL) {
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_PIC_SRC_ADDR_U, pSrcFrame->bufCb);
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_PIC_SRC_ADDR_V, pSrcFrame->bufCr);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_PIC_SRC_ADDR_U, pSrcFrame->bufCr);
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_PIC_SRC_ADDR_V, pSrcFrame->bufCb);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
switch (pOpenParam->srcFormat) {
|
||
|
|
case FORMAT_420:
|
||
|
|
case FORMAT_422:
|
||
|
|
case FORMAT_YUYV:
|
||
|
|
case FORMAT_YVYU:
|
||
|
|
case FORMAT_UYVY:
|
||
|
|
case FORMAT_VYUY:
|
||
|
|
justified = WTL_LEFT_JUSTIFIED;
|
||
|
|
formatNo = WTL_PIXEL_8BIT;
|
||
|
|
srcStrideC = (pSrcFrame->cbcrInterleave == 1) ? pSrcFrame->stride : (pSrcFrame->stride/2);
|
||
|
|
srcStrideC = (pOpenParam->srcFormat == FORMAT_422) ? srcStrideC*2 : srcStrideC;
|
||
|
|
break;
|
||
|
|
case FORMAT_420_P10_16BIT_MSB:
|
||
|
|
case FORMAT_422_P10_16BIT_MSB:
|
||
|
|
case FORMAT_YUYV_P10_16BIT_MSB:
|
||
|
|
case FORMAT_YVYU_P10_16BIT_MSB:
|
||
|
|
case FORMAT_UYVY_P10_16BIT_MSB:
|
||
|
|
case FORMAT_VYUY_P10_16BIT_MSB:
|
||
|
|
justified = WTL_RIGHT_JUSTIFIED;
|
||
|
|
formatNo = WTL_PIXEL_16BIT;
|
||
|
|
srcStrideC = (pSrcFrame->cbcrInterleave == 1) ? pSrcFrame->stride : (pSrcFrame->stride/2);
|
||
|
|
srcStrideC = (pOpenParam->srcFormat == FORMAT_422_P10_16BIT_MSB) ? srcStrideC*2 : srcStrideC;
|
||
|
|
break;
|
||
|
|
case FORMAT_420_P10_16BIT_LSB:
|
||
|
|
case FORMAT_422_P10_16BIT_LSB:
|
||
|
|
case FORMAT_YUYV_P10_16BIT_LSB:
|
||
|
|
case FORMAT_YVYU_P10_16BIT_LSB:
|
||
|
|
case FORMAT_UYVY_P10_16BIT_LSB:
|
||
|
|
case FORMAT_VYUY_P10_16BIT_LSB:
|
||
|
|
justified = WTL_LEFT_JUSTIFIED;
|
||
|
|
formatNo = WTL_PIXEL_16BIT;
|
||
|
|
srcStrideC = (pSrcFrame->cbcrInterleave == 1) ? pSrcFrame->stride : (pSrcFrame->stride/2);
|
||
|
|
srcStrideC = (pOpenParam->srcFormat == FORMAT_422_P10_16BIT_LSB) ? srcStrideC*2 : srcStrideC;
|
||
|
|
break;
|
||
|
|
case FORMAT_420_P10_32BIT_MSB:
|
||
|
|
case FORMAT_422_P10_32BIT_MSB:
|
||
|
|
case FORMAT_YUYV_P10_32BIT_MSB:
|
||
|
|
case FORMAT_YVYU_P10_32BIT_MSB:
|
||
|
|
case FORMAT_UYVY_P10_32BIT_MSB:
|
||
|
|
case FORMAT_VYUY_P10_32BIT_MSB:
|
||
|
|
justified = WTL_RIGHT_JUSTIFIED;
|
||
|
|
formatNo = WTL_PIXEL_32BIT;
|
||
|
|
srcStrideC = (pSrcFrame->cbcrInterleave == 1) ? pSrcFrame->stride : VPU_ALIGN16(pSrcFrame->stride/2)*(1<<pSrcFrame->cbcrInterleave);
|
||
|
|
srcStrideC = (pOpenParam->srcFormat == FORMAT_422_P10_32BIT_MSB) ? srcStrideC*2 : srcStrideC;
|
||
|
|
break;
|
||
|
|
case FORMAT_420_P10_32BIT_LSB:
|
||
|
|
case FORMAT_422_P10_32BIT_LSB:
|
||
|
|
case FORMAT_YUYV_P10_32BIT_LSB:
|
||
|
|
case FORMAT_YVYU_P10_32BIT_LSB:
|
||
|
|
case FORMAT_UYVY_P10_32BIT_LSB:
|
||
|
|
case FORMAT_VYUY_P10_32BIT_LSB:
|
||
|
|
justified = WTL_LEFT_JUSTIFIED;
|
||
|
|
formatNo = WTL_PIXEL_32BIT;
|
||
|
|
srcStrideC = (pSrcFrame->cbcrInterleave == 1) ? pSrcFrame->stride : VPU_ALIGN16(pSrcFrame->stride/2)*(1<<pSrcFrame->cbcrInterleave);
|
||
|
|
srcStrideC = (pOpenParam->srcFormat == FORMAT_422_P10_32BIT_LSB) ? srcStrideC*2 : srcStrideC;
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
return RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
|
||
|
|
srcFrameFormat = (pOpenParam->cbcrInterleave<<1) | (pOpenParam->nv21);
|
||
|
|
switch (pOpenParam->packedFormat) {
|
||
|
|
case PACKED_YUYV: srcFrameFormat = 4; break;
|
||
|
|
case PACKED_YVYU: srcFrameFormat = 5; break;
|
||
|
|
case PACKED_UYVY: srcFrameFormat = 6; break;
|
||
|
|
case PACKED_VYUY: srcFrameFormat = 7; break;
|
||
|
|
default: break;
|
||
|
|
}
|
||
|
|
|
||
|
|
regVal = vdi_convert_endian(coreIdx, pOpenParam->sourceEndian);
|
||
|
|
bsEndian = (~regVal&VDI_128BIT_ENDIAN_MASK);
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_PIC_SRC_STRIDE, (pSrcFrame->stride<<16) | srcStrideC);
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_PIC_SRC_FORMAT, (srcFrameFormat<<0) |
|
||
|
|
(formatNo<<3) |
|
||
|
|
(justified<<5) |
|
||
|
|
(bsEndian<<6));
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_PIC_CUSTOM_MAP_OPTION_ADDR, option->customMapOpt.addrCustomMap);
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_PIC_CUSTOM_MAP_OPTION_PARAM, (option->customMapOpt.customRoiMapEnable << 0) |
|
||
|
|
(option->customMapOpt.roiAvgQp << 1) |
|
||
|
|
(option->customMapOpt.customLambdaMapEnable<< 8) |
|
||
|
|
(option->customMapOpt.customModeMapEnable<< 9) |
|
||
|
|
(option->customMapOpt.customCoefDropEnable<< 10));
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_PIC_LONGTERM_PIC, (option->useCurSrcAsLongtermPic<<0) | (option->useLongtermRef<<1));
|
||
|
|
|
||
|
|
if (instance->codecMode == W_HEVC_ENC || instance->codecMode == W_AVC_ENC) {
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_PIC_WP_PIXEL_SIGMA_Y, option->wpPixSigmaY);
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_PIC_WP_PIXEL_SIGMA_C, (option->wpPixSigmaCr<<16) | option->wpPixSigmaCb);
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_PIC_WP_PIXEL_MEAN_Y, option->wpPixMeanY);
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_PIC_WP_PIXEL_MEAN_C, (option->wpPixMeanCr<<16) | (option->wpPixMeanCb));
|
||
|
|
}
|
||
|
|
else if (instance->codecMode == W_SVAC_ENC) {
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_PIC_LF_PARAM_0, ((option->lfRefDeltaIntra&0x7f)<<0) |
|
||
|
|
((option->lfRefDeltaRef0&0x7f)<<7) |
|
||
|
|
((option->lfRefDeltaRef1&0x7f)<<14) |
|
||
|
|
((option->lfModeDelta&0x7f)<<21) |
|
||
|
|
(option->sharpLevel<<28));
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_PIC_LF_PARAM_1, (option->userFilterLevelEnable<<0) | ((option->lfFilterLevel&0x3f)<<1));
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_PIC_PREFIX_SEI_INFO, ((pEncInfo->prefixSeiDataSize << 16) | (pEncInfo->prefixSeiNalEnable&0x01)));
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_PIC_PREFIX_SEI_NAL_ADDR, pEncInfo->prefixSeiNalAddr);
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_PIC_SUFFIX_SEI_INFO, ((pEncInfo->suffixSeiDataSize << 16) | (pEncInfo->suffixSeiNalEnable&0x01)));
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_PIC_SUFFIX_SEI_NAL_ADDR, pEncInfo->suffixSeiNalAddr);
|
||
|
|
|
||
|
|
|
||
|
|
Wave5BitIssueCommand(instance, W5_ENC_PIC);
|
||
|
|
|
||
|
|
if (vdi_wait_vpu_busy(instance->coreIdx, __VPU_BUSY_TIMEOUT, W5_VPU_BUSY_STATUS) == -1) { // Check QUEUE_DONE
|
||
|
|
if (instance->loggingEnable)
|
||
|
|
vdi_log(instance->coreIdx, instance->instIndex, W5_ENC_PIC, 2);
|
||
|
|
return RETCODE_VPU_RESPONSE_TIMEOUT;
|
||
|
|
}
|
||
|
|
|
||
|
|
regVal = VpuReadReg(instance->coreIdx, W5_RET_QUEUE_STATUS);
|
||
|
|
|
||
|
|
pEncInfo->instanceQueueCount = (regVal>>16)&0xff;
|
||
|
|
pEncInfo->reportQueueCount = (regVal & 0xffff);
|
||
|
|
|
||
|
|
if (VpuReadReg(instance->coreIdx, W5_RET_SUCCESS) == FALSE) { // FAILED for adding a command into VCPU QUEUE
|
||
|
|
regVal = VpuReadReg(instance->coreIdx, W5_RET_FAIL_REASON);
|
||
|
|
if (regVal != WAVE5_SYSERR_QUEUEING_FAIL)
|
||
|
|
VLOG(ERR, "FAIL_REASON = 0x%x\n", regVal);
|
||
|
|
|
||
|
|
if (regVal == WAVE5_SYSERR_QUEUEING_FAIL) {
|
||
|
|
regVal = VpuReadReg(instance->coreIdx, W5_RET_QUEUE_FAIL_REASON);
|
||
|
|
VLOG(ERR, "QUEUE_FAIL_REASON = 0x%x\n", regVal);
|
||
|
|
return RETCODE_QUEUEING_FAILURE;
|
||
|
|
}
|
||
|
|
else if (regVal == WAVE5_SYSERR_WATCHDOG_TIMEOUT)
|
||
|
|
return RETCODE_VPU_RESPONSE_TIMEOUT;
|
||
|
|
else if (regVal == WAVE5_SYSERR_BUS_ERROR || regVal == WAVE5_SYSERR_DOUBLE_FAULT)
|
||
|
|
return RETCODE_VPU_BUS_ERROR;
|
||
|
|
else
|
||
|
|
return RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
|
||
|
|
return RETCODE_SUCCESS;
|
||
|
|
}
|
||
|
|
|
||
|
|
RetCode Wave5VpuEncGetResult(CodecInst* instance, EncOutputInfo* result)
|
||
|
|
{
|
||
|
|
RetCode ret = RETCODE_SUCCESS;
|
||
|
|
Uint32 encodingSuccess;
|
||
|
|
Uint32 regVal;
|
||
|
|
Int32 coreIdx;
|
||
|
|
EncInfo* pEncInfo = VPU_HANDLE_TO_ENCINFO(instance);
|
||
|
|
vpu_instance_pool_t* instancePool = NULL;
|
||
|
|
|
||
|
|
coreIdx = instance->coreIdx;
|
||
|
|
|
||
|
|
ret = SendQuery(instance, GET_RESULT);
|
||
|
|
if (ret != RETCODE_SUCCESS) {
|
||
|
|
regVal = VpuReadReg(instance->coreIdx, W5_RET_FAIL_REASON);
|
||
|
|
if (regVal != WAVE5_SYSERR_QUEUEING_FAIL)
|
||
|
|
VLOG(ERR, "FAIL_REASON = 0x%x\n", regVal);
|
||
|
|
|
||
|
|
if (regVal == WAVE5_SYSERR_RESULT_NOT_READY)
|
||
|
|
return RETCODE_REPORT_NOT_READY;
|
||
|
|
else if(regVal == WAVE5_SYSERR_ACCESS_VIOLATION_HW)
|
||
|
|
return RETCODE_MEMORY_ACCESS_VIOLATION;
|
||
|
|
else if (regVal == WAVE5_SYSERR_WATCHDOG_TIMEOUT)
|
||
|
|
return RETCODE_VPU_RESPONSE_TIMEOUT;
|
||
|
|
else if (regVal == WAVE5_SYSERR_BUS_ERROR || regVal == WAVE5_SYSERR_DOUBLE_FAULT)
|
||
|
|
return RETCODE_VPU_BUS_ERROR;
|
||
|
|
else
|
||
|
|
return RETCODE_QUERY_FAILURE;
|
||
|
|
}
|
||
|
|
if (instance->loggingEnable)
|
||
|
|
vdi_log(coreIdx, instance->instIndex, W5_ENC_PIC, 0);
|
||
|
|
|
||
|
|
regVal = VpuReadReg(coreIdx, W5_RET_QUEUE_STATUS);
|
||
|
|
|
||
|
|
pEncInfo->instanceQueueCount = (regVal>>16)&0xff;
|
||
|
|
pEncInfo->reportQueueCount = (regVal & 0xffff);
|
||
|
|
|
||
|
|
encodingSuccess = VpuReadReg(coreIdx, W5_RET_ENC_ENCODING_SUCCESS);
|
||
|
|
if (encodingSuccess == FALSE) {
|
||
|
|
result->errorReason = VpuReadReg(coreIdx, W5_RET_ENC_ERR_INFO);
|
||
|
|
if (result->errorReason == WAVE5_SYSERR_VLC_BUF_FULL) {
|
||
|
|
return RETCODE_VLC_BUF_FULL;
|
||
|
|
}
|
||
|
|
return RETCODE_FAILURE;
|
||
|
|
} else {
|
||
|
|
result->warnInfo = VpuReadReg(instance->coreIdx, W5_RET_ENC_WARN_INFO);
|
||
|
|
}
|
||
|
|
|
||
|
|
result->encPicCnt = VpuReadReg(coreIdx, W5_RET_ENC_PIC_NUM);
|
||
|
|
regVal= VpuReadReg(coreIdx, W5_RET_ENC_PIC_TYPE);
|
||
|
|
result->picType = regVal & 0xFFFF;
|
||
|
|
|
||
|
|
result->encVclNut = VpuReadReg(coreIdx, W5_RET_ENC_VCL_NUT);
|
||
|
|
result->reconFrameIndex = VpuReadReg(coreIdx, W5_RET_ENC_PIC_IDX);
|
||
|
|
|
||
|
|
if (result->reconFrameIndex >= 0)
|
||
|
|
result->reconFrame = pEncInfo->frameBufPool[result->reconFrameIndex];
|
||
|
|
result->isSvcLayerEL = VpuReadReg(coreIdx, W5_RET_ENC_SVC_LAYER);
|
||
|
|
if (pEncInfo->openParam.EncStdParam.waveParam.svcEnable == 1 && result->isSvcLayerEL == FALSE) {
|
||
|
|
if (result->reconFrameIndex >= 0)
|
||
|
|
result->reconFrame = pEncInfo->frameBufPool[result->reconFrameIndex+pEncInfo->numFrameBuffers];
|
||
|
|
}
|
||
|
|
|
||
|
|
result->numOfSlices = VpuReadReg(coreIdx, W5_RET_ENC_PIC_SLICE_NUM);
|
||
|
|
result->picSkipped = VpuReadReg(coreIdx, W5_RET_ENC_PIC_SKIP);
|
||
|
|
result->numOfIntra = VpuReadReg(coreIdx, W5_RET_ENC_PIC_NUM_INTRA);
|
||
|
|
result->numOfMerge = VpuReadReg(coreIdx, W5_RET_ENC_PIC_NUM_MERGE);
|
||
|
|
result->numOfSkipBlock = VpuReadReg(coreIdx, W5_RET_ENC_PIC_NUM_SKIP);
|
||
|
|
result->bitstreamWrapAround = 0; // only support line-buffer mode.
|
||
|
|
|
||
|
|
result->avgCtuQp = VpuReadReg(coreIdx, W5_RET_ENC_PIC_AVG_CTU_QP);
|
||
|
|
result->encPicByte = VpuReadReg(coreIdx, W5_RET_ENC_PIC_BYTE);
|
||
|
|
|
||
|
|
result->encGopPicIdx = VpuReadReg(coreIdx, W5_RET_ENC_GOP_PIC_IDX);
|
||
|
|
result->encPicPoc = VpuReadReg(coreIdx, W5_RET_ENC_PIC_POC);
|
||
|
|
result->encSrcIdx = VpuReadReg(coreIdx, W5_RET_ENC_USED_SRC_IDX);
|
||
|
|
result->releaseSrcFlag = VpuReadReg(coreIdx, W5_RET_ENC_SRC_BUF_FLAG);
|
||
|
|
pEncInfo->streamWrPtr = VpuReadReg(coreIdx, pEncInfo->streamWrPtrRegAddr);
|
||
|
|
pEncInfo->streamRdPtr = VpuReadReg(coreIdx, pEncInfo->streamRdPtrRegAddr);
|
||
|
|
|
||
|
|
result->picDistortionLow = VpuReadReg(coreIdx, W5_RET_ENC_PIC_DIST_LOW);
|
||
|
|
result->picDistortionHigh = VpuReadReg(coreIdx, W5_RET_ENC_PIC_DIST_HIGH);
|
||
|
|
|
||
|
|
result->bitstreamBuffer = VpuReadReg(coreIdx, pEncInfo->streamRdPtrRegAddr);
|
||
|
|
result->rdPtr = pEncInfo->streamRdPtr;
|
||
|
|
result->wrPtr = pEncInfo->streamWrPtr;
|
||
|
|
|
||
|
|
if (result->reconFrameIndex == RECON_IDX_FLAG_HEADER_ONLY) //result for header only(no vcl) encoding
|
||
|
|
result->bitstreamSize = result->encPicByte;
|
||
|
|
else if (result->reconFrameIndex < 0)
|
||
|
|
result->bitstreamSize = 0;
|
||
|
|
else
|
||
|
|
result->bitstreamSize = result->encPicByte;
|
||
|
|
|
||
|
|
result->encHostCmdTick = VpuReadReg(coreIdx, W5_RET_ENC_HOST_CMD_TICK);
|
||
|
|
result->encPrepareStartTick = VpuReadReg(coreIdx, W5_RET_ENC_PREPARE_START_TICK);
|
||
|
|
result->encPrepareEndTick = VpuReadReg(coreIdx, W5_RET_ENC_PREPARE_END_TICK);
|
||
|
|
result->encProcessingStartTick = VpuReadReg(coreIdx, W5_RET_ENC_PROCESSING_START_TICK);
|
||
|
|
result->encProcessingEndTick = VpuReadReg(coreIdx, W5_RET_ENC_PROCESSING_END_TICK);
|
||
|
|
result->encEncodeStartTick = VpuReadReg(coreIdx, W5_RET_ENC_ENCODING_START_TICK);
|
||
|
|
result->encEncodeEndTick = VpuReadReg(coreIdx, W5_RET_ENC_ENCODING_END_TICK);
|
||
|
|
|
||
|
|
instancePool = vdi_get_instance_pool(instance->coreIdx);
|
||
|
|
if (instancePool) {
|
||
|
|
if ( pEncInfo->firstCycleCheck == FALSE ) {
|
||
|
|
result->frameCycle = (result->encEncodeEndTick - result->encHostCmdTick) * pEncInfo->cyclePerTick;
|
||
|
|
pEncInfo->firstCycleCheck = TRUE;
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
result->frameCycle = (result->encEncodeEndTick - instancePool->lastPerformanceCycles) * pEncInfo->cyclePerTick;
|
||
|
|
if (instancePool->lastPerformanceCycles < result->encHostCmdTick)
|
||
|
|
result->frameCycle = (result->encEncodeEndTick - result->encHostCmdTick) * pEncInfo->cyclePerTick;
|
||
|
|
}
|
||
|
|
instancePool->lastPerformanceCycles = result->encEncodeEndTick;
|
||
|
|
}
|
||
|
|
result->prepareCycle = (result->encPrepareEndTick - result->encPrepareStartTick) * pEncInfo->cyclePerTick;
|
||
|
|
result->processing = (result->encProcessingEndTick - result->encProcessingStartTick) * pEncInfo->cyclePerTick;
|
||
|
|
result->EncodedCycle = (result->encEncodeEndTick - result->encEncodeStartTick) * pEncInfo->cyclePerTick;
|
||
|
|
|
||
|
|
return RETCODE_SUCCESS;
|
||
|
|
}
|
||
|
|
|
||
|
|
RetCode Wave5VpuEncGetHeader(EncHandle instance, EncHeaderParam * encHeaderParam)
|
||
|
|
{
|
||
|
|
Int32 coreIdx;
|
||
|
|
Uint32 regVal = 0;
|
||
|
|
EncInfo* pEncInfo = VPU_HANDLE_TO_ENCINFO(instance);
|
||
|
|
|
||
|
|
coreIdx = instance->coreIdx;
|
||
|
|
|
||
|
|
EnterLock(coreIdx);
|
||
|
|
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_BS_START_ADDR, (Uint32)encHeaderParam->buf);
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_BS_SIZE, (Uint32)encHeaderParam->size);
|
||
|
|
pEncInfo->streamRdPtr = encHeaderParam->buf;
|
||
|
|
pEncInfo->streamWrPtr = encHeaderParam->buf;
|
||
|
|
pEncInfo->streamBufStartAddr = encHeaderParam->buf;
|
||
|
|
pEncInfo->streamBufSize = (Int32)encHeaderParam->size;
|
||
|
|
pEncInfo->streamBufEndAddr = (PhysicalAddress)(encHeaderParam->buf + encHeaderParam->size);
|
||
|
|
|
||
|
|
/* Secondary AXI */
|
||
|
|
regVal = (pEncInfo->secAxiInfo.u.wave.useEncRdoEnable << 11) | (pEncInfo->secAxiInfo.u.wave.useEncLfEnable << 15);
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_PIC_USE_SEC_AXI, regVal);
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_PIC_CODE_OPTION, (encHeaderParam->headerType) | (encHeaderParam->encodeAUD<<5));
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_PIC_SRC_PIC_IDX, 0);
|
||
|
|
|
||
|
|
Wave5BitIssueCommand(instance, W5_ENC_PIC);
|
||
|
|
|
||
|
|
if (vdi_wait_vpu_busy(instance->coreIdx, __VPU_BUSY_TIMEOUT, W5_VPU_BUSY_STATUS) == -1) { // Check QUEUE_DONE
|
||
|
|
if (instance->loggingEnable)
|
||
|
|
vdi_log(instance->coreIdx, instance->instIndex, W5_ENC_PIC, 2);
|
||
|
|
LeaveLock(coreIdx);
|
||
|
|
return RETCODE_VPU_RESPONSE_TIMEOUT;
|
||
|
|
}
|
||
|
|
|
||
|
|
regVal = VpuReadReg(instance->coreIdx, W5_RET_QUEUE_STATUS);
|
||
|
|
|
||
|
|
pEncInfo->instanceQueueCount = (regVal>>16)&0xff;
|
||
|
|
pEncInfo->reportQueueCount = (regVal & 0xffff);
|
||
|
|
|
||
|
|
if (VpuReadReg(instance->coreIdx, W5_RET_SUCCESS) == FALSE) { // FAILED for adding a command into VCPU QUEUE
|
||
|
|
regVal = VpuReadReg(instance->coreIdx, W5_RET_FAIL_REASON);
|
||
|
|
if (regVal != WAVE5_SYSERR_QUEUEING_FAIL)
|
||
|
|
VLOG(ERR, "FAIL_REASON = 0x%x\n", regVal);
|
||
|
|
|
||
|
|
if (regVal == WAVE5_SYSERR_QUEUEING_FAIL) {
|
||
|
|
regVal = VpuReadReg(instance->coreIdx, W5_RET_QUEUE_FAIL_REASON);
|
||
|
|
VLOG(ERR, "QUEUE_FAIL_REASON = 0x%x\n", regVal);
|
||
|
|
LeaveLock(coreIdx);
|
||
|
|
return RETCODE_QUEUEING_FAILURE;
|
||
|
|
}
|
||
|
|
else if (regVal == WAVE5_SYSERR_ACCESS_VIOLATION_HW) {
|
||
|
|
LeaveLock(coreIdx);
|
||
|
|
return RETCODE_MEMORY_ACCESS_VIOLATION;
|
||
|
|
}
|
||
|
|
else if (regVal == WAVE5_SYSERR_WATCHDOG_TIMEOUT) {
|
||
|
|
LeaveLock(coreIdx);
|
||
|
|
return RETCODE_VPU_RESPONSE_TIMEOUT;
|
||
|
|
}
|
||
|
|
else if (regVal == WAVE5_SYSERR_BUS_ERROR || regVal == WAVE5_SYSERR_DOUBLE_FAULT) {
|
||
|
|
LeaveLock(coreIdx);
|
||
|
|
return RETCODE_VPU_BUS_ERROR;
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
LeaveLock(coreIdx);
|
||
|
|
return RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
LeaveLock(coreIdx);
|
||
|
|
return RETCODE_SUCCESS;
|
||
|
|
}
|
||
|
|
|
||
|
|
RetCode Wave5VpuEncFiniSeq(CodecInst* instance )
|
||
|
|
{
|
||
|
|
RetCode ret = RETCODE_SUCCESS;
|
||
|
|
|
||
|
|
Wave5BitIssueCommand(instance, W5_DESTROY_INSTANCE);
|
||
|
|
|
||
|
|
|
||
|
|
if (vdi_wait_vpu_busy(instance->coreIdx, __VPU_BUSY_TIMEOUT, W5_VPU_BUSY_STATUS) == -1)
|
||
|
|
return RETCODE_VPU_RESPONSE_TIMEOUT;
|
||
|
|
|
||
|
|
if (VpuReadReg(instance->coreIdx, W5_RET_SUCCESS) == FALSE) {
|
||
|
|
Uint32 regVal = VpuReadReg(instance->coreIdx, W5_RET_FAIL_REASON);
|
||
|
|
|
||
|
|
if (regVal == WAVE5_SYSERR_VPU_STILL_RUNNING)
|
||
|
|
ret = RETCODE_VPU_STILL_RUNNING;
|
||
|
|
else if (regVal == WAVE5_SYSERR_BUS_ERROR || regVal == WAVE5_SYSERR_DOUBLE_FAULT)
|
||
|
|
ret = RETCODE_VPU_BUS_ERROR;
|
||
|
|
else
|
||
|
|
ret = RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
RetCode Wave5VpuEncParaChange(EncHandle instance, EncChangeParam* param)
|
||
|
|
{
|
||
|
|
Int32 coreIdx;
|
||
|
|
Uint32 regVal = 0;
|
||
|
|
EncInfo* pEncInfo;
|
||
|
|
coreIdx = instance->coreIdx;
|
||
|
|
pEncInfo = &instance->CodecInfo->encInfo;
|
||
|
|
|
||
|
|
EnterLock(coreIdx);
|
||
|
|
|
||
|
|
/* SET_PARAM + COMMON */
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_SET_PARAM_OPTION, OPT_CHANGE_PARAM);
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_SET_PARAM_ENABLE, param->enable_option);
|
||
|
|
|
||
|
|
if (param->enable_option & ENC_SET_CHANGE_PARAM_PPS) {
|
||
|
|
if (instance->codecMode == W_SVAC_ENC) {
|
||
|
|
regVal = (param->disableDeblk<<5) |
|
||
|
|
((param->chromaDcQpOffset&0x1F)<<14) |
|
||
|
|
((param->chromaAcQpOffset&0x1F)<<19) |
|
||
|
|
((param->lumaDcQpOffset&0x1F)<<24);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
regVal = (param->constIntraPredFlag<<1) |
|
||
|
|
(param->lfCrossSliceBoundaryEnable<<2) |
|
||
|
|
((param->weightPredEnable&1)<<3) |
|
||
|
|
(param->disableDeblk<<5) |
|
||
|
|
((param->betaOffsetDiv2&0xF)<<6) |
|
||
|
|
((param->tcOffsetDiv2&0xF)<<10) |
|
||
|
|
((param->chromaCbQpOffset&0x1F)<<14) |
|
||
|
|
((param->chromaCrQpOffset&0x1F)<<19) |
|
||
|
|
(param->transform8x8Enable<<29) |
|
||
|
|
(param->entropyCodingMode<<30);
|
||
|
|
}
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_PPS_PARAM, regVal);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (param->enable_option & ENC_SET_CHANGE_PARAM_INTRA_PARAM) {
|
||
|
|
if (instance->codecMode == W_AVC_ENC) {
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_INTRA_PARAM, (param->intraQP<<0) | ( (param->intraPeriod&0x7ff)<<6) | ( (param->avcIdrPeriod&0x7ff)<<17) | ( (param->forcedIdrHeaderEnable&3)<<28));
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_INTRA_PARAM, (param->intraQP<<3) | (param->forcedIdrHeaderEnable<<9) | (param->intraPeriod<<16));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (param->enable_option & ENC_SET_CHANGE_PARAM_RC_FRAME_RATE) {
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_RC_FRAME_RATE, param->frameRate);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (param->enable_option & ENC_SET_CHANGE_PARAM_RC_TARGET_RATE) {
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_RC_TARGET_RATE, param->bitRate);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (param->enable_option & ENC_SET_CHANGE_PARAM_RC) {
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_RC_PARAM, (param->hvsQPEnable<<2) |
|
||
|
|
(param->hvsQpScale<<4) |
|
||
|
|
(param->vbvBufferSize<<20));
|
||
|
|
}
|
||
|
|
|
||
|
|
if (param->enable_option & ENC_SET_CHANGE_PARAM_RC_MIN_MAX_QP) {
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_RC_MIN_MAX_QP, (param->minQpI<<0) |
|
||
|
|
(param->maxQpI<<6) |
|
||
|
|
(param->hvsMaxDeltaQp<<12));
|
||
|
|
}
|
||
|
|
|
||
|
|
if (param->enable_option & ENC_SET_CHANGE_PARAM_RC_INTER_MIN_MAX_QP) {
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_RC_INTER_MIN_MAX_QP, (param->minQpP<<0) |
|
||
|
|
(param->maxQpP<<6) |
|
||
|
|
(param->minQpB<<12) |
|
||
|
|
(param->maxQpB<<18));
|
||
|
|
}
|
||
|
|
|
||
|
|
if (param->enable_option & ENC_SET_CHANGE_PARAM_RC_BIT_RATIO_LAYER) {
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_RC_BIT_RATIO_LAYER_0_3, (param->fixedBitRatio[0]<<0) |
|
||
|
|
(param->fixedBitRatio[1]<<8) |
|
||
|
|
(param->fixedBitRatio[2]<<16) |
|
||
|
|
(param->fixedBitRatio[3]<<24));
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_RC_BIT_RATIO_LAYER_4_7, (param->fixedBitRatio[4]<<0) |
|
||
|
|
(param->fixedBitRatio[5]<<8) |
|
||
|
|
(param->fixedBitRatio[6]<<16) |
|
||
|
|
(param->fixedBitRatio[7]<<24));
|
||
|
|
}
|
||
|
|
if (param->enable_option & ENC_SET_CHANGE_PARAM_VUI_HRD_PARAM) {
|
||
|
|
regVal = (param->hrdRbspDataSize<<18) |
|
||
|
|
(param->vuiRbspDataSize<<4) |
|
||
|
|
(param->encodeHrdRbspInVPS<<2) |
|
||
|
|
(param->encodeVuiRbsp);
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_VUI_HRD_PARAM, regVal);
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_VUI_RBSP_ADDR, param->vuiRbspDataAddr);
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_HRD_RBSP_ADDR, param->hrdRbspDataAddr);
|
||
|
|
}
|
||
|
|
if (param->enable_option & ENC_SET_CHANGE_PARAM_RC_WEIGHT) {
|
||
|
|
regVal = (param->rcWeightBuf<<8 | param->rcWeightParam);
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_RC_WEIGHT_PARAM, regVal);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (param->enable_option & ENC_SET_CHANGE_PARAM_RDO) {
|
||
|
|
regVal = (param->rdoSkip<<2) |
|
||
|
|
(param->lambdaScalingEnable<<3) |
|
||
|
|
(param->coefClearDisable<<4) |
|
||
|
|
(param->intraNxNEnable<<8) |
|
||
|
|
(param->maxNumMerge<<18) |
|
||
|
|
(param->customMDEnable<<20) |
|
||
|
|
(param->customLambdaEnable<<21);
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_RDO_PARAM, regVal);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (param->enable_option & ENC_SET_CHANGE_PARAM_INDEPEND_SLICE) {
|
||
|
|
if (instance->codecMode == W_HEVC_ENC ) {
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_INDEPENDENT_SLICE, param->independSliceModeArg<<16 | param->independSliceMode);
|
||
|
|
}
|
||
|
|
else if (instance->codecMode == W_AVC_ENC) {
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_INDEPENDENT_SLICE, param->avcSliceArg<<16 | param->avcSliceMode);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (instance->codecMode == W_HEVC_ENC && param->enable_option & ENC_SET_CHANGE_PARAM_DEPEND_SLICE) {
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_DEPENDENT_SLICE, param->dependSliceModeArg<<16 | param->dependSliceMode);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (instance->codecMode == W_HEVC_ENC && param->enable_option & ENC_SET_CHANGE_PARAM_NR) {
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_NR_PARAM, (param->nrYEnable<<0) |
|
||
|
|
(param->nrCbEnable<<1) |
|
||
|
|
(param->nrCrEnable<<2) |
|
||
|
|
(param->nrNoiseEstEnable<<3)|
|
||
|
|
(param->nrNoiseSigmaY<<4) |
|
||
|
|
(param->nrNoiseSigmaCb<<12) |
|
||
|
|
(param->nrNoiseSigmaCr<<20));
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_NR_WEIGHT, (param->nrIntraWeightY<<0) |
|
||
|
|
(param->nrIntraWeightCb<<5) |
|
||
|
|
(param->nrIntraWeightCr<<10)|
|
||
|
|
(param->nrInterWeightY<<15) |
|
||
|
|
(param->nrInterWeightCb<<20)|
|
||
|
|
(param->nrInterWeightCr<<25));
|
||
|
|
}
|
||
|
|
|
||
|
|
if (param->enable_option & ENC_SET_CHANGE_PARAM_BG) {
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_BG_PARAM, (param->bgThrDiff<<1) |
|
||
|
|
(param->bgThrMeanDiff<<10) |
|
||
|
|
(param->bgLambdaQp<<18) |
|
||
|
|
((param->bgDeltaQp&0x1F)<<24) |
|
||
|
|
(instance->codecMode == W_AVC_ENC ? param->s2fmeDisable<<29 : 0));
|
||
|
|
}
|
||
|
|
if (instance->codecMode == W_HEVC_ENC && param->enable_option & ENC_SET_CHANGE_PARAM_CUSTOM_MD) {
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_CUSTOM_MD_PU04, (param->pu04DeltaRate&0xFF) |
|
||
|
|
((param->pu04IntraPlanarDeltaRate&0xFF)<<8) |
|
||
|
|
((param->pu04IntraDcDeltaRate&0xFF)<<16) |
|
||
|
|
((param->pu04IntraAngleDeltaRate&0xFF)<<24));
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_CUSTOM_MD_PU08, (param->pu08DeltaRate&0xFF) |
|
||
|
|
((param->pu08IntraPlanarDeltaRate&0xFF)<<8) |
|
||
|
|
((param->pu08IntraDcDeltaRate&0xFF)<<16) |
|
||
|
|
((param->pu08IntraAngleDeltaRate&0xFF)<<24));
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_CUSTOM_MD_PU16, (param->pu16DeltaRate&0xFF) |
|
||
|
|
((param->pu16IntraPlanarDeltaRate&0xFF)<<8) |
|
||
|
|
((param->pu16IntraDcDeltaRate&0xFF)<<16) |
|
||
|
|
((param->pu16IntraAngleDeltaRate&0xFF)<<24));
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_CUSTOM_MD_PU32, (param->pu32DeltaRate&0xFF) |
|
||
|
|
((param->pu32IntraPlanarDeltaRate&0xFF)<<8) |
|
||
|
|
((param->pu32IntraDcDeltaRate&0xFF)<<16) |
|
||
|
|
((param->pu32IntraAngleDeltaRate&0xFF)<<24));
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_CUSTOM_MD_CU08, (param->cu08IntraDeltaRate&0xFF) |
|
||
|
|
((param->cu08InterDeltaRate&0xFF)<<8) |
|
||
|
|
((param->cu08MergeDeltaRate&0xFF)<<16));
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_CUSTOM_MD_CU16, (param->cu16IntraDeltaRate&0xFF) |
|
||
|
|
((param->cu16InterDeltaRate&0xFF)<<8) |
|
||
|
|
((param->cu16MergeDeltaRate&0xFF)<<16));
|
||
|
|
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_CUSTOM_MD_CU32, (param->cu32IntraDeltaRate&0xFF) |
|
||
|
|
((param->cu32InterDeltaRate&0xFF)<<8) |
|
||
|
|
((param->cu32MergeDeltaRate&0xFF)<<16));
|
||
|
|
}
|
||
|
|
|
||
|
|
if (instance->codecMode == W_HEVC_ENC && param->enable_option & ENC_SET_CHANGE_PARAM_CUSTOM_LAMBDA) {
|
||
|
|
VpuWriteReg(coreIdx, W5_CMD_ENC_SEQ_CUSTOM_LAMBDA_ADDR, param->customLambdaAddr);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
Wave5BitIssueCommand(instance, W5_ENC_SET_PARAM);
|
||
|
|
|
||
|
|
|
||
|
|
if (vdi_wait_vpu_busy(coreIdx, __VPU_BUSY_TIMEOUT, W5_VPU_BUSY_STATUS) == -1) {
|
||
|
|
if (instance->loggingEnable)
|
||
|
|
vdi_log(coreIdx, instance->instIndex, W5_ENC_SET_PARAM, 2);
|
||
|
|
return RETCODE_VPU_RESPONSE_TIMEOUT;
|
||
|
|
}
|
||
|
|
|
||
|
|
regVal = VpuReadReg(coreIdx, W5_RET_QUEUE_STATUS);
|
||
|
|
|
||
|
|
pEncInfo->instanceQueueCount = (regVal>>16) & 0xFF;
|
||
|
|
pEncInfo->reportQueueCount = (regVal & 0xFFFF);
|
||
|
|
|
||
|
|
if (VpuReadReg(coreIdx, W5_RET_SUCCESS) == 0) {
|
||
|
|
regVal = VpuReadReg(instance->coreIdx, W5_RET_FAIL_REASON);
|
||
|
|
if (regVal != WAVE5_SYSERR_QUEUEING_FAIL)
|
||
|
|
VLOG(ERR, "FAIL_REASON = 0x%x\n", regVal);
|
||
|
|
|
||
|
|
if (regVal == WAVE5_SYSERR_QUEUEING_FAIL) {
|
||
|
|
regVal = VpuReadReg(instance->coreIdx, W5_RET_QUEUE_FAIL_REASON);
|
||
|
|
VLOG(ERR, "QUEUE_FAIL_REASON = 0x%x\n", regVal);
|
||
|
|
LeaveLock(coreIdx);
|
||
|
|
return RETCODE_QUEUEING_FAILURE;
|
||
|
|
}
|
||
|
|
else if (regVal == WAVE5_SYSERR_ACCESS_VIOLATION_HW) {
|
||
|
|
LeaveLock(coreIdx);
|
||
|
|
return RETCODE_MEMORY_ACCESS_VIOLATION;
|
||
|
|
}
|
||
|
|
else if (regVal == WAVE5_SYSERR_WATCHDOG_TIMEOUT) {
|
||
|
|
LeaveLock(coreIdx);
|
||
|
|
return RETCODE_VPU_RESPONSE_TIMEOUT;
|
||
|
|
}
|
||
|
|
else if (regVal == WAVE5_SYSERR_BUS_ERROR || regVal == WAVE5_SYSERR_DOUBLE_FAULT) {
|
||
|
|
LeaveLock(coreIdx);
|
||
|
|
return RETCODE_VPU_BUS_ERROR;
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
LeaveLock(coreIdx);
|
||
|
|
return RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
LeaveLock(coreIdx);
|
||
|
|
return RETCODE_SUCCESS;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
RetCode Wave5VpuGetSrcBufFlag(CodecInst* instance, Uint32* flag) {
|
||
|
|
|
||
|
|
RetCode ret = RETCODE_SUCCESS;
|
||
|
|
|
||
|
|
ret = SendQuery(instance, GET_SRC_BUF_FLAG);
|
||
|
|
|
||
|
|
if (ret != RETCODE_SUCCESS)
|
||
|
|
return RETCODE_QUERY_FAILURE;
|
||
|
|
|
||
|
|
*flag = VpuReadReg(instance->coreIdx, W5_RET_ENC_SRC_BUF_FLAG);
|
||
|
|
|
||
|
|
|
||
|
|
return RETCODE_SUCCESS;
|
||
|
|
}
|
||
|
|
|
||
|
|
static Uint32 presetGopSize[] = {
|
||
|
|
1, /* Custom GOP, Not used */
|
||
|
|
1, /* All Intra */
|
||
|
|
1, /* IPP Cyclic GOP size 1 */
|
||
|
|
1, /* IBB Cyclic GOP size 1 */
|
||
|
|
2, /* IBP Cyclic GOP size 2 */
|
||
|
|
4, /* IBBBP */
|
||
|
|
4,
|
||
|
|
4,
|
||
|
|
8,
|
||
|
|
1 /* IPP Cyclic GOP size 1, with single reference */
|
||
|
|
};
|
||
|
|
|
||
|
|
RetCode CheckEncCommonParamValid(EncOpenParam* pop)
|
||
|
|
{
|
||
|
|
RetCode ret = RETCODE_SUCCESS;
|
||
|
|
Int32 low_delay = 0;
|
||
|
|
Int32 intra_period_gop_step_size;
|
||
|
|
Int32 i;
|
||
|
|
|
||
|
|
EncWaveParam* param = &pop->EncStdParam.waveParam;
|
||
|
|
|
||
|
|
// check low-delay gop structure
|
||
|
|
if(param->gopPresetIdx == PRESET_IDX_CUSTOM_GOP) // common gop
|
||
|
|
{
|
||
|
|
Int32 minVal = 0;
|
||
|
|
if(param->gopParam.customGopSize > 1)
|
||
|
|
{
|
||
|
|
minVal = param->gopParam.picParam[0].pocOffset;
|
||
|
|
low_delay = 1;
|
||
|
|
for(i = 1; i < param->gopParam.customGopSize; i++)
|
||
|
|
{
|
||
|
|
if(minVal > param->gopParam.picParam[i].pocOffset)
|
||
|
|
{
|
||
|
|
low_delay = 0;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
minVal = param->gopParam.picParam[i].pocOffset;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else if(param->gopPresetIdx == PRESET_IDX_ALL_I ||
|
||
|
|
param->gopPresetIdx == PRESET_IDX_IPP ||
|
||
|
|
param->gopPresetIdx == PRESET_IDX_IBBB ||
|
||
|
|
param->gopPresetIdx == PRESET_IDX_IPPPP ||
|
||
|
|
param->gopPresetIdx == PRESET_IDX_IBBBB ||
|
||
|
|
param->gopPresetIdx == PRESET_IDX_IPP_SINGLE ) // low-delay case (IPPP, IBBB)
|
||
|
|
low_delay = 1;
|
||
|
|
|
||
|
|
if(low_delay) {
|
||
|
|
intra_period_gop_step_size = 1;
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
if (param->gopPresetIdx == PRESET_IDX_CUSTOM_GOP) {
|
||
|
|
intra_period_gop_step_size = param->gopParam.customGopSize;
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
intra_period_gop_step_size = presetGopSize[param->gopPresetIdx];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (pop->bitstreamFormat == STD_HEVC) {
|
||
|
|
if( !low_delay && (param->intraPeriod != 0) && (param->decodingRefreshType != 0) && (intra_period_gop_step_size != 0) &&
|
||
|
|
(param->intraPeriod < intra_period_gop_step_size * 1)) {
|
||
|
|
VLOG(ERR,"CFG FAIL : Not support intra period[%d] for the gop structure\n", param->intraPeriod);
|
||
|
|
VLOG(ERR,"RECOMMEND CONFIG PARAMETER : Intra period >= %d\n", intra_period_gop_step_size * 2);
|
||
|
|
ret = RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else if (pop->bitstreamFormat == STD_SVAC) {
|
||
|
|
if( !low_delay && (param->intraPeriod != 0) && (intra_period_gop_step_size != 0) &&
|
||
|
|
(param->intraPeriod % intra_period_gop_step_size) != 1) {
|
||
|
|
VLOG(ERR,"CFG FAIL : Not support intra period[%d] for the gop structure\n", param->intraPeriod);
|
||
|
|
VLOG(ERR,"RECOMMEND CONFIG PARAMETER : Intra period = %d\n", intra_period_gop_step_size * (param->intraPeriod / intra_period_gop_step_size));
|
||
|
|
ret = RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if( !low_delay && (param->intraPeriod != 0) && (intra_period_gop_step_size != 0) && ((param->intraPeriod % intra_period_gop_step_size) == 1) && param->decodingRefreshType == 0)
|
||
|
|
{
|
||
|
|
VLOG(ERR,"CFG FAIL : Not support decoding refresh type[%d] for closed gop structure\n", param->decodingRefreshType );
|
||
|
|
VLOG(ERR,"RECOMMEND CONFIG PARAMETER : Decoding refresh type = IDR\n");
|
||
|
|
ret = RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (param->gopPresetIdx == PRESET_IDX_CUSTOM_GOP) {
|
||
|
|
for(i = 0; i < param->gopParam.customGopSize; i++)
|
||
|
|
{
|
||
|
|
if (param->gopParam.picParam[i].temporalId >= MAX_NUM_TEMPORAL_LAYER )
|
||
|
|
{
|
||
|
|
VLOG(ERR,"CFG FAIL : temporalId %d exceeds MAX_NUM_TEMPORAL_LAYER\n", param->gopParam.picParam[i].temporalId);
|
||
|
|
VLOG(ERR,"RECOMMEND CONFIG PARAMETER : Adjust temporal ID under MAX_NUM_TEMPORAL_LAYER(7) in GOP structure\n");
|
||
|
|
ret = RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (param->gopParam.picParam[i].temporalId < 0)
|
||
|
|
{
|
||
|
|
VLOG(ERR,"CFG FAIL : Must be %d-th temporal_id >= 0\n",param->gopParam.picParam[i].temporalId);
|
||
|
|
VLOG(ERR,"RECOMMEND CONFIG PARAMETER : Adjust temporal layer above '0' in GOP structure\n");
|
||
|
|
ret = RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// RDO
|
||
|
|
{
|
||
|
|
int align_32_width_flag = pop->picWidth % 32;
|
||
|
|
int align_16_width_flag = pop->picWidth % 16;
|
||
|
|
int align_8_width_flag = pop->picWidth % 8;
|
||
|
|
int align_32_height_flag = pop->picHeight % 32;
|
||
|
|
int align_16_height_flag = pop->picHeight % 16;
|
||
|
|
int align_8_height_flag = pop->picHeight % 8;
|
||
|
|
|
||
|
|
if( ((param->cuSizeMode&0x1) == 0) && ((align_8_width_flag != 0) || (align_8_height_flag != 0)) )
|
||
|
|
{
|
||
|
|
VLOG(ERR,"CFG FAIL : Picture width and height must be aligned with 8 pixels when enable CU8x8 of cuSizeMode \n");
|
||
|
|
VLOG(ERR,"RECOMMEND CONFIG PARAMETER : cuSizeMode |= 0x1 (CU8x8)\n");
|
||
|
|
ret = RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
else if(((param->cuSizeMode&0x1) == 0) && ((param->cuSizeMode&0x2) == 0) && ((align_16_width_flag != 0) || (align_16_height_flag != 0)) )
|
||
|
|
{
|
||
|
|
VLOG(ERR,"CFG FAIL : Picture width and height must be aligned with 16 pixels when enable CU16x16 of cuSizeMode\n");
|
||
|
|
VLOG(ERR,"RECOMMEND CONFIG PARAMETER : cuSizeMode |= 0x2 (CU16x16)\n");
|
||
|
|
ret = RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
else if(((param->cuSizeMode&0x1) == 0) && ((param->cuSizeMode&0x2) == 0) && ((param->cuSizeMode&0x4) == 0) && ((align_32_width_flag != 0) || (align_32_height_flag != 0)) )
|
||
|
|
{
|
||
|
|
VLOG(ERR,"CFG FAIL : Picture width and height must be aligned with 32 pixels when enable CU32x32 of cuSizeMode\n");
|
||
|
|
VLOG(ERR,"RECOMMEND CONFIG PARAMETER : cuSizeMode |= 0x4 (CU32x32)\n");
|
||
|
|
ret = RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Slice
|
||
|
|
{
|
||
|
|
if ( param->wppEnable == 1 && param->independSliceMode == 1) {
|
||
|
|
int num_ctb_in_width = VPU_ALIGN64(pop->picWidth)>>6;
|
||
|
|
if (param->independSliceModeArg % num_ctb_in_width) {
|
||
|
|
VLOG(ERR, "CFG FAIL : If WaveFrontSynchro(WPP) '1', the number of IndeSliceArg(ctb_num) must be multiple of num_ctb_in_width\n");
|
||
|
|
VLOG(ERR, "RECOMMEND CONFIG PARAMETER : IndeSliceArg = num_ctb_in_width * a\n");
|
||
|
|
ret = RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// multi-slice & wpp
|
||
|
|
if(param->wppEnable == 1 && param->dependSliceMode != 0) {
|
||
|
|
VLOG(ERR,"CFG FAIL : If WaveFrontSynchro(WPP) '1', the option of multi-slice must be '0'\n");
|
||
|
|
VLOG(ERR,"RECOMMEND CONFIG PARAMETER : independSliceMode = 0, dependSliceMode = 0\n");
|
||
|
|
ret = RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
|
||
|
|
if(param->independSliceMode == 0 && param->dependSliceMode != 0)
|
||
|
|
{
|
||
|
|
VLOG(ERR,"CFG FAIL : If independSliceMode is '0', dependSliceMode must be '0'\n");
|
||
|
|
VLOG(ERR,"RECOMMEND CONFIG PARAMETER : independSliceMode = 1, independSliceModeArg = TotalCtuNum\n");
|
||
|
|
ret = RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
else if((param->independSliceMode == 1) && (param->dependSliceMode == 1) )
|
||
|
|
{
|
||
|
|
if(param->independSliceModeArg < param->dependSliceModeArg)
|
||
|
|
{
|
||
|
|
VLOG(ERR,"CFG FAIL : If independSliceMode & dependSliceMode is both '1' (multi-slice with ctu count), must be independSliceModeArg >= dependSliceModeArg\n");
|
||
|
|
VLOG(ERR,"RECOMMEND CONFIG PARAMETER : dependSliceMode = 0\n");
|
||
|
|
ret = RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (param->independSliceMode != 0)
|
||
|
|
{
|
||
|
|
if (param->independSliceModeArg > 65535)
|
||
|
|
{
|
||
|
|
VLOG(ERR,"CFG FAIL : If independSliceMode is not 0, must be independSliceModeArg <= 0xFFFF\n");
|
||
|
|
ret = RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (param->dependSliceMode != 0)
|
||
|
|
{
|
||
|
|
if (param->dependSliceModeArg > 65535)
|
||
|
|
{
|
||
|
|
VLOG(ERR,"CFG FAIL : If dependSliceMode is not 0, must be dependSliceModeArg <= 0xFFFF\n");
|
||
|
|
ret = RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (param->confWinTop % 2) {
|
||
|
|
VLOG(ERR, "CFG FAIL : conf_win_top : %d value is not available. The value should be equal to multiple of 2.\n", param->confWinTop);
|
||
|
|
ret = RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (param->confWinBot % 2) {
|
||
|
|
VLOG(ERR, "CFG FAIL : conf_win_bot : %d value is not available. The value should be equal to multiple of 2.\n", param->confWinBot);
|
||
|
|
ret = RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (param->confWinLeft % 2) {
|
||
|
|
VLOG(ERR, "CFG FAIL : conf_win_left : %d value is not available. The value should be equal to multiple of 2.\n", param->confWinLeft);
|
||
|
|
ret = RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (param->confWinRight % 2) {
|
||
|
|
VLOG(ERR, "CFG FAIL : conf_win_right : %d value is not available. The value should be equal to multiple of 2.\n", param->confWinRight);
|
||
|
|
ret = RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
|
||
|
|
// RDO
|
||
|
|
if (param->cuSizeMode == 0) {
|
||
|
|
VLOG(ERR, "CFG FAIL : EnCu8x8, EnCu16x16, and EnCu32x32 must be equal to 1 respectively.\n");
|
||
|
|
ret = RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (param->losslessEnable && (param->nrYEnable || param->nrCbEnable || param->nrCrEnable)) {
|
||
|
|
VLOG(ERR, "CFG FAIL : LosslessCoding and NoiseReduction (EnNrY, EnNrCb, and EnNrCr) cannot be used simultaneously.\n");
|
||
|
|
ret = RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (param->losslessEnable && param->bgDetectEnable) {
|
||
|
|
VLOG(ERR, "CFG FAIL : LosslessCoding and BgDetect cannot be used simultaneously.\n");
|
||
|
|
ret = RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (param->losslessEnable && pop->rcEnable) {
|
||
|
|
VLOG(ERR, "CFG FAIL : osslessCoding and RateControl cannot be used simultaneously.\n");
|
||
|
|
ret = RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (param->losslessEnable && param->roiEnable) {
|
||
|
|
VLOG(ERR, "CFG FAIL : LosslessCoding and Roi cannot be used simultaneously.\n");
|
||
|
|
ret = RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (param->losslessEnable && !param->skipIntraTrans) {
|
||
|
|
VLOG(ERR, "CFG FAIL : IntraTransSkip must be enabled when LosslessCoding is enabled.\n");
|
||
|
|
ret = RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Intra refresh
|
||
|
|
{
|
||
|
|
Int32 num_ctu_row = (pop->picHeight + 64 - 1) / 64;
|
||
|
|
Int32 num_ctu_col = (pop->picWidth + 64 - 1) / 64;
|
||
|
|
|
||
|
|
if(param->intraRefreshMode && param->intraRefreshArg <= 0)
|
||
|
|
{
|
||
|
|
VLOG(ERR, "CFG FAIL : IntraCtuRefreshArg must be greater then 0 when IntraCtuRefreshMode is enabled.\n");
|
||
|
|
ret = RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
if(param->intraRefreshMode == 1 && param->intraRefreshArg > num_ctu_row)
|
||
|
|
{
|
||
|
|
VLOG(ERR, "CFG FAIL : IntraCtuRefreshArg must be less then the number of CTUs in a row when IntraCtuRefreshMode is equal to 1.\n");
|
||
|
|
ret = RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
if(param->intraRefreshMode == 2 && param->intraRefreshArg > num_ctu_col)
|
||
|
|
{
|
||
|
|
VLOG(ERR, "CFG FAIL : IntraCtuRefreshArg must be less then the number of CTUs in a column when IntraCtuRefreshMode is equal to 2.\n");
|
||
|
|
ret = RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
if(param->intraRefreshMode == 3 && param->intraRefreshArg > num_ctu_row*num_ctu_col)
|
||
|
|
{
|
||
|
|
VLOG(ERR, "CFG FAIL : IntraCtuRefreshArg must be less then the number of CTUs in a picture when IntraCtuRefreshMode is equal to 3.\n");
|
||
|
|
ret = RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
if(param->intraRefreshMode == 4 && param->intraRefreshArg > num_ctu_row*num_ctu_col)
|
||
|
|
{
|
||
|
|
VLOG(ERR, "CFG FAIL : IntraCtuRefreshArg must be less then the number of CTUs in a picture when IntraCtuRefreshMode is equal to 4.\n");
|
||
|
|
ret = RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
if(param->intraRefreshMode == 4 && param->losslessEnable)
|
||
|
|
{
|
||
|
|
VLOG(ERR, "CFG FAIL : LosslessCoding and IntraCtuRefreshMode (4) cannot be used simultaneously.\n");
|
||
|
|
ret = RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
if(param->intraRefreshMode == 4 && param->roiEnable)
|
||
|
|
{
|
||
|
|
VLOG(ERR, "CFG FAIL : Roi and IntraCtuRefreshMode (4) cannot be used simultaneously.\n");
|
||
|
|
ret = RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
RetCode CheckEncRcParamValid(EncOpenParam* pop)
|
||
|
|
{
|
||
|
|
RetCode ret = RETCODE_SUCCESS;
|
||
|
|
EncWaveParam* param = &pop->EncStdParam.waveParam;
|
||
|
|
|
||
|
|
if(pop->rcEnable == 1)
|
||
|
|
{
|
||
|
|
if((param->minQpI > param->maxQpI) || (param->minQpP > param->maxQpP) || (param->minQpB > param->maxQpB))
|
||
|
|
{
|
||
|
|
VLOG(ERR,"CFG FAIL : Not allowed MinQP > MaxQP\n");
|
||
|
|
VLOG(ERR,"RECOMMEND CONFIG PARAMETER : MinQP = MaxQP\n");
|
||
|
|
ret = RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
|
||
|
|
if(pop->bitRate <= (int) pop->frameRateInfo)
|
||
|
|
{
|
||
|
|
VLOG(ERR,"CFG FAIL : Not allowed EncBitRate <= FrameRate\n");
|
||
|
|
VLOG(ERR,"RECOMMEND CONFIG PARAMETER : EncBitRate = FrameRate * 10000\n");
|
||
|
|
ret = RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
RetCode CheckEncCustomGopParamValid(EncOpenParam* pop)
|
||
|
|
{
|
||
|
|
RetCode ret = RETCODE_SUCCESS;
|
||
|
|
CustomGopParam* gopParam;
|
||
|
|
CustomGopPicParam* gopPicParam;
|
||
|
|
|
||
|
|
CustomGopPicParam new_gop[MAX_GOP_NUM*2 +1];
|
||
|
|
Int32 curr_poc, i, ei, gi, gop_size;
|
||
|
|
Int32 enc_tid[MAX_GOP_NUM*2 +1];
|
||
|
|
|
||
|
|
gopParam = &(pop->EncStdParam.waveParam.gopParam);
|
||
|
|
gop_size = gopParam->customGopSize;
|
||
|
|
|
||
|
|
new_gop[0].pocOffset = 0;
|
||
|
|
new_gop[0].temporalId = 0;
|
||
|
|
new_gop[0].picType = PIC_TYPE_I;
|
||
|
|
new_gop[0].useMultiRefP = 0;
|
||
|
|
enc_tid[0] = 0;
|
||
|
|
|
||
|
|
for(i = 0; i < gop_size * 2; i++)
|
||
|
|
{
|
||
|
|
ei = i % gop_size;
|
||
|
|
gi = i / gop_size;
|
||
|
|
gopPicParam = &gopParam->picParam[ei];
|
||
|
|
|
||
|
|
curr_poc = gi * gop_size + gopPicParam->pocOffset;
|
||
|
|
new_gop[i + 1].pocOffset = curr_poc;
|
||
|
|
new_gop[i + 1].temporalId = gopPicParam->temporalId;
|
||
|
|
new_gop[i + 1].picType = gopPicParam->picType;
|
||
|
|
new_gop[i + 1].refPocL0 = gopPicParam->refPocL0 + gi * gop_size;
|
||
|
|
new_gop[i + 1].refPocL1 = gopPicParam->refPocL1 + gi * gop_size;
|
||
|
|
new_gop[i + 1].useMultiRefP = gopPicParam->useMultiRefP;
|
||
|
|
enc_tid[i + 1] = -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
for(i = 0; i < gop_size; i++)
|
||
|
|
{
|
||
|
|
gopPicParam = &gopParam->picParam[i];
|
||
|
|
|
||
|
|
if(gopPicParam->pocOffset <= 0)
|
||
|
|
{
|
||
|
|
VLOG(ERR, "CFG FAIL : the POC of the %d-th picture must be greater then -1\n", i+1);
|
||
|
|
ret = RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
if(gopPicParam->pocOffset > gop_size)
|
||
|
|
{
|
||
|
|
VLOG(ERR, "CFG FAIL : the POC of the %d-th picture must be less then GopSize + 1\n", i+1);
|
||
|
|
ret = RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
if(gopPicParam->temporalId < 0)
|
||
|
|
{
|
||
|
|
VLOG(ERR, "CFG FAIL : the temporal_id of the %d-th picture must be greater than -1\n", i+1);
|
||
|
|
ret = RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
for(ei = 1; ei < gop_size * 2 + 1; ei++)
|
||
|
|
{
|
||
|
|
CustomGopPicParam* cur_pic = &new_gop[ei];
|
||
|
|
if(ei <= gop_size)
|
||
|
|
{
|
||
|
|
enc_tid[cur_pic->pocOffset] = cur_pic->temporalId;
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
if(new_gop[ei].picType != PIC_TYPE_I)
|
||
|
|
{
|
||
|
|
Int32 ref_poc = cur_pic->refPocL0;
|
||
|
|
if(enc_tid[ref_poc] < 0) // reference picture is not encoded yet
|
||
|
|
{
|
||
|
|
VLOG(ERR, "CFG FAIL : the 1st reference picture cannot be used as the reference of the picture (POC %d) in encoding order\n", cur_pic->pocOffset - gop_size);
|
||
|
|
ret = RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
if(enc_tid[ref_poc] > cur_pic->temporalId)
|
||
|
|
{
|
||
|
|
VLOG(ERR, "CFG FAIL : the temporal_id of the picture (POC %d) is wrong\n", cur_pic->pocOffset - gop_size);
|
||
|
|
ret = RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
if(ref_poc >= cur_pic->pocOffset)
|
||
|
|
{
|
||
|
|
VLOG(ERR, "CFG FAIL : the POC of the 1st reference picture of %d-th picture is wrong\n", cur_pic->pocOffset - gop_size);
|
||
|
|
ret = RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if(new_gop[ei].picType != PIC_TYPE_P)
|
||
|
|
{
|
||
|
|
Int32 ref_poc = cur_pic->refPocL1;
|
||
|
|
if(enc_tid[ref_poc] < 0) // reference picture is not encoded yet
|
||
|
|
{
|
||
|
|
VLOG(ERR, "CFG FAIL : the 2nd reference picture cannot be used as the reference of the picture (POC %d) in encoding order\n", cur_pic->pocOffset - gop_size);
|
||
|
|
ret = RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
if(enc_tid[ref_poc] > cur_pic->temporalId)
|
||
|
|
{
|
||
|
|
VLOG(ERR, "CFG FAIL : the temporal_id of %d-th picture is wrong\n", cur_pic->pocOffset - gop_size);
|
||
|
|
ret = RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
if(new_gop[ei].picType == PIC_TYPE_P && new_gop[ei].useMultiRefP > 0)
|
||
|
|
{
|
||
|
|
if(ref_poc >= cur_pic->pocOffset)
|
||
|
|
{
|
||
|
|
VLOG(ERR, "CFG FAIL : the POC of the 2nd reference picture of %d-th picture is wrong\n", cur_pic->pocOffset - gop_size);
|
||
|
|
ret = RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else // HOST_PIC_TYPE_B
|
||
|
|
{
|
||
|
|
if(ref_poc == cur_pic->pocOffset)
|
||
|
|
{
|
||
|
|
VLOG(ERR, "CFG FAIL : the POC of the 2nd reference picture of %d-th picture is wrong\n", cur_pic->pocOffset - gop_size);
|
||
|
|
ret = RETCODE_FAILURE;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
curr_poc = cur_pic->pocOffset;
|
||
|
|
enc_tid[curr_poc] = cur_pic->temporalId;
|
||
|
|
}
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
|