637 lines
18 KiB
C
637 lines
18 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 /* End of #ifdef __cplusplus */
|
|
|
|
#include <assert.h>
|
|
#include <error.h>
|
|
#include <fcntl.h>
|
|
#include <getopt.h>
|
|
#include <pthread.h>
|
|
#include <semaphore.h>
|
|
#include <signal.h>
|
|
|
|
#include <sample_comm.h>
|
|
|
|
#define GET_STREAM_TIMEOUT 2000
|
|
#define SEND_STREAM_TIMEOUT 2000
|
|
#define BUFFER_SIZE 255
|
|
#define VENC_CHN_MAX 2
|
|
#define VENC_COMBO_CHN 1
|
|
|
|
static RK_BOOL g_quit = RK_FALSE;
|
|
static RK_S32 g_exit_result = RK_SUCCESS;
|
|
static RK_BOOL g_bIfVencThreadQuit[VENC_CHN_MAX] = {RK_FALSE};
|
|
static RK_U32 g_u32MainVencWidth = 1920;
|
|
static RK_U32 g_u32MainVencHeight = 1080;
|
|
static RK_CHAR *g_pOutPath = RK_NULL;
|
|
static RK_S32 g_s32loopCnt = -1;
|
|
static RK_BOOL g_wrap = RK_FALSE;
|
|
static RK_S32 g_s32JpegCaptureNum = 1;
|
|
|
|
static void program_handle_error(const char *func, RK_U32 line) {
|
|
RK_LOGE("func: <%s> line: <%d> error exit!", func, line);
|
|
g_exit_result = RK_FAILURE;
|
|
g_quit = RK_TRUE;
|
|
}
|
|
|
|
static void program_normal_exit(const char *func, RK_U32 line) {
|
|
RK_LOGE("func: <%s> line: <%d> normal exit!", func, line);
|
|
g_quit = 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:l:o:r:j:";
|
|
static const struct option long_options[] = {
|
|
{"aiq", optional_argument, NULL, 'a'},
|
|
{"width", required_argument, NULL, 'w'},
|
|
{"height", required_argument, NULL, 'h'},
|
|
{"loop_count", required_argument, NULL, 'l'},
|
|
{"output_path", required_argument, NULL, 'o'},
|
|
{"wrap", required_argument, NULL, 'r'},
|
|
{"jpeg_capture_num", required_argument, NULL, 'j'},
|
|
{"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/ -l -1 -o /userdata/\n", name);
|
|
#ifdef RKAIQ
|
|
printf("\t-a | --aiq: enable aiq with dirpath provided, eg:-a /etc/iqfiles/, "
|
|
"set dirpath empty to using path by default, \n"
|
|
"\t without this option aiq "
|
|
"should run in other application\n");
|
|
#endif
|
|
printf("\t-w | --width: Vi width, Default 1920\n");
|
|
printf("\t-h | --height: Vi height, Default 1080\n");
|
|
printf("\t-l | --loop_count: loop count, Default -1\n");
|
|
printf("\t-o | --output_path: Venc output file path, Default NULL\n");
|
|
printf("\t-r | --wrap: wrap mode, 0:close 1:open. Default: 0\n");
|
|
printf("\t-j | --jpeg_capture_num: set jpeg capture photos one time. Default: 1\n");
|
|
}
|
|
|
|
static void *venc_get_stream(void *pArgs) {
|
|
|
|
RK_S32 s32ChnId = *(RK_S32 *)pArgs;
|
|
RK_S32 s32Ret = RK_FAILURE;
|
|
FILE *fp = RK_NULL;
|
|
RK_S32 s32fd = 0;
|
|
RK_S32 loopCount = 0;
|
|
RK_VOID *pData = RK_NULL;
|
|
RK_CHAR name[BUFFER_SIZE] = {0};
|
|
VENC_STREAM_S stFrame;
|
|
|
|
if (g_pOutPath) {
|
|
snprintf(name, sizeof(name), "/%s/venc_%d.bin", g_pOutPath, s32ChnId);
|
|
fp = fopen(name, "wb");
|
|
if (fp == RK_NULL) {
|
|
RK_LOGE("chn %d can't open %s file !\n", s32ChnId, g_pOutPath);
|
|
program_handle_error(__func__, __LINE__);
|
|
return RK_NULL;
|
|
}
|
|
s32fd = fileno(fp);
|
|
}
|
|
memset(&stFrame, 0, sizeof(VENC_STREAM_S));
|
|
stFrame.pstPack = (VENC_PACK_S *)(malloc(sizeof(VENC_PACK_S)));
|
|
if (!stFrame.pstPack) {
|
|
RK_LOGE("malloc for stFrame.pstPack failure, chnid:%d", s32ChnId);
|
|
program_handle_error(__func__, __LINE__);
|
|
return RK_NULL;
|
|
}
|
|
while (!g_bIfVencThreadQuit[s32ChnId]) {
|
|
s32Ret = RK_MPI_VENC_GetStream(s32ChnId, &stFrame, -1);
|
|
if (s32Ret == RK_SUCCESS) {
|
|
pData = RK_MPI_MB_Handle2VirAddr(stFrame.pstPack->pMbBlk);
|
|
|
|
if (g_s32loopCnt > 0 && loopCount >= g_s32loopCnt) {
|
|
RK_MPI_VENC_ReleaseStream(s32ChnId, &stFrame);
|
|
program_normal_exit(__func__, __LINE__);
|
|
break;
|
|
}
|
|
|
|
if (fp) {
|
|
fwrite(pData, 1, stFrame.pstPack->u32Len, fp);
|
|
fflush(fp);
|
|
}
|
|
|
|
RK_LOGE("venc %d get_stream count: %d", s32ChnId, loopCount);
|
|
|
|
RK_MPI_VENC_ReleaseStream(s32ChnId, &stFrame);
|
|
loopCount++;
|
|
}
|
|
}
|
|
|
|
if (fp) {
|
|
fsync(s32fd);
|
|
fclose(fp);
|
|
fp = RK_NULL;
|
|
}
|
|
if (stFrame.pstPack) {
|
|
free(stFrame.pstPack);
|
|
stFrame.pstPack = RK_NULL;
|
|
}
|
|
RK_LOGE("venc_get_stream chnid:%d exit", s32ChnId);
|
|
return RK_NULL;
|
|
}
|
|
|
|
static void *combo_jpeg_get_stream(void *pArgs) {
|
|
|
|
RK_S32 s32ChnId = *(RK_S32 *)pArgs;
|
|
RK_S32 s32Ret = RK_FAILURE;
|
|
FILE *fp = RK_NULL;
|
|
RK_S32 s32fd = 0;
|
|
RK_S32 loopCount = 0;
|
|
RK_VOID *pData = RK_NULL;
|
|
RK_CHAR name[BUFFER_SIZE] = {0};
|
|
VENC_STREAM_S stFrame;
|
|
RK_U32 u32TakePhotoCount = 0;
|
|
VENC_RECV_PIC_PARAM_S stRecvParam;
|
|
|
|
memset(&stFrame, 0, sizeof(VENC_STREAM_S));
|
|
stFrame.pstPack = (VENC_PACK_S *)(malloc(sizeof(VENC_PACK_S)));
|
|
if (!stFrame.pstPack) {
|
|
RK_LOGE("malloc for stFrame.pstPack failure, chnid:%d", s32ChnId);
|
|
program_handle_error(__func__, __LINE__);
|
|
return RK_NULL;
|
|
}
|
|
|
|
while (!g_bIfVencThreadQuit[s32ChnId]) {
|
|
s32Ret = RK_MPI_VENC_GetStream(s32ChnId, &stFrame, 2000);
|
|
if (s32Ret == RK_SUCCESS) {
|
|
pData = RK_MPI_MB_Handle2VirAddr(stFrame.pstPack->pMbBlk);
|
|
|
|
if (g_pOutPath) {
|
|
snprintf(name, sizeof(name), "/%s/jpeg_chn%d_%d.jpeg", g_pOutPath,
|
|
s32ChnId, u32TakePhotoCount);
|
|
fp = fopen(name, "wb");
|
|
if (fp == RK_NULL) {
|
|
RK_LOGE("chn %d can't open %s file !\n", s32ChnId, g_pOutPath);
|
|
program_handle_error(__func__, __LINE__);
|
|
return RK_NULL;
|
|
}
|
|
s32fd = fileno(fp);
|
|
}
|
|
|
|
if (fp) {
|
|
fwrite(pData, 1, stFrame.pstPack->u32Len, fp);
|
|
fflush(fp);
|
|
fsync(s32fd);
|
|
fclose(fp);
|
|
fp = RK_NULL;
|
|
}
|
|
|
|
RK_LOGE("-------------------venc %d get_stream count: %d", s32ChnId,
|
|
loopCount);
|
|
|
|
RK_MPI_VENC_ReleaseStream(s32ChnId, &stFrame);
|
|
loopCount++;
|
|
u32TakePhotoCount++;
|
|
|
|
if (g_s32loopCnt > 0 && loopCount >= g_s32loopCnt) {
|
|
program_normal_exit(__func__, __LINE__);
|
|
break;
|
|
}
|
|
|
|
if (u32TakePhotoCount >= g_s32JpegCaptureNum) {
|
|
RK_LOGE("restart take photo");
|
|
RK_MPI_VENC_StopRecvFrame(s32ChnId);
|
|
memset(&stRecvParam, 0, sizeof(VENC_RECV_PIC_PARAM_S));
|
|
stRecvParam.s32RecvPicNum = g_s32JpegCaptureNum;
|
|
s32Ret = RK_MPI_VENC_StartRecvFrame(s32ChnId, &stRecvParam);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
RK_LOGE("RK_MPI_VENC_StartRecvFrame failure:%X, s32Ret");
|
|
}
|
|
u32TakePhotoCount = 0;
|
|
}
|
|
|
|
} else {
|
|
RK_LOGE("RK_MPI_VENC_GetStream failure:%X", s32Ret);
|
|
}
|
|
}
|
|
|
|
if (stFrame.pstPack) {
|
|
free(stFrame.pstPack);
|
|
stFrame.pstPack = RK_NULL;
|
|
}
|
|
RK_LOGE("venc_get_stream chnid:%d exit", s32ChnId);
|
|
return RK_NULL;
|
|
}
|
|
|
|
static RK_S32 vi_init(RK_S32 s32DevId, RK_S32 s32ChnId, RK_U32 u32Width,
|
|
RK_U32 u32Height) {
|
|
RK_S32 s32Ret = RK_FAILURE;
|
|
RK_S32 s32PipeId = s32DevId;
|
|
VI_DEV_ATTR_S stDevAttr;
|
|
VI_DEV_BIND_PIPE_S stBindPipe;
|
|
VI_CHN_ATTR_S stChnAttr;
|
|
|
|
memset(&stDevAttr, 0, sizeof(VI_DEV_ATTR_S));
|
|
s32Ret = RK_MPI_VI_GetDevAttr(s32DevId, &stDevAttr);
|
|
if (s32Ret == RK_ERR_VI_NOT_CONFIG) {
|
|
/* config dev */
|
|
s32Ret = RK_MPI_VI_SetDevAttr(s32DevId, &stDevAttr);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
RK_LOGE("RK_MPI_VI_SetDevAttr failed with %#x!\n", s32Ret);
|
|
program_handle_error(__func__, __LINE__);
|
|
goto __FAILED1;
|
|
}
|
|
} else {
|
|
RK_LOGE("RK_MPI_VI_SetDevAttr already!");
|
|
}
|
|
|
|
/* get dev enable status */
|
|
s32Ret = RK_MPI_VI_GetDevIsEnable(s32DevId);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
/* enable dev */
|
|
s32Ret = RK_MPI_VI_EnableDev(s32DevId);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
RK_LOGE("RK_MPI_VI_EnableDev failed with %#x!\n", s32Ret);
|
|
program_handle_error(__func__, __LINE__);
|
|
goto __FAILED1;
|
|
}
|
|
memset(&stBindPipe, 0, sizeof(VI_DEV_BIND_PIPE_S));
|
|
/* bind dev/pipe */
|
|
stBindPipe.u32Num = 1;
|
|
stBindPipe.PipeId[0] = s32PipeId;
|
|
s32Ret = RK_MPI_VI_SetDevBindPipe(s32DevId, &stBindPipe);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
RK_LOGE("RK_MPI_VI_SetDevBindPipe failed with %#x!\n", s32Ret);
|
|
program_handle_error(__func__, __LINE__);
|
|
goto __FAILED2;
|
|
}
|
|
} else {
|
|
RK_LOGE("RK_MPI_VI_EnableDev already!");
|
|
}
|
|
|
|
/* config channel */
|
|
memset(&stChnAttr, 0, sizeof(VI_CHN_ATTR_S));
|
|
stChnAttr.stSize.u32Width = u32Width;
|
|
stChnAttr.stSize.u32Height = u32Height;
|
|
stChnAttr.stIspOpt.stMaxSize.u32Width = u32Width;
|
|
stChnAttr.stIspOpt.stMaxSize.u32Height = u32Height;
|
|
stChnAttr.stIspOpt.u32BufCount = 3;
|
|
stChnAttr.stIspOpt.enMemoryType = VI_V4L2_MEMORY_TYPE_DMABUF;
|
|
stChnAttr.u32Depth = 1;
|
|
stChnAttr.enPixelFormat = RK_FMT_YUV420SP;
|
|
stChnAttr.enCompressMode = COMPRESS_MODE_NONE;
|
|
stChnAttr.stFrameRate.s32SrcFrameRate = -1;
|
|
stChnAttr.stFrameRate.s32DstFrameRate = -1;
|
|
s32Ret = RK_MPI_VI_SetChnAttr(s32PipeId, s32ChnId, &stChnAttr);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
RK_LOGE("RK_MPI_VI_SetChnAttr failed with %#x!\n", s32Ret);
|
|
program_handle_error(__func__, __LINE__);
|
|
goto __FAILED2;
|
|
}
|
|
|
|
if (g_wrap) {
|
|
VI_CHN_BUF_WRAP_S stViWrap;
|
|
memset(&stViWrap, 0, sizeof(VI_CHN_BUF_WRAP_S));
|
|
|
|
stViWrap.bEnable = RK_TRUE;
|
|
stViWrap.u32BufLine = u32Height / 4;
|
|
stViWrap.u32WrapBufferSize = stViWrap.u32BufLine * u32Width * 3 / 2;
|
|
s32Ret = RK_MPI_VI_SetChnWrapBufAttr(s32PipeId, s32ChnId, &stViWrap);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
RK_LOGE("RK_MPI_VI_SetChnWrapBufAttr failure:%X", s32Ret);
|
|
program_handle_error(__func__, __LINE__);
|
|
goto __FAILED2;
|
|
}
|
|
}
|
|
|
|
/* enable channel */
|
|
s32Ret = RK_MPI_VI_EnableChn(s32PipeId, s32ChnId);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
RK_LOGE("RK_MPI_VI_EnableChn failed with %#x!\n", s32Ret);
|
|
program_handle_error(__func__, __LINE__);
|
|
goto __FAILED2;
|
|
}
|
|
|
|
return RK_SUCCESS;
|
|
|
|
/* disable dev(will diabled all chn) */
|
|
__FAILED2:
|
|
s32Ret = RK_MPI_VI_DisableDev(s32DevId);
|
|
RK_LOGE("RK_MPI_VI_DisableDev with %#x!\n", s32Ret);
|
|
__FAILED1:
|
|
return s32Ret;
|
|
}
|
|
|
|
static RK_S32 venc_init(RK_S32 s32ChnId, RK_U32 u32Width, RK_U32 u32Height,
|
|
CODEC_TYPE_E enCodecType, RK_BOOL bIfEnableCombo) {
|
|
RK_S32 s32Ret = RK_FAILURE;
|
|
VENC_RECV_PIC_PARAM_S stRecvParam;
|
|
VENC_CHN_ATTR_S stAttr;
|
|
|
|
memset(&stAttr, 0, sizeof(VENC_CHN_ATTR_S));
|
|
/* set venc_attr*/
|
|
if (enCodecType == RK_CODEC_TYPE_H264) {
|
|
stAttr.stVencAttr.enType = RK_VIDEO_ID_AVC;
|
|
} else if (enCodecType == RK_CODEC_TYPE_JPEG) {
|
|
stAttr.stVencAttr.enType = RK_VIDEO_ID_JPEG;
|
|
} else {
|
|
RK_LOGE("the enType is no support in this simple");
|
|
program_handle_error(__func__, __LINE__);
|
|
return s32Ret;
|
|
}
|
|
|
|
stAttr.stVencAttr.enPixelFormat = RK_FMT_YUV420SP;
|
|
stAttr.stVencAttr.u32MaxPicWidth = u32Width;
|
|
stAttr.stVencAttr.u32MaxPicHeight = u32Height;
|
|
stAttr.stVencAttr.u32PicWidth = u32Width;
|
|
stAttr.stVencAttr.u32PicHeight = u32Height;
|
|
stAttr.stVencAttr.u32VirWidth = RK_ALIGN_2(u32Width);
|
|
stAttr.stVencAttr.u32VirHeight = RK_ALIGN_2(u32Height);
|
|
stAttr.stVencAttr.u32StreamBufCnt = 3;
|
|
stAttr.stVencAttr.u32BufSize = u32Width * u32Height / 2;
|
|
|
|
/* set rc_attr */
|
|
if (enCodecType == RK_CODEC_TYPE_H264) {
|
|
stAttr.stRcAttr.enRcMode = VENC_RC_MODE_H264CBR;
|
|
stAttr.stRcAttr.stH264Cbr.u32Gop = 50;
|
|
stAttr.stRcAttr.stH264Cbr.u32BitRate = 2 * 1024;
|
|
} else if (enCodecType == RK_CODEC_TYPE_JPEG) {
|
|
stAttr.stRcAttr.enRcMode = VENC_RC_MODE_MJPEGCBR;
|
|
stAttr.stVencAttr.stAttrJpege.bSupportDCF = RK_FALSE;
|
|
stAttr.stVencAttr.stAttrJpege.stMPFCfg.u8LargeThumbNailNum = 0;
|
|
stAttr.stVencAttr.stAttrJpege.enReceiveMode = VENC_PIC_RECEIVE_SINGLE;
|
|
}
|
|
|
|
/* set gop_attr */
|
|
if (enCodecType == RK_CODEC_TYPE_H264) {
|
|
stAttr.stGopAttr.enGopMode = VENC_GOPMODE_NORMALP;
|
|
} else if (enCodecType == RK_CODEC_TYPE_JPEG) {
|
|
stAttr.stGopAttr.enGopMode = VENC_GOPMODE_INIT;
|
|
}
|
|
|
|
s32Ret = RK_MPI_VENC_CreateChn(s32ChnId, &stAttr);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
RK_LOGE("RK_MPI_VENC_CreateChn failure:%X chnid:%d", s32Ret, s32ChnId);
|
|
program_handle_error(__func__, __LINE__);
|
|
return s32Ret;
|
|
}
|
|
|
|
if (g_wrap) {
|
|
VENC_CHN_BUF_WRAP_S stVencChnBufWrap;
|
|
memset(&stVencChnBufWrap, 0, sizeof(VENC_CHN_BUF_WRAP_S));
|
|
|
|
stVencChnBufWrap.bEnable = RK_TRUE;
|
|
stVencChnBufWrap.u32BufLine = u32Height / 4;
|
|
s32Ret = RK_MPI_VENC_SetChnBufWrapAttr(s32ChnId, &stVencChnBufWrap);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
RK_LOGE("RK_MPI_VENC_SetChnBufWrapAttr failure:%X", s32Ret);
|
|
program_handle_error(__func__, __LINE__);
|
|
return RK_FAILURE;
|
|
}
|
|
}
|
|
|
|
memset(&stRecvParam, 0, sizeof(VENC_RECV_PIC_PARAM_S));
|
|
if (enCodecType == RK_CODEC_TYPE_JPEG) {
|
|
stRecvParam.s32RecvPicNum = g_s32JpegCaptureNum;
|
|
} else {
|
|
stRecvParam.s32RecvPicNum = -1;
|
|
}
|
|
s32Ret = RK_MPI_VENC_StartRecvFrame(s32ChnId, &stRecvParam);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
RK_LOGE("RK_MPI_VENC_StartRecvFrame failure:%X", s32Ret);
|
|
program_handle_error(__func__, __LINE__);
|
|
return s32Ret;
|
|
}
|
|
|
|
/* set combo */
|
|
if (bIfEnableCombo) {
|
|
VENC_COMBO_ATTR_S stComboAttr;
|
|
memset(&stComboAttr, 0, sizeof(VENC_COMBO_ATTR_S));
|
|
stComboAttr.bEnable = RK_TRUE;
|
|
stComboAttr.s32ChnId = 0;
|
|
s32Ret = RK_MPI_VENC_SetComboAttr(s32ChnId, &stComboAttr);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
RK_LOGE("RK_MPI_VENC_SetComboAttr failure:%X", s32Ret);
|
|
program_handle_error(__func__, __LINE__);
|
|
return RK_FAILURE;
|
|
}
|
|
}
|
|
|
|
return s32Ret;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* function : main()
|
|
* Description : main
|
|
******************************************************************************/
|
|
int main(int argc, char *argv[]) {
|
|
RK_S32 s32Ret = RK_FAILURE;
|
|
RK_S32 s32CamId = 0;
|
|
RK_S32 s32ViChnId = 0;
|
|
RK_S32 s32ViDevId = 0;
|
|
RK_S32 s32PipeId = 0;
|
|
RK_S32 s32MainVencChnId = 0;
|
|
RK_S32 s32ComboVencChnId = 1;
|
|
rk_aiq_working_mode_t hdr_mode = RK_AIQ_WORKING_MODE_NORMAL;
|
|
MPP_CHN_S stSrcChn, stDestChn;
|
|
|
|
pthread_t main_venc_thread_id, combo_venc_thread_id;
|
|
|
|
if (argc < 2) {
|
|
print_usage(argv[0]);
|
|
return 0;
|
|
}
|
|
|
|
signal(SIGINT, sigterm_handler);
|
|
signal(SIGTERM, sigterm_handler);
|
|
|
|
#ifdef RKAIQ
|
|
RK_BOOL bMultictx = RK_FALSE;
|
|
#endif
|
|
int c;
|
|
char *iq_file_dir = NULL;
|
|
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 'w':
|
|
g_u32MainVencWidth = atoi(optarg);
|
|
break;
|
|
case 'h':
|
|
g_u32MainVencHeight = atoi(optarg);
|
|
break;
|
|
case 'l':
|
|
g_s32loopCnt = atoi(optarg);
|
|
break;
|
|
case 'o':
|
|
g_pOutPath = optarg;
|
|
break;
|
|
case 'r':
|
|
if (0 == atoi(optarg)) {
|
|
g_wrap = RK_FALSE;
|
|
} else if (1 == atoi(optarg)) {
|
|
g_wrap = RK_TRUE;
|
|
} else {
|
|
RK_LOGE("input wrap mode is no support(invalid)");
|
|
print_usage(argv[0]);
|
|
return RK_FALSE;
|
|
}
|
|
break;
|
|
case 'j':
|
|
g_s32JpegCaptureNum = atoi(optarg);
|
|
break;
|
|
case '?':
|
|
default:
|
|
print_usage(argv[0]);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
printf("#CameraIdx: %d\n", s32CamId);
|
|
printf("#Output Path: %s\n", g_pOutPath);
|
|
printf("#IQ Path: %s\n", iq_file_dir);
|
|
if (iq_file_dir) {
|
|
#ifdef RKAIQ
|
|
printf("#Rkaiq XML DirPath: %s\n", iq_file_dir);
|
|
printf("#bMultictx: %d\n\n", bMultictx);
|
|
|
|
s32Ret = SAMPLE_COMM_ISP_Init(s32CamId, hdr_mode, bMultictx, iq_file_dir);
|
|
s32Ret != SAMPLE_COMM_ISP_Run(s32CamId);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
RK_LOGE("ISP init failure:%X", s32Ret);
|
|
g_exit_result = RK_FALSE;
|
|
goto __FAILED2;
|
|
}
|
|
#endif
|
|
}
|
|
RK_LOGE("ISP init success");
|
|
if (RK_MPI_SYS_Init() != RK_SUCCESS) {
|
|
g_exit_result = RK_FALSE;
|
|
goto __FAILED;
|
|
}
|
|
|
|
// Init VI
|
|
vi_init(s32ViDevId, s32ViChnId, g_u32MainVencWidth, g_u32MainVencHeight);
|
|
|
|
/* Init VENC[0] */
|
|
venc_init(s32MainVencChnId, g_u32MainVencWidth, g_u32MainVencHeight,
|
|
RK_CODEC_TYPE_H264, RK_FALSE);
|
|
/* Init combo VENC[1] */
|
|
venc_init(s32ComboVencChnId, g_u32MainVencWidth, g_u32MainVencHeight,
|
|
RK_CODEC_TYPE_JPEG, RK_TRUE);
|
|
|
|
/* VI[0] bind VENC[0] */
|
|
stSrcChn.enModId = RK_ID_VI;
|
|
stSrcChn.s32DevId = s32ViDevId;
|
|
stSrcChn.s32ChnId = s32ViChnId;
|
|
stDestChn.enModId = RK_ID_VENC;
|
|
stDestChn.s32DevId = 0;
|
|
stDestChn.s32ChnId = s32MainVencChnId;
|
|
s32Ret = RK_MPI_SYS_Bind(&stSrcChn, &stDestChn);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
RK_LOGE("VI and VENC bind failure:%X", s32Ret);
|
|
program_handle_error(__func__, __LINE__);
|
|
}
|
|
|
|
pthread_create(&main_venc_thread_id, 0, venc_get_stream, &s32MainVencChnId);
|
|
pthread_create(&combo_venc_thread_id, 0, combo_jpeg_get_stream, &s32ComboVencChnId);
|
|
|
|
printf("%s initial finish\n", __func__);
|
|
|
|
while (!g_quit) {
|
|
sleep(1);
|
|
}
|
|
|
|
printf("%s exit!\n", __func__);
|
|
|
|
/* Venc[1] deinit */
|
|
g_bIfVencThreadQuit[s32ComboVencChnId] = RK_TRUE;
|
|
pthread_join(combo_venc_thread_id, RK_NULL);
|
|
s32Ret = RK_MPI_VENC_StopRecvFrame(s32ComboVencChnId);
|
|
s32Ret |= RK_MPI_VENC_DestroyChn(s32ComboVencChnId);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
RK_LOGE("Venc 0 destroy failure");
|
|
g_exit_result = RK_FALSE;
|
|
}
|
|
RK_LOGE("Venc 1 destroy success");
|
|
|
|
/* Venc[0] deinit */
|
|
g_bIfVencThreadQuit[s32MainVencChnId] = RK_TRUE;
|
|
pthread_join(main_venc_thread_id, RK_NULL);
|
|
|
|
/* vi[0] venc[0] ubind*/
|
|
stSrcChn.enModId = RK_ID_VI;
|
|
stSrcChn.s32DevId = s32ViDevId;
|
|
stSrcChn.s32ChnId = s32ViChnId;
|
|
stDestChn.enModId = RK_ID_VENC;
|
|
stDestChn.s32DevId = 0;
|
|
stDestChn.s32ChnId = s32MainVencChnId;
|
|
s32Ret = RK_MPI_SYS_UnBind(&stSrcChn, &stDestChn);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
RK_LOGE("VI and VENC bind failure:%X", s32Ret);
|
|
g_exit_result = RK_FAILURE;
|
|
}
|
|
|
|
s32Ret = RK_MPI_VENC_StopRecvFrame(s32MainVencChnId);
|
|
s32Ret |= RK_MPI_VENC_DestroyChn(s32MainVencChnId);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
RK_LOGE("Venc 0 destroy failure");
|
|
g_exit_result = RK_FALSE;
|
|
}
|
|
|
|
RK_LOGE("Venc 0 destroy success");
|
|
|
|
/* Destroy Vi deinit */
|
|
s32Ret = RK_MPI_VI_DisableChn(s32PipeId, s32ViChnId);
|
|
s32Ret |= RK_MPI_VI_DisableDev(s32ViDevId);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
RK_LOGE("RK_MPI_VI_Close failed with %X!", s32Ret);
|
|
g_exit_result = RK_FALSE;
|
|
}
|
|
|
|
__FAILED:
|
|
RK_MPI_SYS_Exit();
|
|
if (iq_file_dir) {
|
|
#ifdef RKAIQ
|
|
SAMPLE_COMM_ISP_Stop(s32CamId);
|
|
#endif
|
|
}
|
|
|
|
__FAILED2:
|
|
return g_exit_result;
|
|
}
|
|
|
|
#ifdef __cplusplus
|
|
#if __cplusplus
|
|
}
|
|
#endif
|
|
#endif /* End of #ifdef __cplusplus */
|