luckfox-pico-sdk/media/samples/example/common/sample_comm_venc.c
luckfox-eng29 8f34c2760d project:build.sh: Added fastboot support; custom modifications to U-Boot and kernel implemented using patches.
project:cfg:BoardConfig_IPC: Added fastboot BoardConfig file and firmware post-scripts, distinguishing between
the BoardConfigs for Luckfox Pico Pro and Luckfox Pico Max. project:app: Added fastboot_client and rk_smart_door
for quick boot applications; updated rkipc app to adapt to the latest media library. media:samples: Added more
usage examples. media:rockit: Fixed bugs; removed support for retrieving data frames from VPSS. media:isp:
Updated rkaiq library and related tools to support connection to RKISP_Tuner. sysdrv:Makefile: Added support for
compiling drv_ko on Luckfox Pico Ultra W using Ubuntu; added support for custom root filesystem.
sysdrv:tools:board: Updated Buildroot optional mirror sources, updated some software versions, and stored device
tree files and configuration files that undergo multiple modifications for U-Boot and kernel separately.
sysdrv:source:mcu: Used RISC-V MCU SDK with RT-Thread system, mainly for initializing camera AE during quick
boot. sysdrv:source:uboot: Added support for fastboot; added high baud rate DDR bin for serial firmware upgrades.
sysdrv:source:kernel: Upgraded to version 5.10.160; increased NPU frequency for RV1106G3; added support for
fastboot.

Signed-off-by: luckfox-eng29 <eng29@luckfox.com>
2024-10-14 09:47:04 +08:00

340 lines
12 KiB
C

