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>
703 lines
21 KiB
C
703 lines
21 KiB
C
/*
|
||
* Copyright 2022 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
|
||
|
||
#include <assert.h>
|
||
#include <errno.h>
|
||
#include <fcntl.h>
|
||
#include <getopt.h>
|
||
#include <pthread.h>
|
||
#include <semaphore.h>
|
||
#include <signal.h>
|
||
#include <stdbool.h>
|
||
#include <stdio.h>
|
||
#include <stdlib.h>
|
||
#include <string.h>
|
||
#include <sys/prctl.h>
|
||
#include <time.h>
|
||
#include <unistd.h>
|
||
|
||
#include "rtsp_demo.h"
|
||
#include "sample_comm.h"
|
||
|
||
#define VI_CHN_MAX 2
|
||
#define CAM_NUM_MAX 2
|
||
|
||
#define BUFFER_SIZE 255
|
||
#define SEND_FRAME_TIMEOUT 2000
|
||
#define GET_FRAME_TIMEOUT 2000
|
||
typedef struct _rkModeTest {
|
||
RK_BOOL bIfMainThreadQuit;
|
||
RK_BOOL bIfViHandleThreadQuit;
|
||
RK_BOOL bIfVencThreadQuit;
|
||
RK_S32 s32EptzTestLoop;
|
||
RK_S32 s32EptzViIndex;
|
||
RK_U32 u32ViTestFrame;
|
||
RK_U32 u32ZoomStep;
|
||
RK_U32 u32ZoomSwitch;
|
||
RK_U32 u32ZoomLimit;
|
||
RK_U32 u32CamNum;
|
||
} RK_MODE_TEST_S;
|
||
|
||
typedef struct _rkIspInitParam {
|
||
RK_BOOL bMultictx;
|
||
RK_BOOL bIfIspGroupInit;
|
||
RK_CHAR *pIqFileDir;
|
||
RK_S32 s32CamId[CAM_NUM_MAX];
|
||
RK_S32 s32CamGroupId;
|
||
RK_U32 u32CamNum;
|
||
#if (defined RKAIQ) && (defined UAPI2)
|
||
rk_aiq_working_mode_t eHdrMode;
|
||
#endif
|
||
} RK_ISP_INIT_PARAM_S;
|
||
|
||
typedef struct _rkMpiCtx {
|
||
SAMPLE_VI_CTX_S vi[VI_CHN_MAX];
|
||
SAMPLE_VENC_CTX_S venc;
|
||
} SAMPLE_MPI_CTX_S;
|
||
|
||
static RK_BOOL g_rtsp_ifenbale = RK_FALSE;
|
||
static RK_S32 g_ProExitReturnValue = RK_SUCCESS;
|
||
static RK_MODE_TEST_S *gModeTest = RK_NULL;
|
||
static rtsp_demo_handle g_rtsplive = RK_NULL;
|
||
static rtsp_session_handle g_rtsp_session = RK_NULL;
|
||
|
||
static void program_handle_error(const char *func, RK_U32 line) {
|
||
RK_LOGE("func: <%s> line: <%d> error exit!", func, line);
|
||
g_ProExitReturnValue = RK_FAILURE;
|
||
gModeTest->bIfMainThreadQuit = RK_TRUE;
|
||
}
|
||
|
||
static void program_normal_exit(const char *func, RK_U32 line) {
|
||
RK_LOGE("func: <%s> line: <%d> normal exit!", func, line);
|
||
gModeTest->bIfMainThreadQuit = RK_TRUE;
|
||
}
|
||
|
||
static void sigterm_handler(int sig) {
|
||
fprintf(stderr, "signal %d\n", sig);
|
||
program_normal_exit(__func__, __LINE__);
|
||
}
|
||
|
||
static RK_CHAR optstr[] = "?::a::w:h:o:e:s:t:l:f:i:";
|
||
static const struct option long_options[] = {
|
||
{"aiq", optional_argument, NULL, 'a'},
|
||
{"width", required_argument, NULL, 'w'},
|
||
{"height", required_argument, NULL, 'h'},
|
||
{"output_path", required_argument, NULL, 'o'},
|
||
{"encode", required_argument, NULL, 'e'},
|
||
{"zoom_step", required_argument, NULL, 's'},
|
||
{"zoom_switch", required_argument, NULL, 't'},
|
||
{"zoom_limit", required_argument, NULL, 't' + 'l'},
|
||
{"test_frame", required_argument, NULL, 't' + 'f'},
|
||
{"ispLaunchMode", required_argument, NULL, 'i'},
|
||
{"help", optional_argument, NULL, '?'},
|
||
{NULL, 0, NULL, 0},
|
||
};
|
||
|
||
/******************************************************************************
|
||
* function : show usage
|
||
******************************************************************************/
|
||
static void print_usage(const RK_CHAR *name) {
|
||
printf("usage example:\n");
|
||
printf("\t%s -w 1920 -h 1080 -a /etc/iqfiles/ --test_frame 30 -o /userdata/\n", name);
|
||
#if (defined RKAIQ) && (defined UAPI2)
|
||
printf(
|
||
"\t-a | --aiq : enable aiq with dirpath provided, eg:-a /etc/iqfiles/, \n"
|
||
"\t set dirpath empty to using path by default, without this option aiq \n"
|
||
"\t should run in other application\n");
|
||
#endif
|
||
printf("\t-w | --width : camera width, Default: 1920\n");
|
||
printf("\t-h | --height : camera height, Default: 1080\n");
|
||
printf("\t-o | --output_path : encode output file path, Default: NULL\n");
|
||
printf("\t-e | --encode : set encode type, Value: h264cbr, h264vbr, h265cbr, "
|
||
"h265vbr, default: h264cbr \n");
|
||
printf("\t-s | --zoom_step : zoom step, 1: 0.1, 2: 0.2, 3: 0.3, 4: 0.4, 5: 0.5, 6:0.6"
|
||
"default: 1\n");
|
||
printf("\t-t --zoom_switch : Switching to camera 1, Default: 20\n");
|
||
printf("\t-l --zoom_limit : max zoom, Default: 60\n");
|
||
printf("\t-f --test_frame : when Vi outputs frameCount equal to "
|
||
"<test_frame>\n");
|
||
printf(
|
||
"\t-i --ispLaunchMode : 0: single cam init, 1: camera group init. default: 0\n");
|
||
}
|
||
|
||
static RK_S32 isp_init(RK_ISP_INIT_PARAM_S *pstIspParam) {
|
||
RK_S32 s32Ret = RK_FAILURE;
|
||
|
||
#if (defined RKAIQ) && (defined UAPI2)
|
||
if (pstIspParam->bIfIspGroupInit == RK_FALSE) {
|
||
for (RK_S32 i = 0; i < pstIspParam->u32CamNum; i++) {
|
||
s32Ret =
|
||
SAMPLE_COMM_ISP_Init(pstIspParam->s32CamId[i], pstIspParam->eHdrMode,
|
||
pstIspParam->bMultictx, pstIspParam->pIqFileDir);
|
||
s32Ret |= SAMPLE_COMM_ISP_Run(pstIspParam->s32CamId[i]);
|
||
if (s32Ret != RK_SUCCESS) {
|
||
RK_LOGE("ISP init failure camid:%d", i);
|
||
return RK_FAILURE;
|
||
}
|
||
}
|
||
} else if (pstIspParam->bIfIspGroupInit == RK_TRUE) {
|
||
rk_aiq_camgroup_instance_cfg_t camgroup_cfg;
|
||
memset(&camgroup_cfg, 0, sizeof(rk_aiq_camgroup_instance_cfg_t));
|
||
camgroup_cfg.sns_num = pstIspParam->u32CamNum;
|
||
camgroup_cfg.config_file_dir = pstIspParam->pIqFileDir;
|
||
s32Ret = SAMPLE_COMM_ISP_CamGroup_Init(
|
||
pstIspParam->s32CamGroupId, pstIspParam->eHdrMode, pstIspParam->bMultictx, 0,
|
||
RK_NULL, &camgroup_cfg);
|
||
if (s32Ret != RK_SUCCESS) {
|
||
printf("%s : isp cam group init\n", __func__);
|
||
return RK_FAILURE;
|
||
}
|
||
} else {
|
||
RK_LOGE("ISP dosen't support this launch mode %d", pstIspParam->bIfIspGroupInit);
|
||
return RK_FAILURE;
|
||
}
|
||
#endif
|
||
return RK_SUCCESS;
|
||
}
|
||
|
||
static RK_S32 isp_deinit(RK_ISP_INIT_PARAM_S *pstIspParam) {
|
||
RK_S32 s32Ret = RK_SUCCESS;
|
||
#if (defined RKAIQ) && (defined UAPI2)
|
||
if (pstIspParam->bIfIspGroupInit == RK_FALSE) {
|
||
for (RK_S32 i = 0; i < pstIspParam->u32CamNum; i++) {
|
||
s32Ret = SAMPLE_COMM_ISP_Stop(i);
|
||
if (s32Ret != RK_SUCCESS) {
|
||
RK_LOGE("SAMPLE_COMM_ISP_Stop failure:%#X", s32Ret);
|
||
return s32Ret;
|
||
}
|
||
}
|
||
} else if (pstIspParam->bIfIspGroupInit == RK_TRUE) {
|
||
s32Ret = SAMPLE_COMM_ISP_CamGroup_Stop(pstIspParam->s32CamGroupId);
|
||
if (s32Ret != RK_SUCCESS) {
|
||
RK_LOGE("SAMPLE_COMM_ISP_CamGroup_Stop failure:%#X", s32Ret);
|
||
return s32Ret;
|
||
}
|
||
} else {
|
||
RK_LOGE("ISP deinit dosen't support this mode %d", pstIspParam->bIfIspGroupInit);
|
||
return RK_FAILURE;
|
||
}
|
||
#endif
|
||
return RK_SUCCESS;
|
||
}
|
||
|
||
static RK_S32 sample_eptz_switch(SAMPLE_VI_CTX_S *ctx) {
|
||
RK_S32 s32Ret = RK_FAILURE;
|
||
RK_U32 u32SrcWidth = ctx->u32Width * 10;
|
||
RK_U32 u32SrcHeight = ctx->u32Height * 10;
|
||
static RK_U32 u32MultipleOfZoom = 10;
|
||
VI_CROP_INFO_S stCropInfo;
|
||
memset(&stCropInfo, 0, sizeof(VI_CROP_INFO_S));
|
||
s32Ret = RK_MPI_VI_GetEptz(ctx->u32PipeId, ctx->s32ChnId, &stCropInfo);
|
||
if (s32Ret != RK_SUCCESS) {
|
||
RK_LOGE("RK_MPI_VI_GetEptz failure:%#X pipe:%d chnid:%d index:%d", s32Ret,
|
||
ctx->u32PipeId, ctx->s32ChnId, gModeTest->s32EptzViIndex);
|
||
program_handle_error(__func__, __LINE__);
|
||
return s32Ret;
|
||
}
|
||
|
||
stCropInfo.stCropRect.u32Width = RK_ALIGN_2(u32SrcWidth / u32MultipleOfZoom);
|
||
stCropInfo.stCropRect.u32Height = RK_ALIGN_2(u32SrcHeight / u32MultipleOfZoom);
|
||
stCropInfo.stCropRect.s32X =
|
||
RK_ALIGN_2((ctx->u32Width - stCropInfo.stCropRect.u32Width) / 2);
|
||
stCropInfo.stCropRect.s32Y =
|
||
RK_ALIGN_2((ctx->u32Height - stCropInfo.stCropRect.u32Height) / 2);
|
||
s32Ret = RK_MPI_VI_SetEptz(ctx->u32PipeId, ctx->s32ChnId, stCropInfo);
|
||
if (s32Ret != RK_SUCCESS) {
|
||
RK_LOGE("RK_MPI_VI_SetEptz failure:%#X pipe:%d chnid:%d", s32Ret, ctx->u32PipeId,
|
||
ctx->s32ChnId);
|
||
program_handle_error(__func__, __LINE__);
|
||
return s32Ret;
|
||
}
|
||
u32MultipleOfZoom += gModeTest->u32ZoomStep;
|
||
if (u32MultipleOfZoom > gModeTest->u32ZoomLimit) {
|
||
u32MultipleOfZoom = 10;
|
||
}
|
||
|
||
if (u32MultipleOfZoom > gModeTest->u32ZoomSwitch) {
|
||
gModeTest->s32EptzViIndex = 1;
|
||
} else {
|
||
gModeTest->s32EptzViIndex = 0;
|
||
}
|
||
return RK_SUCCESS;
|
||
}
|
||
|
||
static RK_VOID *handle_vi_stream(RK_VOID *pArgs) {
|
||
SAMPLE_MPI_CTX_S *ctx = (SAMPLE_MPI_CTX_S *)pArgs;
|
||
RK_S32 s32Ret = RK_FAILURE;
|
||
RK_U32 u32GetStreamCount = 0;
|
||
RK_S32 s32EptzTestloop = 0;
|
||
|
||
while (!gModeTest->bIfViHandleThreadQuit) {
|
||
|
||
s32Ret = RK_MPI_VI_GetChnFrame(ctx->vi[0].u32PipeId, ctx->vi[0].s32ChnId,
|
||
&ctx->vi[0].stViFrame, GET_FRAME_TIMEOUT);
|
||
if (s32Ret != RK_SUCCESS) {
|
||
RK_LOGE("RK_MPI_VI_GetChnFrame failure:%#X, pipe:%d chnid:%d ", s32Ret,
|
||
ctx->vi[0].u32PipeId, ctx->vi[0].s32ChnId);
|
||
continue;
|
||
}
|
||
s32Ret = RK_MPI_VI_GetChnFrame(ctx->vi[1].u32PipeId, ctx->vi[1].s32ChnId,
|
||
&ctx->vi[1].stViFrame, GET_FRAME_TIMEOUT);
|
||
if (s32Ret != RK_SUCCESS) {
|
||
RK_LOGE("RK_MPI_VI_GetChnFrame failure:%#X, pipe:%d chnid:%d ", s32Ret,
|
||
ctx->vi[1].u32PipeId, ctx->vi[1].s32ChnId);
|
||
RK_MPI_VI_ReleaseChnFrame(ctx->vi[0].u32PipeId, ctx->vi[0].s32ChnId,
|
||
&ctx->vi[0].stViFrame);
|
||
continue;
|
||
}
|
||
|
||
/* eptz handle */
|
||
if (u32GetStreamCount == gModeTest->u32ViTestFrame) {
|
||
u32GetStreamCount = 0;
|
||
s32Ret = sample_eptz_switch(&ctx->vi[gModeTest->s32EptzViIndex]);
|
||
if (s32Ret != RK_SUCCESS) {
|
||
RK_LOGE("sample_eptz_switch failure:%#X Vi index:%d", s32Ret,
|
||
gModeTest->s32EptzViIndex);
|
||
program_handle_error(__func__, __LINE__);
|
||
}
|
||
|
||
s32EptzTestloop++;
|
||
|
||
if (gModeTest->s32EptzTestLoop > 0 &&
|
||
s32EptzTestloop > gModeTest->s32EptzTestLoop) {
|
||
RK_LOGE("---------------Eptz test end:%d ", gModeTest->s32EptzTestLoop);
|
||
program_normal_exit(__func__, __LINE__);
|
||
}
|
||
}
|
||
|
||
/* send frame to venc */
|
||
s32Ret = RK_MPI_VENC_SendFrame(0, &ctx->vi[gModeTest->s32EptzViIndex].stViFrame,
|
||
SEND_FRAME_TIMEOUT);
|
||
if (s32Ret != RK_SUCCESS) {
|
||
RK_LOGE("RK_MPI_VENC_SendFrame timeout:%#X vi index:%d", s32Ret,
|
||
gModeTest->s32EptzViIndex);
|
||
program_handle_error(__func__, __LINE__);
|
||
}
|
||
|
||
/* release vi frame */
|
||
for (RK_U32 i = 0; i < gModeTest->u32CamNum; i++) {
|
||
RK_MPI_VI_ReleaseChnFrame(ctx->vi[i].u32PipeId, ctx->vi[i].s32ChnId,
|
||
&ctx->vi[i].stViFrame);
|
||
}
|
||
u32GetStreamCount++;
|
||
RK_LOGD("-------------------------------------------------- vi handle "
|
||
"u32GetStreamCount:%d",
|
||
u32GetStreamCount);
|
||
}
|
||
|
||
RK_LOGD("-------------------------handle vi thread eixt");
|
||
return RK_NULL;
|
||
}
|
||
|
||
static RK_VOID *venc_get_stream(RK_VOID *pArgs) {
|
||
SAMPLE_VENC_CTX_S *ctx = (SAMPLE_VENC_CTX_S *)pArgs;
|
||
RK_S32 s32Ret = RK_FAILURE;
|
||
RK_S32 s32Fd = 0;
|
||
RK_S32 s32LoopCount = 0;
|
||
RK_U8 *pData = RK_NULL;
|
||
RK_CHAR name[BUFFER_SIZE] = {0};
|
||
FILE *fp = RK_NULL;
|
||
|
||
if (ctx->dstFilePath) {
|
||
snprintf(name, sizeof(name), "/%s/venc_%d.bin", ctx->dstFilePath, ctx->s32ChnId);
|
||
fp = fopen(name, "wb");
|
||
if (fp == RK_NULL) {
|
||
RK_LOGE("chn %d can't open %s file !\n", ctx->s32ChnId, ctx->dstFilePath);
|
||
program_handle_error(__func__, __LINE__);
|
||
return RK_NULL;
|
||
}
|
||
s32Fd = fileno(fp);
|
||
}
|
||
while (!gModeTest->bIfVencThreadQuit) {
|
||
s32Ret = SAMPLE_COMM_VENC_GetStream(ctx, (void **)&pData);
|
||
if (s32Ret == RK_SUCCESS) {
|
||
|
||
if (fp && !gModeTest->bIfMainThreadQuit) {
|
||
fwrite(pData, 1, ctx->stFrame.pstPack->u32Len, fp);
|
||
fflush(fp);
|
||
}
|
||
|
||
if (g_rtsp_ifenbale) {
|
||
rtsp_tx_video(g_rtsp_session, pData, ctx->stFrame.pstPack->u32Len,
|
||
ctx->stFrame.pstPack->u64PTS);
|
||
rtsp_do_event(g_rtsplive);
|
||
} else {
|
||
RK_LOGD("venc %d get_stream count: %d", ctx->s32ChnId, s32LoopCount);
|
||
}
|
||
SAMPLE_COMM_VENC_ReleaseStream(ctx);
|
||
s32LoopCount++;
|
||
|
||
if (ctx->s32loopCount > 0 && s32LoopCount >= ctx->s32loopCount) {
|
||
program_normal_exit(__func__, __LINE__);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (fp) {
|
||
fsync(s32Fd);
|
||
fclose(fp);
|
||
fp = RK_NULL;
|
||
}
|
||
|
||
RK_LOGD("chnId:%d venc_get_stream exit!!!", ctx->s32ChnId);
|
||
return RK_NULL;
|
||
}
|
||
|
||
static RK_S32 rtsp_init(CODEC_TYPE_E enCodecType) {
|
||
g_rtsplive = create_rtsp_demo(554);
|
||
g_rtsp_session = rtsp_new_session(g_rtsplive, "/live/0");
|
||
if (enCodecType == RK_CODEC_TYPE_H264) {
|
||
rtsp_set_video(g_rtsp_session, RTSP_CODEC_ID_VIDEO_H264, RK_NULL, 0);
|
||
} else if (enCodecType == RK_CODEC_TYPE_H265) {
|
||
rtsp_set_video(g_rtsp_session, RTSP_CODEC_ID_VIDEO_H265, RK_NULL, 0);
|
||
} else {
|
||
RK_LOGE("not support other type\n");
|
||
return RK_SUCCESS;
|
||
}
|
||
rtsp_sync_video_ts(g_rtsp_session, rtsp_get_reltime(), rtsp_get_ntptime());
|
||
RK_LOGD("rtsp <%s> init success", "/live/0");
|
||
g_rtsp_ifenbale = RK_TRUE;
|
||
return RK_SUCCESS;
|
||
}
|
||
|
||
static RK_S32 rtsp_deinit(void) {
|
||
if (g_rtsplive)
|
||
rtsp_del_demo(g_rtsplive);
|
||
g_rtsp_ifenbale = RK_FALSE;
|
||
return RK_SUCCESS;
|
||
}
|
||
|
||
static RK_S32 globol_param_init(void) {
|
||
gModeTest = (RK_MODE_TEST_S *)malloc(sizeof(RK_MODE_TEST_S));
|
||
if (gModeTest == RK_NULL) {
|
||
RK_LOGE("malloc for gModeTest failure");
|
||
return RK_FAILURE;
|
||
}
|
||
memset(gModeTest, 0, sizeof(RK_MODE_TEST_S));
|
||
gModeTest->s32EptzTestLoop = -1;
|
||
gModeTest->u32ZoomStep = 1;
|
||
gModeTest->u32ZoomSwitch = 20;
|
||
gModeTest->u32ZoomLimit = 60;
|
||
|
||
g_ProExitReturnValue = RK_SUCCESS;
|
||
return RK_SUCCESS;
|
||
}
|
||
|
||
static RK_S32 globol_param_deinit(void) {
|
||
if (gModeTest) {
|
||
free(gModeTest);
|
||
gModeTest = RK_NULL;
|
||
}
|
||
return RK_SUCCESS;
|
||
}
|
||
|
||
int main(int argc, char *argv[]) {
|
||
RK_S32 s32Ret = RK_FAILURE;
|
||
RK_U32 u32VideoWidth = 1920;
|
||
RK_U32 u32VideoHeight = 1080;
|
||
RK_U32 u32CamNum = 2;
|
||
RK_U32 i = 0;
|
||
RK_U32 u32BitRate = 2 * 1024;
|
||
RK_U32 u32MultipleOfZoom = 0;
|
||
RK_CHAR *pIqFileDir = "/oem/usr/share/iqfiles/";
|
||
RK_CHAR *pOutPathVenc = RK_NULL;
|
||
SAMPLE_MPI_CTX_S *ctx = RK_NULL;
|
||
RK_ISP_INIT_PARAM_S *pstIspParam = RK_NULL;
|
||
CODEC_TYPE_E enCodecType = RK_CODEC_TYPE_H264;
|
||
VENC_RC_MODE_E enRcMode = VENC_RC_MODE_H264CBR;
|
||
|
||
pthread_t vi_handle_thread_id;
|
||
|
||
if (argc < 2) {
|
||
print_usage(argv[0]);
|
||
g_ProExitReturnValue = RK_FAILURE;
|
||
goto __PARAM_INIT_FAILED;
|
||
}
|
||
|
||
ctx = (SAMPLE_MPI_CTX_S *)malloc(sizeof(SAMPLE_MPI_CTX_S));
|
||
if (ctx == RK_NULL) {
|
||
RK_LOGE("malloc for ctx failure");
|
||
g_ProExitReturnValue = RK_FAILURE;
|
||
goto __FAILED2;
|
||
}
|
||
memset(ctx, 0, sizeof(SAMPLE_MPI_CTX_S));
|
||
|
||
pstIspParam = (RK_ISP_INIT_PARAM_S *)malloc(sizeof(RK_ISP_INIT_PARAM_S));
|
||
if (pstIspParam == RK_NULL) {
|
||
RK_LOGE("malloc for pstIspParam failure");
|
||
g_ProExitReturnValue = RK_FAILURE;
|
||
goto __FAILED2;
|
||
}
|
||
memset(pstIspParam, 0, sizeof(RK_ISP_INIT_PARAM_S));
|
||
|
||
s32Ret = globol_param_init();
|
||
if (s32Ret != RK_SUCCESS) {
|
||
RK_LOGE("globol_param_init");
|
||
g_ProExitReturnValue = RK_FAILURE;
|
||
goto __FAILED2;
|
||
}
|
||
|
||
signal(SIGINT, sigterm_handler);
|
||
signal(SIGTERM, sigterm_handler);
|
||
|
||
RK_S32 c = 0;
|
||
while ((c = getopt_long(argc, argv, optstr, long_options, RK_NULL)) != -1) {
|
||
const char *tmp_optarg = optarg;
|
||
switch (c) {
|
||
case 'a':
|
||
if (!optarg && RK_NULL != argv[optind] && '-' != argv[optind][0]) {
|
||
tmp_optarg = argv[optind++];
|
||
}
|
||
if (tmp_optarg) {
|
||
pIqFileDir = (char *)tmp_optarg;
|
||
} else {
|
||
pIqFileDir = RK_NULL;
|
||
}
|
||
break;
|
||
case 'w':
|
||
u32VideoWidth = atoi(optarg);
|
||
break;
|
||
case 'h':
|
||
u32VideoHeight = atoi(optarg);
|
||
break;
|
||
case 'o':
|
||
pOutPathVenc = optarg;
|
||
break;
|
||
case 'e':
|
||
if (!strcmp(optarg, "h264cbr")) {
|
||
enCodecType = RK_CODEC_TYPE_H264;
|
||
enRcMode = VENC_RC_MODE_H264CBR;
|
||
} else if (!strcmp(optarg, "h264vbr")) {
|
||
enCodecType = RK_CODEC_TYPE_H264;
|
||
enRcMode = VENC_RC_MODE_H264VBR;
|
||
} else if (!strcmp(optarg, "h264avbr")) {
|
||
enCodecType = RK_CODEC_TYPE_H264;
|
||
enRcMode = VENC_RC_MODE_H264AVBR;
|
||
} else if (!strcmp(optarg, "h265cbr")) {
|
||
enCodecType = RK_CODEC_TYPE_H265;
|
||
enRcMode = VENC_RC_MODE_H265CBR;
|
||
} else if (!strcmp(optarg, "h265vbr")) {
|
||
enCodecType = RK_CODEC_TYPE_H265;
|
||
enRcMode = VENC_RC_MODE_H265VBR;
|
||
} else if (!strcmp(optarg, "h265avbr")) {
|
||
enCodecType = RK_CODEC_TYPE_H265;
|
||
enRcMode = VENC_RC_MODE_H265AVBR;
|
||
} else {
|
||
printf("ERROR: Invalid encoder type.\n");
|
||
print_usage(argv[0]);
|
||
g_ProExitReturnValue = RK_FAILURE;
|
||
goto __PARAM_INIT_FAILED;
|
||
}
|
||
break;
|
||
case 'z':
|
||
u32MultipleOfZoom = atoi(optarg);
|
||
break;
|
||
case 's':
|
||
gModeTest->u32ZoomStep = atoi(optarg);
|
||
break;
|
||
case 't':
|
||
gModeTest->u32ZoomSwitch = atoi(optarg);
|
||
break;
|
||
case 't' + 'l':
|
||
gModeTest->u32ZoomLimit = atoi(optarg);
|
||
break;
|
||
case 't' + 'f':
|
||
gModeTest->u32ViTestFrame = atoi(optarg);
|
||
break;
|
||
case 'i':
|
||
pstIspParam->bIfIspGroupInit = atoi(optarg);
|
||
break;
|
||
case '?':
|
||
default:
|
||
print_usage(argv[0]);
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
if (pIqFileDir) {
|
||
#if (defined RKAIQ) && (defined UAPI2)
|
||
printf("#Rkaiq XML DirPath: %s\n", pIqFileDir);
|
||
rk_aiq_working_mode_t hdr_mode = RK_AIQ_WORKING_MODE_NORMAL;
|
||
pstIspParam->bMultictx = RK_TRUE;
|
||
pstIspParam->eHdrMode = hdr_mode;
|
||
pstIspParam->pIqFileDir = pIqFileDir;
|
||
pstIspParam->u32CamNum = u32CamNum;
|
||
gModeTest->u32CamNum = u32CamNum;
|
||
if (pstIspParam->bIfIspGroupInit == RK_FALSE) {
|
||
for (RK_S32 i = 0; i < u32CamNum; i++) {
|
||
pstIspParam->s32CamId[i] = i;
|
||
}
|
||
} else if (pstIspParam->bIfIspGroupInit == RK_TRUE) {
|
||
pstIspParam->s32CamGroupId = 0;
|
||
}
|
||
s32Ret = isp_init(pstIspParam);
|
||
if (s32Ret != RK_SUCCESS) {
|
||
RK_LOGE("isp init failure");
|
||
goto __FAILED2;
|
||
}
|
||
#endif
|
||
}
|
||
|
||
if (RK_MPI_SYS_Init() != RK_SUCCESS) {
|
||
g_ProExitReturnValue = RK_FAILURE;
|
||
goto __FAILED;
|
||
}
|
||
|
||
/* init rtsp*/
|
||
rtsp_init(enCodecType);
|
||
|
||
/* init vi */
|
||
for (i = 0; i < u32CamNum; i++) {
|
||
ctx->vi[i].u32Width = u32VideoWidth;
|
||
ctx->vi[i].u32Height = u32VideoHeight;
|
||
ctx->vi[i].s32DevId = i;
|
||
ctx->vi[i].u32PipeId = i;
|
||
ctx->vi[i].s32ChnId = 0;
|
||
ctx->vi[i].stChnAttr.stIspOpt.stMaxSize.u32Width = u32VideoWidth;
|
||
ctx->vi[i].stChnAttr.stIspOpt.stMaxSize.u32Height = u32VideoHeight;
|
||
ctx->vi[i].stChnAttr.stIspOpt.u32BufCount = 2;
|
||
ctx->vi[i].stChnAttr.stIspOpt.enMemoryType = VI_V4L2_MEMORY_TYPE_DMABUF;
|
||
ctx->vi[i].stChnAttr.u32Depth = 2;
|
||
ctx->vi[i].stChnAttr.enPixelFormat = RK_FMT_YUV420SP;
|
||
ctx->vi[i].stChnAttr.enCompressMode = COMPRESS_MODE_NONE;
|
||
ctx->vi[i].stChnAttr.stFrameRate.s32SrcFrameRate = -1;
|
||
ctx->vi[i].stChnAttr.stFrameRate.s32DstFrameRate = -1;
|
||
ctx->vi[i].bIfIspGroupInit = pstIspParam->bIfIspGroupInit;
|
||
if (u32MultipleOfZoom && i == 0) {
|
||
ctx->vi[i].bIfOpenEptz = RK_TRUE;
|
||
ctx->vi[i].stCropInfo.stCropRect.u32Width =
|
||
RK_ALIGN_2(ctx->vi[i].u32Width / u32MultipleOfZoom);
|
||
ctx->vi[i].stCropInfo.stCropRect.u32Height =
|
||
RK_ALIGN_2(ctx->vi[i].u32Height / u32MultipleOfZoom);
|
||
ctx->vi[i].stCropInfo.stCropRect.s32X = RK_ALIGN_2(
|
||
(ctx->vi[i].u32Width - ctx->vi[i].stCropInfo.stCropRect.u32Width) / 2);
|
||
ctx->vi[i].stCropInfo.stCropRect.s32Y = RK_ALIGN_2(
|
||
(ctx->vi[i].u32Height - ctx->vi[i].stCropInfo.stCropRect.u32Height) / 2);
|
||
}
|
||
SAMPLE_COMM_VI_CreateChn(&ctx->vi[i]);
|
||
}
|
||
|
||
/* Start pipe */
|
||
if (pstIspParam->bIfIspGroupInit == RK_TRUE) { /* isp group init */
|
||
for (i = 0; i < u32CamNum; i++) {
|
||
s32Ret = RK_MPI_VI_StartPipe(ctx->vi[i].u32PipeId);
|
||
if (s32Ret != RK_SUCCESS) {
|
||
RK_LOGE("RK_MPI_VI_StartPipe failure:$#X pipe:%d", s32Ret,
|
||
ctx->vi[i].u32PipeId);
|
||
g_ProExitReturnValue = RK_FALSE;
|
||
goto __VI_INITFAIL;
|
||
}
|
||
}
|
||
}
|
||
|
||
/* init venc */
|
||
ctx->venc.s32ChnId = 0;
|
||
ctx->venc.u32Width = u32VideoWidth;
|
||
ctx->venc.u32Height = u32VideoHeight;
|
||
ctx->venc.u32Gop = 50;
|
||
ctx->venc.u32BitRate = u32BitRate;
|
||
ctx->venc.enCodecType = enCodecType;
|
||
ctx->venc.enRcMode = enRcMode;
|
||
ctx->venc.enable_buf_share = 1;
|
||
ctx->venc.getStreamCbFunc = venc_get_stream;
|
||
ctx->venc.dstFilePath = pOutPathVenc;
|
||
/*
|
||
H264 66:Baseline 77:Main Profile 100:High Profile
|
||
H265 0:Main Profile 1:Main 10 Profile
|
||
MJPEG 0:Baseline
|
||
*/
|
||
if (RK_CODEC_TYPE_H264 != enCodecType) {
|
||
ctx->venc.stChnAttr.stVencAttr.u32Profile = 0;
|
||
} else {
|
||
ctx->venc.stChnAttr.stVencAttr.u32Profile = 100;
|
||
}
|
||
/* VENC_GOPMODE_SMARTP */
|
||
ctx->venc.stChnAttr.stGopAttr.enGopMode = VENC_GOPMODE_NORMALP;
|
||
SAMPLE_COMM_VENC_CreateChn(&ctx->venc);
|
||
|
||
/* vi handle thread launch */
|
||
pthread_create(&vi_handle_thread_id, RK_NULL, handle_vi_stream, (void *)ctx);
|
||
|
||
RK_LOGD("multi camerm eptz init finish");
|
||
while (!gModeTest->bIfMainThreadQuit) {
|
||
sleep(1);
|
||
}
|
||
RK_LOGD("multi camerm eptz exit");
|
||
|
||
/* venc deinit */
|
||
gModeTest->bIfVencThreadQuit = RK_TRUE;
|
||
pthread_join(ctx->venc.getStreamThread, RK_NULL);
|
||
SAMPLE_COMM_VENC_DestroyChn(&ctx->venc);
|
||
|
||
/* rtsp deinit */
|
||
rtsp_deinit();
|
||
|
||
/* Vi thread exit */
|
||
gModeTest->bIfViHandleThreadQuit = RK_TRUE;
|
||
pthread_join(vi_handle_thread_id, RK_NULL);
|
||
|
||
__VI_INITFAIL:
|
||
/* vi deinit */
|
||
if (pstIspParam->bIfIspGroupInit == RK_TRUE) { /* isp group init */
|
||
for (i = 0; i < u32CamNum; i++) {
|
||
s32Ret = RK_MPI_VI_StopPipe(ctx->vi[i].u32PipeId);
|
||
if (s32Ret != RK_SUCCESS) {
|
||
RK_LOGE("RK_MPI_VI_StopPipe failure:$#X pipe:%d", s32Ret,
|
||
ctx->vi[i].u32PipeId);
|
||
g_ProExitReturnValue = RK_FALSE;
|
||
}
|
||
}
|
||
}
|
||
for (i = 0; i < u32CamNum; i++) {
|
||
SAMPLE_COMM_VI_DestroyChn(&ctx->vi[i]);
|
||
}
|
||
|
||
__FAILED:
|
||
RK_MPI_SYS_Exit();
|
||
if (pIqFileDir) {
|
||
#if (defined RKAIQ) && (defined UAPI2)
|
||
isp_deinit(pstIspParam);
|
||
#endif
|
||
}
|
||
|
||
__FAILED2:
|
||
globol_param_deinit();
|
||
if (pstIspParam) {
|
||
free(pstIspParam);
|
||
pstIspParam = RK_NULL;
|
||
}
|
||
if (ctx) {
|
||
free(ctx);
|
||
ctx = RK_NULL;
|
||
}
|
||
|
||
__PARAM_INIT_FAILED:
|
||
return g_ProExitReturnValue;
|
||
}
|
||
|
||
#ifdef __cplusplus
|
||
#if __cplusplus
|
||
}
|
||
#endif
|
||
#endif
|