481 lines
14 KiB
C
481 lines
14 KiB
C
#include <errno.h>
|
||
#include <pthread.h>
|
||
#include <signal.h>
|
||
#include <stdio.h>
|
||
#include <sys/poll.h>
|
||
#include <time.h>
|
||
#include <unistd.h>
|
||
|
||
#include "sample_comm.h"
|
||
|
||
static FILE *venc0_file;
|
||
static RK_S32 g_s32FrameCnt = -1;
|
||
static bool quit = false;
|
||
|
||
static void sigterm_handler(int sig) {
|
||
fprintf(stderr, "signal %d\n", sig);
|
||
quit = true;
|
||
}
|
||
//大小端问题,设置的ARGB 但是颜色是BGRA
|
||
// for argb8888
|
||
#define TEST_ARGB32_PIX_SIZE 4
|
||
#define TEST_ARGB32_RED 0xFF0000FF
|
||
#define TEST_ARGB32_GREEN 0x00FF00FF
|
||
#define TEST_ARGB32_BLUE 0x0000FFFF
|
||
#define TEST_ARGB32_TRANS 0x00000000
|
||
#define TEST_ARGB32_BLACK 0x000000FF
|
||
|
||
static void set_argb8888_buffer(RK_U32 *buf, RK_U32 size, RK_U32 color) {
|
||
for (RK_U32 i = 0; buf && (i < size); i++)
|
||
*(buf + i) = color;
|
||
}
|
||
|
||
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 */
|
||
}
|
||
|
||
static void *GetMediaBuffer0(void *arg) {
|
||
(void)arg;
|
||
printf("========%s========\n", __func__);
|
||
void *pData = RK_NULL;
|
||
int loopCount = 0;
|
||
int s32Ret;
|
||
|
||
VENC_STREAM_S stFrame;
|
||
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();
|
||
|
||
RK_LOGD("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);
|
||
|
||
s32Ret = RK_MPI_VENC_ReleaseStream(0, &stFrame);
|
||
if (s32Ret != RK_SUCCESS) {
|
||
RK_LOGE("RK_MPI_VENC_ReleaseStream fail %x", s32Ret);
|
||
}
|
||
loopCount++;
|
||
} else {
|
||
RK_LOGE("RK_MPI_VI_GetChnFrame fail %x", s32Ret);
|
||
}
|
||
|
||
if ((g_s32FrameCnt >= 0) && (loopCount > g_s32FrameCnt)) {
|
||
quit = true;
|
||
break;
|
||
}
|
||
|
||
usleep(10 * 1000);
|
||
}
|
||
|
||
if (venc0_file)
|
||
fclose(venc0_file);
|
||
|
||
free(stFrame.pstPack);
|
||
return NULL;
|
||
}
|
||
|
||
RK_S32 load_file_osdmem(const RK_CHAR *filename, RK_U8 *pu8Virt, RK_U32 u32Width,
|
||
RK_U32 u32Height, RK_U32 pixel_size, RK_U32 shift_value) {
|
||
RK_U32 mem_len = u32Width;
|
||
RK_U32 read_len = mem_len * pixel_size >> shift_value;
|
||
RK_U32 read_height;
|
||
FILE *file = NULL;
|
||
|
||
file = fopen(filename, "rb");
|
||
if (file == NULL) {
|
||
RK_LOGE("open filename: %s file failed!", filename);
|
||
return RK_FAILURE;
|
||
}
|
||
for (read_height = 0; read_height < u32Height; read_height++) {
|
||
fread((pu8Virt + (u32Width * read_height * pixel_size >> shift_value)), 1,
|
||
read_len, file);
|
||
}
|
||
fclose(file);
|
||
return RK_SUCCESS;
|
||
}
|
||
|
||
RK_S32 test_rgn_overlay_process() {
|
||
printf("========%s========\n", __func__);
|
||
RK_S32 s32Ret = RK_SUCCESS;
|
||
RGN_HANDLE RgnHandle = 0;
|
||
BITMAP_S stBitmap;
|
||
RGN_ATTR_S stRgnAttr;
|
||
RGN_CHN_ATTR_S stRgnChnAttr;
|
||
|
||
int u32Width = 128;
|
||
int u32Height = 128;
|
||
int s32X = 100;
|
||
int s32Y = 100;
|
||
|
||
RK_CHAR *filename = "/data/res/rgn/44";
|
||
|
||
MPP_CHN_S stMppChn;
|
||
|
||
stMppChn.enModId = RK_ID_VENC;
|
||
stMppChn.s32DevId = 0;
|
||
stMppChn.s32ChnId = 0;
|
||
|
||
/****************************************
|
||
step 1: create overlay regions
|
||
****************************************/
|
||
stRgnAttr.enType = OVERLAY_RGN;
|
||
stRgnAttr.unAttr.stOverlay.enPixelFmt = (PIXEL_FORMAT_E)RK_FMT_ARGB8888;
|
||
stRgnAttr.unAttr.stOverlay.stSize.u32Width = u32Width;
|
||
stRgnAttr.unAttr.stOverlay.stSize.u32Height = u32Height;
|
||
stRgnAttr.unAttr.stOverlay.u32ClutNum = 0;
|
||
|
||
s32Ret = RK_MPI_RGN_Create(RgnHandle, &stRgnAttr);
|
||
if (RK_SUCCESS != s32Ret) {
|
||
RK_LOGE("RK_MPI_RGN_Create (%d) failed with %#x!", RgnHandle, s32Ret);
|
||
RK_MPI_RGN_Destroy(RgnHandle);
|
||
return RK_FAILURE;
|
||
}
|
||
RK_LOGI("The handle: %d, create success!", RgnHandle);
|
||
|
||
/*********************************************
|
||
step 2: display overlay regions to groups
|
||
*********************************************/
|
||
memset(&stRgnChnAttr, 0, sizeof(stRgnChnAttr));
|
||
stRgnChnAttr.bShow = RK_TRUE;
|
||
stRgnChnAttr.enType = OVERLAY_RGN;
|
||
stRgnChnAttr.unChnAttr.stOverlayChn.stPoint.s32X = s32X;
|
||
stRgnChnAttr.unChnAttr.stOverlayChn.stPoint.s32Y = s32Y;
|
||
stRgnChnAttr.unChnAttr.stOverlayChn.u32BgAlpha = 0;
|
||
stRgnChnAttr.unChnAttr.stOverlayChn.u32FgAlpha = 0;
|
||
stRgnChnAttr.unChnAttr.stOverlayChn.u32Layer = 0;
|
||
stRgnChnAttr.unChnAttr.stOverlayChn.stQpInfo.bEnable = RK_FALSE;
|
||
stRgnChnAttr.unChnAttr.stOverlayChn.stQpInfo.bForceIntra = RK_TRUE;
|
||
stRgnChnAttr.unChnAttr.stOverlayChn.stQpInfo.bAbsQp = RK_FALSE;
|
||
stRgnChnAttr.unChnAttr.stOverlayChn.stQpInfo.s32Qp = RK_FALSE;
|
||
stRgnChnAttr.unChnAttr.stOverlayChn.u32ColorLUT[0] = 0x00;
|
||
stRgnChnAttr.unChnAttr.stOverlayChn.u32ColorLUT[1] = 0xFFFFFF;
|
||
stRgnChnAttr.unChnAttr.stOverlayChn.stInvertColor.bInvColEn = RK_FALSE;
|
||
stRgnChnAttr.unChnAttr.stOverlayChn.stInvertColor.stInvColArea.u32Width = 16;
|
||
stRgnChnAttr.unChnAttr.stOverlayChn.stInvertColor.stInvColArea.u32Height = 16;
|
||
stRgnChnAttr.unChnAttr.stOverlayChn.stInvertColor.enChgMod = LESSTHAN_LUM_THRESH;
|
||
stRgnChnAttr.unChnAttr.stOverlayChn.stInvertColor.u32LumThresh = 100;
|
||
s32Ret = RK_MPI_RGN_AttachToChn(RgnHandle, &stMppChn, &stRgnChnAttr);
|
||
if (RK_SUCCESS != s32Ret) {
|
||
RK_LOGE("RK_MPI_RGN_AttachToChn (%d) failed with %#x!", RgnHandle, s32Ret);
|
||
return RK_FAILURE;
|
||
}
|
||
RK_LOGI("Display region to chn success!");
|
||
|
||
/*********************************************
|
||
step 3: show bitmap
|
||
*********************************************/
|
||
RK_S64 s64ShowBmpStart = TEST_COMM_GetNowUs();
|
||
stBitmap.enPixelFormat = (PIXEL_FORMAT_E)RK_FMT_ARGB8888;
|
||
stBitmap.u32Width = u32Width;
|
||
stBitmap.u32Height = u32Height;
|
||
|
||
RK_U16 ColorBlockSize = stBitmap.u32Height * stBitmap.u32Width;
|
||
stBitmap.pData = malloc(ColorBlockSize * TEST_ARGB32_PIX_SIZE);
|
||
RK_U8 *ColorData = (RK_U8 *)stBitmap.pData;
|
||
if (filename) {
|
||
s32Ret = load_file_osdmem(filename, stBitmap.pData, u32Width, u32Height,
|
||
TEST_ARGB32_PIX_SIZE, 0);
|
||
if (RK_SUCCESS != s32Ret) {
|
||
set_argb8888_buffer((RK_U32 *)ColorData, ColorBlockSize / 4, TEST_ARGB32_RED);
|
||
set_argb8888_buffer((RK_U32 *)(ColorData + ColorBlockSize),
|
||
ColorBlockSize / 4, TEST_ARGB32_GREEN);
|
||
set_argb8888_buffer((RK_U32 *)(ColorData + 2 * ColorBlockSize),
|
||
ColorBlockSize / 4, TEST_ARGB32_BLUE);
|
||
set_argb8888_buffer((RK_U32 *)(ColorData + 3 * ColorBlockSize),
|
||
ColorBlockSize / 4, TEST_ARGB32_BLACK);
|
||
}
|
||
}
|
||
|
||
s32Ret = RK_MPI_RGN_SetBitMap(RgnHandle, &stBitmap);
|
||
if (s32Ret != RK_SUCCESS) {
|
||
RK_LOGE("RK_MPI_RGN_SetBitMap failed with %#x!", s32Ret);
|
||
return RK_FAILURE;
|
||
}
|
||
RK_S64 s64ShowBmpEnd = TEST_COMM_GetNowUs();
|
||
RK_LOGI("Handle:%d, space time %lld us, load bmp success!", RgnHandle,
|
||
s64ShowBmpEnd - s64ShowBmpStart);
|
||
|
||
//另一种刷osd的方式
|
||
#if 0
|
||
/*********************************************
|
||
step 4: use update canvas interface
|
||
*********************************************/
|
||
s64ShowBmpStart = TEST_COMM_GetNowUs();
|
||
|
||
RGN_CANVAS_INFO_S stCanvasInfo;
|
||
memset(&stCanvasInfo, 0, sizeof(RGN_CANVAS_INFO_S));
|
||
|
||
s32Ret = RK_MPI_RGN_GetCanvasInfo(RgnHandle, &stCanvasInfo);
|
||
if (s32Ret != RK_SUCCESS) {
|
||
RK_LOGE("RK_MPI_RGN_GetCanvasInfo failed with %#x!", s32Ret);
|
||
return RK_FAILURE;
|
||
}
|
||
memset(reinterpret_cast<void *>(stCanvasInfo.u64VirAddr), 0xff,
|
||
stCanvasInfo.u32VirWidth * stCanvasInfo.u32VirHeight >> 2);
|
||
s32Ret = RK_MPI_RGN_UpdateCanvas(RgnHandle);
|
||
if (s32Ret != RK_SUCCESS) {
|
||
RK_LOGE("RK_MPI_RGN_UpdateCanvas failed with %#x!", s32Ret);
|
||
return RK_FAILURE;
|
||
}
|
||
s64ShowBmpEnd = TEST_COMM_GetNowUs();
|
||
RK_LOGI("Handle:%d, space time %lld us, update canvas success!", RgnHandle, s64ShowBmpEnd - s64ShowBmpStart);
|
||
#endif
|
||
|
||
return 0;
|
||
}
|
||
|
||
static RK_S32 test_venc_init(int chnId, int width, int height, RK_CODEC_ID_E enType) {
|
||
printf("========%s========\n", __func__);
|
||
VENC_RECV_PIC_PARAM_S stRecvParam;
|
||
VENC_CHN_ATTR_S stAttr;
|
||
memset(&stAttr, 0, sizeof(VENC_CHN_ATTR_S));
|
||
|
||
stAttr.stRcAttr.enRcMode = VENC_RC_MODE_H264CBR;
|
||
stAttr.stRcAttr.stH264Cbr.u32BitRate = 10 * 1024;
|
||
stAttr.stRcAttr.stH264Cbr.u32Gop = 60;
|
||
|
||
stAttr.stVencAttr.enType = enType;
|
||
stAttr.stVencAttr.enPixelFormat = RK_FMT_YUV420SP;
|
||
stAttr.stVencAttr.u32Profile = H264E_PROFILE_HIGH;
|
||
stAttr.stVencAttr.u32PicWidth = width;
|
||
stAttr.stVencAttr.u32PicHeight = height;
|
||
stAttr.stVencAttr.u32VirWidth = width;
|
||
stAttr.stVencAttr.u32VirHeight = height;
|
||
stAttr.stVencAttr.u32StreamBufCnt = 2;
|
||
stAttr.stVencAttr.u32BufSize = width * height * 3 / 2;
|
||
stAttr.stVencAttr.enMirror = MIRROR_NONE;
|
||
|
||
RK_MPI_VENC_CreateChn(chnId, &stAttr);
|
||
|
||
// stRecvParam.s32RecvPicNum = 100; //recv 100 slice
|
||
// RK_MPI_VENC_StartRecvFrame(chnId, &stRecvParam);
|
||
|
||
memset(&stRecvParam, 0, sizeof(VENC_RECV_PIC_PARAM_S));
|
||
stRecvParam.s32RecvPicNum = -1;
|
||
RK_MPI_VENC_StartRecvFrame(chnId, &stRecvParam);
|
||
|
||
return 0;
|
||
}
|
||
|
||
// demo板dev默认都是0,根据不同的channel 来选择不同的vi节点
|
||
int vi_dev_init() {
|
||
printf("%s\n", __func__);
|
||
int ret = 0;
|
||
int devId = 0;
|
||
int pipeId = devId;
|
||
|
||
VI_DEV_ATTR_S stDevAttr;
|
||
VI_DEV_BIND_PIPE_S stBindPipe;
|
||
memset(&stDevAttr, 0, sizeof(stDevAttr));
|
||
memset(&stBindPipe, 0, sizeof(stBindPipe));
|
||
// 0. get dev config status
|
||
ret = RK_MPI_VI_GetDevAttr(devId, &stDevAttr);
|
||
if (ret == RK_ERR_VI_NOT_CONFIG) {
|
||
// 0-1.config dev
|
||
ret = RK_MPI_VI_SetDevAttr(devId, &stDevAttr);
|
||
if (ret != RK_SUCCESS) {
|
||
printf("RK_MPI_VI_SetDevAttr %x\n", ret);
|
||
return -1;
|
||
}
|
||
} else {
|
||
printf("RK_MPI_VI_SetDevAttr already\n");
|
||
}
|
||
// 1.get dev enable status
|
||
ret = RK_MPI_VI_GetDevIsEnable(devId);
|
||
if (ret != RK_SUCCESS) {
|
||
// 1-2.enable dev
|
||
ret = RK_MPI_VI_EnableDev(devId);
|
||
if (ret != RK_SUCCESS) {
|
||
printf("RK_MPI_VI_EnableDev %x\n", ret);
|
||
return -1;
|
||
}
|
||
// 1-3.bind dev/pipe
|
||
stBindPipe.u32Num = pipeId;
|
||
stBindPipe.PipeId[0] = pipeId;
|
||
ret = RK_MPI_VI_SetDevBindPipe(devId, &stBindPipe);
|
||
if (ret != RK_SUCCESS) {
|
||
printf("RK_MPI_VI_SetDevBindPipe %x\n", ret);
|
||
return -1;
|
||
}
|
||
} else {
|
||
printf("RK_MPI_VI_EnableDev already\n");
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
int vi_chn_init(int channelId, int width, int height) {
|
||
int ret;
|
||
int buf_cnt = 2;
|
||
// VI init
|
||
VI_CHN_ATTR_S vi_chn_attr;
|
||
memset(&vi_chn_attr, 0, sizeof(vi_chn_attr));
|
||
vi_chn_attr.stIspOpt.u32BufCount = buf_cnt;
|
||
vi_chn_attr.stIspOpt.enMemoryType =
|
||
VI_V4L2_MEMORY_TYPE_DMABUF; // VI_V4L2_MEMORY_TYPE_MMAP;
|
||
vi_chn_attr.stSize.u32Width = width;
|
||
vi_chn_attr.stSize.u32Height = height;
|
||
vi_chn_attr.enPixelFormat = RK_FMT_YUV420SP;
|
||
vi_chn_attr.enCompressMode = COMPRESS_MODE_NONE; // COMPRESS_AFBC_16x16;
|
||
vi_chn_attr.u32Depth = 2;
|
||
ret = RK_MPI_VI_SetChnAttr(0, channelId, &vi_chn_attr);
|
||
ret |= RK_MPI_VI_EnableChn(0, channelId);
|
||
if (ret) {
|
||
printf("ERROR: create VI error! ret=%d\n", ret);
|
||
return ret;
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
|
||
static RK_CHAR optstr[] = "?::w:h:c:I:e:o:";
|
||
static void print_usage(const RK_CHAR *name) {
|
||
printf("usage example:\n");
|
||
printf("\t%s -I 0 -w 1920 -h 1080 -o /tmp/venc.h264\n", name);
|
||
printf("\t-w | --width: VI width, Default:1920\n");
|
||
printf("\t-h | --heght: VI height, Default:1080\n");
|
||
printf("\t-c | --frame_cnt: frame number of output, Default:-1\n");
|
||
printf("\t-I | --camid: camera ctx id, Default 0. "
|
||
"0:rkisp_mainpath,1:rkisp_selfpath,2:rkisp_bypasspath\n");
|
||
printf("\t-e | --encode: encode type, Default:h264, Value:h264, h265, mjpeg\n");
|
||
printf("\t-o: output path, Default:NULL\n");
|
||
}
|
||
|
||
int main(int argc, char *argv[]) {
|
||
RK_S32 s32Ret = RK_FAILURE;
|
||
RK_U32 u32Width = 1920;
|
||
RK_U32 u32Height = 1080;
|
||
RK_CHAR *pOutPath = NULL;
|
||
RK_CODEC_ID_E enCodecType = RK_VIDEO_ID_AVC;
|
||
RK_CHAR *pCodecName = "H264";
|
||
RK_S32 s32chnlId = 0;
|
||
int c;
|
||
|
||
while ((c = getopt(argc, argv, optstr)) != -1) {
|
||
switch (c) {
|
||
case 'w':
|
||
u32Width = atoi(optarg);
|
||
break;
|
||
case 'h':
|
||
u32Height = atoi(optarg);
|
||
break;
|
||
case 'I':
|
||
s32chnlId = atoi(optarg);
|
||
break;
|
||
case 'c':
|
||
g_s32FrameCnt = atoi(optarg);
|
||
break;
|
||
case 'e':
|
||
if (!strcmp(optarg, "h264")) {
|
||
enCodecType = RK_VIDEO_ID_AVC;
|
||
pCodecName = "H264";
|
||
} else if (!strcmp(optarg, "h265")) {
|
||
enCodecType = RK_VIDEO_ID_HEVC;
|
||
pCodecName = "H265";
|
||
} else if (!strcmp(optarg, "mjpeg")) {
|
||
enCodecType = RK_VIDEO_ID_MJPEG;
|
||
pCodecName = "MJPEG";
|
||
} else {
|
||
printf("ERROR: Invalid encoder type.\n");
|
||
return 0;
|
||
}
|
||
break;
|
||
case 'o':
|
||
pOutPath = optarg;
|
||
break;
|
||
case '?':
|
||
default:
|
||
print_usage(argv[0]);
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
printf("#CodecName:%s\n", pCodecName);
|
||
printf("#Resolution: %dx%d\n", u32Width, u32Height);
|
||
printf("#Output Path: %s\n", pOutPath);
|
||
printf("#CameraIdx: %d\n\n", s32chnlId);
|
||
printf("#Frame Count to save: %d\n", g_s32FrameCnt);
|
||
|
||
if (pOutPath) {
|
||
venc0_file = fopen(pOutPath, "w");
|
||
if (!venc0_file) {
|
||
printf("ERROR: open file: %s fail, exit\n", pOutPath);
|
||
return 0;
|
||
}
|
||
}
|
||
signal(SIGINT, sigterm_handler);
|
||
|
||
if (RK_MPI_SYS_Init() != RK_SUCCESS) {
|
||
RK_LOGE("rk mpi sys init fail!");
|
||
goto __FAILED;
|
||
}
|
||
|
||
vi_dev_init();
|
||
vi_chn_init(s32chnlId, u32Width, u32Height);
|
||
|
||
// venc init
|
||
test_venc_init(0, u32Width, u32Height,
|
||
enCodecType); // RK_VIDEO_ID_AVC RK_VIDEO_ID_HEVC
|
||
|
||
MPP_CHN_S stSrcChn, stDestChn;
|
||
// bind vi to venc
|
||
stSrcChn.enModId = RK_ID_VI;
|
||
stSrcChn.s32DevId = 0;
|
||
stSrcChn.s32ChnId = s32chnlId;
|
||
|
||
stDestChn.enModId = RK_ID_VENC;
|
||
stDestChn.s32DevId = 0;
|
||
stDestChn.s32ChnId = 0;
|
||
printf("====RK_MPI_SYS_Bind vi0 to venc0====\n");
|
||
s32Ret = RK_MPI_SYS_Bind(&stSrcChn, &stDestChn);
|
||
if (s32Ret != RK_SUCCESS) {
|
||
RK_LOGE("bind 0 ch venc failed");
|
||
goto __FAILED;
|
||
}
|
||
test_rgn_overlay_process();
|
||
pthread_t main_thread;
|
||
pthread_create(&main_thread, NULL, GetMediaBuffer0, NULL);
|
||
|
||
while (!quit) {
|
||
usleep(50000);
|
||
}
|
||
pthread_join(&main_thread, NULL);
|
||
|
||
s32Ret = RK_MPI_SYS_UnBind(&stSrcChn, &stDestChn);
|
||
if (s32Ret != RK_SUCCESS) {
|
||
RK_LOGE("RK_MPI_SYS_UnBind fail %x", s32Ret);
|
||
}
|
||
|
||
s32Ret = RK_MPI_VI_DisableChn(0, s32chnlId);
|
||
RK_LOGE("RK_MPI_VI_DisableChn %x", s32Ret);
|
||
|
||
s32Ret = RK_MPI_VENC_StopRecvFrame(0);
|
||
if (s32Ret != RK_SUCCESS) {
|
||
return s32Ret;
|
||
}
|
||
|
||
s32Ret = RK_MPI_VENC_DestroyChn(0);
|
||
if (s32Ret != RK_SUCCESS) {
|
||
RK_LOGE("RK_MPI_VDEC_DestroyChn fail %x", s32Ret);
|
||
}
|
||
|
||
s32Ret = RK_MPI_VI_DisableDev(0);
|
||
RK_LOGE("RK_MPI_VI_DisableDev %x", s32Ret);
|
||
|
||
__FAILED:
|
||
RK_LOGE("test running exit:%d", s32Ret);
|
||
RK_MPI_SYS_Exit();
|
||
|
||
return 0;
|
||
}
|