mirror of
https://github.com/LuckfoxTECH/luckfox-pico.git
synced 2026-01-18 03:28:19 +01:00
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>
This commit is contained in:
1
project/app/component/fastboot_server/.gitignore
vendored
Normal file
1
project/app/component/fastboot_server/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
out
|
||||
106
project/app/component/fastboot_server/Makefile
Normal file
106
project/app/component/fastboot_server/Makefile
Normal file
@@ -0,0 +1,106 @@
|
||||
|
||||
ifeq ($(APP_PARAM), )
|
||||
APP_PARAM:=../../Makefile.param
|
||||
include $(APP_PARAM)
|
||||
endif
|
||||
|
||||
export LC_ALL=C
|
||||
SHELL:=/bin/bash
|
||||
|
||||
CURRENT_DIR := $(shell pwd)
|
||||
|
||||
PKG_NAME := fastboot_server
|
||||
PKG_BIN ?= out
|
||||
|
||||
RK_APP_CFLAGS = -I $(RK_APP_MEDIA_INCLUDE_PATH) \
|
||||
-I $(RK_APP_MEDIA_INCLUDE_PATH)/libdrm \
|
||||
-I $(RK_APP_MEDIA_INCLUDE_PATH)/rkaiq \
|
||||
-I $(RK_APP_MEDIA_INCLUDE_PATH)/rkaiq/uAPI \
|
||||
-I $(RK_APP_MEDIA_INCLUDE_PATH)/rkaiq/uAPI2 \
|
||||
-I $(RK_APP_MEDIA_INCLUDE_PATH)/rkaiq/algos \
|
||||
-I $(RK_APP_MEDIA_INCLUDE_PATH)/rkaiq/common \
|
||||
-I $(RK_APP_MEDIA_INCLUDE_PATH)/rkaiq/xcore \
|
||||
-I $(RK_APP_MEDIA_INCLUDE_PATH)/rkaiq/iq_parser \
|
||||
-I $(RK_APP_MEDIA_INCLUDE_PATH)/rkaiq/iq_parser_v2 \
|
||||
-I $(RK_APP_OUTPUT)/include \
|
||||
-I $(RK_APP_OUTPUT)/include/freetype2 \
|
||||
-I $(RK_APP_MEDIA_INCLUDE_PATH)/easymedia
|
||||
|
||||
RK_APP_LDFLAGS = -L $(RK_APP_MEDIA_LIBS_PATH) -L$(RK_APP_OUTPUT)/lib
|
||||
|
||||
RK_APP_OPTS += -Wl,-rpath-link,$(RK_APP_MEDIA_LIBS_PATH):$(RK_APP_PATH_LIB_INCLUDE)/root/usr/lib:$(RK_APP_OUTPUT)/lib
|
||||
|
||||
ifneq (, $(filter SMART_DOOR_RV1106_RMSL, $(RK_APP_TYPE)))
|
||||
FASTBOOT_SERVER_SRC := fastboot_server_multi_cam.c v4l2_link.c
|
||||
FASTBOOT_PKG_LDFLAGS := -Wl,-Bstatic \
|
||||
-lrockit_tiny -lrockchip_mpp -lrksysutils \
|
||||
-Wl,-Bdynamic \
|
||||
-ldl -lstdc++
|
||||
else
|
||||
|
||||
ifneq (, $(filter RK_FASTBOOT_CLIENT_DUAL_CAMERA, $(RK_APP_TYPE)))
|
||||
PKG_TARGET_RES_DIR := $(PKG_BIN)/root/oem/usr/share
|
||||
FASTBOOT_SERVER_SRC := fastboot_server_dual_camera.c
|
||||
FASTBOOT_PKG_LDFLAGS := -Wl,-Bstatic -pthread -lrockit_full -lrtsp \
|
||||
-O2 -mthumb -mthumb-interwork \
|
||||
-lrockchip_mpp -lrksysutils -lsmartIr \
|
||||
-lrkaudio_detect -laec_bf_process \
|
||||
-lrga -Wl,-Bdynamic \
|
||||
-Wl,--gc-sections -Wl,--as-needed \
|
||||
-lrkaiq -lstdc++ -lm
|
||||
endif
|
||||
|
||||
ifneq (, $(filter RK_FASTBOOT_SERVER, $(RK_APP_TYPE)))
|
||||
FASTBOOT_SERVER_BUILD_WITH_DLOPEN := y
|
||||
FASTBOOT_SERVER_SRC := fastboot_server.c
|
||||
ifeq ($(FASTBOOT_SERVER_BUILD_WITH_DLOPEN),y)
|
||||
RK_APP_CFLAGS += -DRKAIQ_USE_DLOPEN
|
||||
else
|
||||
FASTBOOT_PKG_LDFLAGS := -Wl,-Bstatic -lrkaiq -Wl,-Bdynamic
|
||||
endif
|
||||
|
||||
FASTBOOT_PKG_LDFLAGS += -Wl,-Bstatic \
|
||||
-lrockit_tiny -lrockchip_mpp -lrksysutils -lstdc++ \
|
||||
-Wl,-Bdynamic \
|
||||
-ldl
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
ifeq ("$(RK_ENABLE_AOV)", "y")
|
||||
RK_APP_CFLAGS += -DENABLE_AOV
|
||||
endif
|
||||
|
||||
ifneq ($(filter RK_FASTBOOT_SERVER SMART_DOOR_RV1106_RMSL RK_FASTBOOT_CLIENT_DUAL_CAMERA,$(RK_APP_TYPE)),)
|
||||
PKG_TARGET := fastboot_server-build
|
||||
endif
|
||||
|
||||
ifeq ($(PKG_BIN),)
|
||||
$(error ### $(CURRENT_DIR): PKG_BIN is NULL, Please Check !!!)
|
||||
endif
|
||||
|
||||
all: $(PKG_TARGET)
|
||||
@echo "build $(PKG_NAME) done"
|
||||
|
||||
fastboot_server-build:
|
||||
rm -rf $(PKG_BIN); \
|
||||
mkdir -p $(PKG_BIN)/bin;
|
||||
@echo "$(PKG_NAME) building $(FASTBOOT_SERVER_SRC)"
|
||||
@$(RK_APP_CROSS)-gcc $(FASTBOOT_SERVER_SRC) -o $(PKG_BIN)/bin/fastboot_server \
|
||||
-O2 -mthumb -mthumb-interwork \
|
||||
-fdata-sections -ffunction-sections -Wl,--gc-sections \
|
||||
$(RK_APP_LDFLAGS) $(RK_APP_CFLAGS) \
|
||||
-L$(RK_APP_MEDIA_LIBS_PATH)/lib \
|
||||
$(FASTBOOT_PKG_LDFLAGS)
|
||||
@test -z $(PKG_TARGET_RES_DIR) || (mkdir -p $(PKG_TARGET_RES_DIR); cp $(CURRENT_DIR)/osd_image.data $(PKG_TARGET_RES_DIR);)
|
||||
$(call MAROC_COPY_PKG_TO_APP_OUTPUT, $(RK_APP_OUTPUT), $(PKG_BIN))
|
||||
|
||||
clean:
|
||||
@rm -rf $(PKG_BIN)
|
||||
|
||||
distclean: clean
|
||||
|
||||
info:
|
||||
ifneq ($(RK_ENABLE_FASTBOOT),)
|
||||
@echo -e "$(C_YELLOW)-------------------------------------------------------------------------$(C_NORMAL)"
|
||||
endif
|
||||
729
project/app/component/fastboot_server/fastboot_server.c
Normal file
729
project/app/component/fastboot_server/fastboot_server.c
Normal file
@@ -0,0 +1,729 @@
|
||||
/* thunder boot service
|
||||
/1.aiq init & run
|
||||
/2.rockit vi & venc init, bind
|
||||
*/
|
||||
#include <dlfcn.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sched.h>
|
||||
#include <signal.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/poll.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "rk_debug.h"
|
||||
#include "rk_defines.h"
|
||||
#include "rk_mpi_sys.h"
|
||||
#include "rk_mpi_venc.h"
|
||||
#include "rk_mpi_vi.h"
|
||||
#include "rk_type.h"
|
||||
#include <rk_aiq_user_api2_camgroup.h>
|
||||
#include <rk_aiq_user_api2_imgproc.h>
|
||||
#include <rk_aiq_user_api2_sysctl.h>
|
||||
|
||||
#include "rk_gpio.h"
|
||||
#include "rk_meta.h"
|
||||
#include "rk_meta_app_param.h"
|
||||
#include "sensor_init_info.h"
|
||||
#include "sensor_iq_info.h"
|
||||
|
||||
#define RKAIQ
|
||||
|
||||
#ifdef RKAIQ_USE_DLOPEN
|
||||
void *rkaiq_dl = NULL;
|
||||
XCamReturn (*dlsym_rk_aiq_uapi2_sysctl_enumStaticMetas)(int, rk_aiq_static_info_t*);
|
||||
XCamReturn (*dlsym_rk_aiq_uapi2_sysctl_preInit_scene)(const char*, const char*, const char*);
|
||||
XCamReturn (*dlsym_rk_aiq_uapi2_sysctl_preInit_iq_addr)(const char*, void *, size_t);
|
||||
XCamReturn (*dlsym_rk_aiq_uapi2_sysctl_preInit_tb_info)(const char*, const rk_aiq_tb_info_t*);
|
||||
rk_aiq_sys_ctx_t* (*dlsym_rk_aiq_uapi2_sysctl_init)(const char*,
|
||||
const char*,
|
||||
rk_aiq_error_cb ,
|
||||
rk_aiq_metas_cb );
|
||||
|
||||
XCamReturn (*dlsym_rk_aiq_uapi2_sysctl_prepare)(const rk_aiq_sys_ctx_t*,
|
||||
uint32_t , uint32_t ,
|
||||
rk_aiq_working_mode_t );
|
||||
|
||||
XCamReturn (*dlsym_rk_aiq_uapi2_sysctl_start)(const rk_aiq_sys_ctx_t *);
|
||||
XCamReturn (*dlsym_rk_aiq_uapi2_sysctl_stop)(const rk_aiq_sys_ctx_t*, bool);
|
||||
XCamReturn (*dlsym_rk_aiq_uapi2_sysctl_deinit)(const rk_aiq_sys_ctx_t*);
|
||||
#endif
|
||||
//#define ENABLE_GET_STREAM
|
||||
|
||||
#define MAP_SIZE (4096UL * 50) // MAP_SIZE = 4 * 50 K
|
||||
#define MAP_MASK (MAP_SIZE - 1) // MAP_MASK = 0XFFF
|
||||
|
||||
#define MAP_SIZE_NIGHT (4096UL) // MAP_SIZE = 4K
|
||||
#define MAP_MASK_NIGHT (MAP_SIZE_NIGHT - 1) // MAP_MASK = 0XFFF
|
||||
|
||||
static FILE *venc0_file = NULL;
|
||||
static RK_S32 g_s32FrameCnt = -1;
|
||||
static VI_CHN_BUF_WRAP_S g_stViWrap;
|
||||
static bool g_bWrap = true;
|
||||
static RK_U32 g_u32WrapLine = 0;
|
||||
static char *g_sEntityName = NULL;
|
||||
static bool quit = false;
|
||||
static struct app_param_info *g_pAppParam = NULL;
|
||||
static struct sensor_init_cfg *g_pSensorInitParam = NULL;
|
||||
|
||||
static void sigterm_handler(int sig) { quit = true; }
|
||||
|
||||
#ifdef ENABLE_AOV
|
||||
#define AOV_LUNCH_FILE "/tmp/aov_lunch"
|
||||
#endif
|
||||
|
||||
#ifdef RKAIQ_USE_DLOPEN
|
||||
static int dlsym_rkaiq (void)
|
||||
{
|
||||
rkaiq_dl = dlopen("/usr/lib/librkaiq.so", RTLD_LAZY);
|
||||
if (!rkaiq_dl) {
|
||||
printf("\ndlopen /usr/lib/librkaiq.so error\n");
|
||||
return -1;
|
||||
}
|
||||
dlsym_rk_aiq_uapi2_sysctl_enumStaticMetas = dlsym(rkaiq_dl, "rk_aiq_uapi2_sysctl_enumStaticMetas");
|
||||
dlsym_rk_aiq_uapi2_sysctl_preInit_scene = dlsym(rkaiq_dl, "rk_aiq_uapi2_sysctl_preInit_scene");
|
||||
dlsym_rk_aiq_uapi2_sysctl_preInit_iq_addr = dlsym(rkaiq_dl, "rk_aiq_uapi2_sysctl_preInit_iq_addr");
|
||||
dlsym_rk_aiq_uapi2_sysctl_preInit_tb_info = dlsym(rkaiq_dl, "rk_aiq_uapi2_sysctl_preInit_tb_info");
|
||||
dlsym_rk_aiq_uapi2_sysctl_init = dlsym(rkaiq_dl, "rk_aiq_uapi2_sysctl_init");
|
||||
dlsym_rk_aiq_uapi2_sysctl_prepare = dlsym(rkaiq_dl, "rk_aiq_uapi2_sysctl_prepare");
|
||||
dlsym_rk_aiq_uapi2_sysctl_start = dlsym(rkaiq_dl, "rk_aiq_uapi2_sysctl_start");
|
||||
dlsym_rk_aiq_uapi2_sysctl_stop = dlsym(rkaiq_dl, "rk_aiq_uapi2_sysctl_stop");
|
||||
dlsym_rk_aiq_uapi2_sysctl_deinit = dlsym(rkaiq_dl, "rk_aiq_uapi2_sysctl_deinit");
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#define dlsym_rk_aiq_uapi2_sysctl_enumStaticMetas rk_aiq_uapi2_sysctl_enumStaticMetas
|
||||
#define dlsym_rk_aiq_uapi2_sysctl_preInit_scene rk_aiq_uapi2_sysctl_preInit_scene
|
||||
#define dlsym_rk_aiq_uapi2_sysctl_preInit_iq_addr rk_aiq_uapi2_sysctl_preInit_iq_addr
|
||||
#define dlsym_rk_aiq_uapi2_sysctl_preInit_tb_info rk_aiq_uapi2_sysctl_preInit_tb_info
|
||||
#define dlsym_rk_aiq_uapi2_sysctl_init rk_aiq_uapi2_sysctl_init
|
||||
#define dlsym_rk_aiq_uapi2_sysctl_prepare rk_aiq_uapi2_sysctl_prepare
|
||||
#define dlsym_rk_aiq_uapi2_sysctl_start rk_aiq_uapi2_sysctl_start
|
||||
#define dlsym_rk_aiq_uapi2_sysctl_stop rk_aiq_uapi2_sysctl_stop
|
||||
#define dlsym_rk_aiq_uapi2_sysctl_deinit rk_aiq_uapi2_sysctl_deinit
|
||||
#endif
|
||||
|
||||
/*
|
||||
* * get cmdline from /proc/cmdline
|
||||
* */
|
||||
static int read_cmdline_to_buf(void *buf, int len) {
|
||||
int fd;
|
||||
int ret;
|
||||
if (buf == NULL || len < 0) {
|
||||
printf("%s: illegal para\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
memset(buf, 0, len);
|
||||
fd = open("/proc/cmdline", O_RDONLY);
|
||||
if (fd < 0) {
|
||||
perror("open:");
|
||||
return -1;
|
||||
}
|
||||
ret = read(fd, buf, len);
|
||||
close(fd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
long get_cmd_val(const char *string, int len) {
|
||||
char *addr;
|
||||
long value = 0;
|
||||
char key_equal[16];
|
||||
static char cmdline[1024];
|
||||
static char cmd_init = 0;
|
||||
|
||||
if (cmd_init == 0) {
|
||||
cmd_init = 1;
|
||||
memset(cmdline, 0, sizeof(cmdline));
|
||||
read_cmdline_to_buf(cmdline, sizeof(cmdline));
|
||||
}
|
||||
|
||||
snprintf(key_equal, sizeof(key_equal), "%s=", string);
|
||||
addr = strstr(cmdline, string);
|
||||
if (addr) {
|
||||
value = strtol(addr + strlen(string) + 1, NULL, len);
|
||||
printf("get %s value: 0x%0lx\n", string, value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
RK_U64 TEST_COMM_GetNowUs() {
|
||||
struct timespec time = {0, 0};
|
||||
clock_gettime(CLOCK_MONOTONIC, &time);
|
||||
return (RK_U64)time.tv_sec * 1000000 + (RK_U64)time.tv_nsec / 1000; /* microseconds */
|
||||
}
|
||||
|
||||
#ifdef ENABLE_GET_STREAM
|
||||
|
||||
// fast client to get media buffer.
|
||||
static void *GetMediaBuffer0(void *arg) {
|
||||
(void)arg;
|
||||
void *pData = RK_NULL;
|
||||
int loopCount = 0;
|
||||
int s32Ret;
|
||||
VENC_STREAM_S stFrame;
|
||||
|
||||
FILE *fp = fopen("/tmp/pts.txt", "wb");
|
||||
|
||||
stFrame.pstPack = malloc(sizeof(VENC_PACK_S));
|
||||
|
||||
while (!quit) {
|
||||
s32Ret = RK_MPI_VENC_GetStream(0, &stFrame, -1);
|
||||
if (s32Ret == RK_SUCCESS) {
|
||||
if (venc0_file) {
|
||||
pData = RK_MPI_MB_Handle2VirAddr(stFrame.pstPack->pMbBlk);
|
||||
fwrite(pData, 1, stFrame.pstPack->u32Len, venc0_file);
|
||||
fflush(venc0_file);
|
||||
}
|
||||
RK_U64 nowUs = TEST_COMM_GetNowUs();
|
||||
|
||||
printf("chn:0, loopCount:%d enc->seq:%d wd:%d pts=%lld delay=%lldus\n",
|
||||
loopCount, stFrame.u32Seq, stFrame.pstPack->u32Len,
|
||||
stFrame.pstPack->u64PTS, nowUs - stFrame.pstPack->u64PTS);
|
||||
if (fp) {
|
||||
char str[128];
|
||||
snprintf(str, sizeof(str), "seq:%u, pts:%llums\n", stFrame.u32Seq,
|
||||
stFrame.pstPack->u64PTS / 1000);
|
||||
fputs(str, fp);
|
||||
fsync(fileno(fp));
|
||||
}
|
||||
|
||||
s32Ret = RK_MPI_VENC_ReleaseStream(0, &stFrame);
|
||||
loopCount++;
|
||||
} else {
|
||||
printf("RK_MPI_VENC_GetChnFrame fail %x\n", s32Ret);
|
||||
}
|
||||
|
||||
if ((g_s32FrameCnt >= 0) && (loopCount > g_s32FrameCnt)) {
|
||||
quit = true;
|
||||
break;
|
||||
}
|
||||
|
||||
usleep(10 * 1000);
|
||||
}
|
||||
|
||||
if (venc0_file)
|
||||
fclose(venc0_file);
|
||||
|
||||
if (fp)
|
||||
fclose(fp);
|
||||
|
||||
free(stFrame.pstPack);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
static RK_S32 test_venc_init(int chnId, int width, int height, int max_width,
|
||||
int max_height, RK_CODEC_ID_E enType) {
|
||||
VENC_RECV_PIC_PARAM_S stRecvParam;
|
||||
VENC_CHN_BUF_WRAP_S stVencChnBufWrap;
|
||||
VENC_CHN_REF_BUF_SHARE_S stVencChnRefBufShare;
|
||||
VENC_CHN_ATTR_S stAttr;
|
||||
RK_U32 fps = 0;
|
||||
RK_U32 gop = 0;
|
||||
|
||||
fps = (RK_U32)get_cmd_val("rk_cam_fps", 10);
|
||||
RK_ASSERT(fps > 0);
|
||||
gop = fps * 2;
|
||||
|
||||
memset(&stAttr, 0, sizeof(VENC_CHN_ATTR_S));
|
||||
|
||||
memset(&stVencChnRefBufShare, 0, sizeof(VENC_CHN_REF_BUF_SHARE_S));
|
||||
stVencChnRefBufShare.bEnable = true;
|
||||
|
||||
#if 0
|
||||
if (enType == RK_VIDEO_ID_AVC) {
|
||||
stAttr.stRcAttr.enRcMode = VENC_RC_MODE_H264CBR;
|
||||
stAttr.stRcAttr.stH264Cbr.u32BitRate = g_pAppParam->venc_bitrate;
|
||||
stAttr.stRcAttr.stH264Cbr.u32Gop = gop;
|
||||
} else if (enType == RK_VIDEO_ID_HEVC) {
|
||||
stAttr.stRcAttr.enRcMode = VENC_RC_MODE_H265CBR;
|
||||
stAttr.stRcAttr.stH265Cbr.u32BitRate = g_pAppParam->venc_bitrate;
|
||||
stAttr.stRcAttr.stH265Cbr.u32Gop = gop;
|
||||
}
|
||||
#endif
|
||||
if (enType == RK_VIDEO_ID_AVC) {
|
||||
stAttr.stRcAttr.enRcMode = VENC_RC_MODE_H264VBR;
|
||||
stAttr.stRcAttr.stH264Vbr.u32BitRate = g_pAppParam->venc_bitrate;
|
||||
stAttr.stRcAttr.stH264Vbr.u32MaxBitRate = g_pAppParam->venc_bitrate;
|
||||
stAttr.stRcAttr.stH264Vbr.u32MinBitRate = 200;
|
||||
stAttr.stRcAttr.stH264Vbr.u32Gop = gop;
|
||||
stAttr.stRcAttr.stH264Vbr.u32SrcFrameRateNum = fps;
|
||||
stAttr.stRcAttr.stH264Vbr.u32SrcFrameRateDen = 1;
|
||||
stAttr.stRcAttr.stH264Vbr.fr32DstFrameRateNum = fps;
|
||||
stAttr.stRcAttr.stH264Vbr.fr32DstFrameRateDen = 1;
|
||||
} else if (enType == RK_VIDEO_ID_HEVC) {
|
||||
stAttr.stRcAttr.enRcMode = VENC_RC_MODE_H265VBR;
|
||||
stAttr.stRcAttr.stH265Vbr.u32BitRate = g_pAppParam->venc_bitrate;
|
||||
stAttr.stRcAttr.stH265Vbr.u32MaxBitRate = g_pAppParam->venc_bitrate;
|
||||
stAttr.stRcAttr.stH265Vbr.u32MinBitRate = 200;
|
||||
stAttr.stRcAttr.stH265Vbr.u32Gop = gop;
|
||||
stAttr.stRcAttr.stH265Vbr.u32SrcFrameRateNum = fps;
|
||||
stAttr.stRcAttr.stH265Vbr.u32SrcFrameRateDen = 1;
|
||||
stAttr.stRcAttr.stH265Vbr.fr32DstFrameRateNum = fps;
|
||||
stAttr.stRcAttr.stH265Vbr.fr32DstFrameRateDen = 1;
|
||||
}
|
||||
|
||||
stAttr.stVencAttr.enType = enType;
|
||||
stAttr.stVencAttr.enPixelFormat = RK_FMT_YUV420SP;
|
||||
if (enType == RK_VIDEO_ID_AVC)
|
||||
stAttr.stVencAttr.u32Profile = H264E_PROFILE_HIGH;
|
||||
else if (enType == RK_VIDEO_ID_HEVC)
|
||||
stAttr.stVencAttr.u32Profile = H265E_PROFILE_MAIN;
|
||||
stAttr.stVencAttr.u32PicWidth = width;
|
||||
stAttr.stVencAttr.u32PicHeight = height;
|
||||
stAttr.stVencAttr.u32VirWidth = width;
|
||||
stAttr.stVencAttr.u32VirHeight = height;
|
||||
stAttr.stVencAttr.u32MaxPicWidth = max_width;
|
||||
stAttr.stVencAttr.u32MaxPicHeight = max_height;
|
||||
stAttr.stVencAttr.u32StreamBufCnt = 4;
|
||||
/* stAttr.stVencAttr.u32BufSize = max_width * max_height / 2; */
|
||||
stAttr.stVencAttr.u32BufSize = max_width * max_height;
|
||||
stAttr.stVencAttr.enMirror = MIRROR_NONE;
|
||||
|
||||
RK_MPI_VENC_CreateChn(chnId, &stAttr);
|
||||
if (g_bWrap == true) {
|
||||
stVencChnBufWrap.bEnable = g_bWrap;
|
||||
stVencChnBufWrap.u32BufLine = g_u32WrapLine;
|
||||
RK_MPI_VENC_SetChnBufWrapAttr(chnId, &stVencChnBufWrap);
|
||||
}
|
||||
RK_MPI_VENC_SetChnRefBufShareAttr(chnId, &stVencChnRefBufShare);
|
||||
|
||||
VENC_RC_PARAM_S stRcParam;
|
||||
memset(&stRcParam, 0, sizeof(stRcParam));
|
||||
if (enType == RK_VIDEO_ID_AVC) {
|
||||
stRcParam.s32FirstFrameStartQp = 28;
|
||||
stRcParam.stParamH264.u32MinQp = 10;
|
||||
stRcParam.stParamH264.u32MaxQp = 51;
|
||||
stRcParam.stParamH264.u32MinIQp = 10;
|
||||
stRcParam.stParamH264.u32MaxIQp = 51;
|
||||
stRcParam.stParamH264.u32FrmMinQp = 25;
|
||||
stRcParam.stParamH264.u32FrmMinIQp = 24;
|
||||
stRcParam.stParamH264.u32FrmMaxQp = 41;
|
||||
stRcParam.stParamH264.u32FrmMaxIQp = 35;
|
||||
} else if (enType == RK_VIDEO_ID_HEVC) {
|
||||
stRcParam.s32FirstFrameStartQp = 28;
|
||||
stRcParam.stParamH265.u32MinQp = 10;
|
||||
stRcParam.stParamH265.u32MaxQp = 51;
|
||||
stRcParam.stParamH265.u32MinIQp = 10;
|
||||
stRcParam.stParamH265.u32MaxIQp = 51;
|
||||
stRcParam.stParamH265.u32FrmMinQp = 25;
|
||||
stRcParam.stParamH265.u32FrmMinIQp = 24;
|
||||
stRcParam.stParamH265.u32FrmMaxQp = 41;
|
||||
stRcParam.stParamH265.u32FrmMaxIQp = 35;
|
||||
}
|
||||
RK_MPI_VENC_SetRcParam(chnId, &stRcParam);
|
||||
|
||||
RK_MPI_VENC_EnableSvc(chnId, RK_TRUE);
|
||||
|
||||
memset(&stRecvParam, 0, sizeof(VENC_RECV_PIC_PARAM_S));
|
||||
stRecvParam.s32RecvPicNum = -1;
|
||||
RK_MPI_VENC_StartRecvFrame(chnId, &stRecvParam);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vi_dev_init() {
|
||||
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) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// 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) {
|
||||
return -1;
|
||||
}
|
||||
// 1-3.bind dev/pipe
|
||||
stBindPipe.u32Num = 1;
|
||||
stBindPipe.PipeId[0] = pipeId;
|
||||
stBindPipe.bUserStartPipe[0] = RK_TRUE;
|
||||
ret = RK_MPI_VI_SetDevBindPipe(devId, &stBindPipe);
|
||||
if (ret != RK_SUCCESS) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vi_chn_init(int channelId, int width, int height, int max_width, int max_height) {
|
||||
int ret;
|
||||
int buf_cnt = 3;
|
||||
|
||||
// VI init
|
||||
VI_CHN_ATTR_S vi_chn_attr;
|
||||
|
||||
if (g_bWrap == false) {
|
||||
buf_cnt = 1;
|
||||
}
|
||||
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_chn_attr.stSize.u32Width = width;
|
||||
vi_chn_attr.stSize.u32Height = height;
|
||||
vi_chn_attr.stIspOpt.stMaxSize.u32Width = max_width;
|
||||
vi_chn_attr.stIspOpt.stMaxSize.u32Height = max_height;
|
||||
vi_chn_attr.enPixelFormat = RK_FMT_YUV420SP;
|
||||
vi_chn_attr.enCompressMode = COMPRESS_MODE_NONE;
|
||||
vi_chn_attr.u32Depth = 2;
|
||||
|
||||
if (g_sEntityName != NULL)
|
||||
memcpy(vi_chn_attr.stIspOpt.aEntityName, g_sEntityName, strlen(g_sEntityName));
|
||||
ret = RK_MPI_VI_SetChnAttr(0, channelId, &vi_chn_attr);
|
||||
|
||||
if (g_bWrap == true) {
|
||||
g_stViWrap.bEnable = g_bWrap;
|
||||
g_stViWrap.u32BufLine = g_u32WrapLine;
|
||||
g_stViWrap.u32WrapBufferSize = g_stViWrap.u32BufLine * max_width * 3 / 2;
|
||||
RK_MPI_VI_SetChnWrapBufAttr(0, channelId, &g_stViWrap);
|
||||
|
||||
ret |= RK_MPI_VI_EnableChnExt(0, channelId);
|
||||
if (ret) {
|
||||
printf("ERROR: create VI error! ret=%d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
ret |= RK_MPI_VI_EnableChn(0, channelId);
|
||||
if (ret) {
|
||||
printf("ERROR: create VI error! ret=%d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int g_err_cnt = 0;
|
||||
static bool g_should_quit = false;
|
||||
|
||||
static XCamReturn SAMPLE_COMM_ISP_ErrCb(rk_aiq_err_msg_t *msg) {
|
||||
g_err_cnt++;
|
||||
if (g_err_cnt <= 2)
|
||||
printf("=== %u ===\n", msg->err_code);
|
||||
if (msg->err_code == XCAM_RETURN_BYPASS)
|
||||
g_should_quit = true;
|
||||
}
|
||||
|
||||
#if 1
|
||||
void klog(const char *log) {
|
||||
FILE *fp = fopen("/dev/kmsg", "w");
|
||||
if (NULL != fp) {
|
||||
fprintf(fp, "[app]: %s\n", log);
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
#else
|
||||
void klog(const char *log) { return; }
|
||||
#endif
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
klog("main");
|
||||
|
||||
RK_S32 s32Ret = RK_FAILURE;
|
||||
RK_U32 u32Width = 0;
|
||||
RK_U32 u32Height = 0;
|
||||
RK_U32 u32MaxWidth = 0;
|
||||
RK_U32 u32MaxHeight = 0;
|
||||
RK_CHAR *pOutPath = NULL;
|
||||
RK_CHAR *pCodecName = "H264";
|
||||
|
||||
RK_CODEC_ID_E enCodecType = RK_VIDEO_ID_Max; // RK_VIDEO_ID_HEVC;
|
||||
RK_S32 s32chnlId = 0;
|
||||
|
||||
int mem_fd = -1;
|
||||
off_t appParamOffs = 0, metaAddr = 0;
|
||||
void *metaVirmem = NULL, *appVirAddr = NULL, *SensorInitVirAddr;
|
||||
RK_U32 metaSize = (RK_U32)get_cmd_val("meta_part_size", 16);
|
||||
metaAddr = (off_t)get_cmd_val("meta_load_addr", 16);
|
||||
if ((mem_fd = open("/dev/mem", O_RDWR | O_SYNC)) < 0) {
|
||||
printf("cannot open /dev/mem.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
metaVirmem =
|
||||
mmap(NULL, metaSize, PROT_READ | PROT_WRITE, MAP_SHARED, mem_fd, metaAddr);
|
||||
if (metaVirmem != MAP_FAILED) {
|
||||
// get sensir init cfg addr, include ircut info
|
||||
SensorInitVirAddr = metaVirmem + SENSOR_INIT_OFFSET;
|
||||
g_pSensorInitParam = (struct sensor_init_cfg *)(SensorInitVirAddr);
|
||||
// get app param addr
|
||||
appVirAddr = metaVirmem + APP_PARAM_OFFSET;
|
||||
g_pAppParam = (struct app_param_info *)(appVirAddr);
|
||||
u32Width = g_pAppParam->venc_w;
|
||||
u32Height = g_pAppParam->venc_h;
|
||||
u32MaxWidth = g_pSensorInitParam->cam_w;
|
||||
u32MaxHeight = g_pSensorInitParam->cam_h;
|
||||
|
||||
switch (g_pAppParam->venc_type) {
|
||||
case 1:
|
||||
enCodecType = RK_VIDEO_ID_AVC; // h.264
|
||||
break;
|
||||
case 2:
|
||||
default:
|
||||
enCodecType = RK_VIDEO_ID_HEVC; // h.265
|
||||
break;
|
||||
}
|
||||
printf("\n read from meta: w:%d, h:%d, bitrate:%d, venc type:%d\n",
|
||||
g_pAppParam->venc_w, g_pAppParam->venc_h, g_pAppParam->venc_bitrate,
|
||||
g_pAppParam->venc_type);
|
||||
} else {
|
||||
printf("mmap fail.\n");
|
||||
goto __FAILED;
|
||||
}
|
||||
|
||||
// ircut pull down to low power mode
|
||||
int gpio_ircut_a = g_pSensorInitParam->ircut_a.gpio_index;
|
||||
int gpio_ircut_b = g_pSensorInitParam->ircut_b.gpio_index;
|
||||
if (gpio_ircut_a >= 0 && gpio_ircut_b >= 0) {
|
||||
rk_gpio_export(gpio_ircut_a);
|
||||
rk_gpio_set_direction(gpio_ircut_a, RK_FALSE);
|
||||
rk_gpio_set_value(gpio_ircut_a, 0);
|
||||
rk_gpio_export(gpio_ircut_b);
|
||||
rk_gpio_set_direction(gpio_ircut_b, RK_FALSE);
|
||||
rk_gpio_set_value(gpio_ircut_b, 0);
|
||||
}
|
||||
|
||||
if (g_bWrap)
|
||||
g_u32WrapLine = u32MaxHeight / 4; // 360 // 1080
|
||||
g_s32FrameCnt = 20;
|
||||
g_sEntityName = "/dev/video11";
|
||||
|
||||
#ifdef ENABLE_GET_STREAM
|
||||
pOutPath = "/tmp/venc-test.bin";
|
||||
|
||||
if (pOutPath) {
|
||||
venc0_file = fopen(pOutPath, "w");
|
||||
if (!venc0_file) {
|
||||
goto __FAILED;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
signal(SIGINT, sigterm_handler);
|
||||
|
||||
if (RK_MPI_SYS_Init() != RK_SUCCESS) {
|
||||
goto __FAILED;
|
||||
}
|
||||
klog("sys_init");
|
||||
test_venc_init(0, u32Width, u32Height, u32MaxWidth, u32MaxHeight,
|
||||
enCodecType); // RK_VIDEO_ID_AVC RK_VIDEO_ID_HEVC
|
||||
klog("venc_init");
|
||||
|
||||
vi_dev_init();
|
||||
klog("vi_dev");
|
||||
vi_chn_init(s32chnlId, u32Width, u32Height, u32MaxWidth, u32MaxHeight);
|
||||
klog("vi_chn");
|
||||
|
||||
MPP_CHN_S stSrcChn, stDestChn;
|
||||
// bind vi to venc
|
||||
stSrcChn.enModId = RK_ID_VI;
|
||||
stSrcChn.s32DevId = 0;
|
||||
stSrcChn.s32ChnId = 0;
|
||||
|
||||
stDestChn.enModId = RK_ID_VENC;
|
||||
stDestChn.s32DevId = 0;
|
||||
stDestChn.s32ChnId = 0;
|
||||
s32Ret = RK_MPI_SYS_Bind(&stSrcChn, &stDestChn);
|
||||
if (s32Ret != RK_SUCCESS) {
|
||||
goto __FAILED;
|
||||
}
|
||||
klog("bind");
|
||||
|
||||
#if 1
|
||||
// venc init, if is fast boot, must first init venc.
|
||||
if (fork() > 0) {
|
||||
|
||||
} else {
|
||||
int loop_time = 0;
|
||||
while (1) {
|
||||
usleep(1000 * 1000); // when client online
|
||||
#ifdef ENABLE_AOV
|
||||
if (loop_time >= 3 && access(AOV_LUNCH_FILE, F_OK) == 0) {
|
||||
printf("file %s has been detect\n", AOV_LUNCH_FILE);
|
||||
break; //kill fastboot_server
|
||||
}
|
||||
#endif
|
||||
loop_time++;
|
||||
}
|
||||
printf("sub service exit main\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
RK_MPI_VI_StartPipe(0);
|
||||
klog("vi resume");
|
||||
#endif
|
||||
|
||||
#ifdef RKAIQ
|
||||
size_t file_size;
|
||||
int ret = 0;
|
||||
void *vir_iqaddr;
|
||||
RK_S64 s64AiqInitStart = TEST_COMM_GetNowUs();
|
||||
|
||||
#ifdef RKAIQ_USE_DLOPEN
|
||||
if (dlsym_rkaiq() != 0) {
|
||||
goto __FAILED;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (pOutPath) {
|
||||
venc0_file = fopen(pOutPath, "w");
|
||||
if (!venc0_file) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// addr_iq = (off_t)get_cmd_val("rk_iqbin_addr", 16);
|
||||
file_size = (int)get_cmd_val("rk_iqbin_size", 16);
|
||||
vir_iqaddr =
|
||||
metaVirmem + SENSOR_IQ_BIN_OFFSET + offsetof(struct sensor_iq_info, data);
|
||||
klog("mmap iq mem");
|
||||
|
||||
int cam_hdr = (int)get_cmd_val("rk_cam_hdr", 0);
|
||||
rk_aiq_working_mode_t hdr_mode =
|
||||
(cam_hdr == 5) ? RK_AIQ_WORKING_MODE_ISP_HDR2 : RK_AIQ_WORKING_MODE_NORMAL;
|
||||
|
||||
rk_aiq_sys_ctx_t *aiq_ctx;
|
||||
rk_aiq_static_info_t aiq_static_info;
|
||||
dlsym_rk_aiq_uapi2_sysctl_enumStaticMetas(s32chnlId, &aiq_static_info);
|
||||
klog("aiq enum");
|
||||
|
||||
if (g_pAppParam->color_mode) {
|
||||
printf("=====night mode=====\n");
|
||||
ret = dlsym_rk_aiq_uapi2_sysctl_preInit_scene(aiq_static_info.sensor_info.sensor_name,
|
||||
"normal", "night");
|
||||
if (ret < 0) {
|
||||
printf("%s: failed to set night scene\n",
|
||||
aiq_static_info.sensor_info.sensor_name);
|
||||
goto __FAILED;
|
||||
}
|
||||
} else {
|
||||
printf("=====day mode=======\n");
|
||||
ret = dlsym_rk_aiq_uapi2_sysctl_preInit_scene(aiq_static_info.sensor_info.sensor_name,
|
||||
"normal", "day");
|
||||
if (ret < 0) {
|
||||
printf("%s: failed to set day scene\n",
|
||||
aiq_static_info.sensor_info.sensor_name);
|
||||
goto __FAILED;
|
||||
}
|
||||
}
|
||||
klog("preint scene");
|
||||
|
||||
ret = dlsym_rk_aiq_uapi2_sysctl_preInit_iq_addr(aiq_static_info.sensor_info.sensor_name,
|
||||
vir_iqaddr, file_size);
|
||||
if (ret < 0) {
|
||||
printf("%s: failed to load binary iqfiles\n",
|
||||
aiq_static_info.sensor_info.sensor_name);
|
||||
}
|
||||
klog("preinit iq addr");
|
||||
|
||||
rk_aiq_tb_info_t tb_info;
|
||||
memset(&tb_info, 0, sizeof(rk_aiq_tb_info_t));
|
||||
tb_info.magic = sizeof(rk_aiq_tb_info_t) - 2;
|
||||
tb_info.is_pre_aiq = true;
|
||||
tb_info.prd_type = RK_AIQ_PRD_TYPE_TB_BATIPC;
|
||||
dlsym_rk_aiq_uapi2_sysctl_preInit_tb_info(aiq_static_info.sensor_info.sensor_name,
|
||||
&tb_info);
|
||||
klog("preinit tb info");
|
||||
|
||||
aiq_ctx =
|
||||
dlsym_rk_aiq_uapi2_sysctl_init(aiq_static_info.sensor_info.sensor_name, "/etc/iqfiles/",
|
||||
SAMPLE_COMM_ISP_ErrCb, NULL);
|
||||
klog("sysctl init");
|
||||
if (aiq_ctx == NULL) {
|
||||
printf("%s: failed to init aiq\n", aiq_static_info.sensor_info.sensor_name);
|
||||
}
|
||||
|
||||
if (dlsym_rk_aiq_uapi2_sysctl_prepare(aiq_ctx, 0, 0, hdr_mode)) {
|
||||
printf("rkaiq engine prepare failed !\n");
|
||||
goto __FAILED;
|
||||
}
|
||||
klog("sysctl prepare");
|
||||
|
||||
if (dlsym_rk_aiq_uapi2_sysctl_start(aiq_ctx)) {
|
||||
printf("rk_aiq_uapi2_sysctl_start failed\n");
|
||||
goto __FAILED;
|
||||
}
|
||||
klog("sysctl start");
|
||||
RK_S64 s64AiqInitEnd = TEST_COMM_GetNowUs();
|
||||
printf("Aiq:%lld us\n", s64AiqInitEnd - s64AiqInitStart);
|
||||
#endif
|
||||
klog("aiq start");
|
||||
#ifdef ENABLE_GET_STREAM
|
||||
pOutPath = "/tmp/venc-test.bin";
|
||||
|
||||
if (pOutPath) {
|
||||
venc0_file = fopen(pOutPath, "w");
|
||||
if (!venc0_file) {
|
||||
goto __FAILED;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_GET_STREAM
|
||||
GetMediaBuffer0(NULL);
|
||||
|
||||
s32Ret = RK_MPI_SYS_UnBind(&stSrcChn, &stDestChn);
|
||||
s32Ret = RK_MPI_VI_DisableChn(0, 0);
|
||||
s32Ret = RK_MPI_VENC_StopRecvFrame(0);
|
||||
if (s32Ret != RK_SUCCESS) {
|
||||
goto __FAILED;
|
||||
}
|
||||
|
||||
s32Ret = RK_MPI_VENC_DestroyChn(0);
|
||||
s32Ret = RK_MPI_VI_DisableDev(0);
|
||||
#endif
|
||||
|
||||
#ifdef RKAIQ
|
||||
int loop_cnt = 0x400;
|
||||
while (1) {
|
||||
if (g_should_quit) {
|
||||
klog("should quit");
|
||||
dlsym_rk_aiq_uapi2_sysctl_stop(aiq_ctx, false);
|
||||
klog("aiq stop");
|
||||
dlsym_rk_aiq_uapi2_sysctl_deinit(aiq_ctx);
|
||||
klog("aiq deinit");
|
||||
break;
|
||||
}
|
||||
usleep(1 * 1000); // when client online
|
||||
if (loop_cnt-- == 0) {
|
||||
klog("aiq timeout exit");
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
__FAILED:
|
||||
#ifdef RKAIQ_USE_DLOPEN
|
||||
if (rkaiq_dl != NULL) {
|
||||
dlclose(rkaiq_dl);
|
||||
}
|
||||
#endif
|
||||
if (metaVirmem != MAP_FAILED)
|
||||
munmap(metaVirmem, metaSize);
|
||||
if (mem_fd != -1)
|
||||
close(mem_fd);
|
||||
printf("main service exit main\n");
|
||||
return 0;
|
||||
}
|
||||
1490
project/app/component/fastboot_server/fastboot_server_dual_camera.c
Normal file
1490
project/app/component/fastboot_server/fastboot_server_dual_camera.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,682 @@
|
||||
/* thunder boot service
|
||||
/1.aiq init & run
|
||||
/2.rockit vi & venc init, bind
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <sys/poll.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include <stdbool.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <dlfcn.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "rk_type.h"
|
||||
#include "rk_debug.h"
|
||||
#include "rk_defines.h"
|
||||
#include "rk_mpi_venc.h"
|
||||
#include "rk_mpi_vi.h"
|
||||
#include "rk_mpi_sys.h"
|
||||
#include <rk_aiq_user_api2_camgroup.h>
|
||||
#include <rk_aiq_user_api2_imgproc.h>
|
||||
#include <rk_aiq_user_api2_sysctl.h>
|
||||
#include <mediactl/mediactl.h>
|
||||
|
||||
#include "v4l2_link.h"
|
||||
#include "rk_gpio.h"
|
||||
#include "rk_meta.h"
|
||||
#include "sensor_init_info.h"
|
||||
#include "sensor_iq_info.h"
|
||||
#include "rk_meta_app_param.h"
|
||||
|
||||
#define RKAIQ
|
||||
//#define ENABLE_GET_STREAM
|
||||
|
||||
#define SMART_DOOR_IR_FLOOD_MDEV "/dev/media3"
|
||||
#define SMART_DOOR_IR_PROJECTOR_MDEV "/dev/media4"
|
||||
|
||||
#define MAP_SIZE (4096UL * 50) //MAP_SIZE = 4 * 50 K
|
||||
#define MAP_MASK (MAP_SIZE - 1) //MAP_MASK = 0XFFF
|
||||
|
||||
#define MAP_SIZE_NIGHT (4096UL) //MAP_SIZE = 4K
|
||||
#define MAP_MASK_NIGHT (MAP_SIZE_NIGHT - 1) //MAP_MASK = 0XFFF
|
||||
|
||||
void *rkaiq_dl = NULL;
|
||||
XCamReturn (*dlsym_rk_aiq_uapi2_sysctl_enumStaticMetas)(int, rk_aiq_static_info_t*);
|
||||
XCamReturn (*dlsym_rk_aiq_uapi2_sysctl_preInit_scene)(const char*, const char*, const char*);
|
||||
XCamReturn (*dlsym_rk_aiq_uapi2_sysctl_preInit_iq_addr)(const char*, void *, size_t);
|
||||
XCamReturn (*dlsym_rk_aiq_uapi2_sysctl_preInit_tb_info)(const char*, const rk_aiq_tb_info_t*);
|
||||
rk_aiq_sys_ctx_t* (*dlsym_rk_aiq_uapi2_sysctl_init)(const char*,
|
||||
const char*,
|
||||
rk_aiq_error_cb ,
|
||||
rk_aiq_metas_cb );
|
||||
|
||||
XCamReturn (*dlsym_rk_aiq_uapi2_sysctl_prepare)(const rk_aiq_sys_ctx_t*,
|
||||
uint32_t , uint32_t ,
|
||||
rk_aiq_working_mode_t );
|
||||
|
||||
XCamReturn (*dlsym_rk_aiq_uapi2_sysctl_start)(const rk_aiq_sys_ctx_t *);
|
||||
XCamReturn (*dlsym_rk_aiq_uapi2_sysctl_stop)(const rk_aiq_sys_ctx_t*, bool);
|
||||
XCamReturn (*dlsym_rk_aiq_uapi2_sysctl_deinit)(const rk_aiq_sys_ctx_t*);
|
||||
|
||||
static RK_S32 g_s32FrameCnt = -1;
|
||||
static VI_CHN_BUF_WRAP_S g_stViWrap;
|
||||
static bool g_bWrap = false;
|
||||
static RK_U32 g_u32WrapLine = 0;
|
||||
static RK_U32 g_prd_type = RK_AIQ_PRD_TYPE_TB_DOORLOCK;
|
||||
static char *g_sEntityName = NULL;
|
||||
static bool quit = false;
|
||||
static struct app_param_info *g_pAppParam = NULL;
|
||||
static struct sensor_init_cfg *g_pSensorInitParam = NULL;
|
||||
|
||||
|
||||
static void sigterm_handler(int sig)
|
||||
{
|
||||
quit = true;
|
||||
}
|
||||
|
||||
static int dlsym_rkaiq (void)
|
||||
{
|
||||
rkaiq_dl = dlopen("/usr/lib/librkaiq.so", RTLD_LAZY);
|
||||
if (!rkaiq_dl) {
|
||||
printf("\ndlopen /usr/lib/librkaiq.so error\n");
|
||||
return -1;
|
||||
}
|
||||
dlsym_rk_aiq_uapi2_sysctl_enumStaticMetas = dlsym(rkaiq_dl, "rk_aiq_uapi2_sysctl_enumStaticMetas");
|
||||
dlsym_rk_aiq_uapi2_sysctl_preInit_scene = dlsym(rkaiq_dl, "rk_aiq_uapi2_sysctl_preInit_scene");
|
||||
dlsym_rk_aiq_uapi2_sysctl_preInit_iq_addr = dlsym(rkaiq_dl, "rk_aiq_uapi2_sysctl_preInit_iq_addr");
|
||||
dlsym_rk_aiq_uapi2_sysctl_preInit_tb_info = dlsym(rkaiq_dl, "rk_aiq_uapi2_sysctl_preInit_tb_info");
|
||||
dlsym_rk_aiq_uapi2_sysctl_init = dlsym(rkaiq_dl, "rk_aiq_uapi2_sysctl_init");
|
||||
dlsym_rk_aiq_uapi2_sysctl_prepare = dlsym(rkaiq_dl, "rk_aiq_uapi2_sysctl_prepare");
|
||||
dlsym_rk_aiq_uapi2_sysctl_start = dlsym(rkaiq_dl, "rk_aiq_uapi2_sysctl_start");
|
||||
dlsym_rk_aiq_uapi2_sysctl_stop = dlsym(rkaiq_dl, "rk_aiq_uapi2_sysctl_stop");
|
||||
dlsym_rk_aiq_uapi2_sysctl_deinit = dlsym(rkaiq_dl, "rk_aiq_uapi2_sysctl_deinit");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* * get cmdline from /proc/cmdline
|
||||
* */
|
||||
static int read_cmdline_to_buf(void *buf, int len)
|
||||
{
|
||||
int fd;
|
||||
int ret;
|
||||
if (buf == NULL || len < 0) {
|
||||
printf("%s: illegal para\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
memset(buf, 0, len);
|
||||
fd = open("/proc/cmdline", O_RDONLY);
|
||||
if (fd < 0) {
|
||||
perror("open:");
|
||||
return -1;
|
||||
}
|
||||
ret = read(fd, buf, len);
|
||||
close(fd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
long get_cmd_val(const char *string, int len)
|
||||
{
|
||||
char *addr;
|
||||
long value = 0;
|
||||
char key_equal[16];
|
||||
static char cmdline[1024];
|
||||
static char cmd_init = 0;
|
||||
|
||||
if (cmd_init == 0) {
|
||||
cmd_init = 1;
|
||||
memset(cmdline, 0, sizeof(cmdline));
|
||||
read_cmdline_to_buf(cmdline, sizeof(cmdline));
|
||||
}
|
||||
|
||||
snprintf(key_equal, sizeof(key_equal), "%s=", string);
|
||||
addr = strstr(cmdline, string);
|
||||
if (addr) {
|
||||
value = strtol(addr + strlen(string) + 1, NULL, len);
|
||||
printf("get %s value: 0x%0lx\n", string, value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
RK_U64 TEST_COMM_GetNowUs()
|
||||
{
|
||||
struct timespec time = {0, 0};
|
||||
clock_gettime(CLOCK_MONOTONIC, &time);
|
||||
return (RK_U64)time.tv_sec * 1000000 + (RK_U64)time.tv_nsec / 1000; /* microseconds */
|
||||
}
|
||||
|
||||
#ifdef ENABLE_GET_STREAM
|
||||
|
||||
// fast client to get media buffer.
|
||||
static void *GetMediaBuffer0(void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
void *pData = RK_NULL;
|
||||
int loopCount = 0;
|
||||
int s32Ret;
|
||||
VENC_STREAM_S stFrame;
|
||||
|
||||
char *pOutPath = "/tmp/venc-test.bin";
|
||||
FILE *venc0_file = fopen(pOutPath, "w");
|
||||
if (!venc0_file) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
FILE *fp = fopen("/tmp/pts.txt", "wb");
|
||||
|
||||
stFrame.pstPack = malloc(sizeof(VENC_PACK_S));
|
||||
|
||||
while (!quit) {
|
||||
s32Ret = RK_MPI_VENC_GetStream(0, &stFrame, -1);
|
||||
if (s32Ret == RK_SUCCESS) {
|
||||
if (venc0_file) {
|
||||
pData = RK_MPI_MB_Handle2VirAddr(stFrame.pstPack->pMbBlk);
|
||||
fwrite(pData, 1, stFrame.pstPack->u32Len, venc0_file);
|
||||
fflush(venc0_file);
|
||||
}
|
||||
RK_U64 nowUs = TEST_COMM_GetNowUs();
|
||||
|
||||
printf("chn:0, loopCount:%d enc->seq:%d wd:%d pts=%lld delay=%lldus\n", loopCount,
|
||||
stFrame.u32Seq, stFrame.pstPack->u32Len, stFrame.pstPack->u64PTS, nowUs - stFrame.pstPack->u64PTS);
|
||||
if (fp) {
|
||||
char str[128];
|
||||
snprintf(str, sizeof(str), "seq:%u, pts:%llums\n", stFrame.u32Seq, stFrame.pstPack->u64PTS / 1000);
|
||||
fputs(str, fp);
|
||||
fsync(fileno(fp));
|
||||
}
|
||||
|
||||
s32Ret = RK_MPI_VENC_ReleaseStream(0, &stFrame);
|
||||
loopCount++;
|
||||
} else {
|
||||
printf("RK_MPI_VENC_GetChnFrame fail %x\n", s32Ret);
|
||||
}
|
||||
|
||||
if ((g_s32FrameCnt >= 0) && (loopCount > g_s32FrameCnt)) {
|
||||
quit = true;
|
||||
break;
|
||||
}
|
||||
|
||||
usleep(10 * 1000);
|
||||
}
|
||||
|
||||
if (venc0_file)
|
||||
fclose(venc0_file);
|
||||
|
||||
if (fp)
|
||||
fclose(fp);
|
||||
|
||||
free(stFrame.pstPack);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
static RK_S32 test_venc_init(int chnId, int width, int height, int max_width, int max_height,
|
||||
RK_CODEC_ID_E enType)
|
||||
{
|
||||
VENC_RECV_PIC_PARAM_S stRecvParam;
|
||||
VENC_CHN_BUF_WRAP_S stVencChnBufWrap;
|
||||
VENC_CHN_REF_BUF_SHARE_S stVencChnRefBufShare;
|
||||
VENC_CHN_ATTR_S stAttr;
|
||||
RK_U32 fps = 0;
|
||||
RK_U32 gop = 0;
|
||||
|
||||
fps = (RK_U32)get_cmd_val("rk_cam_fps", 10);
|
||||
RK_ASSERT(fps > 0);
|
||||
gop = fps * 2;
|
||||
|
||||
memset(&stAttr, 0, sizeof(VENC_CHN_ATTR_S));
|
||||
stVencChnBufWrap.bEnable = g_bWrap;
|
||||
stVencChnBufWrap.u32BufLine = g_u32WrapLine;
|
||||
|
||||
memset(&stVencChnRefBufShare, 0, sizeof(VENC_CHN_REF_BUF_SHARE_S));
|
||||
stVencChnRefBufShare.bEnable = true;
|
||||
|
||||
#if 0
|
||||
if (enType == RK_VIDEO_ID_AVC) {
|
||||
stAttr.stRcAttr.enRcMode = VENC_RC_MODE_H264CBR;
|
||||
stAttr.stRcAttr.stH264Cbr.u32BitRate = g_pAppParam->venc_bitrate;
|
||||
stAttr.stRcAttr.stH264Cbr.u32Gop = gop;
|
||||
} else if (enType == RK_VIDEO_ID_HEVC) {
|
||||
stAttr.stRcAttr.enRcMode = VENC_RC_MODE_H265CBR;
|
||||
stAttr.stRcAttr.stH265Cbr.u32BitRate = g_pAppParam->venc_bitrate;
|
||||
stAttr.stRcAttr.stH265Cbr.u32Gop = gop;
|
||||
}
|
||||
#endif
|
||||
if (enType == RK_VIDEO_ID_AVC) {
|
||||
stAttr.stRcAttr.enRcMode = VENC_RC_MODE_H264VBR;
|
||||
stAttr.stRcAttr.stH264Vbr.u32BitRate = g_pAppParam->venc_bitrate;
|
||||
stAttr.stRcAttr.stH264Vbr.u32MaxBitRate = g_pAppParam->venc_bitrate;
|
||||
stAttr.stRcAttr.stH264Vbr.u32MinBitRate = 200;
|
||||
stAttr.stRcAttr.stH264Vbr.u32Gop = gop;
|
||||
stAttr.stRcAttr.stH264Vbr.u32SrcFrameRateNum = fps;
|
||||
stAttr.stRcAttr.stH264Vbr.u32SrcFrameRateDen = 1;
|
||||
stAttr.stRcAttr.stH264Vbr.fr32DstFrameRateNum = fps;
|
||||
stAttr.stRcAttr.stH264Vbr.fr32DstFrameRateDen = 1;
|
||||
} else if (enType == RK_VIDEO_ID_HEVC) {
|
||||
stAttr.stRcAttr.enRcMode = VENC_RC_MODE_H265VBR;
|
||||
stAttr.stRcAttr.stH265Vbr.u32BitRate = g_pAppParam->venc_bitrate;
|
||||
stAttr.stRcAttr.stH265Vbr.u32MaxBitRate = g_pAppParam->venc_bitrate;
|
||||
stAttr.stRcAttr.stH265Vbr.u32MinBitRate = 200;
|
||||
stAttr.stRcAttr.stH265Vbr.u32Gop = gop;
|
||||
stAttr.stRcAttr.stH265Vbr.u32SrcFrameRateNum = fps;
|
||||
stAttr.stRcAttr.stH265Vbr.u32SrcFrameRateDen = 1;
|
||||
stAttr.stRcAttr.stH265Vbr.fr32DstFrameRateNum = fps;
|
||||
stAttr.stRcAttr.stH265Vbr.fr32DstFrameRateDen = 1;
|
||||
}
|
||||
|
||||
stAttr.stVencAttr.enType = enType;
|
||||
stAttr.stVencAttr.enPixelFormat = RK_FMT_YUV420SP;
|
||||
if (enType == RK_VIDEO_ID_AVC)
|
||||
stAttr.stVencAttr.u32Profile = H264E_PROFILE_HIGH;
|
||||
else if (enType == RK_VIDEO_ID_HEVC)
|
||||
stAttr.stVencAttr.u32Profile = H265E_PROFILE_MAIN;
|
||||
stAttr.stVencAttr.u32PicWidth = width;
|
||||
stAttr.stVencAttr.u32PicHeight = height;
|
||||
stAttr.stVencAttr.u32VirWidth = width;
|
||||
stAttr.stVencAttr.u32VirHeight = height;
|
||||
stAttr.stVencAttr.u32MaxPicWidth = max_width;
|
||||
stAttr.stVencAttr.u32MaxPicHeight = max_height;
|
||||
stAttr.stVencAttr.u32StreamBufCnt = 4;
|
||||
/* stAttr.stVencAttr.u32BufSize = max_width * max_height / 2; */
|
||||
stAttr.stVencAttr.u32BufSize = max_width * max_height;
|
||||
stAttr.stVencAttr.enMirror = MIRROR_NONE;
|
||||
|
||||
RK_MPI_VENC_CreateChn(chnId, &stAttr);
|
||||
if (g_bWrap)
|
||||
RK_MPI_VENC_SetChnBufWrapAttr(chnId, &stVencChnBufWrap);
|
||||
RK_MPI_VENC_SetChnRefBufShareAttr(chnId, &stVencChnRefBufShare);
|
||||
|
||||
VENC_RC_PARAM_S stRcParam;
|
||||
memset(&stRcParam, 0, sizeof(stRcParam));
|
||||
if (enType == RK_VIDEO_ID_AVC) {
|
||||
stRcParam.s32FirstFrameStartQp = 28;
|
||||
stRcParam.stParamH264.u32MinQp = 10;
|
||||
stRcParam.stParamH264.u32MaxQp = 51;
|
||||
stRcParam.stParamH264.u32MinIQp = 10;
|
||||
stRcParam.stParamH264.u32MaxIQp = 51;
|
||||
stRcParam.stParamH264.u32FrmMinQp = 25;
|
||||
stRcParam.stParamH264.u32FrmMinIQp = 24;
|
||||
stRcParam.stParamH264.u32FrmMaxQp = 41;
|
||||
stRcParam.stParamH264.u32FrmMaxIQp = 35;
|
||||
} else if (enType == RK_VIDEO_ID_HEVC) {
|
||||
stRcParam.s32FirstFrameStartQp = 28;
|
||||
stRcParam.stParamH265.u32MinQp = 10;
|
||||
stRcParam.stParamH265.u32MaxQp = 51;
|
||||
stRcParam.stParamH265.u32MinIQp = 10;
|
||||
stRcParam.stParamH265.u32MaxIQp = 51;
|
||||
stRcParam.stParamH265.u32FrmMinQp = 25;
|
||||
stRcParam.stParamH265.u32FrmMinIQp = 24;
|
||||
stRcParam.stParamH265.u32FrmMaxQp = 41;
|
||||
stRcParam.stParamH265.u32FrmMaxIQp = 35;
|
||||
}
|
||||
RK_MPI_VENC_SetRcParam(chnId, &stRcParam);
|
||||
|
||||
RK_MPI_VENC_EnableSvc(chnId, RK_TRUE);
|
||||
|
||||
memset(&stRecvParam, 0, sizeof(VENC_RECV_PIC_PARAM_S));
|
||||
stRecvParam.s32RecvPicNum = -1;
|
||||
RK_MPI_VENC_StartRecvFrame(chnId, &stRecvParam);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vi_dev_init()
|
||||
{
|
||||
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) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// 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) {
|
||||
return -1;
|
||||
}
|
||||
// 1-3.bind dev/pipe
|
||||
stBindPipe.u32Num = 1;
|
||||
stBindPipe.PipeId[0] = pipeId;
|
||||
stBindPipe.bUserStartPipe[0] = RK_TRUE;
|
||||
ret = RK_MPI_VI_SetDevBindPipe(devId, &stBindPipe);
|
||||
if (ret != RK_SUCCESS) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vi_chn_init(int channelId, int width, int height, int max_width, int max_height)
|
||||
{
|
||||
int ret;
|
||||
int buf_cnt = 3;
|
||||
|
||||
// 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_chn_attr.stSize.u32Width = width;
|
||||
vi_chn_attr.stSize.u32Height = height;
|
||||
vi_chn_attr.stIspOpt.stMaxSize.u32Width = max_width;
|
||||
vi_chn_attr.stIspOpt.stMaxSize.u32Height = max_height;
|
||||
vi_chn_attr.enPixelFormat = RK_FMT_YUV420SP;
|
||||
vi_chn_attr.enCompressMode = COMPRESS_MODE_NONE;
|
||||
vi_chn_attr.u32Depth = 2;
|
||||
|
||||
if (g_sEntityName != NULL)
|
||||
memcpy(vi_chn_attr.stIspOpt.aEntityName, g_sEntityName, strlen(g_sEntityName));
|
||||
ret = RK_MPI_VI_SetChnAttr(0, channelId, &vi_chn_attr);
|
||||
|
||||
g_stViWrap.bEnable = g_bWrap;
|
||||
g_stViWrap.u32BufLine = g_u32WrapLine;
|
||||
g_stViWrap.u32WrapBufferSize = g_stViWrap.u32BufLine * max_width * 3 / 2;
|
||||
if (g_bWrap)
|
||||
RK_MPI_VI_SetChnWrapBufAttr(0, channelId, &g_stViWrap);
|
||||
|
||||
ret |= RK_MPI_VI_EnableChnExt(0, channelId);
|
||||
if (ret) {
|
||||
printf("ERROR: create VI error! ret=%d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int g_err_cnt = 0;
|
||||
static bool g_should_quit = false;
|
||||
|
||||
static XCamReturn SAMPLE_COMM_ISP_ErrCb(rk_aiq_err_msg_t *msg)
|
||||
{
|
||||
g_err_cnt++;
|
||||
if (g_err_cnt <= 2)
|
||||
printf("=== %u ===\n", msg->err_code);
|
||||
if (msg->err_code == XCAM_RETURN_BYPASS)
|
||||
g_should_quit = true;
|
||||
}
|
||||
|
||||
#if 1
|
||||
void klog(const char *log)
|
||||
{
|
||||
FILE *fp = fopen("/dev/kmsg", "w");
|
||||
if (NULL != fp) {
|
||||
fprintf(fp, "[app]: %s\n", log);
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
#else
|
||||
void klog(const char *log)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* link isp before all video stream on */
|
||||
int v4l2_isp_luma_link_init(const char *mdev_path_isp_flood, const char *mdev_path_isp_pro)
|
||||
{
|
||||
v4l2_media_link_rawrd(mdev_path_isp_flood, true);
|
||||
|
||||
v4l2_media_link_rawrd(mdev_path_isp_pro, true);
|
||||
|
||||
v4l2_media_copy_isp_entity(mdev_path_isp_flood, mdev_path_isp_pro);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
klog(__FILE__);
|
||||
|
||||
RK_S32 s32Ret = RK_FAILURE;
|
||||
RK_U32 u32Width = 0;
|
||||
RK_U32 u32Height = 0;
|
||||
RK_U32 u32MaxWidth = 0;
|
||||
RK_U32 u32MaxHeight = 0;
|
||||
RK_CHAR *pCodecName = "H264";
|
||||
|
||||
RK_CODEC_ID_E enCodecType = RK_VIDEO_ID_Max;//RK_VIDEO_ID_HEVC;
|
||||
RK_S32 s32chnlId = 0;
|
||||
int aiq_index = -1;
|
||||
|
||||
v4l2_isp_luma_link_init(SMART_DOOR_IR_FLOOD_MDEV, SMART_DOOR_IR_PROJECTOR_MDEV);
|
||||
|
||||
int mem_fd = -1;
|
||||
off_t appParamOffs = 0, metaAddr = 0;
|
||||
void *metaVirmem = NULL, *appVirAddr = NULL, *SensorInitVirAddr;
|
||||
RK_U32 metaSize = (RK_U32)get_cmd_val("meta_part_size", 16);
|
||||
metaAddr = (off_t)get_cmd_val("meta_load_addr", 16);
|
||||
if ((mem_fd = open("/dev/mem", O_RDWR | O_SYNC)) < 0) {
|
||||
printf("cannot open /dev/mem.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
metaVirmem = mmap(NULL, metaSize, PROT_READ | PROT_WRITE, MAP_SHARED, mem_fd, metaAddr);
|
||||
if (metaVirmem != MAP_FAILED) {
|
||||
//get sensir init cfg addr, include ircut info
|
||||
SensorInitVirAddr = metaVirmem + SENSOR_INIT_OFFSET;
|
||||
g_pSensorInitParam = (struct sensor_init_cfg *)(SensorInitVirAddr);
|
||||
//get app param addr
|
||||
appVirAddr = metaVirmem + APP_PARAM_OFFSET;
|
||||
g_pAppParam = (struct app_param_info *)(appVirAddr);
|
||||
u32Width = g_pAppParam->venc_w;
|
||||
u32Height = g_pAppParam->venc_h;
|
||||
u32MaxWidth = g_pSensorInitParam->cam_w;
|
||||
u32MaxHeight = g_pSensorInitParam->cam_h;
|
||||
|
||||
switch (g_pAppParam->venc_type) {
|
||||
case 1:
|
||||
enCodecType = RK_VIDEO_ID_AVC; // h.264
|
||||
break;
|
||||
case 2:
|
||||
default:
|
||||
enCodecType = RK_VIDEO_ID_HEVC; // h.265
|
||||
break;
|
||||
}
|
||||
printf("\n read from meta: w:%d, h:%d, bitrate:%d, venc type:%d\n",
|
||||
g_pAppParam->venc_w, g_pAppParam->venc_h,
|
||||
g_pAppParam->venc_bitrate, g_pAppParam->venc_type);
|
||||
} else {
|
||||
printf("mmap fail.\n");
|
||||
goto __FAILED;
|
||||
}
|
||||
|
||||
//ircut pull down to low power mode
|
||||
int gpio_ircut_a = g_pSensorInitParam->ircut_a.gpio_index;
|
||||
int gpio_ircut_b = g_pSensorInitParam->ircut_b.gpio_index;
|
||||
if (gpio_ircut_a >= 0 && gpio_ircut_b >= 0) {
|
||||
rk_gpio_export(gpio_ircut_a);
|
||||
rk_gpio_set_direction(gpio_ircut_a, RK_FALSE);
|
||||
rk_gpio_set_value(gpio_ircut_a, 0);
|
||||
rk_gpio_export(gpio_ircut_b);
|
||||
rk_gpio_set_direction(gpio_ircut_b, RK_FALSE);
|
||||
rk_gpio_set_value(gpio_ircut_b, 0);
|
||||
}
|
||||
|
||||
if (g_bWrap)
|
||||
g_u32WrapLine = u32Height / 4; // 360 // 1080
|
||||
g_s32FrameCnt = 20;
|
||||
g_sEntityName = "/dev/video22";
|
||||
|
||||
signal(SIGINT, sigterm_handler);
|
||||
|
||||
if (RK_MPI_SYS_Init() != RK_SUCCESS) {
|
||||
goto __FAILED;
|
||||
}
|
||||
klog("sys_init");
|
||||
test_venc_init(0, u32Width, u32Height, u32MaxWidth, u32MaxHeight,
|
||||
enCodecType);//RK_VIDEO_ID_AVC RK_VIDEO_ID_HEVC
|
||||
klog("venc_init");
|
||||
|
||||
vi_dev_init();
|
||||
klog("vi_dev");
|
||||
vi_chn_init(s32chnlId, u32Width, u32Height, u32MaxWidth, u32MaxHeight);
|
||||
klog("vi_chn");
|
||||
|
||||
MPP_CHN_S stSrcChn, stDestChn;
|
||||
// bind vi to venc
|
||||
stSrcChn.enModId = RK_ID_VI;
|
||||
stSrcChn.s32DevId = 0;
|
||||
stSrcChn.s32ChnId = 0;
|
||||
|
||||
stDestChn.enModId = RK_ID_VENC;
|
||||
stDestChn.s32DevId = 0;
|
||||
stDestChn.s32ChnId = 0;
|
||||
s32Ret = RK_MPI_SYS_Bind(&stSrcChn, &stDestChn);
|
||||
if (s32Ret != RK_SUCCESS) {
|
||||
goto __FAILED;
|
||||
}
|
||||
klog("bind");
|
||||
|
||||
#if 1
|
||||
// venc init, if is fast boot, must first init venc.
|
||||
if (fork() > 0) {
|
||||
|
||||
} else {
|
||||
while (1)
|
||||
usleep(1000 * 1000); //when client online
|
||||
printf("sub service exit main\n");
|
||||
goto __FAILED;
|
||||
}
|
||||
|
||||
RK_MPI_VI_StartPipe(0);
|
||||
klog("vi resume");
|
||||
#endif
|
||||
|
||||
#ifdef RKAIQ
|
||||
size_t file_size;
|
||||
int ret = 0;
|
||||
void *vir_iqaddr;
|
||||
RK_S64 s64AiqInitStart = TEST_COMM_GetNowUs();
|
||||
|
||||
if (dlsym_rkaiq() != 0) {
|
||||
goto __FAILED;
|
||||
}
|
||||
|
||||
// addr_iq = (off_t)get_cmd_val("rk_iqbin_addr", 16);
|
||||
file_size = (int)get_cmd_val("rk_iqbin_size", 16);
|
||||
vir_iqaddr = metaVirmem + SENSOR_IQ_BIN_OFFSET + offsetof(struct sensor_iq_info, data);
|
||||
klog("mmap iq mem");
|
||||
|
||||
int cam_hdr = (int)get_cmd_val("rk_cam_hdr", 0);
|
||||
rk_aiq_working_mode_t hdr_mode = (cam_hdr == 5) ? RK_AIQ_WORKING_MODE_ISP_HDR2 :
|
||||
RK_AIQ_WORKING_MODE_NORMAL;
|
||||
|
||||
rk_aiq_sys_ctx_t *aiq_ctx;
|
||||
const char *sensor_name = "m00_b_gc2093 4-0037";
|
||||
|
||||
klog("aiq enum");
|
||||
|
||||
if (g_pAppParam->color_mode) {
|
||||
printf("=====night mode=====\n");
|
||||
ret = dlsym_rk_aiq_uapi2_sysctl_preInit_scene(sensor_name, "normal", "night");
|
||||
if (ret < 0) {
|
||||
printf("%s: failed to set night scene\n", sensor_name);
|
||||
goto __FAILED;
|
||||
}
|
||||
} else {
|
||||
printf("=====day mode=======\n");
|
||||
ret = dlsym_rk_aiq_uapi2_sysctl_preInit_scene(sensor_name, "normal", "day");
|
||||
if (ret < 0) {
|
||||
printf("%s: failed to set day scene\n", sensor_name);
|
||||
goto __FAILED;
|
||||
}
|
||||
}
|
||||
klog("preint scene");
|
||||
|
||||
ret = dlsym_rk_aiq_uapi2_sysctl_preInit_iq_addr(sensor_name, vir_iqaddr,
|
||||
(size_t)file_size);
|
||||
if (ret < 0) {
|
||||
printf("%s: failed to load binary iqfiles\n", sensor_name);
|
||||
}
|
||||
klog("preinit iq addr");
|
||||
|
||||
rk_aiq_tb_info_t tb_info;
|
||||
|
||||
memset(&tb_info, 0x00, sizeof(tb_info));
|
||||
|
||||
tb_info.magic = sizeof(rk_aiq_tb_info_t) - 2;
|
||||
tb_info.is_pre_aiq = true;
|
||||
tb_info.prd_type = g_prd_type;
|
||||
|
||||
dlsym_rk_aiq_uapi2_sysctl_preInit_tb_info(sensor_name, &tb_info);
|
||||
klog("preinit tb info");
|
||||
|
||||
klog(sensor_name);
|
||||
aiq_ctx = dlsym_rk_aiq_uapi2_sysctl_init(sensor_name,
|
||||
"/etc/iqfiles/", SAMPLE_COMM_ISP_ErrCb, NULL);
|
||||
klog("sysctl init");
|
||||
if (!aiq_ctx) {
|
||||
printf("%s: failed to init aiq\n", sensor_name);
|
||||
goto __FAILED;
|
||||
}
|
||||
|
||||
if (dlsym_rk_aiq_uapi2_sysctl_prepare(aiq_ctx, 0, 0, hdr_mode)) {
|
||||
printf("rkaiq engine prepare failed !\n");
|
||||
goto __FAILED;
|
||||
}
|
||||
klog("sysctl prepare");
|
||||
|
||||
if (dlsym_rk_aiq_uapi2_sysctl_start(aiq_ctx)) {
|
||||
printf("rk_aiq_uapi2_sysctl_start failed\n");
|
||||
goto __FAILED;
|
||||
}
|
||||
klog("sysctl start");
|
||||
RK_S64 s64AiqInitEnd = TEST_COMM_GetNowUs();
|
||||
printf("Aiq:%lld us\n", s64AiqInitEnd - s64AiqInitStart);
|
||||
#endif
|
||||
klog("aiq start");
|
||||
|
||||
#ifdef ENABLE_GET_STREAM
|
||||
GetMediaBuffer0(NULL);
|
||||
#endif
|
||||
|
||||
#ifdef RKAIQ
|
||||
int loop_cnt = 0x400;
|
||||
while (1) {
|
||||
if (g_should_quit) {
|
||||
klog("should quit");
|
||||
dlsym_rk_aiq_uapi2_sysctl_stop(aiq_ctx, false);
|
||||
klog("aiq stop");
|
||||
dlsym_rk_aiq_uapi2_sysctl_deinit(aiq_ctx);
|
||||
klog("aiq deinit");
|
||||
break;
|
||||
}
|
||||
usleep(1 * 1000); //when client online
|
||||
if (loop_cnt-- == 0) {
|
||||
klog("aiq timeout exit");
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
__FAILED:
|
||||
if (rkaiq_dl != NULL) {
|
||||
dlclose(rkaiq_dl);
|
||||
}
|
||||
|
||||
if (metaVirmem != MAP_FAILED) munmap(metaVirmem, metaSize);
|
||||
if (mem_fd != -1) close(mem_fd);
|
||||
|
||||
printf("main service exit main\n");
|
||||
return 0;
|
||||
}
|
||||
BIN
project/app/component/fastboot_server/osd_image.data
Normal file
BIN
project/app/component/fastboot_server/osd_image.data
Normal file
Binary file not shown.
247
project/app/component/fastboot_server/v4l2_link.c
Normal file
247
project/app/component/fastboot_server/v4l2_link.c
Normal file
@@ -0,0 +1,247 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <stdbool.h>
|
||||
#include <pthread.h>
|
||||
#include <linux/videodev2.h>
|
||||
|
||||
#include "mediactl/mediactl.h"
|
||||
|
||||
#include "v4l2subdev.h"
|
||||
#include "v4l2_link.h"
|
||||
|
||||
typedef enum {
|
||||
XCAM_RETURN_NO_ERROR = 0,
|
||||
XCAM_RETURN_BYPASS = 1,
|
||||
|
||||
/* errors */
|
||||
XCAM_RETURN_ERROR_FAILED = -1,
|
||||
XCAM_RETURN_ERROR_PARAM = -2,
|
||||
XCAM_RETURN_ERROR_MEM = -3,
|
||||
XCAM_RETURN_ERROR_FILE = -4,
|
||||
XCAM_RETURN_ERROR_ANALYZER = -5,
|
||||
XCAM_RETURN_ERROR_ISP = -6,
|
||||
XCAM_RETURN_ERROR_SENSOR = -7,
|
||||
XCAM_RETURN_ERROR_THREAD = -8,
|
||||
XCAM_RETURN_ERROR_IOCTL = -9,
|
||||
XCAM_RETURN_ERROR_ORDER = -10,
|
||||
XCAM_RETURN_ERROR_TIMEOUT = -20,
|
||||
XCAM_RETURN_ERROR_OUTOFRANGE = -21,
|
||||
XCAM_RETURN_ERROR_UNKNOWN = -255,
|
||||
} XCamReturn;
|
||||
|
||||
#define ISP20HW_SUBM "link:"
|
||||
#define LOGE_CAMHW_SUBM(sub_modules, ...) printf(sub_modules, ##__VA_ARGS__)
|
||||
|
||||
#define GET_ENTITY_NAME(name, path) \
|
||||
do { \
|
||||
entity = rk_media_get_entity_by_name(device, name, \
|
||||
strlen(name));\
|
||||
if(entity) {\
|
||||
entity_name = rk_media_entity_get_devname(entity);\
|
||||
if(entity_name) {\
|
||||
strncpy(isp_info->path, entity_name, \
|
||||
sizeof(isp_info->path));\
|
||||
/*printf("%s node:%s\n", name, entity_name);*/\
|
||||
}\
|
||||
}\
|
||||
} while(0);
|
||||
|
||||
int v4l2_media_link_rawrd(const char *media_dev_path, bool enable)
|
||||
{
|
||||
printf("%s enable:%d\n", __func__, enable);
|
||||
|
||||
struct media_device *device = NULL;
|
||||
struct media_entity *entity = NULL;
|
||||
struct media_pad *src_pad_s = NULL;
|
||||
struct media_pad* src_pad_m = NULL;
|
||||
struct media_pad* src_pad_l = NULL;
|
||||
struct media_pad* sink_pad = NULL;
|
||||
|
||||
device = rk_media_device_new(media_dev_path);
|
||||
if (!device)
|
||||
return XCAM_RETURN_ERROR_FAILED;
|
||||
|
||||
/* Enumerate entities, pads and links. */
|
||||
rk_media_device_enumerate (device);
|
||||
entity = rk_media_get_entity_by_name(device, "rkisp-isp-subdev",
|
||||
strlen("rkisp-isp-subdev"));
|
||||
if(entity) {
|
||||
sink_pad = (struct media_pad *)rk_media_entity_get_pad(entity, 0);
|
||||
if (!sink_pad) {
|
||||
LOGE_CAMHW_SUBM(ISP20HW_SUBM, "get sink pad failed!\n");
|
||||
goto FAIL;
|
||||
}
|
||||
}
|
||||
entity = rk_media_get_entity_by_name(device, "rkisp_rawrd2_s",
|
||||
strlen("rkisp_rawrd2_s"));
|
||||
if(entity) {
|
||||
src_pad_s = (struct media_pad *)rk_media_entity_get_pad(entity, 0);
|
||||
if (!src_pad_s) {
|
||||
LOGE_CAMHW_SUBM(ISP20HW_SUBM, "get source pad s failed!\n");
|
||||
goto FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
if (src_pad_s && sink_pad) {
|
||||
if (enable)
|
||||
rk_media_setup_link(device, src_pad_s, sink_pad, MEDIA_LNK_FL_ENABLED);
|
||||
else
|
||||
rk_media_setup_link(device, src_pad_s, sink_pad, 0);
|
||||
}
|
||||
|
||||
rk_media_device_unref (device);
|
||||
return XCAM_RETURN_NO_ERROR;
|
||||
|
||||
FAIL:
|
||||
rk_media_device_unref (device);
|
||||
return XCAM_RETURN_ERROR_FAILED;
|
||||
}
|
||||
|
||||
static int v4l2_media_copy_pad(struct media_entity *src_entity, struct media_entity *dst_entity, int pad)
|
||||
{
|
||||
enum v4l2_subdev_format_whence which = V4L2_SUBDEV_FORMAT_ACTIVE;
|
||||
struct v4l2_mbus_framefmt format;
|
||||
struct v4l2_rect rect;
|
||||
int ret;
|
||||
|
||||
ret = rk_v4l2_subdev_get_format(src_entity, &format, pad, which);
|
||||
if (ret != 0) {
|
||||
LOGE_CAMHW_SUBM(ISP20HW_SUBM, "v4l2_subdev_get_format pad[%d] error\n", pad);
|
||||
return XCAM_RETURN_ERROR_FAILED;
|
||||
}
|
||||
|
||||
ret = rk_v4l2_subdev_get_selection(src_entity, &rect, pad,
|
||||
V4L2_SEL_TGT_CROP,
|
||||
which);
|
||||
if (ret != 0) {
|
||||
LOGE_CAMHW_SUBM(ISP20HW_SUBM, "v4l2_subdev_get_selection pad[%d] error\n", pad);
|
||||
return XCAM_RETURN_ERROR_FAILED;
|
||||
}
|
||||
|
||||
ret = rk_v4l2_subdev_set_format(dst_entity, &format, pad, which);
|
||||
if (ret != 0) {
|
||||
LOGE_CAMHW_SUBM(ISP20HW_SUBM, "v4l2_subdev_set_format pad[%d] error\n", pad);
|
||||
return XCAM_RETURN_ERROR_FAILED;
|
||||
}
|
||||
|
||||
ret = rk_v4l2_subdev_set_selection(dst_entity, &rect, pad, V4L2_SEL_TGT_CROP, which);
|
||||
if (ret != 0) {
|
||||
LOGE_CAMHW_SUBM(ISP20HW_SUBM, "v4l2_subdev_set_format pad[%d] error\n", pad);
|
||||
return XCAM_RETURN_ERROR_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
int v4l2_media_copy_isp_entity(const char *src_media_dev, const char *dst_media_dev)
|
||||
{
|
||||
struct media_device *src_device = NULL, *dst_device = NULL;
|
||||
struct media_entity *src_entity = NULL, *dst_entity = NULL;
|
||||
int ret;
|
||||
|
||||
src_device = rk_media_device_new(src_media_dev);
|
||||
if (!src_device)
|
||||
return XCAM_RETURN_ERROR_FAILED;
|
||||
|
||||
dst_device = rk_media_device_new(dst_media_dev);
|
||||
if (!dst_device) {
|
||||
rk_media_device_unref(src_device);
|
||||
return XCAM_RETURN_ERROR_FAILED;
|
||||
}
|
||||
|
||||
/* Enumerate entities, pads and links. */
|
||||
rk_media_device_enumerate(src_device);
|
||||
src_entity = rk_media_get_entity_by_name(src_device, "rkisp-isp-subdev",
|
||||
strlen("rkisp-isp-subdev"));
|
||||
if (!src_entity) {
|
||||
LOGE_CAMHW_SUBM(ISP20HW_SUBM, "rkisp-isp-subdev not found in %s!\n", src_media_dev);
|
||||
goto FAIL;
|
||||
}
|
||||
|
||||
/* Enumerate entities, pads and links. */
|
||||
rk_media_device_enumerate(dst_device);
|
||||
dst_entity = rk_media_get_entity_by_name(dst_device, "rkisp-isp-subdev",
|
||||
strlen("rkisp-isp-subdev"));
|
||||
if (!dst_entity) {
|
||||
LOGE_CAMHW_SUBM(ISP20HW_SUBM, "rkisp-isp-subdev not found in %s!\n", dst_media_dev);
|
||||
goto FAIL;
|
||||
}
|
||||
|
||||
ret = v4l2_media_copy_pad(src_entity, dst_entity, 0);
|
||||
if (ret != 0)
|
||||
goto FAIL;
|
||||
|
||||
ret = v4l2_media_copy_pad(src_entity, dst_entity, 2);
|
||||
if (ret != 0)
|
||||
goto FAIL;
|
||||
|
||||
return 0;
|
||||
FAIL:
|
||||
rk_media_device_unref(src_device);
|
||||
rk_media_device_unref(dst_device);
|
||||
return XCAM_RETURN_ERROR_FAILED;
|
||||
}
|
||||
|
||||
int v4l2_media_get_isp_info(const char *media_dev_path,
|
||||
struct media_path_s *isp_info)
|
||||
{
|
||||
struct media_device *device = NULL;
|
||||
struct media_entity *entity = NULL;
|
||||
const char *entity_name = NULL;
|
||||
|
||||
device = rk_media_device_new(media_dev_path);
|
||||
if (!device)
|
||||
return XCAM_RETURN_ERROR_FAILED;
|
||||
|
||||
/* Enumerate entities, pads and links. */
|
||||
rk_media_device_enumerate (device);
|
||||
|
||||
GET_ENTITY_NAME("rkisp-isp-subdev", isp_dev_path);
|
||||
GET_ENTITY_NAME("rkisp_mainpath", main_path);
|
||||
GET_ENTITY_NAME("rkisp_rawrd2_s", rawrd2_s_path);
|
||||
GET_ENTITY_NAME("rkisp-statistics", stats_path);
|
||||
GET_ENTITY_NAME("rkisp-input-params", input_params_path);
|
||||
|
||||
rk_media_device_unref (device);
|
||||
return XCAM_RETURN_NO_ERROR;
|
||||
|
||||
FAIL:
|
||||
rk_media_device_unref (device);
|
||||
return XCAM_RETURN_ERROR_FAILED;
|
||||
}
|
||||
|
||||
int v4l2_media_get_entity_node(const char *media_dev_path,
|
||||
const char *name, char *node)
|
||||
{
|
||||
struct media_device *device = NULL;
|
||||
struct media_entity *entity = NULL;
|
||||
const char *entity_name = NULL;
|
||||
|
||||
device = rk_media_device_new(media_dev_path);
|
||||
if (!device)
|
||||
return XCAM_RETURN_ERROR_FAILED;
|
||||
|
||||
/* Enumerate entities, pads and links. */
|
||||
rk_media_device_enumerate(device);
|
||||
|
||||
entity = rk_media_get_entity_by_name(device, name,
|
||||
strlen(name));
|
||||
if(entity) {
|
||||
entity_name = rk_media_entity_get_devname(entity);
|
||||
if(entity_name) {
|
||||
strcpy(node, entity_name);
|
||||
printf("%s node:%s\n", name, entity_name);
|
||||
}
|
||||
}
|
||||
|
||||
rk_media_device_unref(device);
|
||||
return XCAM_RETURN_NO_ERROR;
|
||||
|
||||
FAIL:
|
||||
rk_media_device_unref(device);
|
||||
return XCAM_RETURN_ERROR_FAILED;
|
||||
}
|
||||
24
project/app/component/fastboot_server/v4l2_link.h
Normal file
24
project/app/component/fastboot_server/v4l2_link.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef __v4l2_link_H__
|
||||
#define __v4l2_link_H__
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#define DEV_PATH_LEN 32
|
||||
struct media_path_s {
|
||||
char media_dev_path[DEV_PATH_LEN];
|
||||
char isp_dev_path[DEV_PATH_LEN];
|
||||
char csi_dev_path[DEV_PATH_LEN];
|
||||
char main_path[DEV_PATH_LEN];
|
||||
char rawrd2_s_path[DEV_PATH_LEN];
|
||||
char stats_path[DEV_PATH_LEN];
|
||||
char input_params_path[DEV_PATH_LEN];
|
||||
};
|
||||
|
||||
int v4l2_media_link_rawrd(const char *media_dev_path, bool enable);
|
||||
int v4l2_media_get_isp_info(const char *media_dev_path,
|
||||
struct media_path_s *isp_info);
|
||||
int v4l2_media_get_entity_node(const char *media_dev_path,
|
||||
const char *name, char *node);
|
||||
int v4l2_media_copy_isp_entity(const char *src_media_dev, const char *dst_media_dev);
|
||||
|
||||
#endif
|
||||
366
project/app/component/fastboot_server/v4l2subdev.h
Normal file
366
project/app/component/fastboot_server/v4l2subdev.h
Normal file
@@ -0,0 +1,366 @@
|
||||
/*
|
||||
* V4L2 subdev interface library
|
||||
*
|
||||
* Copyright (C) 2010-2014 Ideas on board SPRL
|
||||
*
|
||||
* Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published
|
||||
* by the Free Software Foundation; either version 2.1 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __SUBDEV_H__
|
||||
#define __SUBDEV_H__
|
||||
|
||||
#include <linux/v4l2-subdev.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct media_device;
|
||||
struct media_entity;
|
||||
|
||||
/**
|
||||
* @brief Open a sub-device.
|
||||
* @param entity - sub-device media entity.
|
||||
*
|
||||
* Open the V4L2 subdev device node associated with @a entity. The file
|
||||
* descriptor is stored in the media_entity structure.
|
||||
*
|
||||
* @return 0 on success, or a negative error code on failure.
|
||||
*/
|
||||
int rk_v4l2_subdev_open(struct media_entity* entity);
|
||||
|
||||
/**
|
||||
* @brief Close a sub-device.
|
||||
* @param entity - sub-device media entity.
|
||||
*
|
||||
* Close the V4L2 subdev device node associated with the @a entity and opened by
|
||||
* a previous call to v4l2_subdev_open() (either explicit or implicit).
|
||||
*/
|
||||
void rk_v4l2_subdev_close(struct media_entity* entity);
|
||||
|
||||
/**
|
||||
* @brief Retrieve the format on a pad.
|
||||
* @param entity - subdev-device media entity.
|
||||
* @param format - format to be filled.
|
||||
* @param pad - pad number.
|
||||
* @param which - identifier of the format to get.
|
||||
*
|
||||
* Retrieve the current format on the @a entity @a pad and store it in the
|
||||
* @a format structure.
|
||||
*
|
||||
* @a which is set to V4L2_SUBDEV_FORMAT_TRY to retrieve the try format stored
|
||||
* in the file handle, of V4L2_SUBDEV_FORMAT_ACTIVE to retrieve the current
|
||||
* active format.
|
||||
*
|
||||
* @return 0 on success, or a negative error code on failure.
|
||||
*/
|
||||
int rk_v4l2_subdev_get_format(struct media_entity* entity, struct v4l2_mbus_framefmt* format, unsigned int pad,
|
||||
enum v4l2_subdev_format_whence which);
|
||||
|
||||
/**
|
||||
* @brief Set the format on a pad.
|
||||
* @param entity - subdev-device media entity.
|
||||
* @param format - format.
|
||||
* @param pad - pad number.
|
||||
* @param which - identifier of the format to set.
|
||||
*
|
||||
* Set the format on the @a entity @a pad to @a format. The driver is allowed to
|
||||
* modify the requested format, in which case @a format is updated with the
|
||||
* modifications.
|
||||
*
|
||||
* @a which is set to V4L2_SUBDEV_FORMAT_TRY to set the try format stored in the
|
||||
* file handle, of V4L2_SUBDEV_FORMAT_ACTIVE to configure the device with an
|
||||
* active format.
|
||||
*
|
||||
* @return 0 on success, or a negative error code on failure.
|
||||
*/
|
||||
int rk_v4l2_subdev_set_format(struct media_entity* entity, struct v4l2_mbus_framefmt* format, unsigned int pad,
|
||||
enum v4l2_subdev_format_whence which);
|
||||
|
||||
/**
|
||||
* @brief Retrieve a selection rectangle on a pad.
|
||||
* @param entity - subdev-device media entity.
|
||||
* @param r - rectangle to be filled.
|
||||
* @param pad - pad number.
|
||||
* @param target - selection target
|
||||
* @param which - identifier of the format to get.
|
||||
*
|
||||
* Retrieve the @a target selection rectangle on the @a entity @a pad
|
||||
* and store it in the @a rect structure.
|
||||
*
|
||||
* @a which is set to V4L2_SUBDEV_FORMAT_TRY to retrieve the try
|
||||
* selection rectangle stored in the file handle, or
|
||||
* V4L2_SUBDEV_FORMAT_ACTIVE to retrieve the current active selection
|
||||
* rectangle.
|
||||
*
|
||||
* @return 0 on success, or a negative error code on failure.
|
||||
*/
|
||||
int rk_v4l2_subdev_get_selection(struct media_entity* entity, struct v4l2_rect* rect, unsigned int pad,
|
||||
unsigned int target, enum v4l2_subdev_format_whence which);
|
||||
|
||||
/**
|
||||
* @brief Set a selection rectangle on a pad.
|
||||
* @param entity - subdev-device media entity.
|
||||
* @param rect - crop rectangle.
|
||||
* @param pad - pad number.
|
||||
* @param target - selection target
|
||||
* @param which - identifier of the format to set.
|
||||
*
|
||||
* Set the @a target selection rectangle on the @a entity @a pad to @a
|
||||
* rect. The driver is allowed to modify the requested rectangle, in
|
||||
* which case @a rect is updated with the modifications.
|
||||
*
|
||||
* @a which is set to V4L2_SUBDEV_FORMAT_TRY to set the try crop rectangle
|
||||
* stored in the file handle, of V4L2_SUBDEV_FORMAT_ACTIVE to configure the
|
||||
* device with an active crop rectangle.
|
||||
*
|
||||
* @return 0 on success, or a negative error code on failure.
|
||||
*/
|
||||
int rk_v4l2_subdev_set_selection(struct media_entity* entity, struct v4l2_rect* rect, unsigned int pad,
|
||||
unsigned int target, enum v4l2_subdev_format_whence which);
|
||||
|
||||
/**
|
||||
* @brief Query the digital video capabilities of a pad.
|
||||
* @param entity - subdev-device media entity.
|
||||
* @param cap - capabilities to be filled.
|
||||
*
|
||||
* Retrieve the digital video capabilities of the @a entity pad specified by
|
||||
* @a cap.pad and store it in the @a cap structure.
|
||||
*
|
||||
* @return 0 on success, or a negative error code on failure.
|
||||
*/
|
||||
int rk_v4l2_subdev_get_dv_timings_caps(struct media_entity* entity, struct v4l2_dv_timings_cap* caps);
|
||||
|
||||
/**
|
||||
* @brief Query the digital video timings of a sub-device
|
||||
* @param entity - subdev-device media entity.
|
||||
* @param timings timings to be filled.
|
||||
*
|
||||
* Retrieve the detected digital video timings for the currently selected input
|
||||
* of @a entity and store them in the @a timings structure.
|
||||
*
|
||||
* @return 0 on success, or a negative error code on failure.
|
||||
*/
|
||||
int rk_v4l2_subdev_query_dv_timings(struct media_entity* entity, struct v4l2_dv_timings* timings);
|
||||
|
||||
/**
|
||||
* @brief Get the current digital video timings of a sub-device
|
||||
* @param entity - subdev-device media entity.
|
||||
* @param timings timings to be filled.
|
||||
*
|
||||
* Retrieve the current digital video timings for the currently selected input
|
||||
* of @a entity and store them in the @a timings structure.
|
||||
*
|
||||
* @return 0 on success, or a negative error code on failure.
|
||||
*/
|
||||
int rk_v4l2_subdev_get_dv_timings(struct media_entity* entity, struct v4l2_dv_timings* timings);
|
||||
|
||||
/**
|
||||
* @brief Set the digital video timings of a sub-device
|
||||
* @param entity - subdev-device media entity.
|
||||
* @param timings timings to be set.
|
||||
*
|
||||
* Set the digital video timings of @a entity to @a timings. The driver is
|
||||
* allowed to modify the requested format, in which case @a timings is updated
|
||||
* with the modifications.
|
||||
*
|
||||
* @return 0 on success, or a negative error code on failure.
|
||||
*/
|
||||
int rk_v4l2_subdev_set_dv_timings(struct media_entity* entity, struct v4l2_dv_timings* timings);
|
||||
|
||||
/**
|
||||
* @brief Retrieve the frame interval on a sub-device.
|
||||
* @param entity - subdev-device media entity.
|
||||
* @param interval - frame interval to be filled.
|
||||
*
|
||||
* Retrieve the current frame interval on subdev @a entity and store it in the
|
||||
* @a interval structure.
|
||||
*
|
||||
* Frame interval retrieving is usually supported only on devices at the
|
||||
* beginning of video pipelines, such as sensors.
|
||||
*
|
||||
* @return 0 on success, or a negative error code on failure.
|
||||
*/
|
||||
|
||||
int rk_v4l2_subdev_get_frame_interval(struct media_entity* entity, struct v4l2_fract* interval, unsigned int pad);
|
||||
|
||||
/**
|
||||
* @brief Set the frame interval on a sub-device.
|
||||
* @param entity - subdev-device media entity.
|
||||
* @param interval - frame interval.
|
||||
*
|
||||
* Set the frame interval on subdev @a entity to @a interval. The driver is
|
||||
* allowed to modify the requested frame interval, in which case @a interval is
|
||||
* updated with the modifications.
|
||||
*
|
||||
* Frame interval setting is usually supported only on devices at the beginning
|
||||
* of video pipelines, such as sensors.
|
||||
*
|
||||
* @return 0 on success, or a negative error code on failure.
|
||||
*/
|
||||
int rk_v4l2_subdev_set_frame_interval(struct media_entity* entity, struct v4l2_fract* interval, unsigned int pad);
|
||||
|
||||
/**
|
||||
* @brief Parse a string and apply format, crop and frame interval settings.
|
||||
* @param media - media device.
|
||||
* @param p - input string
|
||||
* @param endp - pointer to string p where parsing ended (return)
|
||||
*
|
||||
* Parse string @a p and apply format, crop and frame interval settings to a
|
||||
* subdev pad specified in @a p. @a endp will be written a pointer where
|
||||
* parsing of @a p ended.
|
||||
*
|
||||
* Format strings are separeted by commas (,).
|
||||
*
|
||||
* @return 0 on success, or a negative error code on failure.
|
||||
*/
|
||||
int rk_v4l2_subdev_parse_setup_formats(struct media_device* media, const char* p);
|
||||
|
||||
/**
|
||||
* @brief Convert media bus pixel code to string.
|
||||
* @param code - input string
|
||||
*
|
||||
* Convert media bus pixel code @a code to a human-readable string.
|
||||
*
|
||||
* @return A pointer to a string on success, NULL on failure.
|
||||
*/
|
||||
const char* rk_v4l2_subdev_pixelcode_to_string(enum v4l2_mbus_pixelcode code);
|
||||
|
||||
/**
|
||||
* @brief Parse string to media bus pixel code.
|
||||
* @param string - nul terminalted string, textual media bus pixel code
|
||||
*
|
||||
* Parse human readable string @a string to an media bus pixel code.
|
||||
*
|
||||
* @return media bus pixelcode on success, -1 on failure.
|
||||
*/
|
||||
enum v4l2_mbus_pixelcode rk_v4l2_subdev_string_to_pixelcode(const char* string);
|
||||
|
||||
/**
|
||||
* @brief Convert a field order to string.
|
||||
* @param field - field order
|
||||
*
|
||||
* Convert field order @a field to a human-readable string.
|
||||
*
|
||||
* @return A pointer to a string on success, NULL on failure.
|
||||
*/
|
||||
const char* rk_v4l2_subdev_field_to_string(enum v4l2_field field);
|
||||
|
||||
/**
|
||||
* @brief Parse string to field order.
|
||||
* @param string - nul terminated string, textual media bus pixel code
|
||||
*
|
||||
* Parse human readable string @a string to field order.
|
||||
*
|
||||
* @return field order on success, -1 on failure.
|
||||
*/
|
||||
enum v4l2_field rk_v4l2_subdev_string_to_field(const char* string);
|
||||
|
||||
/**
|
||||
* @brief Convert a colorspace to string.
|
||||
* @param colorspace - colorspace
|
||||
*
|
||||
* Convert colorspace @a colorspace to a human-readable string.
|
||||
*
|
||||
* @return A pointer to a string on success, NULL on failure.
|
||||
*/
|
||||
const char* rk_v4l2_subdev_colorspace_to_string(enum v4l2_colorspace colorspace);
|
||||
|
||||
/**
|
||||
* @brief Parse string to colorspace.
|
||||
* @param string - nul terminated string, textual colorspace
|
||||
*
|
||||
* Parse human readable string @a string to colorspace.
|
||||
*
|
||||
* @return colorspace on success, -1 on failure.
|
||||
*/
|
||||
enum v4l2_colorspace rk_v4l2_subdev_string_to_colorspace(const char* string);
|
||||
|
||||
/**
|
||||
* @brief Convert a transfer function to string.
|
||||
* @param xfer_func - transfer function
|
||||
*
|
||||
* Convert transfer function @a xfer_func to a human-readable string.
|
||||
*
|
||||
* @return A pointer to a string on success, NULL on failure.
|
||||
*/
|
||||
const char* rk_v4l2_subdev_xfer_func_to_string(enum v4l2_xfer_func xfer_func);
|
||||
|
||||
/**
|
||||
* @brief Parse string to transfer function.
|
||||
* @param string - nul terminated string, textual transfer function
|
||||
*
|
||||
* Parse human readable string @a string to xfer_func.
|
||||
*
|
||||
* @return xfer_func on success, -1 on failure.
|
||||
*/
|
||||
enum v4l2_xfer_func rk_v4l2_subdev_string_to_xfer_func(const char* string);
|
||||
|
||||
/**
|
||||
* @brief Convert a YCbCr encoding to string.
|
||||
* @param ycbcr_enc - YCbCr encoding
|
||||
*
|
||||
* Convert YCbCr encoding @a ycbcr_enc to a human-readable string.
|
||||
*
|
||||
* @return A pointer to a string on success, NULL on failure.
|
||||
*/
|
||||
const char* rk_v4l2_subdev_ycbcr_encoding_to_string(enum v4l2_ycbcr_encoding ycbcr_enc);
|
||||
|
||||
/**
|
||||
* @brief Parse string to YCbCr encoding.
|
||||
* @param string - nul terminated string, textual YCbCr encoding
|
||||
*
|
||||
* Parse human readable string @a string to YCbCr encoding.
|
||||
*
|
||||
* @return ycbcr_enc on success, -1 on failure.
|
||||
*/
|
||||
enum v4l2_ycbcr_encoding rk_v4l2_subdev_string_to_ycbcr_encoding(const char* string);
|
||||
|
||||
/**
|
||||
* @brief Convert a quantization to string.
|
||||
* @param quantization - quantization
|
||||
*
|
||||
* Convert quantization @a quantization to a human-readable string.
|
||||
*
|
||||
* @return A pointer to a string on success, NULL on failure.
|
||||
*/
|
||||
const char* rk_v4l2_subdev_quantization_to_string(enum v4l2_quantization quantization);
|
||||
|
||||
/**
|
||||
* @brief Parse string to quantization.
|
||||
* @param string - nul terminated string, textual quantization
|
||||
*
|
||||
* Parse human readable string @a string to quantization.
|
||||
*
|
||||
* @return quantization on success, -1 on failure.
|
||||
*/
|
||||
enum v4l2_quantization rk_v4l2_subdev_string_to_quantization(const char* string);
|
||||
|
||||
/**
|
||||
* @brief Enumerate library supported media bus pixel codes.
|
||||
* @param length - the number of the supported pixel codes
|
||||
*
|
||||
* Obtain pixel codes supported by libv4l2subdev.
|
||||
*
|
||||
* @return A pointer to the pixel code array
|
||||
*/
|
||||
const enum v4l2_mbus_pixelcode* rk_v4l2_subdev_pixelcode_list(unsigned int* length);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user