diff --git a/vendor/rockchip/common/vpu/lib/libsculptor/arm/libsculptor.so b/vendor/rockchip/common/vpu/lib/libsculptor/arm/libsculptor.so index 1882a4daed9..c794dde92c4 100644 Binary files a/vendor/rockchip/common/vpu/lib/libsculptor/arm/libsculptor.so and b/vendor/rockchip/common/vpu/lib/libsculptor/arm/libsculptor.so differ diff --git a/vendor/rockchip/common/vpu/lib/libsculptor/arm64/libsculptor.so b/vendor/rockchip/common/vpu/lib/libsculptor/arm64/libsculptor.so index 09acd8a5313..808dddb756c 100644 Binary files a/vendor/rockchip/common/vpu/lib/libsculptor/arm64/libsculptor.so and b/vendor/rockchip/common/vpu/lib/libsculptor/arm64/libsculptor.so differ diff --git a/vendor/rockchip/hardware/interfaces/codec2/component/base/C2RKVersion.h b/vendor/rockchip/hardware/interfaces/codec2/component/base/C2RKVersion.h index 69c18fa2334..983a4f69418 100644 --- a/vendor/rockchip/hardware/interfaces/codec2/component/base/C2RKVersion.h +++ b/vendor/rockchip/hardware/interfaces/codec2/component/base/C2RKVersion.h @@ -23,8 +23,8 @@ /* Codec2 Component Verison */ #define C2_MAJOR_VERSION 1 #define C2_MINOR_VERSION 14 -#define C2_REVIS_VERSION 14 -#define C2_BUILD_VERSION 2 +#define C2_REVIS_VERSION 15 +#define C2_BUILD_VERSION 0 #define C2_COMPONENT_FULL_VERSION \ C2_VERSION_STR(C2_MAJOR_VERSION) "." \ diff --git a/vendor/rockchip/hardware/interfaces/codec2/component/osal/C2RKChipCapDef.cpp b/vendor/rockchip/hardware/interfaces/codec2/component/osal/C2RKChipCapDef.cpp index 1548730e827..52462412ff3 100644 --- a/vendor/rockchip/hardware/interfaces/codec2/component/osal/C2RKChipCapDef.cpp +++ b/vendor/rockchip/hardware/interfaces/codec2/component/osal/C2RKChipCapDef.cpp @@ -292,12 +292,19 @@ uint32_t C2RKChipCapDef::getFastModeSupport(MppCodingType codecId) { } int32_t C2RKChipCapDef::getFbcOutputMode(MppCodingType codecId) { - uint32_t fbcMode = 0; + int32_t fbcMode = 0; - for (int i = 0; i < mChipCapInfo->fbcCapNum; i++) { - if (mChipCapInfo->fbcCaps[i].codecId == codecId) { - fbcMode = mChipCapInfo->fbcCaps[i].fbcMode; - break; + if (codecId != MPP_VIDEO_CodingUnused) { + for (int i = 0; i < mChipCapInfo->fbcCapNum; i++) { + if (mChipCapInfo->fbcCaps[i].codecId == codecId) { + fbcMode = mChipCapInfo->fbcCaps[i].fbcMode; + break; + } + } + } else { + // get chip fbc mode cap if coding not specified + if (mChipCapInfo->fbcCaps != nullptr) { + fbcMode = mChipCapInfo->fbcCaps[0].fbcMode; } } diff --git a/vendor/rockchip/hardware/interfaces/codec2/component/osal/C2RKDump.cpp b/vendor/rockchip/hardware/interfaces/codec2/component/osal/C2RKDump.cpp index 03c34e40a35..d564342cbe4 100644 --- a/vendor/rockchip/hardware/interfaces/codec2/component/osal/C2RKDump.cpp +++ b/vendor/rockchip/hardware/interfaces/codec2/component/osal/C2RKDump.cpp @@ -174,12 +174,14 @@ void C2RKDump::recordFile( void C2RKDump::recordFrameTime(int64_t frameIndex) { if (hasDebugFlags(C2_DUMP_FRAME_TIMING)) { + Mutex::Autolock autoLock(mRecordLock); mRecordStartTimes.add(frameIndex, getCurrentTimeMillis()); } } void C2RKDump::showFrameTiming(int64_t frameIndex) { if (hasDebugFlags(C2_DUMP_FRAME_TIMING)) { + Mutex::Autolock autoLock(mRecordLock); ssize_t index = mRecordStartTimes.indexOfKey(frameIndex); if (index != NAME_NOT_FOUND) { int64_t startTime = mRecordStartTimes.valueAt(index); diff --git a/vendor/rockchip/hardware/interfaces/codec2/component/osal/C2RKMediaUtils.cpp b/vendor/rockchip/hardware/interfaces/codec2/component/osal/C2RKMediaUtils.cpp index 77cb6b10207..7be6c97d45d 100644 --- a/vendor/rockchip/hardware/interfaces/codec2/component/osal/C2RKMediaUtils.cpp +++ b/vendor/rockchip/hardware/interfaces/codec2/component/osal/C2RKMediaUtils.cpp @@ -24,13 +24,14 @@ #include "C2RKMediaUtils.h" #include "C2RKDmaBufSync.h" +#include "C2RKChipCapDef.h" #include "C2RKLog.h" using namespace android; typedef struct { int32_t level; - int32_t maxDpbPixs; /* Max dpb picture total pixels */ + int32_t maxDpbPixs; /* Max dpb picture total pixels */ const char *name; } C2LevelInfo; @@ -160,8 +161,13 @@ void dumpFrameInfo(C2FrameInfo &info, const char *tag) { info.width, info.height, info.hstride, info.vstride); } -uint32_t C2RKMediaUtils::getHalPixerFormat(int32_t format, int32_t fbcMode) { - uint32_t androidFormat = HAL_PIXEL_FORMAT_YCrCb_NV12; +int32_t C2RKMediaUtils::getHalPixerFormat(int32_t format) { + int32_t androidFormat = HAL_PIXEL_FORMAT_YCrCb_NV12; + int32_t fbcMode = 0; + + if (MPP_FRAME_FMT_IS_FBC(format)) { + fbcMode = C2RKChipCapDef::get()->getFbcOutputMode(); + } int32_t i = 0; for (i = 0; i < gNumFormatList; i++) { diff --git a/vendor/rockchip/hardware/interfaces/codec2/component/osal/include/C2RKChipCapDef.h b/vendor/rockchip/hardware/interfaces/codec2/component/osal/include/C2RKChipCapDef.h index 092a20bc58a..4e7ab119fd4 100644 --- a/vendor/rockchip/hardware/interfaces/codec2/component/osal/include/C2RKChipCapDef.h +++ b/vendor/rockchip/hardware/interfaces/codec2/component/osal/include/C2RKChipCapDef.h @@ -126,7 +126,7 @@ public: uint32_t getGrallocVersion(); uint32_t getFastModeSupport(MppCodingType codecId); - int32_t getFbcOutputMode(MppCodingType codecId); + int32_t getFbcOutputMode(MppCodingType codecId = MPP_VIDEO_CodingUnused); int32_t getFbcMinStride(int32_t fbcMode); int32_t getFbcOutputOffset(MppCodingType codecId, int32_t *offsetX, int32_t *offsetY); diff --git a/vendor/rockchip/hardware/interfaces/codec2/component/osal/include/C2RKDump.h b/vendor/rockchip/hardware/interfaces/codec2/component/osal/include/C2RKDump.h index d257368a603..99578ea67fa 100644 --- a/vendor/rockchip/hardware/interfaces/codec2/component/osal/include/C2RKDump.h +++ b/vendor/rockchip/hardware/interfaces/codec2/component/osal/include/C2RKDump.h @@ -20,6 +20,7 @@ #include #include #include +#include #include "rk_mpi.h" @@ -67,6 +68,7 @@ private: static int32_t mFlag; /* */ KeyedVector mRecordStartTimes; + Mutex mRecordLock; bool mIsEncoder; diff --git a/vendor/rockchip/hardware/interfaces/codec2/component/osal/include/C2RKMediaUtils.h b/vendor/rockchip/hardware/interfaces/codec2/component/osal/include/C2RKMediaUtils.h index 633768490d9..2e05df92f20 100644 --- a/vendor/rockchip/hardware/interfaces/codec2/component/osal/include/C2RKMediaUtils.h +++ b/vendor/rockchip/hardware/interfaces/codec2/component/osal/include/C2RKMediaUtils.h @@ -81,7 +81,7 @@ typedef struct { class C2RKMediaUtils { public: // get hal pixer format from mpp format - static uint32_t getHalPixerFormat(int32_t format, int32_t fbcMode); + static int32_t getHalPixerFormat(int32_t format); // get hal stride alignment usage if support static uint64_t getStrideUsage(int32_t width, int32_t stride); diff --git a/vendor/rockchip/hardware/interfaces/codec2/component/video/C2RKMpiDec.cpp b/vendor/rockchip/hardware/interfaces/codec2/component/video/C2RKMpiDec.cpp index c1c35ebd4b7..1a0517abbe1 100644 --- a/vendor/rockchip/hardware/interfaces/codec2/component/video/C2RKMpiDec.cpp +++ b/vendor/rockchip/hardware/interfaces/codec2/component/video/C2RKMpiDec.cpp @@ -44,6 +44,8 @@ namespace android { /* max support video resolution */ +constexpr uint64_t kCpuReadWriteUsage = (GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN); + constexpr uint32_t kMaxVideoWidth = 8192; constexpr uint32_t kMaxVideoHeight = 4320; @@ -796,6 +798,8 @@ C2RKMpiDec::C2RKMpiDec( mHeight(0), mHorStride(0), mVerStride(0), + mLeftCorner(0), + mTopCorner(0), mOutputDelay(0), mReduceFactor(0), mGrallocVersion(C2RKChipCapDef::get()->getGrallocVersion()), @@ -807,7 +811,6 @@ C2RKMpiDec::C2RKMpiDec( mSignalledInputEos(false), mOutputEos(false), mSignalledError(false), - mLowLatencyMode(false), mIsGBSource(false), mHdrMetaEnabled(false), mTunneled(false), @@ -979,7 +982,7 @@ void C2RKMpiDec::stopAndReleaseLooper() { } int32_t C2RKMpiDec::getFbcOutputMode(const std::unique_ptr &work) { - uint32_t fbcMode = C2RKChipCapDef::get()->getFbcOutputMode(mCodingType); + int32_t fbcMode = C2RKChipCapDef::get()->getFbcOutputMode(mCodingType); if (!fbcMode || mIsGBSource || mBufferMode) { return 0; @@ -1163,7 +1166,6 @@ c2_status_t C2RKMpiDec::checkUseScaleDown(buffer_handle_t handle) { mScaleInfo.hstride = mpp_frame_get_hor_stride(frame); mScaleInfo.vstride = mpp_frame_get_ver_stride(frame); mScaleInfo.format = mpp_frame_get_fmt(frame); - mFbcCfg.mode = MPP_FRAME_FMT_IS_FBC(mScaleInfo.format); mScaleMode = C2_SCALE_MODE_DOWN_SCALE; c2_info("update down-scaling config: w %d h %d hor %d ver %d fmt %x", mScaleInfo.width, mScaleInfo.height, mScaleInfo.hstride, @@ -1258,16 +1260,16 @@ c2_status_t C2RKMpiDec::configTunneledPlayback(const std::unique_ptr &wo c2_status_t err = C2_OK; TunnelParams params; - params.left = mFbcCfg.mode ? mFbcCfg.paddingX : 0; - params.top = mFbcCfg.mode ? mFbcCfg.paddingY : 0; + params.left = mLeftCorner; + params.top = mTopCorner; params.right = mWidth; params.bottom = mHeight; params.width = mHorStride; params.height = mVerStride; - params.format = C2RKMediaUtils::getHalPixerFormat(mColorFormat, mFbcCfg.mode); + params.format = C2RKMediaUtils::getHalPixerFormat(mColorFormat); params.usage = 0; params.dataSpace = 0; - params.compressMode = mFbcCfg.mode ? 1 : 0; + params.compressMode = MPP_FRAME_FMT_IS_FBC(mColorFormat) ? 1 : 0; if (!mTunneledSession->configure(params)) { c2_err("failed to congigure tunneled session"); @@ -1313,16 +1315,12 @@ c2_status_t C2RKMpiDec::updateDecoderArgs(const std::shared_ptr &po int32_t width = mIntf->getSize_l()->width; int32_t height = mIntf->getSize_l()->height; int32_t pixelFormat = mIntf->getPixelFormat_l()->value; - int32_t lowLatency = mIntf->getIsLowLatencyMode(); int32_t colorFormat = mIntf->getIs10bit() ? MPP_FMT_YUV420SP_10BIT : MPP_FMT_YUV420SP; + bool tunneled = mIntf->getIsTunnelMode(); + bool bufferMode = (pool->getLocalId() <= C2BlockPool::PLATFORM_START); - bool tunneled = mIntf->getIsTunnelMode(); - bool bufferMode = (pool->getLocalId() <= C2BlockPool::PLATFORM_START); - - // needs mpp frame update - needsUpdate = (mWidth != width) || - (mHeight != height) || - ((mColorFormat & MPP_FRAME_FMT_MASK) != colorFormat); + // needs mpp frame update, initial setup in initDecoder() + needsUpdate = (mWidth != width) || (mHeight != height); // av1 support convert to user-set format internally if (mCodingType == MPP_VIDEO_CodingAV1 @@ -1334,15 +1332,15 @@ c2_status_t C2RKMpiDec::updateDecoderArgs(const std::shared_ptr &po // without stride since they don't want to deal with crop. if (mIntf->getOutputCropEnable()) { c2_info("got request for output crop"); - if (!bufferMode) - bufferMode = true; + bufferMode = true; } - // p010 is different with decoding output compact 10bit, so reset to - // output buffer mode and do one more extry copy to format p010. - if (!bufferMode && colorFormat == MPP_FMT_YUV420SP_10BIT) { + // since P010 format is different from the decoder's compact 10-bit output + // format, switch to output buffer mode and do an extra copy operation to + // convert to P010 format. + if (colorFormat == MPP_FMT_YUV420SP_10BIT) { if (pixelFormat == HAL_PIXEL_FORMAT_YCBCR_P010) { - c2_warn("got p010 format request, use output buffer mode."); + c2_info("got p010 format request, use output buffer mode"); bufferMode = true; } if (width * height <= 176 * 144) { @@ -1354,18 +1352,19 @@ c2_status_t C2RKMpiDec::updateDecoderArgs(const std::shared_ptr &po mBlockPool = pool; mWidth = width; mHeight = height; - mTunneled = tunneled; mPixelFormat = pixelFormat; - mColorFormat = (MppFrameFormat)colorFormat; - mLowLatencyMode = lowLatency; + mTunneled = tunneled; + mColorFormat = (mStarted) ? mColorFormat : (MppFrameFormat)colorFormat; } - int32_t fbcMode = getFbcOutputMode(); - needsUpdate |= (mFbcCfg.mode != fbcMode); - if (needsUpdate) { - err = updateMppFrameInfo(fbcMode); + err = updateMppFrameInfo(getFbcOutputMode()); + if (err == C2_OK) { + mUseRgaBlit = true; + mAllocParams.needUpdate = true; + } } + return err; } @@ -1377,13 +1376,13 @@ c2_status_t C2RKMpiDec::updateMppFrameInfo(int32_t fbcMode) { MPP_RET err = MPP_OK; MppFrame frame = nullptr; int32_t format = mColorFormat; - int32_t paddingX = 0, paddingY = 0; + int32_t leftCorner = 0, topCorner = 0; if (fbcMode) { format |= MPP_FRAME_FBC_AFBC_V2; /* fbc decode output has padding inside, set crop before display */ - C2RKChipCapDef::get()->getFbcOutputOffset(mCodingType, &paddingX, &paddingY); - c2_info("use mpp fbc output mode, padding offset(%d, %d)", paddingX, paddingY); + C2RKChipCapDef::get()->getFbcOutputOffset(mCodingType, &leftCorner, &topCorner); + c2_info("use mpp fbc output mode, padding offset(%d, %d)", leftCorner, topCorner); } else { format &= ~MPP_FRAME_FBC_AFBC_V2; } @@ -1405,12 +1404,11 @@ c2_status_t C2RKMpiDec::updateMppFrameInfo(int32_t fbcMode) { mHorStride = mpp_frame_get_hor_stride(frame); mVerStride = mpp_frame_get_ver_stride(frame); mColorFormat = mpp_frame_get_fmt(frame); - - mFbcCfg.mode = fbcMode; - mFbcCfg.paddingX = paddingX; - mFbcCfg.paddingY = paddingY; + mLeftCorner = leftCorner; + mTopCorner = topCorner; mpp_frame_deinit(&frame); + return C2_OK; } @@ -1442,13 +1440,13 @@ c2_status_t C2RKMpiDec::initDecoder(const std::unique_ptr &work) { uint32_t fastPlay = 2; // 0: disable, 1: enable, 2: enable_once mMppMpi->control(mMppCtx, MPP_DEC_SET_ENABLE_FAST_PLAY, &fastPlay); - if (mLowLatencyMode) { + IntfImpl::Lock lock = mIntf->lock(); + if (mIntf->getIsLowLatencyMode()) { uint32_t fastOut = 1; mMppMpi->control(mMppCtx, MPP_DEC_SET_IMMEDIATE_OUT, &fastOut); c2_info("enable lowLatency, enable mpp fast-out mode"); } - IntfImpl::Lock lock = mIntf->lock(); if (mIntf->getIsDisableDpbCheck()) { uint32_t disableCheck = 1; mMppMpi->control(mMppCtx, MPP_DEC_SET_DISABLE_DPB_CHECK, &disableCheck); @@ -1578,8 +1576,8 @@ void C2RKMpiDec::finishWork(OutWorkEntry entry) { } if (outblock) { - uint32_t left = mFbcCfg.mode ? mFbcCfg.paddingX : 0; - uint32_t top = mFbcCfg.mode ? mFbcCfg.paddingY : 0; + uint32_t left = mLeftCorner; + uint32_t top = mTopCorner; c2Buffer = createGraphicBuffer( std::move(outblock), C2Rect(mWidth, mHeight).at(left, top)); @@ -1707,7 +1705,6 @@ void C2RKMpiDec::process( // scene ddr frequency control setMppPerformance(true); - mAllocParams.needUpdate = true; mStarted = true; } @@ -1831,7 +1828,8 @@ void C2RKMpiDec::setDefaultCodecColorAspectsIfNeeded(ColorAspects &aspects) { aspects.mMatrixCoeffs = CA::MatrixUnspecified; } } - } else if (aspects.mPrimaries == CA::PrimariesBT601_6_625) { + } else if (aspects.mPrimaries == CA::PrimariesBT601_6_625 || + aspects.mPrimaries == CA::PrimariesBT601_6_525) { // unadjusted standard is not allowed, update aspect to avoid get unsupport // StandardBT601_625_Unadjusted and StandardBT601_525_Unadjusted. if (aspects.mMatrixCoeffs == CA::MatrixBT709_5 || @@ -1895,33 +1893,13 @@ void C2RKMpiDec::getVuiParams(MppFrame frame) { } c2_status_t C2RKMpiDec::updateFbcModeIfNeeded() { - c2_status_t err = C2_OK; - bool needsUpdate = false; - uint32_t fbcMode = getFbcOutputMode(); - - if (!MPP_FRAME_FMT_IS_FBC(mColorFormat)) { - if (fbcMode) { - needsUpdate = true; - c2_info("change use mpp fbc output mode"); - } - } else { - if (!fbcMode) { - needsUpdate = true; - c2_info("change use mpp non-fbc output mode"); - } - } - - if (needsUpdate) { - err = updateMppFrameInfo(fbcMode); - } + c2_status_t err = C2_OK; + bool nowIsFbcMode = MPP_FRAME_FMT_IS_FBC(mColorFormat); + bool dstIsFbcMode = (getFbcOutputMode() != 0); - if (err != C2_OK || !needsUpdate) { - mFbcCfg.mode = MPP_FRAME_FMT_IS_FBC(mColorFormat); - if (mFbcCfg.mode) { - /* fbc decode output has padding inside, set crop before display */ - C2RKChipCapDef::get()->getFbcOutputOffset( - mCodingType, &mFbcCfg.paddingX, &mFbcCfg.paddingY); - } + if (nowIsFbcMode != dstIsFbcMode) { + c2_info("update use mpp %s output mode", dstIsFbcMode ? "fbc" : "non-fbc"); + err = updateMppFrameInfo(dstIsFbcMode); } return err; @@ -1932,40 +1910,40 @@ c2_status_t C2RKMpiDec::updateAllocParamsIfNeeded(AllocParams *params) { return C2_OK; } - int32_t allocW = 0, allocH = 0, allocFmt = 0; - int64_t allocUsage = RK_GRALLOC_USAGE_SPECIFY_STRIDE; + int32_t allocWidth = 0, allocHeight = 0, allocFormat = 0; + int64_t allocUsage = RK_GRALLOC_USAGE_SPECIFY_STRIDE; - int32_t videoW = mWidth; - int32_t videoH = mHeight; - int32_t frameW = mHorStride; - int32_t frameH = mVerStride; - int32_t mppFormat = mColorFormat; + int32_t videoWidth = mWidth; + int32_t videoHeight = mHeight; + int32_t frameWidth = mHorStride; + int32_t frameHeight = mVerStride; + int32_t colorFormat = mColorFormat; if (mScaleMode == C2_SCALE_MODE_DOWN_SCALE) { // update scale thumbnail info in down scale mode - videoW = mScaleInfo.width; - videoH = mScaleInfo.height; - frameW = mScaleInfo.hstride; - frameH = mScaleInfo.vstride; - mppFormat = mScaleInfo.format; + videoWidth = mScaleInfo.width; + videoHeight = mScaleInfo.height; + frameWidth = mScaleInfo.hstride; + frameHeight = mScaleInfo.vstride; + colorFormat = mScaleInfo.format; } - allocW = frameW; - allocH = frameH; - allocFmt = C2RKMediaUtils::getHalPixerFormat(mppFormat, mFbcCfg.mode); + allocWidth = frameWidth; + allocHeight = frameHeight; + allocFormat = C2RKMediaUtils::getHalPixerFormat(colorFormat); - if (mFbcCfg.mode) { + if (MPP_FRAME_FMT_IS_FBC(colorFormat)) { // NOTE: FBC case may have offset y on top and vertical stride // should aligned to 16. - allocH = C2_ALIGN(frameH + mFbcCfg.paddingY, 16); + allocHeight = C2_ALIGN(frameHeight + mTopCorner, 16); // In fbc 10bit mode, surfaceCB treat width as pixel stride. - if (allocFmt == HAL_PIXEL_FORMAT_YUV420_10BIT_I || - allocFmt == HAL_PIXEL_FORMAT_Y210 || - allocFmt == HAL_PIXEL_FORMAT_YUV420_10BIT_RFBC || - allocFmt == HAL_PIXEL_FORMAT_YUV422_10BIT_RFBC || - allocFmt == HAL_PIXEL_FORMAT_YUV444_10BIT_RFBC) { - allocW = C2_ALIGN(videoW, 64); + if (allocFormat == HAL_PIXEL_FORMAT_YUV420_10BIT_I || + allocFormat == HAL_PIXEL_FORMAT_Y210 || + allocFormat == HAL_PIXEL_FORMAT_YUV420_10BIT_RFBC || + allocFormat == HAL_PIXEL_FORMAT_YUV422_10BIT_RFBC || + allocFormat == HAL_PIXEL_FORMAT_YUV444_10BIT_RFBC) { + allocWidth = C2_ALIGN(videoWidth, 64); } } else { // NOTE: private gralloc stride usage only support in 4.0. @@ -1974,22 +1952,22 @@ c2_status_t C2RKMpiDec::updateAllocParamsIfNeeded(AllocParams *params) { uint64_t horUsage = 0, verUsage = 0; // 10bit video calculate stride base on (width * 10 / 8) - if (MPP_FRAME_FMT_IS_YUV_10BIT(mppFormat)) { - horUsage = C2RKMediaUtils::getStrideUsage(videoW * 10 / 8, frameW); + if (MPP_FRAME_FMT_IS_YUV_10BIT(colorFormat)) { + horUsage = C2RKMediaUtils::getStrideUsage(videoWidth * 10 / 8, frameWidth); } else { - horUsage = C2RKMediaUtils::getStrideUsage(videoW, frameW); + horUsage = C2RKMediaUtils::getStrideUsage(videoWidth, frameWidth); } - verUsage = C2RKMediaUtils::getHStrideUsage(videoH, frameH); + verUsage = C2RKMediaUtils::getHStrideUsage(videoHeight, frameHeight); if (horUsage > 0 && verUsage > 0) { - allocW = videoW; - allocH = videoH; + allocWidth = videoWidth; + allocHeight = videoHeight; allocUsage &= ~RK_GRALLOC_USAGE_SPECIFY_STRIDE; allocUsage |= (horUsage | verUsage); c2_info("update use stride usage 0x%llx", allocUsage); } } else if (mCodingType == MPP_VIDEO_CodingVP9 && mGrallocVersion < 4) { - allocW = C2_ALIGN_ODD(videoW, 256); + allocWidth = C2_ALIGN_ODD(videoWidth, 256); } } @@ -2041,7 +2019,7 @@ c2_status_t C2RKMpiDec::updateAllocParamsIfNeeded(AllocParams *params) { // required for SurfaceFlinger_NV12-10bit to 16bit conversion if (C2RKChipCapDef::get()->getChipType() == RK_CHIP_3399 || C2RKChipCapDef::get()->getChipType() == RK_CHIP_3288) { - allocUsage |= GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN; + allocUsage |= kCpuReadWriteUsage; } // For rk356x, RGA rotation and scaling maybe used for render, so @@ -2051,10 +2029,10 @@ c2_status_t C2RKMpiDec::updateAllocParamsIfNeeded(AllocParams *params) { } } - params->width = allocW; - params->height = allocH; + params->width = allocWidth; + params->height = allocHeight; params->usage = allocUsage; - params->format = allocFmt; + params->format = allocFormat; params->needUpdate = false; return C2_OK; @@ -2187,10 +2165,10 @@ c2_status_t C2RKMpiDec::ensureDecoderState() { int32_t bWidth = C2_ALIGN(mWidth, 2); int32_t bHeight = C2_ALIGN(mHeight, 2); int32_t bFormat = (MPP_FRAME_FMT_IS_YUV_10BIT(mColorFormat)) ? mPixelFormat : format; - int64_t bUsage = (GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN); + int64_t bUsage = kCpuReadWriteUsage; // use cachable memory for higher cpu-copy performance - usage |= (GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN); + usage |= kCpuReadWriteUsage; // allocate buffer within 4G to avoid rga2 error. if (C2RKChipCapDef::get()->getChipType() == RK_CHIP_3588 || @@ -2485,9 +2463,11 @@ c2_status_t C2RKMpiDec::getoutframe(OutWorkEntry *entry) { int32_t dstFd = c2Handle->data[0]; int32_t srcFmt = MPP_FRAME_FMT_IS_YUV_10BIT(format) ? - HAL_PIXEL_FORMAT_YCrCb_NV12_10 : HAL_PIXEL_FORMAT_YCrCb_NV12; + HAL_PIXEL_FORMAT_YCrCb_NV12_10 : + HAL_PIXEL_FORMAT_YCrCb_NV12; int32_t dstFmt = mPixelFormat == HAL_PIXEL_FORMAT_YCBCR_P010 ? - HAL_PIXEL_FORMAT_YCBCR_P010 : HAL_PIXEL_FORMAT_YCrCb_NV12; + HAL_PIXEL_FORMAT_YCBCR_P010 : + HAL_PIXEL_FORMAT_YCrCb_NV12; C2GraphicView dstView = mOutBlock->map().get(); if (dstView.error()) { @@ -2503,9 +2483,11 @@ c2_status_t C2RKMpiDec::getoutframe(OutWorkEntry *entry) { RgaInfo srcInfo, dstInfo; C2RKRgaDef::SetRgaInfo( - &srcInfo, srcFd, srcFmt,width, height, hstride, vstride); + &srcInfo, srcFd, srcFmt, + width, height, hstride, vstride); C2RKRgaDef::SetRgaInfo( - &dstInfo, dstFd, dstFmt, width, height, dstStride, dstVStride); + &dstInfo, dstFd, dstFmt, + width, height, dstStride, dstVStride); if (!C2RKRgaDef::DoBlit(srcInfo, dstInfo)) { mUseRgaBlit = false; c2_warn("failed RGA blit, fallback software copy"); diff --git a/vendor/rockchip/hardware/interfaces/codec2/component/video/C2RKMpiDec.h b/vendor/rockchip/hardware/interfaces/codec2/component/video/C2RKMpiDec.h index 09da51b155e..5c3a73a1dfa 100644 --- a/vendor/rockchip/hardware/interfaces/codec2/component/video/C2RKMpiDec.h +++ b/vendor/rockchip/hardware/interfaces/codec2/component/video/C2RKMpiDec.h @@ -150,6 +150,9 @@ private: int32_t mHeight; int32_t mHorStride; int32_t mVerStride; + // fbc output has padding inside, set crop before display + int32_t mLeftCorner; + int32_t mTopCorner; int32_t mOutputDelay; // reduce factor for low memory mode int32_t mReduceFactor; @@ -163,7 +166,6 @@ private: bool mSignalledInputEos; bool mOutputEos; bool mSignalledError; - bool mLowLatencyMode; bool mIsGBSource; bool mHdrMetaEnabled; bool mTunneled; @@ -183,13 +185,6 @@ private: int32_t format; } mAllocParams; - struct FbcConfig { - int32_t mode; - // fbc decode output padding - int32_t paddingX; - int32_t paddingY; - } mFbcCfg; - struct ScaleThumbInfo { int32_t width; int32_t height; diff --git a/vendor/rockchip/hardware/interfaces/codec2/component/video/C2RKMpiEnc.cpp b/vendor/rockchip/hardware/interfaces/codec2/component/video/C2RKMpiEnc.cpp index cebe1a32df7..a2d1041f745 100644 --- a/vendor/rockchip/hardware/interfaces/codec2/component/video/C2RKMpiEnc.cpp +++ b/vendor/rockchip/hardware/interfaces/codec2/component/video/C2RKMpiEnc.cpp @@ -1454,9 +1454,14 @@ c2_status_t C2RKMpiEnc::setupBaseCodec() { mpp_enc_cfg_set_s32(mEncCfg, "prep:width", mSize->width); mpp_enc_cfg_set_s32(mEncCfg, "prep:height", mSize->height); - mpp_enc_cfg_set_s32(mEncCfg, "prep:hor_stride", mHorStride); mpp_enc_cfg_set_s32(mEncCfg, "prep:ver_stride", mVerStride); - mpp_enc_cfg_set_s32(mEncCfg, "prep:format", MPP_FMT_YUV420SP); + mpp_enc_cfg_set_s32(mEncCfg, "prep:format", mInputMppFmt); + + if (mInputMppFmt == MPP_FMT_RGBA8888) { + mpp_enc_cfg_set_s32(mEncCfg, "prep:hor_stride", mHorStride * 4); + } else { + mpp_enc_cfg_set_s32(mEncCfg, "prep:hor_stride", mHorStride); + } return C2_OK; } @@ -1472,17 +1477,9 @@ c2_status_t C2RKMpiEnc::setupInputScalar() { mSize->width, mSize->height, c2Scalar->width, c2Scalar->height); mSize->width = c2Scalar->width; mSize->height = c2Scalar->height; - mHorStride = C2_ALIGN(mSize->width, 16); - if (mCodingType == MPP_VIDEO_CodingVP8) { - mVerStride = C2_ALIGN(mSize->height, 16); - } else { - mVerStride = C2_ALIGN(mSize->height, 8); - } - mpp_enc_cfg_set_s32(mEncCfg, "prep:width", mSize->width); - mpp_enc_cfg_set_s32(mEncCfg, "prep:height", mSize->height); - mpp_enc_cfg_set_s32(mEncCfg, "prep:hor_stride", mHorStride); - mpp_enc_cfg_set_s32(mEncCfg, "prep:ver_stride", mVerStride); + // set encoder to new size config + setupBaseCodec(); mInputScalar = true; } @@ -2098,6 +2095,8 @@ c2_status_t C2RKMpiEnc::setupTemporalLayers() { } c2_status_t C2RKMpiEnc::setupPrependHeaderSetting() { + MPP_RET err = MPP_OK; + MppEncHeaderMode mode = MPP_ENC_HEADER_MODE_DEFAULT; std::shared_ptr prepend; IntfImpl::Lock lock = mIntf->lock(); @@ -2106,12 +2105,16 @@ c2_status_t C2RKMpiEnc::setupPrependHeaderSetting() { if (prepend->value == C2Config::PREPEND_HEADER_TO_ALL_SYNC) { c2_info("setupPrependHeaderSetting: prepend sps pps to idr frames."); - MppEncHeaderMode mode = MPP_ENC_HEADER_MODE_EACH_IDR; - MPP_RET err = mMppMpi->control(mMppCtx, MPP_ENC_SET_HEADER_MODE, &mode); - if (err != MPP_OK) { - c2_err("setupPrependHeaderSetting: failed to set mode, err %d", err); - return C2_CORRUPTED; - } + mode = MPP_ENC_HEADER_MODE_EACH_IDR; + } + + err = mMppMpi->control(mMppCtx, MPP_ENC_SET_HEADER_MODE, &mode); + if (err != MPP_OK) { + c2_err("setupPrependHeaderSetting: failed to set mode, err %d", err); + return C2_CORRUPTED; + } else if (mode == MPP_ENC_HEADER_MODE_EACH_IDR) { + // disable csd to avoid duplicated sps/pps in stream header + mSpsPpsHeaderReceived = true; } return C2_OK; @@ -2330,8 +2333,10 @@ c2_status_t C2RKMpiEnc::setupMlvecIfNeeded() { mCurLayerCount = layerCount; } - // mlvec need pic_order_cnt_type equal to 2 - mpp_enc_cfg_set_s32(mEncCfg, "h264:poc_type", 2); + if (mCodingType == MPP_VIDEO_CodingAVC) { + // mlvec need pic_order_cnt_type equal to 2 + mpp_enc_cfg_set_s32(mEncCfg, "h264:poc_type", 2); + } } return C2_OK; @@ -2409,6 +2414,10 @@ c2_status_t C2RKMpiEnc::setupEncCfg() { c2_info("disable sei info output"); seiMode = MPP_ENC_SEI_MODE_DISABLE; } + // FIXME: MLVEC not support HEVC SEI parser currently + if (mMlvec && mCodingType == MPP_VIDEO_CodingHEVC) { + seiMode = MPP_ENC_SEI_MODE_DISABLE; + } mMppMpi->control(mMppCtx, MPP_ENC_SET_SEI_CFG, &seiMode); } @@ -2429,14 +2438,15 @@ c2_status_t C2RKMpiEnc::initEncoder() { } /* - * NOTE: We need temporary buffer to store rga nv12 output for some rgba input, - * since mpp can't process rgba input properly. in addition to this, alloc buffer - * within 4G in view of rga efficiency. + * NOTE: A temporary buffer is required to store the RGA NV12 output + * when processing specific RGBA input formats, because MPP lacks proper + * support for RGBA input handling. + * Furthermore, the buffer is allocated within the 4GB address space to + * maximize RGA hardware acceleration efficiency and ensure DMA compatibility. */ - buffer_handle_t bufferHandle; uint32_t stride = 0; - uint64_t usage = (GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN); + buffer_handle_t bufferHandle; // allocate buffer within 4G to avoid rga2 error. if (mChipType == RK_CHIP_3588 || mChipType == RK_CHIP_356X) { @@ -2474,6 +2484,16 @@ c2_status_t C2RKMpiEnc::initEncoder() { c2_err("failed to set output timeout %d, err %d", timeout, err); goto error; } + // Enable non-blocking input mode under asynchronous operation, so as + // to activate dual-core encoding. + if (mHandler) { + timeout = MPP_POLL_NON_BLOCK; + err = mMppMpi->control(mMppCtx, MPP_SET_INPUT_TIMEOUT, &timeout); + if (err != MPP_OK) { + c2_err("failed to set input timeout %d, err %d", timeout, err); + goto error; + } + } } err = mpp_init(mMppCtx, MPP_CTX_ENC, mCodingType); @@ -2560,14 +2580,25 @@ void C2RKMpiEnc::finishWork( // copy mpp output to c2 output memcpy(wView.data(), data, len); - RK_S32 isIntra = 0; std::shared_ptr buffer = createLinearBuffer(block, 0, len); MppMeta meta = mpp_packet_get_meta(packet); - mpp_meta_get_s32(meta, KEY_OUTPUT_INTRA, &isIntra); - if (isIntra) { - c2_info("IDR frame produced"); - buffer->setInfo(std::make_shared( - 0u /* stream id */, C2Config::SYNC_FRAME)); + if (meta != nullptr) { + int32_t isIntra = 0; + MppFrame frame = nullptr; + + mpp_meta_get_s32(meta, KEY_OUTPUT_INTRA, &isIntra); + if (isIntra) { + c2_info("IDR frame produced"); + buffer->setInfo(std::make_shared( + 0u /* stream id */, C2Config::SYNC_FRAME)); + } + + mpp_meta_get_frame(meta, KEY_INPUT_FRAME, &frame); + if (frame != nullptr) { + mpp_frame_deinit(&frame); + } else if (mHandler) { + ALOGW("unexpected null frame pointer"); + } } mpp_packet_deinit(&packet); @@ -2945,7 +2976,7 @@ c2_status_t C2RKMpiEnc::handleRoiRegionRequest( MppMeta meta, Vector regions) { if (regions.size() == 0) return C2_OK; - if (!mRoiCtx) { + if (mRoiCtx == nullptr) { if (mpp_enc_roi_init(&mRoiCtx, mSize->width, mSize->height, mCodingType)) { c2_err("failed to init roi context"); return C2_CORRUPTED; @@ -2955,12 +2986,12 @@ c2_status_t C2RKMpiEnc::handleRoiRegionRequest( for (int i = 0; i < regions.size(); i++) { RoiRegionCfg *region = ®ions.editItemAt(i); - if (region->x > mSize->width || region->y > mSize->height || - region->w > mSize->width || region->h > mSize->height || + if ((region->x > mSize->width) || (region->y > mSize->height) || + (region->w > mSize->width) || (region->h > mSize->height) || (region->x + region->w) > mSize->width || (region->y + region->h) > mSize->height) { - c2_err("size limit [%d,%d] qpVal in range 1~51", mSize->width, mSize->height); - c2_err("got invalid roi region, rect [%d,%d,%d,%d] intra %d mode %d qp %d", + c2_err("please check user roi settings, size [%d,%d]", mSize->width, mSize->height); + c2_err("current rect [%d,%d,%d,%d] intra %d mode %d qp %d", region->x, region->y, region->w, region->h, region->force_intra, region->qp_mode, region->qp_val); } else { @@ -3011,31 +3042,29 @@ c2_status_t C2RKMpiEnc::onDetectResultReady(ImageBuffer *srcImage, void *result) c2_status_t C2RKMpiEnc::handleRknnDetection( const std::unique_ptr &work, MyDmaBuffer_t dbuffer) { - if (!mRknnSession) return C2_CORRUPTED; - - // ignore empty input buffer - if (dbuffer.fd <= 0) return C2_CORRUPTED; + if (!mRknnSession || dbuffer.fd <= 0) { + return C2_CORRUPTED; + } - uint32_t flags = work->input.flags; + int32_t flags = work->input.flags; uint64_t frameIndex = work->input.ordinal.frameIndex.peekull(); - - ImageBuffer srcImage; - memset(&srcImage, 0, sizeof(ImageBuffer)); - - srcImage.width = mSize->width; - srcImage.height = mSize->height; - srcImage.hstride = mHorStride; - srcImage.vstride = mVerStride; - srcImage.fd = dbuffer.fd; - srcImage.size = dbuffer.size; - srcImage.pts = frameIndex; - srcImage.flags = flags; - - if (mInputMppFmt == MPP_FMT_RGBA8888) { - srcImage.format = IMAGE_FORMAT_RGBA8888; - } else { - srcImage.format = IMAGE_FORMAT_YUV420SP_NV12; - } + ImageFormat format = IMAGE_FORMAT_RGBA8888; + if (mInputMppFmt != MPP_FMT_RGBA8888) { + format = IMAGE_FORMAT_YUV420SP_NV12; + } + + ImageBuffer srcImage { + .fd = dbuffer.fd, + .size = dbuffer.size, + .virAddr = nullptr, + .width = static_cast(mSize->width), + .height = static_cast(mSize->height), + .hstride = mHorStride, + .vstride = mVerStride, + .flags = flags, + .pts = frameIndex, + .format = format + }; if (!mRknnSession->startDetect(&srcImage)) { c2_err("failed to start detection"); @@ -3240,6 +3269,7 @@ c2_status_t C2RKMpiEnc::getInBufferFromWork( mVerStride = height; configChanged = true; } + outBuffer->fd = fd; outBuffer->size = mHorStride * mVerStride * 3 / 2; } else { @@ -3290,6 +3320,9 @@ c2_status_t C2RKMpiEnc::sendframe( MPP_RET err = MPP_OK; MppFrame frame = nullptr; MppMeta meta = nullptr; + uint32_t retry = 0; + + static uint32_t kMaxRetryCnt = 1000; mpp_frame_init(&frame); @@ -3300,8 +3333,6 @@ c2_status_t C2RKMpiEnc::sendframe( mpp_frame_set_eos(frame, 1); } - c2_trace("send frame fd %d size %d pts %lld", dBuffer.fd, dBuffer.size, pts); - if (dBuffer.fd > 0) { MppBuffer buffer = nullptr; MppBufferInfo commit; @@ -3309,7 +3340,7 @@ c2_status_t C2RKMpiEnc::sendframe( memset(&commit, 0, sizeof(commit)); commit.type = MPP_BUFFER_TYPE_ION; - commit.fd = dBuffer.fd; + commit.fd = dBuffer.fd; commit.size = dBuffer.size; err = mpp_buffer_import(&buffer, &commit); @@ -3364,15 +3395,6 @@ c2_status_t C2RKMpiEnc::sendframe( /* set npu detection maps */ if (dBuffer.npuMaps) { - /* - * rknn detect session with two types of output: - * - * 1. proto mask, it requires a period of post-processing, but with more - * precise rate control, the sesk mask is process by mpp encoder. - * 2. roi rect arrays, task less time and the quality of ROI regions - * is controlled outside. We enhance quality by reduce relative QP of - * ROI regions. it is a relatively rough control. - */ if (mRknnSession->isMaskResultType()) { err = mpp_meta_set_ptr(meta, KEY_NPU_OBJ_FLAG, dBuffer.npuMaps); if (err != MPP_OK) { @@ -3385,34 +3407,41 @@ c2_status_t C2RKMpiEnc::sendframe( int regionCount = std::clamp(dRegions->count, 0, MPP_MAX_ROI_REGION_COUNT); for (int i = 0; i < regionCount; i++) { - RoiRegionCfg region; - region.x = (dRegions->rects[i].left) & (~0x01); - region.y = (dRegions->rects[i].top) & (~0x01); - region.w = (dRegions->rects[i].right - dRegions->rects[i].left) & (~0x01); - region.h = (dRegions->rects[i].bottom - dRegions->rects[i].top) & (~0x01); - region.force_intra = 0; - region.qp_mode = 0; - region.qp_val = -10; - + RoiRegionCfg region { + .x = (dRegions->rects[i].left) & (~0x01), + .y = (dRegions->rects[i].top) & (~0x01), + .w = (dRegions->rects[i].right - dRegions->rects[i].left) & (~0x01), + .h = (dRegions->rects[i].bottom - dRegions->rects[i].top) & (~0x01), + .force_intra = 0, + .qp_mode = 0, + .qp_val = -10 + }; regions.push(region); } handleRoiRegionRequest(meta, regions); } } - err = mMppMpi->encode_put_frame(mMppCtx, frame); - if (err != MPP_OK) { - ret = C2_NOT_FOUND; - goto error; - } + while (true) { + MPP_RET err = mMppMpi->encode_put_frame(mMppCtx, frame); + if (err == MPP_OK) { + c2_trace("send frame fd %d size %d pts %lld", dBuffer.fd, dBuffer.size, pts); + /* dump show input process fps if neccessary */ + mDump->showDebugFps(ROLE_INPUT); + mInputCount++; + break; + } - /* dump show input process fps if neccessary */ - mDump->showDebugFps(ROLE_INPUT); + if (mSignalledError || ((++retry) > kMaxRetryCnt)) { + ret = C2_CORRUPTED; + goto error; + } - mInputCount++; + usleep(3 * 1000); + } error: - if (frame) { + if (!mHandler && frame) { mpp_frame_deinit(&frame); }