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>
788 lines
25 KiB
C
788 lines
25 KiB
C
/*
|
||
* Copyright 2023 Rockchip Electronics Co. LTD
|
||
*
|
||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||
* you may not use this file except in compliance with the License.
|
||
* You may obtain a copy of the License at
|
||
*
|
||
* http://www.apache.org/licenses/LICENSE-2.0
|
||
*
|
||
* Unless required by applicable law or agreed to in writing, software
|
||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
* See the License for the specific language governing permissions and
|
||
* limitations under the License.
|
||
*
|
||
*/
|
||
#ifdef __cplusplus
|
||
#if __cplusplus
|
||
extern "C" {
|
||
#endif
|
||
#endif /* End of #ifdef __cplusplus */
|
||
|
||
#include <assert.h>
|
||
#include <errno.h>
|
||
#include <fcntl.h>
|
||
#include <getopt.h>
|
||
#include <pthread.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_NUM_MAX 8
|
||
#define VENC_NUM_MAX 2
|
||
|
||
rtsp_demo_handle g_rtsplive = RK_NULL;
|
||
static rtsp_session_handle g_rtsp_session[VENC_NUM_MAX] = {RK_NULL};
|
||
|
||
typedef struct _rkMpiCtx {
|
||
SAMPLE_VI_CTX_S vi[VI_NUM_MAX];
|
||
SAMPLE_AVS_CTX_S avs;
|
||
SAMPLE_VENC_CTX_S venc[VENC_NUM_MAX];
|
||
SAMPLE_RGN_CTX_S rgn;
|
||
} SAMPLE_MPI_CTX_S;
|
||
|
||
static bool g_bMainThreadQuit = RK_FALSE;
|
||
static bool g_bVencThreadQuit[VENC_NUM_MAX] = {RK_FALSE};
|
||
pthread_mutex_t g_rtsp_mutex = {0};
|
||
static void sigterm_handler(int sig) {
|
||
fprintf(stderr, "signal %d\n", sig);
|
||
g_bMainThreadQuit = true;
|
||
}
|
||
|
||
static RK_CHAR optstr[] = "?::a::A:n:b:l:o:e:F:h:m:d:L:v:s:e:i:c:";
|
||
static const struct option long_options[] = {
|
||
{"aiq", optional_argument, NULL, 'a'},
|
||
{"calib_file_path", required_argument, NULL, 'A'},
|
||
{"camera_num", required_argument, NULL, 'n'},
|
||
{"bitrate", required_argument, NULL, 'b'},
|
||
{"vi_size", required_argument, NULL, 'v' + 's'},
|
||
{"avs_chn0_size", required_argument, NULL, 'a' + 's'},
|
||
{"avs_chn1_size", required_argument, NULL, 'a' + 'v'},
|
||
{"loop_count", required_argument, NULL, 'l'},
|
||
{"output_path", required_argument, NULL, 'o'},
|
||
{"encode", required_argument, NULL, 'e'},
|
||
{"dstfps", required_argument, NULL, 'F'},
|
||
{"hdr_mode", required_argument, NULL, 'h' + 'm'},
|
||
{"stitch_distance", required_argument, NULL, 'd'},
|
||
{"cam0_ldch_path", required_argument, NULL, 'L'},
|
||
{"cam1_ldch_path", required_argument, NULL, 'L' + 'm'},
|
||
{"set_ldch", required_argument, NULL, 'l' + 'd'},
|
||
{"ispLaunchMode", required_argument, NULL, 'i'},
|
||
{"input_bmp_path", required_argument, NULL, 'i' + 'b'},
|
||
{"osd_display", required_argument, RK_NULL, 'o' + 'd'},
|
||
{"vi_chnid", required_argument, NULL, 'v' + 'i'},
|
||
{"vi_buffcnt", required_argument, NULL, 'v' + 'c'},
|
||
{"avs_mode_blend", required_argument, NULL, 'a' + 'm' + 'b'},
|
||
{"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 --vi_size 1920x1080 --avs_chn0_size 3840x1080 --avs_chn1_size 1920x544 "
|
||
"-a /etc/iqfiles/ -e h265cbr -b "
|
||
"4096 -n 2\n",
|
||
name);
|
||
printf("\trtsp://xx.xx.xx.xx/live/0, Default OPEN\n");
|
||
#ifdef RKAIQ
|
||
printf("\t-a | --aiq: enable aiq with dirpath provided, eg:-a "
|
||
"/etc/iqfiles/, "
|
||
"set dirpath empty to using path by default, without this option aiq "
|
||
"should run in other application\n");
|
||
#endif
|
||
printf("\t-A | --calib_file_path: input file path of xxx.xml "
|
||
"Default /oem/usr/share/avs_calib/calib_file.xml\n");
|
||
printf("\t-n | --camera_num: camera number, Default 2\n");
|
||
printf("\t-b | --bitrate: encode bitrate, Default 4096\n");
|
||
printf("\t-l | --loop_count: loop count, Default -1\n");
|
||
printf("\t-o | --output_path: encode output file path, Default NULL\n");
|
||
printf("\t-e | --encode: encode type, Default:h264cbr, Value:h264cbr, "
|
||
"h264vbr, h265cbr, h265vbr\n");
|
||
printf("\t-F | --dstfps: set venc output fps, Default: 15\n");
|
||
printf("\t-i | --ispLaunchMode : 0: single cam init, 1: camera group init. default: "
|
||
"1\n");
|
||
printf("\t--vi_size: set vi resolution WidthxHeight, default: 1920x1080\n");
|
||
printf(
|
||
"\t--avs_chn0_size: set avs chn0 resolution WidthxHeight, default: 3840x1080\n");
|
||
printf(
|
||
"\t--avs_chn1_size: set avs chn1 resolution WidthxHeight, default: 1920x544\n");
|
||
printf("\t--hdr_mode: set hdr mode, 0: normal 1: HDR2, 2: HDR3, Default: 0\n");
|
||
printf("\t--stitch_distance: set stitch distance, default: 5.0(m)\n");
|
||
printf("\t--cam0_ldch_path: cam0 ldch mesh path, default: "
|
||
"/oem/usr/share/iqfiles/cam0_ldch_mesh.bin\n");
|
||
printf("\t--cam1_ldch_path: cam1 ldch mesh path, default: "
|
||
"/oem/usr/share/iqfiles/cam1_ldch_mesh.bin\n");
|
||
printf("\t--set_ldch: set ldch, -1: disable, 1: read_file_set_ldch, 2: "
|
||
"read_buff_set_ldch. Default: 2\n");
|
||
printf("\t--input_bmp_path : set bmp path for osd, default: NULL\n");
|
||
printf("\t--osd_display : osd if display, 0: no-display, 1: display. default: 1\n");
|
||
printf("\t--vi_chnid : set vi channel id, default: 1\n");
|
||
printf("\t--vi_buffcnt : set vi buff cnt, default: 2\n");
|
||
printf("\t--avs_mode_blend : set avs blend mode, 0: blend, 1 no-blend-ver, 2 "
|
||
"no-blend-hor. default: 0\n");
|
||
}
|
||
|
||
/******************************************************************************
|
||
* function : venc thread
|
||
******************************************************************************/
|
||
static void *venc_get_stream(void *pArgs) {
|
||
SAMPLE_VENC_CTX_S *ctx = (SAMPLE_VENC_CTX_S *)(pArgs);
|
||
void *pData = RK_NULL;
|
||
char name[256] = {0};
|
||
RK_S32 s32Ret = RK_FAILURE;
|
||
RK_S32 loopCount = 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) {
|
||
printf("chn %d can't open %s file !\n", ctx->s32ChnId, ctx->dstFilePath);
|
||
return RK_NULL;
|
||
}
|
||
}
|
||
|
||
while (!g_bVencThreadQuit[ctx->s32ChnId]) {
|
||
s32Ret = SAMPLE_COMM_VENC_GetStream(ctx, &pData);
|
||
if (s32Ret == RK_SUCCESS) {
|
||
// exit when complete
|
||
if (ctx->s32loopCount > 0) {
|
||
if (loopCount >= ctx->s32loopCount) {
|
||
SAMPLE_COMM_VENC_ReleaseStream(ctx);
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (fp) {
|
||
fwrite(pData, 1, ctx->stFrame.pstPack->u32Len, fp);
|
||
fflush(fp);
|
||
}
|
||
pthread_mutex_lock(&g_rtsp_mutex);
|
||
rtsp_tx_video(g_rtsp_session[ctx->s32ChnId], pData,
|
||
ctx->stFrame.pstPack->u32Len, ctx->stFrame.pstPack->u64PTS);
|
||
rtsp_do_event(g_rtsplive);
|
||
pthread_mutex_unlock(&g_rtsp_mutex);
|
||
|
||
RK_LOGD("chn:%d, loopCount:%d wd:%d\n", ctx->s32ChnId, loopCount,
|
||
ctx->stFrame.pstPack->u32Len);
|
||
|
||
SAMPLE_COMM_VENC_ReleaseStream(ctx);
|
||
loopCount++;
|
||
}
|
||
usleep(1000);
|
||
}
|
||
|
||
if (fp) {
|
||
fclose(fp);
|
||
fp = RK_NULL;
|
||
}
|
||
return RK_NULL;
|
||
}
|
||
|
||
static void handle_pipe(int sig) {
|
||
printf("sigaction will ignore signal %d\n", sig);
|
||
return;
|
||
}
|
||
|
||
/******************************************************************************
|
||
* function : main()
|
||
* Description : main
|
||
******************************************************************************/
|
||
int main(int argc, char *argv[]) {
|
||
RK_S32 s32Ret = RK_FAILURE;
|
||
SAMPLE_MPI_CTX_S *ctx = RK_NULL;
|
||
RK_BOOL bIfOsdDisplay = RK_TRUE;
|
||
RK_U32 u32ViWidth = 1920;
|
||
RK_U32 u32ViHeight = 1080;
|
||
RK_U32 u32AvsChn0Width = 3840;
|
||
RK_U32 u32AvsChn0Height = 1080;
|
||
RK_U32 u32AvsChn1Width = 1920;
|
||
RK_U32 u32AvsChn1Height = 544;
|
||
RK_CHAR *pAvsCalibFilePath = "/oem/usr/share/avs_calib/calib_file.xml";
|
||
RK_CHAR *pAvsMeshAlphaPath = "/tmp/";
|
||
RK_CHAR *pAvsLutFilePath = NULL;
|
||
RK_CHAR *pOutPathVenc = NULL;
|
||
RK_CHAR *pCam0LdchMeshPath = "/oem/usr/share/iqfiles/cam0_ldch_mesh.bin";
|
||
RK_CHAR *pCam1LdchMeshPath = "/oem/usr/share/iqfiles/cam1_ldch_mesh.bin";
|
||
RK_CHAR *pBmpPath = NULL;
|
||
CODEC_TYPE_E enCodecType = RK_CODEC_TYPE_H264;
|
||
VENC_RC_MODE_E enRcMode = VENC_RC_MODE_H264CBR;
|
||
rk_aiq_working_mode_t hdr_mode = RK_AIQ_WORKING_MODE_NORMAL;
|
||
RK_CHAR *pCodecName = "H264";
|
||
MPP_CHN_S stSrcChn, stDestChn;
|
||
RK_S32 s32CamNum = 2;
|
||
RK_S32 s32DstFps = 15;
|
||
RK_S32 s32loopCnt = -1;
|
||
RK_S32 s32BitRate = 4 * 1024;
|
||
RK_S32 s32CamGrpId = 0;
|
||
RK_S32 s32ViChnid = 1;
|
||
RK_S32 s32ViBuffCnt = 2;
|
||
RK_S32 s32AvsModeBlend = 0;
|
||
GET_LDCH_MODE_E eGetLdchMode = RK_GET_LDCH_BY_BUFF;
|
||
RK_FLOAT fStitchDistance = 5;
|
||
RK_VOID *pLdchMeshData[VI_NUM_MAX] = {NULL};
|
||
RK_BOOL bIfIspGroupInit = RK_TRUE;
|
||
|
||
if (argc < 2) {
|
||
print_usage(argv[0]);
|
||
return 0;
|
||
}
|
||
|
||
ctx = (SAMPLE_MPI_CTX_S *)(malloc(sizeof(SAMPLE_MPI_CTX_S)));
|
||
if (!ctx) {
|
||
RK_LOGE("malloc for SAMPLE_MPI_CTX_S ctx failure");
|
||
return RK_FAILURE;
|
||
}
|
||
memset(ctx, 0, sizeof(SAMPLE_MPI_CTX_S));
|
||
|
||
if (RK_SUCCESS != pthread_mutex_init(&g_rtsp_mutex, RK_NULL)) {
|
||
RK_LOGE("pthread_mutex_init failure");
|
||
goto __FAILED2;
|
||
}
|
||
|
||
signal(SIGINT, sigterm_handler);
|
||
struct sigaction action;
|
||
action.sa_handler = handle_pipe;
|
||
sigemptyset(&action.sa_mask);
|
||
action.sa_flags = 0;
|
||
sigaction(SIGPIPE, &action, NULL);
|
||
|
||
#ifdef RKAIQ
|
||
RK_BOOL bMultictx = RK_FALSE;
|
||
#endif
|
||
int c;
|
||
char *iq_file_dir = "/etc/iqfiles/";
|
||
while ((c = getopt_long(argc, argv, optstr, long_options, NULL)) != -1) {
|
||
const char *tmp_optarg = optarg;
|
||
switch (c) {
|
||
case 'a':
|
||
if (!optarg && NULL != argv[optind] && '-' != argv[optind][0]) {
|
||
tmp_optarg = argv[optind++];
|
||
}
|
||
if (tmp_optarg) {
|
||
iq_file_dir = (char *)tmp_optarg;
|
||
} else {
|
||
iq_file_dir = NULL;
|
||
}
|
||
break;
|
||
case 'A':
|
||
pAvsCalibFilePath = optarg;
|
||
break;
|
||
case 'b':
|
||
s32BitRate = atoi(optarg);
|
||
break;
|
||
case 'e':
|
||
if (!strcmp(optarg, "h264cbr")) {
|
||
enCodecType = RK_CODEC_TYPE_H264;
|
||
enRcMode = VENC_RC_MODE_H264CBR;
|
||
pCodecName = "H264";
|
||
} else if (!strcmp(optarg, "h264vbr")) {
|
||
enCodecType = RK_CODEC_TYPE_H264;
|
||
enRcMode = VENC_RC_MODE_H264VBR;
|
||
pCodecName = "H264";
|
||
} else if (!strcmp(optarg, "h265cbr")) {
|
||
enCodecType = RK_CODEC_TYPE_H265;
|
||
enRcMode = VENC_RC_MODE_H265CBR;
|
||
pCodecName = "H265";
|
||
} else if (!strcmp(optarg, "h265vbr")) {
|
||
enCodecType = RK_CODEC_TYPE_H265;
|
||
enRcMode = VENC_RC_MODE_H265VBR;
|
||
pCodecName = "H265";
|
||
} else {
|
||
RK_LOGE("this demo isn't support this encoder type.");
|
||
return 0;
|
||
}
|
||
break;
|
||
case 'n':
|
||
s32CamNum = atoi(optarg);
|
||
break;
|
||
case 'l':
|
||
s32loopCnt = atoi(optarg);
|
||
break;
|
||
case 'o':
|
||
pOutPathVenc = optarg;
|
||
break;
|
||
case 'F':
|
||
s32DstFps = atoi(optarg);
|
||
break;
|
||
case 'd':
|
||
fStitchDistance = atof(optarg);
|
||
break;
|
||
case 'L':
|
||
pCam0LdchMeshPath = optarg;
|
||
break;
|
||
case 'L' + 'm':
|
||
pCam1LdchMeshPath = optarg;
|
||
break;
|
||
case 'v' + 's':
|
||
u32ViWidth = atoi(optarg);
|
||
tmp_optarg = strstr(optarg, "x");
|
||
u32ViHeight = atoi(tmp_optarg + 1);
|
||
break;
|
||
case 'a' + 's':
|
||
u32AvsChn0Width = atoi(optarg);
|
||
tmp_optarg = strstr(optarg, "x");
|
||
u32AvsChn0Height = atoi(tmp_optarg + 1);
|
||
break;
|
||
case 'a' + 'v':
|
||
u32AvsChn1Width = atoi(optarg);
|
||
tmp_optarg = strstr(optarg, "x");
|
||
u32AvsChn1Height = atoi(tmp_optarg + 1);
|
||
break;
|
||
case 'h' + 'm':
|
||
if (atoi(optarg) == 0) {
|
||
hdr_mode = RK_AIQ_WORKING_MODE_NORMAL;
|
||
} else if (atoi(optarg) == 1) {
|
||
hdr_mode = RK_AIQ_WORKING_MODE_ISP_HDR2;
|
||
} else if (atoi(optarg) == 2) {
|
||
hdr_mode = RK_AIQ_WORKING_MODE_ISP_HDR3;
|
||
} else {
|
||
RK_LOGE("input hdr_mode is not support(error)");
|
||
print_usage(argv[0]);
|
||
goto __FAILED2;
|
||
}
|
||
break;
|
||
case 'l' + 'd':
|
||
eGetLdchMode = atoi(optarg);
|
||
break;
|
||
case 'i':
|
||
bIfIspGroupInit = atoi(optarg);
|
||
break;
|
||
case 'i' + 'b':
|
||
pBmpPath = optarg;
|
||
break;
|
||
case 'o' + 'd':
|
||
bIfOsdDisplay = atoi(optarg);
|
||
break;
|
||
case 'v' + 'i':
|
||
s32ViChnid = atoi(optarg);
|
||
break;
|
||
case 'v' + 'c':
|
||
s32ViBuffCnt = atoi(optarg);
|
||
break;
|
||
case 'a' + 'm' + 'b':
|
||
s32AvsModeBlend = atoi(optarg);
|
||
break;
|
||
case '?':
|
||
default:
|
||
print_usage(argv[0]);
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
printf("#CameraGrpIdx: %d\n", s32CamGrpId);
|
||
printf("#pAvsLutFilePath: %s\n", pAvsLutFilePath);
|
||
printf("#pAvsCalibFilePath: %s\n", pAvsCalibFilePath);
|
||
printf("#pAvsMeshAlphaPath: %s\n", pAvsMeshAlphaPath);
|
||
printf("#CodecName:%s\n", pCodecName);
|
||
printf("#Output Path: %s\n", pOutPathVenc);
|
||
printf("#IQ Path: %s\n", iq_file_dir);
|
||
printf("#fStitchDistance: %f\n", fStitchDistance);
|
||
printf("#pCam0LdchMeshPath: %s\n", pCam0LdchMeshPath);
|
||
printf("#pCam1LdchMeshPath: %s\n", pCam1LdchMeshPath);
|
||
printf("#AvsModeBlend: %d\n", s32AvsModeBlend);
|
||
|
||
if (eGetLdchMode == RK_GET_LDCH_BY_FILE && pCam0LdchMeshPath && pCam1LdchMeshPath) {
|
||
pLdchMeshData[0] = pCam0LdchMeshPath;
|
||
pLdchMeshData[1] = pCam1LdchMeshPath;
|
||
}
|
||
|
||
if (RK_MPI_SYS_Init() != RK_SUCCESS) {
|
||
goto __FAILED;
|
||
}
|
||
|
||
/* Init avs[0] */
|
||
ctx->avs.s32GrpId = 0;
|
||
ctx->avs.s32ChnId = 0;
|
||
ctx->avs.eGetLdchMode = eGetLdchMode;
|
||
ctx->avs.u32SrcWidth = u32ViWidth;
|
||
ctx->avs.u32SrcHeight = u32ViHeight;
|
||
ctx->avs.fDistance = fStitchDistance;
|
||
ctx->avs.pLdchMeshData = (RK_U16 **)pLdchMeshData;
|
||
/* GrpAttr setting */
|
||
ctx->avs.stAvsGrpAttr.enMode = s32AvsModeBlend; /* 0: blend 1: no blend */
|
||
ctx->avs.stAvsGrpAttr.u32PipeNum = s32CamNum;
|
||
ctx->avs.stAvsGrpAttr.stGainAttr.enMode = AVS_GAIN_MODE_AUTO;
|
||
ctx->avs.stAvsGrpAttr.stOutAttr.enPrjMode = AVS_PROJECTION_EQUIRECTANGULAR;
|
||
ctx->avs.stAvsGrpAttr.stOutAttr.stSize.u32Width = u32AvsChn0Width;
|
||
ctx->avs.stAvsGrpAttr.stOutAttr.stSize.u32Height = u32AvsChn0Height;
|
||
ctx->avs.stAvsGrpAttr.bSyncPipe = RK_TRUE;
|
||
ctx->avs.stAvsGrpAttr.stFrameRate.s32SrcFrameRate = -1;
|
||
ctx->avs.stAvsGrpAttr.stFrameRate.s32DstFrameRate = -1;
|
||
ctx->avs.stAvsGrpAttr.stInAttr.stSize.u32Width = u32ViWidth;
|
||
ctx->avs.stAvsGrpAttr.stInAttr.stSize.u32Height = u32ViHeight;
|
||
ctx->avs.stAvsGrpAttr.stOutAttr.fDistance = fStitchDistance;
|
||
ctx->avs.stAvsGrpAttr.stInAttr.enParamSource = AVS_PARAM_SOURCE_CALIB;
|
||
ctx->avs.stAvsGrpAttr.stInAttr.stCalib.pCalibFilePath = pAvsCalibFilePath;
|
||
/* set chn0 */
|
||
ctx->avs.stAvsChnAttr[0].enCompressMode = COMPRESS_MODE_NONE;
|
||
ctx->avs.stAvsChnAttr[0].stFrameRate.s32SrcFrameRate = -1;
|
||
ctx->avs.stAvsChnAttr[0].stFrameRate.s32DstFrameRate = -1;
|
||
ctx->avs.stAvsChnAttr[0].u32FrameBufCnt = 2;
|
||
#ifdef RV1126
|
||
ctx->avs.stAvsChnAttr[0].u32FrameBufCnt = 4;
|
||
#endif
|
||
ctx->avs.stAvsChnAttr[0].u32Depth = 0;
|
||
ctx->avs.stAvsChnAttr[0].u32Width = u32AvsChn0Width;
|
||
ctx->avs.stAvsChnAttr[0].u32Height = u32AvsChn0Height;
|
||
ctx->avs.stAvsChnAttr[0].enDynamicRange = DYNAMIC_RANGE_SDR8;
|
||
/* set chn1 */
|
||
ctx->avs.stAvsChnAttr[1].enCompressMode = COMPRESS_MODE_NONE;
|
||
ctx->avs.stAvsChnAttr[1].stFrameRate.s32SrcFrameRate = -1;
|
||
ctx->avs.stAvsChnAttr[1].stFrameRate.s32DstFrameRate = -1;
|
||
ctx->avs.stAvsChnAttr[1].u32FrameBufCnt = 2;
|
||
#ifdef RV1126
|
||
ctx->avs.stAvsChnAttr[1].u32FrameBufCnt = 4;
|
||
#endif
|
||
ctx->avs.stAvsChnAttr[1].u32Depth = 0;
|
||
ctx->avs.stAvsChnAttr[1].u32Width = u32AvsChn1Width;
|
||
ctx->avs.stAvsChnAttr[1].u32Height = u32AvsChn1Height;
|
||
ctx->avs.stAvsChnAttr[1].enDynamicRange = DYNAMIC_RANGE_SDR8;
|
||
/* avs create */
|
||
s32Ret = SAMPLE_COMM_AVS_CreateGrp(&ctx->avs);
|
||
if (s32Ret != RK_SUCCESS) {
|
||
RK_LOGE("SAMPLE_COMM_AVS_CreateGrp failure:%#X", s32Ret);
|
||
}
|
||
|
||
if (iq_file_dir) {
|
||
#ifdef RKAIQ
|
||
printf("#Rkaiq XML DirPath: %s\n", iq_file_dir);
|
||
printf("#bMultictx: %d\n\n", bMultictx);
|
||
if (bIfIspGroupInit == RK_FALSE) {
|
||
for (RK_S32 i = 0; i < s32CamNum; i++) {
|
||
s32Ret = SAMPLE_COMM_ISP_Init(i, hdr_mode, bMultictx, iq_file_dir);
|
||
s32Ret |= SAMPLE_COMM_ISP_Run(i);
|
||
if (s32Ret != RK_SUCCESS) {
|
||
RK_LOGE("ISP init failure camid:%d", i);
|
||
return RK_FAILURE;
|
||
}
|
||
}
|
||
} else {
|
||
#ifdef RKAIQ_GRP
|
||
rk_aiq_camgroup_instance_cfg_t camgroup_cfg;
|
||
|
||
memset(&camgroup_cfg, 0, sizeof(camgroup_cfg));
|
||
camgroup_cfg.sns_num = s32CamNum;
|
||
camgroup_cfg.config_file_dir = iq_file_dir;
|
||
s32Ret =
|
||
SAMPLE_COMM_ISP_CamGroup_Init(s32CamGrpId, hdr_mode, bMultictx,
|
||
eGetLdchMode, pLdchMeshData, &camgroup_cfg);
|
||
if (s32Ret != RK_SUCCESS) {
|
||
RK_LOGE("SAMPLE_COMM_ISP_CamGroup_Init failure");
|
||
return -1;
|
||
} else {
|
||
RK_LOGE("SAMPLE_COMM_ISP_CamGroup_Init success");
|
||
}
|
||
s32Ret = SAMPLE_COMM_ISP_CamGroup_SetFrameRate(s32CamGrpId, s32DstFps);
|
||
if (s32Ret != RK_SUCCESS) {
|
||
RK_LOGE("SAMPLE_COMM_ISP_CamGroup_SetFrameRate failure");
|
||
} else {
|
||
RK_LOGE("SAMPLE_COMM_ISP_CamGroup_SetFrameRate success");
|
||
}
|
||
#endif
|
||
}
|
||
|
||
#endif
|
||
}
|
||
|
||
// init rtsp
|
||
RK_CHAR str_buff[255] = {0};
|
||
g_rtsplive = create_rtsp_demo(554);
|
||
for (RK_S32 i = 0; i < VENC_NUM_MAX; i++) {
|
||
sprintf(str_buff, "/live/%d", i);
|
||
g_rtsp_session[i] = rtsp_new_session(g_rtsplive, str_buff);
|
||
if (enCodecType == RK_CODEC_TYPE_H264) {
|
||
rtsp_set_video(g_rtsp_session[i], RTSP_CODEC_ID_VIDEO_H264, NULL, 0);
|
||
} else if (enCodecType == RK_CODEC_TYPE_H265) {
|
||
rtsp_set_video(g_rtsp_session[i], RTSP_CODEC_ID_VIDEO_H265, NULL, 0);
|
||
} else {
|
||
printf("not support other type\n");
|
||
return -1;
|
||
}
|
||
rtsp_sync_video_ts(g_rtsp_session[i], rtsp_get_reltime(), rtsp_get_ntptime());
|
||
}
|
||
|
||
/* init vi */
|
||
for (RK_S32 i = 0; i < s32CamNum; i++) {
|
||
ctx->vi[i].u32Width = u32ViWidth;
|
||
ctx->vi[i].u32Height = u32ViHeight;
|
||
ctx->vi[i].s32DevId = i;
|
||
ctx->vi[i].u32PipeId = i;
|
||
ctx->vi[i].s32ChnId = s32ViChnid;
|
||
ctx->vi[i].bIfIspGroupInit = bIfIspGroupInit;
|
||
#ifdef RV1126
|
||
ctx->vi[i].bIfIspGroupInit = RK_FALSE;
|
||
#endif
|
||
ctx->vi[i].stChnAttr.stIspOpt.u32BufCount = s32ViBuffCnt;
|
||
ctx->vi[i].stChnAttr.stIspOpt.enMemoryType = VI_V4L2_MEMORY_TYPE_DMABUF;
|
||
ctx->vi[i].stChnAttr.u32Depth = 0;
|
||
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;
|
||
SAMPLE_COMM_VI_CreateChn(&ctx->vi[i]);
|
||
}
|
||
|
||
for (RK_S32 i = 0; i < s32CamNum && ctx->vi[i].bIfIspGroupInit; 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);
|
||
goto __VI_INITFAIL;
|
||
}
|
||
}
|
||
|
||
/* avs startgrp*/
|
||
s32Ret = SAMPLE_COMM_AVS_StartGrp(&ctx->avs);
|
||
if (s32Ret != RK_SUCCESS) {
|
||
printf("func: %s line: %d avs create failure!/n", __func__, __LINE__);
|
||
goto __AVS_FAILED;
|
||
}
|
||
|
||
/* Init VENC[0] */
|
||
ctx->venc[0].s32ChnId = 0;
|
||
ctx->venc[0].u32Width = u32AvsChn0Width;
|
||
ctx->venc[0].u32Height = u32AvsChn0Height;
|
||
ctx->venc[0].u32Fps = s32DstFps;
|
||
ctx->venc[0].u32Gop = s32DstFps * 2;
|
||
ctx->venc[0].u32BitRate = s32BitRate;
|
||
ctx->venc[0].enCodecType = enCodecType;
|
||
ctx->venc[0].enRcMode = enRcMode;
|
||
ctx->venc[0].getStreamCbFunc = venc_get_stream;
|
||
ctx->venc[0].s32loopCount = s32loopCnt;
|
||
ctx->venc[0].dstFilePath = pOutPathVenc;
|
||
ctx->venc[0].u32BuffSize = ctx->venc[0].u32Width * ctx->venc[0].u32Height / 3;
|
||
ctx->venc[0].u32StreamBufCnt = 3;
|
||
#ifdef RV1126
|
||
ctx->venc[0].u32StreamBufCnt = 4;
|
||
#endif
|
||
ctx->venc[0].enable_buf_share = RK_TRUE;
|
||
// H264 66:Baseline 77:Main Profile 100:High Profile
|
||
// H265 0:Main Profile 1:Main 10 Profile
|
||
// MJPEG 0:Baseline
|
||
if (enCodecType == RK_CODEC_TYPE_H264) {
|
||
ctx->venc[0].stChnAttr.stVencAttr.u32Profile = 66;
|
||
} else {
|
||
ctx->venc[0].stChnAttr.stVencAttr.u32Profile = 0;
|
||
}
|
||
ctx->venc[0].stChnAttr.stGopAttr.enGopMode =
|
||
VENC_GOPMODE_NORMALP; // VENC_GOPMODE_SMARTP
|
||
SAMPLE_COMM_VENC_CreateChn(&ctx->venc[0]);
|
||
|
||
/* Init VENC[1] */
|
||
ctx->venc[1].s32ChnId = 1;
|
||
ctx->venc[1].u32Width = u32AvsChn1Width;
|
||
ctx->venc[1].u32Height = u32AvsChn1Height;
|
||
ctx->venc[1].u32Fps = s32DstFps;
|
||
ctx->venc[1].u32Gop = s32DstFps * 2;
|
||
ctx->venc[1].enCodecType = enCodecType;
|
||
ctx->venc[1].enRcMode = enRcMode;
|
||
ctx->venc[1].getStreamCbFunc = venc_get_stream;
|
||
ctx->venc[1].s32loopCount = s32loopCnt;
|
||
ctx->venc[1].dstFilePath = pOutPathVenc;
|
||
ctx->venc[1].u32BuffSize = ctx->venc[1].u32Width * ctx->venc[1].u32Height / 3;
|
||
ctx->venc[1].u32BitRate = 1024;
|
||
ctx->venc[1].u32StreamBufCnt = 3;
|
||
#ifdef RV1126
|
||
ctx->venc[1].u32StreamBufCnt = 4;
|
||
#endif
|
||
ctx->venc[1].enable_buf_share = RK_TRUE;
|
||
// H264 66:Baseline 77:Main Profile 100:High Profile
|
||
// H265 0:Main Profile 1:Main 10 Profile
|
||
// MJPEG 0:Baseline
|
||
if (enCodecType == RK_CODEC_TYPE_H264) {
|
||
ctx->venc[1].stChnAttr.stVencAttr.u32Profile = 66;
|
||
} else {
|
||
ctx->venc[1].stChnAttr.stVencAttr.u32Profile = 0;
|
||
}
|
||
ctx->venc[1].stChnAttr.stGopAttr.enGopMode =
|
||
VENC_GOPMODE_NORMALP; // VENC_GOPMODE_SMARTP
|
||
SAMPLE_COMM_VENC_CreateChn(&ctx->venc[1]);
|
||
|
||
/* Init RGN */
|
||
RK_U32 u32BmpWidth = 0;
|
||
RK_U32 u32BmpHeight = 0;
|
||
s32Ret = SAMPLE_COMM_GetBmpResolution(pBmpPath, &u32BmpWidth, &u32BmpHeight);
|
||
if (s32Ret != RK_SUCCESS) {
|
||
RK_LOGE("SAMPLE_COMM_GetBmpResolution failure");
|
||
u32BmpWidth = 128;
|
||
u32BmpHeight = 128;
|
||
}
|
||
ctx->rgn.rgnHandle = 0;
|
||
ctx->rgn.stRgnAttr.enType = OVERLAY_RGN;
|
||
ctx->rgn.stMppChn.enModId = RK_ID_VENC;
|
||
ctx->rgn.stMppChn.s32ChnId = ctx->venc[0].s32ChnId;
|
||
ctx->rgn.stMppChn.s32DevId = 0;
|
||
ctx->rgn.stRegion.s32X = ctx->venc[0].u32Width / 2; // must be 16 aligned
|
||
ctx->rgn.stRegion.s32Y = 0; // must be 16 aligned
|
||
ctx->rgn.stRegion.u32Width = u32BmpWidth; // must be 16 aligned
|
||
ctx->rgn.stRegion.u32Height = u32BmpHeight; // must be 16 aligned
|
||
ctx->rgn.u32BmpFormat = RK_FMT_BGRA5551;
|
||
ctx->rgn.u32BgAlpha = 128;
|
||
ctx->rgn.u32FgAlpha = 128;
|
||
ctx->rgn.srcFileBmpName = pBmpPath;
|
||
ctx->rgn.u32Layer = 1;
|
||
if (bIfOsdDisplay) {
|
||
SAMPLE_COMM_RGN_CreateChn(&ctx->rgn);
|
||
}
|
||
|
||
// Bind VI[0] and avs[0]
|
||
for (RK_S32 i = 0; i < s32CamNum; i++) {
|
||
stSrcChn.enModId = RK_ID_VI;
|
||
stSrcChn.s32DevId = ctx->vi[i].s32DevId;
|
||
stSrcChn.s32ChnId = ctx->vi[i].s32ChnId;
|
||
stDestChn.enModId = RK_ID_AVS;
|
||
stDestChn.s32DevId = ctx->avs.s32GrpId;
|
||
stDestChn.s32ChnId = i;
|
||
SAMPLE_COMM_Bind(&stSrcChn, &stDestChn);
|
||
}
|
||
|
||
/* Bind AVS[0,0] and VENC[0,0] */
|
||
stSrcChn.enModId = RK_ID_AVS;
|
||
stSrcChn.s32DevId = ctx->avs.s32GrpId;
|
||
stSrcChn.s32ChnId = ctx->avs.s32ChnId;
|
||
stDestChn.enModId = RK_ID_VENC;
|
||
stDestChn.s32DevId = 0;
|
||
stDestChn.s32ChnId = ctx->venc[0].s32ChnId;
|
||
SAMPLE_COMM_Bind(&stSrcChn, &stDestChn);
|
||
|
||
/* Bind AVS[0,1] and VENC[0,1] */
|
||
stSrcChn.enModId = RK_ID_AVS;
|
||
stSrcChn.s32DevId = ctx->avs.s32GrpId;
|
||
stSrcChn.s32ChnId = 1;
|
||
stDestChn.enModId = RK_ID_VENC;
|
||
stDestChn.s32DevId = 0;
|
||
stDestChn.s32ChnId = ctx->venc[1].s32ChnId;
|
||
SAMPLE_COMM_Bind(&stSrcChn, &stDestChn);
|
||
|
||
printf("%s initial finish\n", __func__);
|
||
|
||
while (!g_bMainThreadQuit) {
|
||
sleep(1);
|
||
}
|
||
|
||
printf("%s exit!\n", __func__);
|
||
/* Destroy RGN[0] */
|
||
if (bIfOsdDisplay) {
|
||
SAMPLE_COMM_RGN_DestroyChn(&ctx->rgn);
|
||
}
|
||
// Destroy VENC[0]
|
||
g_bVencThreadQuit[0] = RK_TRUE;
|
||
pthread_join(ctx->venc[0].getStreamThread, NULL);
|
||
/* Bind AVS[0,0] and VENC[0,0] */
|
||
stSrcChn.enModId = RK_ID_AVS;
|
||
stSrcChn.s32DevId = ctx->avs.s32GrpId;
|
||
stSrcChn.s32ChnId = ctx->avs.s32ChnId;
|
||
stDestChn.enModId = RK_ID_VENC;
|
||
stDestChn.s32DevId = 0;
|
||
stDestChn.s32ChnId = ctx->venc[0].s32ChnId;
|
||
s32Ret = SAMPLE_COMM_UnBind(&stSrcChn, &stDestChn);
|
||
if (s32Ret != RK_SUCCESS) {
|
||
RK_LOGE("SAMPLE_COMM_UnBind failure:%#X", s32Ret);
|
||
}
|
||
SAMPLE_COMM_VENC_DestroyChn(&ctx->venc[0]);
|
||
|
||
// Destroy VENC[1]
|
||
g_bVencThreadQuit[1] = RK_TRUE;
|
||
pthread_join(ctx->venc[1].getStreamThread, NULL);
|
||
/* Bind AVS[0,1] and VENC[0,1] */
|
||
stSrcChn.enModId = RK_ID_AVS;
|
||
stSrcChn.s32DevId = ctx->avs.s32GrpId;
|
||
stSrcChn.s32ChnId = 1;
|
||
stDestChn.enModId = RK_ID_VENC;
|
||
stDestChn.s32DevId = 0;
|
||
stDestChn.s32ChnId = ctx->venc[1].s32ChnId;
|
||
s32Ret = SAMPLE_COMM_UnBind(&stSrcChn, &stDestChn);
|
||
if (s32Ret != RK_SUCCESS) {
|
||
RK_LOGE("SAMPLE_COMM_UnBind failure:%#X", s32Ret);
|
||
}
|
||
SAMPLE_COMM_VENC_DestroyChn(&ctx->venc[1]);
|
||
|
||
if (g_rtsplive)
|
||
rtsp_del_demo(g_rtsplive);
|
||
|
||
// UnBind Bind VI[0]~VI[5] and AVS[0]
|
||
for (RK_S32 i = 0; i < s32CamNum; i++) {
|
||
stSrcChn.enModId = RK_ID_VI;
|
||
stSrcChn.s32DevId = ctx->vi[i].s32DevId;
|
||
stSrcChn.s32ChnId = ctx->vi[i].s32ChnId;
|
||
stDestChn.enModId = RK_ID_AVS;
|
||
stDestChn.s32DevId = ctx->avs.s32GrpId;
|
||
stDestChn.s32ChnId = i;
|
||
SAMPLE_COMM_UnBind(&stSrcChn, &stDestChn);
|
||
}
|
||
|
||
// Destroy AVS[0]
|
||
SAMPLE_COMM_AVS_StopGrp(&ctx->avs);
|
||
SAMPLE_COMM_AVS_DestroyGrp(&ctx->avs);
|
||
|
||
__AVS_FAILED:
|
||
|
||
for (RK_S32 i = 0; i < s32CamNum && ctx->vi[i].bIfIspGroupInit; 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);
|
||
}
|
||
}
|
||
|
||
__VI_INITFAIL:
|
||
// Destroy VI[0]
|
||
for (RK_S32 i = 0; i < s32CamNum; i++) {
|
||
SAMPLE_COMM_VI_DestroyChn(&ctx->vi[i]);
|
||
}
|
||
|
||
__FAILED:
|
||
RK_MPI_SYS_Exit();
|
||
if (iq_file_dir) {
|
||
#ifdef RKAIQ
|
||
if (bIfIspGroupInit == RK_FALSE) {
|
||
for (RK_S32 i = 0; i < s32CamNum; i++) {
|
||
s32Ret = SAMPLE_COMM_ISP_Stop(i);
|
||
if (s32Ret != RK_SUCCESS) {
|
||
RK_LOGE("SAMPLE_COMM_ISP_Stop failure:%#X", s32Ret);
|
||
return s32Ret;
|
||
}
|
||
}
|
||
} else if (bIfIspGroupInit == RK_TRUE) {
|
||
#ifdef RKAIQ_GRP
|
||
s32Ret = SAMPLE_COMM_ISP_CamGroup_Stop(s32CamGrpId);
|
||
if (s32Ret != RK_SUCCESS) {
|
||
RK_LOGE("SAMPLE_COMM_ISP_CamGroup_Stop failure:%#X", s32Ret);
|
||
return s32Ret;
|
||
}
|
||
#endif
|
||
} else {
|
||
RK_LOGE("ISP deinit dosen't support this mode %d", bIfIspGroupInit);
|
||
return RK_FAILURE;
|
||
}
|
||
#endif
|
||
}
|
||
pthread_mutex_destroy(&g_rtsp_mutex);
|
||
__FAILED2:
|
||
|
||
if (ctx) {
|
||
free(ctx);
|
||
ctx = RK_NULL;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
#ifdef __cplusplus
|
||
#if __cplusplus
|
||
}
|
||
#endif
|
||
#endif /* End of #ifdef __cplusplus */
|