luckfox-pico-sdk/media/samples/simple_test/simple_vi_bind_ivs.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

354 lines
9.2 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <errno.h>
#include <pthread.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/poll.h>
#include <time.h>
#include <unistd.h>
#include "rk_comm_ivs.h"
#include "rk_debug.h"
#include "rk_defines.h"
#include "rk_mpi_adec.h"
#include "rk_mpi_aenc.h"
#include "rk_mpi_ai.h"
#include "rk_mpi_ao.h"
#include "rk_mpi_avs.h"
#include "rk_mpi_cal.h"
#include "rk_mpi_ivs.h"
#include "rk_mpi_mb.h"
#include "rk_mpi_rgn.h"
#include "rk_mpi_sys.h"
#include "rk_mpi_tde.h"
#include "rk_mpi_vdec.h"
#include "rk_mpi_venc.h"
#include "rk_mpi_vi.h"
#include "rk_mpi_vo.h"
#include "rk_mpi_vpss.h"
struct ivs_info {
RK_U32 u32Width;
RK_U32 u32Height;
RK_U32 u32Sensitivity;
};
static bool quit = false;
static void sigterm_handler(int sig) {
fprintf(stderr, "signal %d\n", sig);
quit = true;
}
static void *GetMediaBuffer0(void *arg) {
struct ivs_info *info = (struct ivs_info *)arg;
printf("========%s========\n", __func__);
int loopCount = 0;
int s32Ret;
IVS_RESULT_INFO_S stResults;
// int width = 1920;
// int height = 1080;
RK_U32 u32SquarePct[5] = {50, 30, 25, 20, 20};
while (!quit) {
memset(&stResults, 0, sizeof(IVS_RESULT_INFO_S));
s32Ret = RK_MPI_IVS_GetResults(0, &stResults, -1);
if (s32Ret == RK_SUCCESS) {
if (stResults.s32ResultNum == 1) {
for (int i = 0; i < stResults.pstResults->stMdInfo.u32RectNum; i++) {
printf("%d: [%d, %d, %d, %d]\n", i,
stResults.pstResults->stMdInfo.stRect[i].s32X,
stResults.pstResults->stMdInfo.stRect[i].s32Y,
stResults.pstResults->stMdInfo.stRect[i].u32Width,
stResults.pstResults->stMdInfo.stRect[i].u32Height);
printf("u32Square %u, u32DetAreaSquare %u, u32DetOutputSquare %u\n",
stResults.pstResults->stMdInfo.u32Square,
stResults.pstResults->stMdInfo.u32DetAreaSquare,
stResults.pstResults->stMdInfo.u32DetOutputSquare);
}
if (1000 * stResults.pstResults->stMdInfo.u32Square / info->u32Width / info->u32Height > u32SquarePct[info->u32Sensitivity])
printf("Detect movement!\n");
}
RK_MPI_IVS_ReleaseResults(0, &stResults);
} else {
RK_LOGE("RK_MPI_IVS_GetResults fail %x", s32Ret);
}
loopCount++;
}
return NULL;
}
// demo板dev默认都是0根据不同的channel 来选择不同的vi节点
int vi_dev_init() {
printf("%s\n", __func__);
int ret = 0;
int devId = 0;
int pipeId = devId;
VI_DEV_ATTR_S stDevAttr;
VI_DEV_BIND_PIPE_S stBindPipe;
memset(&stDevAttr, 0, sizeof(stDevAttr));
memset(&stBindPipe, 0, sizeof(stBindPipe));
// 0. get dev config status
ret = RK_MPI_VI_GetDevAttr(devId, &stDevAttr);
if (ret == RK_ERR_VI_NOT_CONFIG) {
// 0-1.config dev
ret = RK_MPI_VI_SetDevAttr(devId, &stDevAttr);
if (ret != RK_SUCCESS) {
printf("RK_MPI_VI_SetDevAttr %x\n", ret);
return -1;
}
} else {
printf("RK_MPI_VI_SetDevAttr already\n");
}
// 1.get dev enable status
ret = RK_MPI_VI_GetDevIsEnable(devId);
if (ret != RK_SUCCESS) {
// 1-2.enable dev
ret = RK_MPI_VI_EnableDev(devId);
if (ret != RK_SUCCESS) {
printf("RK_MPI_VI_EnableDev %x\n", ret);
return -1;
}
// 1-3.bind dev/pipe
stBindPipe.u32Num = 1;
stBindPipe.PipeId[0] = pipeId;
ret = RK_MPI_VI_SetDevBindPipe(devId, &stBindPipe);
if (ret != RK_SUCCESS) {
printf("RK_MPI_VI_SetDevBindPipe %x\n", ret);
return -1;
}
} else {
printf("RK_MPI_VI_EnableDev already\n");
}
return 0;
}
int vi_chn_init(int channelId, int width, int height) {
int ret;
int buf_cnt = 2;
// VI init
VI_CHN_ATTR_S vi_chn_attr;
memset(&vi_chn_attr, 0, sizeof(vi_chn_attr));
vi_chn_attr.stIspOpt.u32BufCount = buf_cnt;
vi_chn_attr.stIspOpt.enMemoryType =
VI_V4L2_MEMORY_TYPE_DMABUF; // VI_V4L2_MEMORY_TYPE_MMAP;
vi_chn_attr.stSize.u32Width = width;
vi_chn_attr.stSize.u32Height = height;
vi_chn_attr.enPixelFormat = RK_FMT_YUV420SP;
vi_chn_attr.enCompressMode = COMPRESS_MODE_NONE; // COMPRESS_AFBC_16x16;
vi_chn_attr.u32Depth = 0; //0, get fail, 1 - u32BufCount, can get, if bind to other device, must be < u32BufCount
ret = RK_MPI_VI_SetChnAttr(0, channelId, &vi_chn_attr);
ret |= RK_MPI_VI_EnableChn(0, channelId);
if (ret) {
printf("ERROR: create VI error! ret=%d\n", ret);
return ret;
}
return ret;
}
static RK_S32 create_ivs(int width, int height, RK_U32 u32AreaEn, RK_U32 u32Sensitivity) {
RK_S32 s32Ret;
IVS_CHN_ATTR_S attr;
memset(&attr, 0, sizeof(attr));
attr.enMode = IVS_MODE_MD_OD;
attr.u32PicWidth = width;
attr.u32PicHeight = height;
attr.enPixelFormat = RK_FMT_YUV420SP;
attr.s32Gop = 30;
attr.bSmearEnable = RK_FALSE;
attr.bWeightpEnable = RK_FALSE;
attr.bMDEnable = RK_TRUE;
attr.s32MDInterval = 5;
attr.bMDNightMode = RK_FALSE;
attr.bODEnable = RK_TRUE;
attr.s32ODInterval = 1;
attr.s32ODPercent = 7;
if (u32AreaEn) {
attr.stDetAttr.stDetArea.u32AreaNum = 1;
attr.stDetAttr.stDetArea.areas[0].u32PointNum = 4;
attr.stDetAttr.stDetArea.areas[0].points[0].s32X = width / 2;
attr.stDetAttr.stDetArea.areas[0].points[0].s32Y = 0;
attr.stDetAttr.stDetArea.areas[0].points[1].s32X = width;
attr.stDetAttr.stDetArea.areas[0].points[1].s32Y = height / 2;
attr.stDetAttr.stDetArea.areas[0].points[2].s32X = width / 2;
attr.stDetAttr.stDetArea.areas[0].points[2].s32Y = height;
attr.stDetAttr.stDetArea.areas[0].points[3].s32X = 0;
attr.stDetAttr.stDetArea.areas[0].points[3].s32Y = height / 2;
}
s32Ret = RK_MPI_IVS_CreateChn(0, &attr);
if (s32Ret) {
RK_LOGE("ivs create failed:%x", s32Ret);
goto __FAILED;
}
#ifdef RV1106_RV1103
IVS_MD_ATTR_S stMdAttr;
memset(&stMdAttr, 0, sizeof(stMdAttr));
s32Ret = RK_MPI_IVS_GetMdAttr(0, &stMdAttr);
if (s32Ret) {
RK_LOGE("ivs get mdattr failed:%x", s32Ret);
goto __FAILED;
}
switch (u32Sensitivity) {
case 0:
stMdAttr.s32ThreshSad = 96;
stMdAttr.s32ThreshMove = 3;
stMdAttr.s32SwitchSad = 2;
break;
case 1:
stMdAttr.s32ThreshSad = 72;
stMdAttr.s32ThreshMove = 2;
stMdAttr.s32SwitchSad = 2;
break;
case 2:
stMdAttr.s32ThreshSad = 64;
stMdAttr.s32ThreshMove = 2;
stMdAttr.s32SwitchSad = 2;
case 3:
stMdAttr.s32ThreshSad = 48;
stMdAttr.s32ThreshMove = 1;
stMdAttr.s32SwitchSad = 2;
break;
case 4:
stMdAttr.s32ThreshSad = 32;
stMdAttr.s32ThreshMove = 1;
stMdAttr.s32SwitchSad = 0;
break;
default:
stMdAttr.s32ThreshSad = 64;
stMdAttr.s32ThreshMove = 2;
stMdAttr.s32SwitchSad = 2;
break;
}
stMdAttr.bFlycatkinFlt = RK_TRUE;
stMdAttr.s32ThresDustMove = 3;
stMdAttr.s32ThresDustBlk = 3;
stMdAttr.s32ThresDustChng = 50;
s32Ret = RK_MPI_IVS_SetMdAttr(0, &stMdAttr);
if (s32Ret) {
RK_LOGE("ivs set mdattr failed:%x", s32Ret);
goto __FAILED;
}
#endif
return 0;
__FAILED:
return -1;
}
static RK_CHAR optstr[] = "?::w:h:I:A:S:";
static void print_usage(const RK_CHAR *name) {
printf("usage example:\n");
printf("\t%s -I 0 -w 1920 -h 1080\n", name);
printf("\t-w | --width: VI width, Default:1920\n");
printf("\t-h | --heght: VI height, Default:1080\n");
printf("\t-I | --camid: camera ctx id, Default 0. "
"0:rkisp_mainpath,1:rkisp_selfpath,2:rkisp_bypasspath\n");
printf("\t-A | --Area: Area detect, Default:0\n");
printf("\t-S | --Sensitivity: MD sensitivity, range [0, 4], Default: 2\n");
}
int main(int argc, char *argv[]) {
RK_S32 s32Ret = RK_FAILURE;
RK_U32 u32Width = 1920;
RK_U32 u32Height = 1080;
MPP_CHN_S stSrcChn, stIvsChn;
RK_S32 s32chnlId = 0;
RK_U32 u32AreaEn = 0;
RK_U32 u32Sensitivity = 2;
int c;
int ret = -1;
while ((c = getopt(argc, argv, optstr)) != -1) {
switch (c) {
case 'w':
u32Width = atoi(optarg);
break;
case 'h':
u32Height = atoi(optarg);
break;
case 'I':
s32chnlId = atoi(optarg);
break;
case 'A':
u32AreaEn = atoi(optarg);
break;
case 'S':
u32Sensitivity = atoi(optarg);
if (u32Sensitivity > 4)
u32Sensitivity = 4;
break;
case '?':
default:
print_usage(argv[0]);
return -1;
}
}
printf("#Resolution: %dx%d\n", u32Width, u32Height);
printf("#CameraIdx: %d\n\n", s32chnlId);
signal(SIGINT, sigterm_handler);
if (RK_MPI_SYS_Init() != RK_SUCCESS) {
RK_LOGE("rk mpi sys init fail!");
goto __FAILED;
}
vi_dev_init();
vi_chn_init(s32chnlId, u32Width, u32Height);
create_ivs(u32Width, u32Height, u32AreaEn, u32Sensitivity);
stSrcChn.enModId = RK_ID_VI;
stSrcChn.s32DevId = 0;
stSrcChn.s32ChnId = s32chnlId;
stIvsChn.enModId = RK_ID_IVS;
stIvsChn.s32DevId = 0;
stIvsChn.s32ChnId = 0;
printf("====RK_MPI_SYS_Bind vi0 to venc0====\n");
s32Ret = RK_MPI_SYS_Bind(&stSrcChn, &stIvsChn);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("bind 0 ch venc failed");
goto __FAILED;
}
struct ivs_info ivs_info = {u32Width, u32Height, u32Sensitivity};
pthread_t main_thread;
pthread_create(&main_thread, NULL, GetMediaBuffer0, &ivs_info);
while (!quit) {
usleep(5000);
}
pthread_join(main_thread, NULL);
s32Ret = RK_MPI_SYS_UnBind(&stSrcChn, &stIvsChn);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("RK_MPI_SYS_UnBind fail %x", s32Ret);
}
s32Ret = RK_MPI_IVS_DestroyChn(0);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("RK_MPI_IVS_DestroyChn fail %x", s32Ret);
}
s32Ret = RK_MPI_VI_DisableChn(0, s32chnlId);
RK_LOGE("RK_MPI_VI_DisableChn %x", s32Ret);
s32Ret = RK_MPI_VI_DisableDev(0);
RK_LOGE("RK_MPI_VI_DisableDev %x", s32Ret);
ret = 0;
__FAILED:
RK_LOGE("test running exit:%d", s32Ret);
RK_MPI_SYS_Exit();
return ret;
}