/*
* Copyright 2021 Rockchip Electronics Co. LTD
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* End of #ifdef __cplusplus */
#include <errno.h>
#include <pthread.h>
#include <stdio.h>
#include <sys/poll.h>
#include <unistd.h>
#include "sample_comm.h"
RK_S32 SAMPLE_COMM_VENC_CreateChn(SAMPLE_VENC_CTX_S *ctx) {
RK_S32 s32Ret = RK_FAILURE;
VENC_RECV_PIC_PARAM_S stRecvParam;
VENC_RC_PARAM_S pstRcParam;
VENC_CHN_BUF_WRAP_S stVencChnBufWrap;
VENC_CHN_REF_BUF_SHARE_S stVencChnRefBufShare;
switch (ctx->enCodecType) {
case RK_CODEC_TYPE_H265:
ctx->stChnAttr.stVencAttr.enType = RK_VIDEO_ID_HEVC;
if (ctx->enRcMode == VENC_RC_MODE_H265CBR) {
ctx->stChnAttr.stRcAttr.enRcMode = VENC_RC_MODE_H265CBR;
ctx->stChnAttr.stRcAttr.stH265Cbr.u32Gop = ctx->u32Gop;
ctx->stChnAttr.stRcAttr.stH265Cbr.u32BitRate = ctx->u32BitRate;
// frame rate: in u32Fps/1, out u32Fps/1.
ctx->stChnAttr.stRcAttr.stH265Cbr.fr32DstFrameRateDen = 1;
ctx->stChnAttr.stRcAttr.stH265Cbr.fr32DstFrameRateNum = ctx->u32Fps;
ctx->stChnAttr.stRcAttr.stH265Cbr.u32SrcFrameRateDen = 1;
ctx->stChnAttr.stRcAttr.stH265Cbr.u32SrcFrameRateNum = ctx->u32Fps;
} else if (ctx->enRcMode == VENC_RC_MODE_H265VBR) {
ctx->stChnAttr.stRcAttr.enRcMode = VENC_RC_MODE_H265VBR;
ctx->stChnAttr.stRcAttr.stH265Vbr.u32Gop = ctx->u32Gop;
ctx->stChnAttr.stRcAttr.stH265Vbr.u32BitRate = ctx->u32BitRate;
// frame rate: in u32Fps/1, out u32Fps/1.
ctx->stChnAttr.stRcAttr.stH265Vbr.fr32DstFrameRateDen = 1;
ctx->stChnAttr.stRcAttr.stH265Vbr.fr32DstFrameRateNum = ctx->u32Fps;
ctx->stChnAttr.stRcAttr.stH265Vbr.u32SrcFrameRateDen = 1;
ctx->stChnAttr.stRcAttr.stH265Vbr.u32SrcFrameRateNum = ctx->u32Fps;
}
break;
case RK_CODEC_TYPE_MJPEG:
ctx->stChnAttr.stVencAttr.enType = RK_VIDEO_ID_MJPEG;
if (ctx->enRcMode == VENC_RC_MODE_MJPEGCBR) {
ctx->stChnAttr.stRcAttr.enRcMode = VENC_RC_MODE_MJPEGCBR;
// frame rate: in u32Fps/1, out u32Fps/1.
ctx->stChnAttr.stRcAttr.stMjpegCbr.fr32DstFrameRateDen = 1;
ctx->stChnAttr.stRcAttr.stMjpegCbr.fr32DstFrameRateNum = ctx->u32Fps;
ctx->stChnAttr.stRcAttr.stMjpegCbr.u32SrcFrameRateDen = 1;
ctx->stChnAttr.stRcAttr.stMjpegCbr.u32SrcFrameRateNum = ctx->u32Fps;
ctx->stChnAttr.stRcAttr.stMjpegCbr.u32BitRate =
ctx->u32Width * ctx->u32Height * 8;
} else if (ctx->enRcMode == VENC_RC_MODE_MJPEGVBR) {
ctx->stChnAttr.stRcAttr.enRcMode = VENC_RC_MODE_MJPEGVBR;
// frame rate: in u32Fps/1, out u32Fps/1.
ctx->stChnAttr.stRcAttr.stMjpegVbr.fr32DstFrameRateDen = 1;
ctx->stChnAttr.stRcAttr.stMjpegVbr.fr32DstFrameRateNum = ctx->u32Fps;
ctx->stChnAttr.stRcAttr.stMjpegVbr.u32SrcFrameRateDen = 1;
ctx->stChnAttr.stRcAttr.stMjpegVbr.u32SrcFrameRateNum = ctx->u32Fps;
ctx->stChnAttr.stRcAttr.stMjpegVbr.u32BitRate =
ctx->u32Width * ctx->u32Height * 8;
}
break;
case RK_CODEC_TYPE_JPEG:
RK_LOGE("RK_CODEC_TYPE_JPEG setting");
ctx->stChnAttr.stRcAttr.enRcMode = VENC_RC_MODE_MJPEGCBR;
ctx->stChnAttr.stVencAttr.enType = RK_VIDEO_ID_JPEG;
ctx->stChnAttr.stVencAttr.stAttrJpege.bSupportDCF = RK_FALSE;
ctx->stChnAttr.stVencAttr.stAttrJpege.stMPFCfg.u8LargeThumbNailNum = 0;
ctx->stChnAttr.stVencAttr.stAttrJpege.enReceiveMode = VENC_PIC_RECEIVE_SINGLE;
break;
case RK_CODEC_TYPE_H264:
default:
ctx->stChnAttr.stVencAttr.enType = RK_VIDEO_ID_AVC;
if (ctx->enRcMode == VENC_RC_MODE_H264CBR) {
ctx->stChnAttr.stRcAttr.enRcMode = VENC_RC_MODE_H264CBR;
ctx->stChnAttr.stRcAttr.stH264Cbr.u32Gop = ctx->u32Gop;
ctx->stChnAttr.stRcAttr.stH264Cbr.u32BitRate = ctx->u32BitRate;
// frame rate: in u32Fps/1, out u32Fps/1.
ctx->stChnAttr.stRcAttr.stH264Cbr.fr32DstFrameRateDen = 1;
ctx->stChnAttr.stRcAttr.stH264Cbr.fr32DstFrameRateNum = ctx->u32Fps;
ctx->stChnAttr.stRcAttr.stH264Cbr.u32SrcFrameRateDen = 1;
ctx->stChnAttr.stRcAttr.stH264Cbr.u32SrcFrameRateNum = ctx->u32Fps;
} else if (ctx->enRcMode == VENC_RC_MODE_H264VBR) {
ctx->stChnAttr.stRcAttr.enRcMode = VENC_RC_MODE_H264VBR;
ctx->stChnAttr.stRcAttr.stH264Vbr.u32Gop = ctx->u32Gop;
ctx->stChnAttr.stRcAttr.stH264Vbr.u32BitRate = ctx->u32BitRate;
// frame rate: in u32Fps/1, out u32Fps/1.
ctx->stChnAttr.stRcAttr.stH264Vbr.fr32DstFrameRateDen = 1;
ctx->stChnAttr.stRcAttr.stH264Vbr.fr32DstFrameRateNum = ctx->u32Fps;
ctx->stChnAttr.stRcAttr.stH264Vbr.u32SrcFrameRateDen = 1;
ctx->stChnAttr.stRcAttr.stH264Vbr.u32SrcFrameRateNum = ctx->u32Fps;
}
break;
}
ctx->stChnAttr.stVencAttr.enPixelFormat = ctx->enPixelFormat;
ctx->stChnAttr.stVencAttr.u32MaxPicWidth = ctx->u32Width;
ctx->stChnAttr.stVencAttr.u32MaxPicHeight = ctx->u32Height;
ctx->stChnAttr.stVencAttr.u32PicWidth = ctx->u32Width;
ctx->stChnAttr.stVencAttr.u32PicHeight = ctx->u32Height;
ctx->stChnAttr.stVencAttr.u32VirWidth = RK_ALIGN_2(ctx->u32Width);
ctx->stChnAttr.stVencAttr.u32VirHeight = RK_ALIGN_2(ctx->u32Height);
if (ctx->u32StreamBufCnt) {
ctx->stChnAttr.stVencAttr.u32StreamBufCnt = ctx->u32StreamBufCnt;
} else {
ctx->stChnAttr.stVencAttr.u32StreamBufCnt = 3;
}
RK_LOGE("V_C:%d bufferCnt:%d", ctx->s32ChnId,
ctx->stChnAttr.stVencAttr.u32StreamBufCnt);
if (ctx->u32BuffSize) {
ctx->stChnAttr.stVencAttr.u32BufSize = ctx->u32BuffSize;
} else {
ctx->stChnAttr.stVencAttr.u32BufSize = ctx->u32Width * ctx->u32Height * 3 / 2;
}
s32Ret = RK_MPI_VENC_CreateChn(ctx->s32ChnId, &ctx->stChnAttr);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("RK_MPI_VENC_CreateChn failed %x", s32Ret);
return s32Ret;
}
if (ctx->enable_buf_share) {
VENC_CHN_REF_BUF_SHARE_S stVencChnRefBufShare;
memset(&stVencChnRefBufShare, 0, sizeof(VENC_CHN_REF_BUF_SHARE_S));
stVencChnRefBufShare.bEnable = 1;
s32Ret = RK_MPI_VENC_SetChnRefBufShareAttr(ctx->s32ChnId, &stVencChnRefBufShare);
if (s32Ret != RK_SUCCESS) {
printf("RK_MPI_VENC_SetChnRefBufShareAttr failed,ret=%#x\n", s32Ret);
}
}
if (ctx->bWrapIfEnable) {
memset(&stVencChnBufWrap, 0, sizeof(stVencChnBufWrap));
stVencChnBufWrap.bEnable = RK_TRUE;
stVencChnBufWrap.u32BufLine = ctx->u32BufferLine;
memset(&stVencChnRefBufShare, 0, sizeof(VENC_CHN_REF_BUF_SHARE_S));
stVencChnRefBufShare.bEnable = RK_TRUE;
s32Ret = RK_MPI_VENC_SetChnBufWrapAttr(ctx->s32ChnId, &stVencChnBufWrap);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("RK_MPI_VENC_SetChnBufWrapAttr failure:%X", s32Ret);
return RK_FAILURE;
}
RK_MPI_VENC_SetChnRefBufShareAttr(ctx->s32ChnId, &stVencChnRefBufShare);
}
memset(&pstRcParam, 0, sizeof(VENC_RC_PARAM_S));
if (ctx->enCodecType == RK_CODEC_TYPE_H264) {
pstRcParam.stParamH264.u32MinQp = 10;
pstRcParam.stParamH264.u32MaxQp = 51;
pstRcParam.stParamH264.u32MinIQp = 10;
pstRcParam.stParamH264.u32MaxIQp = 51;
pstRcParam.stParamH264.u32FrmMinQp = 28;
pstRcParam.stParamH264.u32FrmMinIQp = 28;
} else if (ctx->enCodecType == RK_CODEC_TYPE_H265) {
pstRcParam.stParamH265.u32MinQp = 10;
pstRcParam.stParamH265.u32MaxQp = 51;
pstRcParam.stParamH265.u32MinIQp = 10;
pstRcParam.stParamH265.u32MaxIQp = 51;
pstRcParam.stParamH265.u32FrmMinQp = 28;
pstRcParam.stParamH265.u32FrmMinIQp = 28;
}
s32Ret = RK_MPI_VENC_SetRcParam(ctx->s32ChnId, &pstRcParam);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("RK_MPI_VENC_SetRcParam failed %X", s32Ret);
return s32Ret;
}
/* ifenable Svc */
if (ctx->bSvcIfEnable) {
s32Ret = RK_MPI_VENC_EnableSvc(ctx->s32ChnId, ctx->bSvcIfEnable);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("RK_MPI_VENC_EnableSvc failed %X", s32Ret);
return s32Ret;
}
}
/* ifenable Motion Deblur */
if (ctx->bMotionDeblurIfEnable) {
s32Ret =
RK_MPI_VENC_EnableMotionDeblur(ctx->s32ChnId, ctx->bMotionDeblurIfEnable);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("RK_MPI_VENC_EnableSvc failed %X", s32Ret);
return s32Ret;
}
}
stRecvParam.s32RecvPicNum = -1;
s32Ret = RK_MPI_VENC_StartRecvFrame(ctx->s32ChnId, &stRecvParam);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("create %d ch venc failed", ctx->s32ChnId);
return s32Ret;
}
if (ctx->stChnAttr.stVencAttr.enType == RK_VIDEO_ID_JPEG) {
VENC_JPEG_PARAM_S stJpegParam;
memset(&stJpegParam, 0, sizeof(VENC_JPEG_PARAM_S));
stJpegParam.u32Qfactor = ctx->u32Qfactor;
s32Ret = RK_MPI_VENC_SetJpegParam(ctx->s32ChnId, &stJpegParam);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("RK_MPI_VENC_SetJpegParam failure:%X", s32Ret);
return s32Ret;
}
}
if (ctx->bComboIfEnable) {
VENC_COMBO_ATTR_S stComboAttr;
memset(&stComboAttr, 0, sizeof(VENC_COMBO_ATTR_S));
stComboAttr.bEnable = RK_TRUE;
stComboAttr.s32ChnId = ctx->u32ComboChnId;
RK_MPI_VENC_SetComboAttr(ctx->s32ChnId, &stComboAttr);
}
if (ctx->getStreamCbFunc) {
ctx->stFrame.pstPack = (VENC_PACK_S *)(malloc(sizeof(VENC_PACK_S)));
pthread_create(&ctx->getStreamThread, 0, ctx->getStreamCbFunc, (void *)(ctx));
}
return RK_SUCCESS;
}
RK_S32 SAMPLE_COMM_VENC_SendStream(SAMPLE_VENC_CTX_S *ctx, void *pdata, RK_S32 width,
RK_S32 height, RK_S32 size,
COMPRESS_MODE_E enCompressMode) {
RK_S32 s32Ret = RK_FAILURE;
MB_BLK blk = RK_NULL;
RK_U8 *pVirAddr = RK_NULL;
RK_S32 s32ReachEOS = 0;
VIDEO_FRAME_INFO_S stFrame;
__RETRY0:
blk = RK_MPI_MB_GetMB(ctx->pool, size, RK_TRUE);
if (RK_NULL == blk) {
RK_LOGE("RK_MPI_MB_GetMB fail %x", blk);
usleep(2000llu);
goto __RETRY0;
}
pVirAddr = (RK_U8 *)(RK_MPI_MB_Handle2VirAddr(blk));
pVirAddr = pdata;
RK_MPI_SYS_MmzFlushCache(blk, RK_FALSE);
stFrame.stVFrame.pMbBlk = blk;
stFrame.stVFrame.u32Width = width;
stFrame.stVFrame.u32Height = height;
stFrame.stVFrame.u32VirWidth = width;
stFrame.stVFrame.u32VirHeight = height;
stFrame.stVFrame.enPixelFormat = RK_FMT_YUV420SP;
stFrame.stVFrame.u32FrameFlag |= s32ReachEOS ? FRAME_FLAG_SNAP_END : 0;
stFrame.stVFrame.enCompressMode = enCompressMode;
__RETRY1:
s32Ret = RK_MPI_VENC_SendFrame(ctx->s32ChnId, &stFrame, -1);
if (s32Ret == RK_SUCCESS) {
RK_MPI_MB_ReleaseMB(blk);
} else {
RK_LOGE("RK_MPI_VENC_SendFrame fail %x", s32Ret);
usleep(10000llu);
goto __RETRY1;
}
return s32Ret;
}
RK_S32 SAMPLE_COMM_VENC_GetStream(SAMPLE_VENC_CTX_S *ctx, void **pdata) {
RK_S32 s32Ret = RK_FAILURE;
while (1) {
s32Ret = RK_MPI_VENC_GetStream(ctx->s32ChnId, &ctx->stFrame, 2000);
if (s32Ret == RK_SUCCESS) {
*pdata = RK_MPI_MB_Handle2VirAddr(ctx->stFrame.pstPack->pMbBlk);
break;
} else {
RK_LOGE("RK_MPI_VENC_GetStream chnid:%d fail %#X", ctx->s32ChnId, s32Ret);
}
}
return s32Ret;
}
RK_S32 SAMPLE_COMM_VENC_ReleaseStream(SAMPLE_VENC_CTX_S *ctx) {
RK_S32 s32Ret = RK_FAILURE;
s32Ret = RK_MPI_VENC_ReleaseStream(ctx->s32ChnId, &ctx->stFrame);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("RK_MPI_VENC_ReleaseStream fail %x", s32Ret);
}
return s32Ret;
}
RK_S32 SAMPLE_COMM_VENC_DestroyChn(SAMPLE_VENC_CTX_S *ctx) {
RK_S32 s32Ret = RK_FAILURE;
s32Ret = RK_MPI_VENC_StopRecvFrame(ctx->s32ChnId);
if (s32Ret != RK_SUCCESS) {
return s32Ret;
}
RK_LOGE("destroy enc chn:%d", ctx->s32ChnId);
s32Ret = RK_MPI_VENC_DestroyChn(ctx->s32ChnId);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("RK_MPI_VDEC_DestroyChn fail %x", s32Ret);
}
if (ctx->stFrame.pstPack) {
free(ctx->stFrame.pstPack);
}
#if defined(RV1106)
RK_MPI_SYS_WaitFreeMB();
#endif
return RK_SUCCESS;
}
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* End of #ifdef __cplusplus */