diff --git a/.justfile b/.justfile index 641d316..8eb69f1 100644 --- a/.justfile +++ b/.justfile @@ -31,6 +31,6 @@ ftp-tui: termscp -P "" ftp://root@192.168.137.3:21:/ tty: - minicom -D /dev/ttyUSB0 -b 115200 + sudo minicom -D /dev/ttyUSB0 -b 115200 all: build sync diff --git a/Hi3516_SDK.lua b/Hi3516_SDK.lua index f1815ad..1e6acba 100755 --- a/Hi3516_SDK.lua +++ b/Hi3516_SDK.lua @@ -83,6 +83,7 @@ target("sample_common") add_defines( "SENSOR0_TYPE=GALAXYCORE_GC2053_MIPI_2M_30FPS_10BIT", "SENSOR1_TYPE=GALAXYCORE_GC2053_MIPI_2M_30FPS_10BIT", + "_DEFAULT_SOURCE", {public = true} ) add_deps("sample_audio") diff --git a/src/common.h b/src/common.h index dacfca2..6aa3186 100755 --- a/src/common.h +++ b/src/common.h @@ -4,6 +4,9 @@ #include "stdbool.h" #include "stdint.h" +#define SUCCESS 0 +#define FAILED (-1) + #ifndef ARRAY_LENGTH #define ARRAY_LENGTH(arr) (sizeof(arr) / sizeof(arr[0])) #endif diff --git a/src/main.cpp b/src/main.cpp index 5e20f7f..c234f56 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,6 +2,7 @@ #include #include "hi_common.h" +#include "sample_comm.h" #include "zlog.h" #include "isp/eb3516_video.h" @@ -38,9 +39,16 @@ int main(int argc, char** argv) { eb3516VideoInit(); eb3516VideoStart(); - eb3516VideoStop(); // eb3516Yolov3Init("./coco_yolov3_detect.wk", "./dog_bike_car_416x416.bgr"); + // nnie_init(); + // nnie_start(); + + PAUSE(); + + // nnie_stop(); // eb3516Yolov3Exit(); + eb3516VideoStop(); + zlog_fini(); diff --git a/src/modules/isp/eb3516_video.c b/src/modules/isp/eb3516_video.c index d4e8cd6..ecb6548 100755 --- a/src/modules/isp/eb3516_video.c +++ b/src/modules/isp/eb3516_video.c @@ -2,6 +2,8 @@ #include "hi_comm_snap.h" #include "hi_common.h" +#include "hi_debug.h" +#include "hi_type.h" #include "mpi_snap.h" #include "sample_comm.h" #include "zlog.h" @@ -29,6 +31,8 @@ static VB_CONFIG_S g_stVbConfig = {0}; static SAMPLE_VO_CONFIG_S stVoConfig; static SAMPLE_VPSS_CONFIG_S g_stVpss0Config = {0}; static SAMPLE_VPSS_CONFIG_S g_stVpss1Config = {0}; +static VI_PIPE videoPipe = 0; +static VI_PIPE snapPipe = 1; // 注意此处不能为通道 0, 因为 hi3516 的 VPSS 通道 0 只支持放大, // 其它通道只支持缩小 @@ -93,10 +97,10 @@ static HI_S32 VPSS_GetParams(SAMPLE_VPSS_CONFIG_S *pstVpssConfig, return HI_SUCCESS; } -bool eb3516VideoInit(void) { +HI_BOOL eb3516VideoInit(void) { log_video = zlog_get_category("eb3516_video"); if (!log_video) { - return false; + return HI_FALSE; } // Get Sensor(VI) Info: picture size , frame rate @@ -131,8 +135,8 @@ bool eb3516VideoInit(void) { g_stViConfig.astViInfo[0].stDevInfo.ViDev = 0; g_stViConfig.astViInfo[0].stDevInfo.enWDRMode = WDR_MODE_NONE; // 设置 VI PIPE 信息 - g_stViConfig.astViInfo[0].stPipeInfo.aPipe[0] = 0; // video pipe - g_stViConfig.astViInfo[0].stPipeInfo.aPipe[1] = 1; // snap pipe + g_stViConfig.astViInfo[0].stPipeInfo.aPipe[0] = videoPipe; // video pipe + g_stViConfig.astViInfo[0].stPipeInfo.aPipe[1] = snapPipe; // snap pipe g_stViConfig.astViInfo[0].stPipeInfo.aPipe[2] = -1; g_stViConfig.astViInfo[0].stPipeInfo.aPipe[3] = -1; g_stViConfig.astViInfo[0].stPipeInfo.enMastPipeMode = VI_OFFLINE_VPSS_OFFLINE; @@ -146,20 +150,21 @@ bool eb3516VideoInit(void) { // 设置 VI 抓拍信息 g_stViConfig.astViInfo[0].stSnapInfo.bSnap = HI_TRUE; g_stViConfig.astViInfo[0].stSnapInfo.bDoublePipe = HI_TRUE; - g_stViConfig.astViInfo[0].stSnapInfo.VideoPipe = 0; - g_stViConfig.astViInfo[0].stSnapInfo.SnapPipe = 1; + g_stViConfig.astViInfo[0].stSnapInfo.VideoPipe = videoPipe; + g_stViConfig.astViInfo[0].stSnapInfo.SnapPipe = snapPipe; g_stViConfig.astViInfo[0].stSnapInfo.enVideoPipeMode = VI_OFFLINE_VPSS_OFFLINE; g_stViConfig.astViInfo[0].stSnapInfo.enSnapPipeMode = VI_OFFLINE_VPSS_OFFLINE; // 配置 VPSS - VPSS_GetParams(&g_stVpss0Config, &stSize, false); - VPSS_GetParams(&g_stVpss1Config, &stSize, true); + VPSS_GetParams(&g_stVpss0Config, &stSize, HI_FALSE); + VPSS_GetParams(&g_stVpss1Config, &stSize, HI_TRUE); zlog_debug(log_video, "eb3516 Video Init Finish..."); + return HI_TRUE; } -bool eb3516VideoStart(void) { +HI_S32 eb3516VideoStart(void) { HI_S32 s32Ret = 0; // 初始化 VB 和 MPI 系统 @@ -208,18 +213,18 @@ bool eb3516VideoStart(void) { zlog_debug(log_video, "eb3516 VPSS1 Start Success..."); // 绑定 VI->VPSS - s32Ret = SAMPLE_COMM_VI_Bind_VPSS( - g_stViConfig.astViInfo[0].stPipeInfo.aPipe[0], - g_stViConfig.astViInfo[0].stChnInfo.ViChn, g_stVpss0Config.s32GrpId); + s32Ret = SAMPLE_COMM_VI_Bind_VPSS(videoPipe, + g_stViConfig.astViInfo[0].stChnInfo.ViChn, + g_stVpss0Config.s32GrpId); if (s32Ret != HI_SUCCESS) { zlog_error(log_video, "VI Video Pipe bind VPSS0 failed with %#x!\n", s32Ret); goto EXIT_VPSS_STOP; } zlog_debug(log_video, "eb3516 VI Bind VPSS0 Success"); - s32Ret = SAMPLE_COMM_VI_Bind_VPSS( - g_stViConfig.astViInfo[0].stPipeInfo.aPipe[1], - g_stViConfig.astViInfo[0].stChnInfo.ViChn, g_stVpss1Config.s32GrpId); + s32Ret = SAMPLE_COMM_VI_Bind_VPSS(snapPipe, + g_stViConfig.astViInfo[0].stChnInfo.ViChn, + g_stVpss1Config.s32GrpId); if (s32Ret != HI_SUCCESS) { zlog_error(log_video, "VI Snap Pipe bind VPSS1 failed with %#x!\n", s32Ret); goto EXIT_VPSS_STOP; @@ -240,6 +245,14 @@ bool eb3516VideoStart(void) { } zlog_debug(log_video, "eb3516 VENC Start Success..."); + // 绑定 VPSS[0,1]->VENC[0] + s32Ret = SAMPLE_COMM_VPSS_Bind_VENC(g_stVpss0Config.s32GrpId, g_Vpss0Chn[0], + g_VencChn[0]); + if (s32Ret != HI_SUCCESS) { + zlog_error(log_video, "Venc bind Vpss failed with %#x!\n", s32Ret); + goto VENC_H265_STOP; + } + /*config vo*/ SAMPLE_COMM_VO_GetDefConfig(&stVoConfig); stVoConfig.enDstDynamicRange = DYNAMIC_RANGE_SDR8; @@ -254,7 +267,8 @@ bool eb3516VideoStart(void) { } zlog_debug(log_video, "eb3516 VO Start Success..."); - /*vpss bind vo*/ + /*vpss bind vo for hdmi output*/ + // Bind VPSS[0,1] -> VENC[0] -> VO(HDMI) s32Ret = SAMPLE_COMM_VPSS_Bind_VO(g_stVpss0Config.s32GrpId, g_Vpss0Chn[0], stVoConfig.VoDev, g_VencChn[0]); if (HI_SUCCESS != s32Ret) { @@ -270,7 +284,7 @@ bool eb3516VideoStart(void) { zlog_error(log_video, "Venc Snap Start failed with %#x\n", s32Ret); goto EXIT_VENC_H264_UNBIND; } - // 绑定 VPSS[1,0]->VENC[2] + // 绑定 VPSS[1,1]->VENC[2] for snap pic s32Ret = SAMPLE_COMM_VPSS_Bind_VENC(g_stVpss1Config.s32GrpId, g_Vpss1Chn, g_VencChn[2]); if (s32Ret != HI_SUCCESS) { @@ -285,14 +299,12 @@ bool eb3516VideoStart(void) { stSnapAttr.stNormalAttr.u32FrameCnt = 1; stSnapAttr.stNormalAttr.u32RepeatSendTimes = 1; stSnapAttr.stNormalAttr.bZSL = HI_FALSE; - s32Ret = HI_MPI_SNAP_SetPipeAttr( - g_stViConfig.astViInfo[0].stPipeInfo.aPipe[1], &stSnapAttr); + s32Ret = HI_MPI_SNAP_SetPipeAttr(snapPipe, &stSnapAttr); if (s32Ret != HI_SUCCESS) { zlog_error(log_video, "HI_MPI_SNAP_SetPipeAttr failed with %#x!\n", s32Ret); goto EXIT_VO_STOP; } - s32Ret = - HI_MPI_SNAP_EnablePipe(g_stViConfig.astViInfo[0].stPipeInfo.aPipe[1]); + s32Ret = HI_MPI_SNAP_EnablePipe(snapPipe); if (s32Ret != HI_SUCCESS) { zlog_error(log_video, "HI_MPI_SNAP_EnablePipe failed with %#x!\n", s32Ret); goto EXIT_VO_STOP; @@ -300,8 +312,7 @@ bool eb3516VideoStart(void) { // 设置照片 EXIF 信息 ISP_DCF_INFO_S stIspDCF; - HI_MPI_ISP_GetDCFInfo(g_stViConfig.astViInfo[0].stPipeInfo.aPipe[0], - &stIspDCF); + HI_MPI_ISP_GetDCFInfo(snapPipe, &stIspDCF); strncpy((char *)stIspDCF.stIspDCFConstInfo.au8ImageDescription, "", DCF_DRSCRIPTION_LENGTH); strncpy((char *)stIspDCF.stIspDCFConstInfo.au8Make, "OurEDA", @@ -310,39 +321,39 @@ bool eb3516VideoStart(void) { DCF_DRSCRIPTION_LENGTH); snprintf((char *)stIspDCF.stIspDCFConstInfo.au8Software, DCF_DRSCRIPTION_LENGTH, "CatFeeder snap"); - s32Ret = HI_MPI_ISP_SetDCFInfo(g_stViConfig.astViInfo[0].stPipeInfo.aPipe[0], + s32Ret = HI_MPI_ISP_SetDCFInfo(g_stViConfig.astViInfo[0].stPipeInfo.aPipe[1], &stIspDCF); if (s32Ret != HI_SUCCESS) { zlog_error(log_video, "HI_MPI_ISP_SetDCFInfo failed with %#x!\n", s32Ret); } - // // 绑定 VPSS[0,0]->VENC[0] - // s32Ret = SAMPLE_COMM_VPSS_Bind_VENC(g_stVpss0Config.s32GrpId, - // g_Vpss0Chn[0], - // g_VencChn[0]); - // if (s32Ret != HI_SUCCESS) { - // zlog_error(log_video, "Venc bind Vpss failed with %#x!\n", s32Ret); - // goto EXIT_VENC_H265_STOP; - // } - - // Start Venc Stream + // // Start Venc Stream // s32Ret = SAMPLE_COMM_VENC_StartGetStream( // g_VencChn + 1, sizeof(g_VencChn) / sizeof(VENC_CHN) - 2); // if (HI_SUCCESS != s32Ret) { - // zlog_error(log_video, "Get venc stream failed!\n"); - // goto EXIT_VENC_H264_STOP; + // zlog_error(log_video, "Get venc stream failed!\n"); + // goto EXIT_VENC_H264_STOP; // } // zlog_debug(log_video, "eb3516 Stream Start Success..."); - // s32Ret = SAMPLE_COMM_VENC_SaveJpeg(g_VencChn[2], 1); - // if (HI_SUCCESS != s32Ret) { - // zlog_error(log_video, "Save Jpeg Failed"); - // } + printf("=======press any key to trigger=====\n"); + getchar(); + + s32Ret = + HI_MPI_SNAP_TriggerPipe(g_stViConfig.astViInfo[0].stPipeInfo.aPipe[1]); + if (HI_SUCCESS != s32Ret) { + SAMPLE_PRT("HI_MPI_SNAP_TriggerPipe failed with %#x!\n", s32Ret); + } + + s32Ret = SAMPLE_COMM_VENC_SaveJpeg(g_VencChn[2], 1); + if (HI_SUCCESS != s32Ret) { + zlog_error(log_video, "Save Jpeg Failed"); + } zlog_info(log_video, "Mpp Start Successfully"); // PAUSE(); - // SAMPLE_COMM_VENC_StopGetStream(); + SAMPLE_COMM_VENC_StopGetStream(); return true; EXIT_VENC_SNAP_STOP: @@ -372,7 +383,7 @@ EXIT_SYS_STOP: SAMPLE_COMM_SYS_Exit(); EXIT_SYS_RST_CLK: EXIT: - return false; + return s32Ret; } void eb3516VideoStop(void) { @@ -394,7 +405,7 @@ void eb3516VideoStop(void) { zlog_info(log_video, "Finish Stopping eb3516 Video"); } -bool eb3516GetPic(void) { +HI_S32 eb3516GetPic(void) { HI_S32 ret = HI_SUCCESS; VIDEO_FRAME_INFO_S stRawInfo; @@ -404,6 +415,8 @@ bool eb3516GetPic(void) { &stRawInfo, milliSec); if (HI_SUCCESS != ret) { zlog_error(log_video, "Get Pipe Frame Failed"); - return false; + return ret; } + + return ret; } \ No newline at end of file diff --git a/src/modules/isp/eb3516_video.h b/src/modules/isp/eb3516_video.h index d3461b7..37cb757 100755 --- a/src/modules/isp/eb3516_video.h +++ b/src/modules/isp/eb3516_video.h @@ -1,6 +1,7 @@ #ifndef __EB3516_VIDEO_H__ #define __EB3516_VIDEO_H__ +#include "hi_type.h" #ifdef __cplusplus extern "C"{ #endif @@ -25,8 +26,8 @@ typedef struct { uint64_t timestamp; // in microseconds } video_packet_t; -bool eb3516VideoInit(void); -bool eb3516VideoStart(void); +HI_BOOL eb3516VideoInit(void); +HI_S32 eb3516VideoStart(void); void eb3516VideoStop(void); #ifdef __cplusplus diff --git a/src/modules/isp/mpp/ive_img.c b/src/modules/isp/mpp/ive_img.c new file mode 100755 index 0000000..1642534 --- /dev/null +++ b/src/modules/isp/mpp/ive_img.c @@ -0,0 +1,335 @@ +/* + * Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED. + * 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. + */ + +#include +#include +#include +#include +#include +#include + +#include "hi_comm_vb.h" +#include "mpi_sys.h" +#include "ive_img.h" +#include "sample_comm_ive.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* End of #ifdef __cplusplus */ + +#define HALF_THE_HEIGHT 2 // Half the height + +HI_U32 HiAlign16(HI_U32 num) +{ + return (((num) + 16 - 1) / 16 * 16); // 16: align 16 +} + +HI_U32 HiAlign32(HI_U32 num) +{ + return (((num) + 32 - 1) / 32 * 32); // 32: align 32 +} + +/* + * VIDEO_FRAME_INFO_S格式转换成IVE_IMAGE_S格式 + * 复制数据指针,不复制数据 + * + * video frame to ive image. + * Copy the data pointer, do not copy the data. + */ +int FrmToOrigImg(const VIDEO_FRAME_INFO_S* frm, IVE_IMAGE_S *img) +{ + static const int chnNum = 2; // Currently only supports YUV420/422, so only the addresses of 2 channels are copied + PIXEL_FORMAT_E pixelFormat = frm->stVFrame.enPixelFormat; + + if (memset_s(img, sizeof(*img), 0, sizeof(*img)) != EOK) { + HI_ASSERT(0); + } + + img->u32Width = frm->stVFrame.u32Width; + img->u32Height = frm->stVFrame.u32Height; + + if (pixelFormat == PIXEL_FORMAT_YVU_SEMIPLANAR_420) { + img->enType = IVE_IMAGE_TYPE_YUV420SP; + } else if (pixelFormat == PIXEL_FORMAT_YVU_SEMIPLANAR_422) { + img->enType = IVE_IMAGE_TYPE_YUV422SP; + } else { + HI_ASSERT(0); + return -1; + } + + for (int i = 0; i < chnNum; i++) { + img->au64PhyAddr[i] = frm->stVFrame.u64PhyAddr[i]; + img->au64VirAddr[i] = frm->stVFrame.u64VirAddr[i]; + img->au32Stride[i] = frm->stVFrame.u32Stride[i]; + } + return 0; +} + +/* + * 计算通道的步长 + * Calculate the stride of a channel + */ +static uint32_t IveCalStride(IVE_IMAGE_TYPE_E enType, uint32_t width, AlignType align) +{ + uint32_t size = 1; + + switch (enType) { + case IVE_IMAGE_TYPE_U8C1: + case IVE_IMAGE_TYPE_S8C1: + case IVE_IMAGE_TYPE_S8C2_PACKAGE: + case IVE_IMAGE_TYPE_S8C2_PLANAR: + case IVE_IMAGE_TYPE_U8C3_PACKAGE: + case IVE_IMAGE_TYPE_U8C3_PLANAR: + size = sizeof(HI_U8); + break; + case IVE_IMAGE_TYPE_S16C1: + case IVE_IMAGE_TYPE_U16C1: + size = sizeof(HI_U16); + break; + case IVE_IMAGE_TYPE_S32C1: + case IVE_IMAGE_TYPE_U32C1: + size = sizeof(uint32_t); + break; + case IVE_IMAGE_TYPE_S64C1: + case IVE_IMAGE_TYPE_U64C1: + size = sizeof(uint64_t); + break; + default: + break; + } + + if (align == ALIGN_TYPE_16) { + return HiAlign16(width * size); + } else if (align == ALIGN_TYPE_32) { + return HiAlign32(width * size); + } else { + HI_ASSERT(0); + return 0; + } +} + +/* + * 根据类型和大小创建缓存 + * Create ive image buffer based on type and size + */ +int IveImgCreate(IVE_IMAGE_S* img, + IVE_IMAGE_TYPE_E enType, uint32_t width, uint32_t height) +{ + HI_ASSERT(img); + uint32_t oneChnSize; + uint32_t size; + int ret; + + if (memset_s(img, sizeof(*img), 0, sizeof(*img)) != EOK) { + HI_ASSERT(0); + } + img->enType = enType; + img->u32Width = width; + img->u32Height = height; + img->au32Stride[0] = IveCalStride(img->enType, img->u32Width, ALIGN_TYPE_16); + + switch (enType) { + case IVE_IMAGE_TYPE_U8C1: + case IVE_IMAGE_TYPE_S8C1: // Only 1 channel + size = img->au32Stride[0] * img->u32Height; + ret = HI_MPI_SYS_MmzAlloc(&img->au64PhyAddr[0], (void**)&img->au64VirAddr[0], NULL, NULL, size); + SAMPLE_CHECK_EXPR_RET(HI_SUCCESS != ret, ret, "Error(%#x), HI_MPI_SYS_MmzAlloc!\n", ret); + break; + /* + * 大小相当于像素的1.5倍(3/2), 相当于2个通道 + * The size is equivalent to 1.5 times (3/2) of the pixel, which is equivalent to 2 channels + */ + case IVE_IMAGE_TYPE_YUV420SP: + /* + * 大小相当于像素的2倍,相当于2个通道 + * The size is equivalent to 2 times the pixel, which is equivalent to 2 channels + */ + case IVE_IMAGE_TYPE_YUV422SP: + if (enType == IVE_IMAGE_TYPE_YUV420SP) { + size = img->au32Stride[0] * img->u32Height * THREE_TIMES / TWO_TIMES; + } else { + size = img->au32Stride[0] * img->u32Height * TWO_TIMES; + } + ret = HI_MPI_SYS_MmzAlloc(&img->au64PhyAddr[0], (void**)&img->au64VirAddr[0], NULL, NULL, size); + SAMPLE_CHECK_EXPR_RET(HI_SUCCESS != ret, ret, "Error(%#x), HI_MPI_SYS_MmzAlloc!\n", ret); + + /* + * 设置通道1地址的步长,两者都需要通道1 + * Set the stride of the address of channel 1, both of which require channel 1 + */ + img->au32Stride[1] = img->au32Stride[0]; + img->au64PhyAddr[1] = img->au64PhyAddr[0] + img->au32Stride[0] * (uint64_t)img->u32Height; + img->au64VirAddr[1] = img->au64VirAddr[0] + img->au32Stride[0] * (uint64_t)img->u32Height; + break; + + case IVE_IMAGE_TYPE_U8C3_PLANAR: // 3 channels, often used for RGB + oneChnSize = img->au32Stride[0] * img->u32Height; + size = oneChnSize * 3; // 3 channels have the same size + ret = HI_MPI_SYS_MmzAlloc(&img->au64PhyAddr[0], (void**)&img->au64VirAddr[0], NULL, NULL, size); + SAMPLE_CHECK_EXPR_RET(HI_SUCCESS != ret, ret, "Error(%#x), HI_MPI_SYS_MmzAlloc!\n", ret); + + /* + * 设置通道1和通道2的地址和步长 + * Set the address and stride of channel 1 and channel 2 + */ + img->au64VirAddr[1] = img->au64VirAddr[0] + oneChnSize; + img->au64PhyAddr[1] = img->au64PhyAddr[0] + oneChnSize; + img->au32Stride[1] = img->au32Stride[0]; + img->au64VirAddr[2] = img->au64VirAddr[1] + oneChnSize; // 2: au64VirAddr array subscript, not out of bounds + img->au64PhyAddr[2] = img->au64PhyAddr[1] + oneChnSize; // 2: au64VirAddr array subscript, not out of bounds + img->au32Stride[2] = img->au32Stride[0]; // 2: au64VirAddr array subscript, not out of bounds + break; + + /* + * 目前如下格式不支持,主要为YVC420P, YUV422P, S8C2_PACKAGE, S8C2_PLANAR, + * S32C1, U32C1, S64C1, U64C1, S16C1, U16C1, U8C3_PACKAGE等 + * + * Types not currently supported: YVC420P, YUV422P, S8C2_PACKAGE, S8C2_PLANAR, + * S32C1, U32C1, S64C1, U64C1, S16C1, U16C1, U8C3_PACKAGE,etc. + */ + default: + HI_ASSERT(0); + break; + } + return HI_SUCCESS; +} + +int ImgYuvCrop(const IVE_IMAGE_S *src, IVE_IMAGE_S *dst, const RectBox* origBox) +{ + RectBox box = *origBox; + int boxWidth = box.xmax - box.xmin; + int boxHeight = box.ymax - box.ymin; + int ret; + + HI_ASSERT(boxWidth > 0 && boxWidth <= src->u32Width); + HI_ASSERT(boxHeight > 0 && boxHeight <= src->u32Height); + HI_ASSERT(src->au64VirAddr[0]); + HI_ASSERT(src->au32Stride[0] >= src->u32Width); + + /* + * 将框的宽度/高度调整为 2 的倍数 + * Adjust the width/height of the box to a multiple of 2 + */ + if (boxWidth == 1 || boxHeight == 1) { + SAMPLE_PRT("box dstWidth=1 && dstHeight=1\n"); + return -1; + } + if (boxWidth % HI_OVEN_BASE) { + box.xmax--; + boxWidth--; + } + if (boxHeight % HI_OVEN_BASE) { + box.ymax--; + boxHeight--; + } + + ret = IveImgCreate(dst, src->enType, boxWidth, boxHeight); + HI_ASSERT(!ret); + + /* + * 将框从源地址复制到目的地址 + * copy box from src to dst + */ + /* + * Y分量 + * Y component + */ + int srcStrideY = src->au32Stride[0]; + int dstStrideY = dst->au32Stride[0]; + uint8_t *srcBufY = (uint8_t*)((uintptr_t)src->au64VirAddr[0]); + uint8_t *dstBufY = (uint8_t*)((uintptr_t)dst->au64VirAddr[0]); + uint8_t *srcPtrY = &srcBufY[box.ymin * srcStrideY]; + uint8_t *dstPtrY = dstBufY; + for (int h = 0; h < boxHeight; h++, srcPtrY += srcStrideY, dstPtrY += dstStrideY) { + if (memcpy_s(dstPtrY, boxWidth, srcPtrY + box.xmin, boxWidth) != EOK) { + HI_ASSERT(0); + } + } + HI_ASSERT(dstPtrY - dstBufY == boxHeight * dstStrideY); + + /* + * UV分量 + * UV component + */ + int srcStrideUV = src->au32Stride[1]; + int dstStrideUV = dst->au32Stride[1]; + uint8_t *srcBufUV = (uint8_t*)((uintptr_t)src->au64VirAddr[1]); + uint8_t *dstBufUV = (uint8_t*)((uintptr_t)dst->au64VirAddr[1]); + uint8_t *srcPtrUV = &srcBufUV[(box.ymin / HALF_THE_HEIGHT) * srcStrideUV]; + uint8_t *dstPtrUV = dstBufUV; + for (int h = 0; h < (boxHeight / HALF_THE_HEIGHT); + h++, srcPtrUV += srcStrideUV, dstPtrUV += dstStrideUV) { + if (memcpy_s(dstPtrUV, boxWidth, srcPtrUV + box.xmin, boxWidth) != EOK) { + HI_ASSERT(0); + } + } + HI_ASSERT(dstPtrUV - dstBufUV == (boxHeight / HALF_THE_HEIGHT) * dstStrideUV); + + return ret; +} + +/* + * 销毁ive image + * Destory ive image + */ +void IveImgDestroy(IVE_IMAGE_S* img) +{ + for (int i = 0; i < IMG_FULL_CHN; i++) { + if (img->au64PhyAddr[0] && img->au64VirAddr[0]) { + HI_MPI_SYS_MmzFree(img->au64PhyAddr[i], (void*)((uintptr_t)img->au64VirAddr[i])); + img->au64PhyAddr[i] = 0; + img->au64VirAddr[i] = 0; + } + } + if (memset_s(img, sizeof(*img), 0, sizeof(*img)) != EOK) { + HI_ASSERT(0); + } +} + +int OrigImgToFrm(const IVE_IMAGE_S *img, VIDEO_FRAME_INFO_S* frm) +{ + static const int chnNum = 2; + IVE_IMAGE_TYPE_E enType = img->enType; + if (memset_s(frm, sizeof(*frm), 0, sizeof(*frm)) != EOK) { + HI_ASSERT(0); + } + + frm->stVFrame.u32Width = img->u32Width; + frm->stVFrame.u32Height = img->u32Height; + + if (enType == IVE_IMAGE_TYPE_YUV420SP) { + frm->stVFrame.enPixelFormat = PIXEL_FORMAT_YVU_SEMIPLANAR_420; + } else if (enType == IVE_IMAGE_TYPE_YUV422SP) { + frm->stVFrame.enPixelFormat = PIXEL_FORMAT_YVU_SEMIPLANAR_422; + } else { + HI_ASSERT(0); + return -1; + } + + for (int i = 0; i < chnNum; i++) { + frm->stVFrame.u64PhyAddr[i] = img->au64PhyAddr[i]; + frm->stVFrame.u64VirAddr[i] = img->au64VirAddr[i]; + frm->stVFrame.u32Stride[i] = img->au32Stride[i]; + } + return 0; +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ diff --git a/src/modules/isp/mpp/ive_img.h b/src/modules/isp/mpp/ive_img.h new file mode 100755 index 0000000..7302507 --- /dev/null +++ b/src/modules/isp/mpp/ive_img.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED. + * 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. + */ + +#ifndef IVE_IMG_H +#define IVE_IMG_H + +#include +#include + +#include "hi_common.h" +#include "hi_comm_ive.h" +#include "hi_comm_video.h" +#include "hi_comm_venc.h" +#include "hi_ive.h" +#include "mpi_ive.h" +#include "util.h" + +#if __cplusplus +extern "C" { +#endif + +/* + * 常量 + * Constant + */ +#define IMG_FULL_CHN 3 // Full channel / three channel, for YUV444, RGB888 +#define IMG_HALF_CHN 2 // Half channel, for YUV420/422 +#define THREE_TIMES 3 +#define TWO_TIMES 2 + +/* + * 字节对齐计算 + * Byte alignment calculation + */ +HI_U32 HiAlign16(HI_U32 num); +HI_U32 HiAlign32(HI_U32 num); + +/* + * 对齐类型 + * Alignment type + */ +typedef enum AlignType { + ALIGN_TYPE_2 = 2, // Align by 2 bytes + ALIGN_TYPE_16 = 16, // Align by 16 bytes + ALIGN_TYPE_32 = 32, // Align by 32 bytes +} AlignType; + +/* + * 根据类型和大小创建缓存 + * Create ive image buffer based on type and size + */ +int IveImgCreate(IVE_IMAGE_S* img, + IVE_IMAGE_TYPE_E enType, uint32_t width, uint32_t height); + +/* + * VIDEO_FRAME_INFO_S格式转换成IVE_IMAGE_S格式 + * 复制数据指针,不复制数据 + * + * video frame to ive image. + * Copy the data pointer, do not copy the data. + */ +int FrmToOrigImg(const VIDEO_FRAME_INFO_S* frm, IVE_IMAGE_S *img); + +/* + * 对yuv格式进行裁剪 + * yuv file crop + */ +int ImgYuvCrop(const IVE_IMAGE_S *src, IVE_IMAGE_S *dst, const RectBox* origBox); + +/* + * 销毁ive image + * Destory ive image + */ +void IveImgDestroy(IVE_IMAGE_S* img); + +int OrigImgToFrm(const IVE_IMAGE_S *img, VIDEO_FRAME_INFO_S* frm); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/modules/isp/mpp/osd_img.c b/src/modules/isp/mpp/osd_img.c new file mode 100755 index 0000000..1fd9c6e --- /dev/null +++ b/src/modules/isp/mpp/osd_img.c @@ -0,0 +1,1265 @@ +/* + * Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED. + * 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. + */ + +#include +#include +#include +#include +#include +#include "mpi_vi.h" +#include "mpi_vpss.h" +#include "mpi_venc.h" +#include "mpi_vo.h" +#include "mpi_region.h" +#include "sample_comm_ive.h" +#include "vgs_img.h" +#include "osd_img.h" + +/* OSD font library */ +static const HI_U8 G_FONT_LIB[] __attribute__((aligned(4))) = { +#include "simsunb_16x32.txt" +}; + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* End of #ifdef __cplusplus */ + +#define OSD_FONT_WIDTH_DEF 40 // Default font width +#define OSD_FONT_HEIGHT_DEF 40 // The default font height +#define NOASCII_CHARACTER_BYTES (2) /* Number of bytes occupied by each Chinese character */ +#define BYTE_BITS (8) + +#define OSD_FONT_ASC +#define OSD_FONT_MOD_W 16 +#define OSD_FONT_MOD_H 32 +#define X_COORDINATE 100 +#define Y_COORDINATE 100 +#define BASE_YAER 1900 +#define MULTIPLE_NUM 100 + +/* + * 全局对象 + * 多个OsdSet实例将从全局池中分配id + * + * Global object. + * Multiple OsdSet instances will allocate ids from the global pool. + */ +static void* g_osdHndPool[HI_OSD_MAX_CNT]; // Used to identify whether the index handle is used +static pthread_mutex_t g_osdMutex; // pool access lock + +/* + * OSD参数数组 + * OSD Parameter Array、 + */ +static OSD_PARAM_S s_stOSDParam[HI_OSD_MAX_CNT]; + +/* + * OSD 模块初始化标志 + * 只能被HI_PDT_OSD_Init/HI_PDT_OSD_DeInit修改 + * + * OSD Module Init Flag + * Only modified by HI_PDT_OSD_Init/HI_PDT_OSD_DeInit + */ +static HI_BOOL s_bOSDInitFlg = HI_FALSE; + +/* + * OSD 字体库,由 HI_PDT_OSD_Init 初始化 + * OSD Fonts Lib, inited by HI_PDT_OSD_Init + */ +static HI_OSD_FONTS_S s_stOSDFonts; + +/* + * OSD 时间更新运行标志 + * 只能被HI_PDT_OSD_Init/HI_PDT_OSD_DeInit修改 + * + * OSD Time Update Runing Flag + * Only modified by HI_PDT_OSD_Init/HI_PDT_OSD_DeInit + */ +static HI_BOOL s_bOSDTimeRun = HI_FALSE; + +/* + * 时间OSD更新任务线程ID,由HI_PDT_OSD_Init创建,由HI_OSD_DeInit销毁 + * Time OSD Update Task Thread ID, created by HI_PDT_OSD_Init, destroyed by HI_OSD_DeInit + */ +static pthread_t s_OSDTimeTskId = 0; + +static HI_OSD_TEXTBITMAP_S s_stOSDTextBitMap; + +static HI_U8* FontMod = NULL; +static HI_S32 FontModLen = 0; + +/* + * 位图行/列索引 + * Bitmap Row/Col Index + */ +static HI_S32 s32BmRow; +static HI_S32 s32BmCol; +struct tm stTime = {0}; + +/* + * OSD Font Step In Lib,以字节为单位 + * OSD Font Step In Lib, in bytes + */ +#define OSD_LIB_FONT_W (s_stOSDFonts.u32FontWidth) +#define OSD_LIB_FONT_H (s_stOSDFonts.u32FontHeight) +#define OSD_LIB_FONT_STEP (OSD_LIB_FONT_W * OSD_LIB_FONT_H / BYTE_BITS) + +/* + * 数据对齐 + * Value Align + */ +HI_S32 HiAppcommAlign(HI_S32 value, HI_S32 base) +{ + return (((value) + (base)-1) / (base) * (base)); +} + +HI_U32 max(HI_U32 a, HI_U32 b) +{ + return (((a) < (b)) ? (b) : (a)); +} + +HI_U32 min(HI_U32 a, HI_U32 b) +{ + return (((a) > (b)) ? (b) : (a)); +} + +HI_S32 IsAscii(HI_S32 a) +{ + return (((a) >= 0x00 && (a) <= 0x7F) ? 1 : 0); +} + +static HI_S32 OSD_GetNonASCNum(HI_CHAR* string, HI_S32 len) +{ + HI_S32 i; + HI_S32 n = 0; + for (i = 0; i < len; i++) { + if (string[i] == '\0') { + break; + } + if (!IsAscii(string[i])) { + i++; + n++; + } + } + return n; +} + +/* + * 创建OsdSet + * Creat OsdSet + */ +OsdSet* OsdsCreate(HI_OSD_BIND_MOD_E bindMod, HI_U32 modHnd, HI_U32 chnHnd) +{ + OsdSet *self = NULL; + + self = (OsdSet*)malloc(sizeof(*self)); + if (!self) { + HI_ASSERT(0); + } + if (memset_s(self, sizeof(*self), 0, sizeof(*self)) != EOK) { + HI_ASSERT(0); + } + + self->bindMod = bindMod; + self->modHnd = modHnd; + self->chnHnd = chnHnd; + return self; +} + +/* + * @brief 获取给定格式的时间字符串 + * @param[in]pstTime : 时间结构,如果为空则获取当前系统时间 + * @param[out]pazStr : 时间字符串缓冲区 + * @param[in]s32Len : 时间字符串缓冲区长度 + * + * @brief get time string with given format + * @param[in]pstTime : time struct, get current system time if null + * @param[out]pazStr : time string buffer + * @param[in]s32Len : time string buffer length + */ +static HI_VOID OSD_GetTimeStr(struct tm* pstTime, HI_CHAR* pazStr, HI_S32 s32Len) +{ + /* + * 获取时间 + * Get Time + */ + time_t nowTime; + + if (!pstTime) { + time(&nowTime); + localtime_r(&nowTime, pstTime); + } + + /* + * 生成时间字符串 + * Generate Time String + */ + if (snprintf_s(pazStr, s32Len, s32Len - 1, "%04d-%02d-%02d %02d:%02d:%02d", + pstTime->tm_year + BASE_YAER, pstTime->tm_mon + 1, pstTime->tm_mday, + pstTime->tm_hour, pstTime->tm_min, pstTime->tm_sec) < 0) { + HI_ASSERT(0); + } + + return; +} + +static HI_S32 OSD_RGNDetach(RGN_HANDLE RgnHdl, const HI_OSD_DISP_ATTR_S* pstDispAttr) +{ + HI_S32 s32Ret = HI_SUCCESS; + MPP_CHN_S stChn; + + stChn.s32DevId = pstDispAttr->ModHdl; + stChn.s32ChnId = pstDispAttr->ChnHdl; + switch (pstDispAttr->enBindedMod) { + case HI_OSD_BINDMOD_VI: + stChn.enModId = HI_ID_VI; + break; + case HI_OSD_BINDMOD_VPSS: + stChn.enModId = HI_ID_VPSS; + break; + case HI_OSD_BINDMOD_AVS: + stChn.enModId = HI_ID_AVS; + break; + case HI_OSD_BINDMOD_VENC: + stChn.s32DevId = 0; + stChn.enModId = HI_ID_VENC; + break; + case HI_OSD_BINDMOD_VO: + stChn.enModId = HI_ID_VO; + break; + default: + SAMPLE_PRT("RgnHdl[%d] invalide bind mode [%d]\n", RgnHdl, pstDispAttr->enBindedMod); + return HI_EINVAL; + } + + s32Ret = HI_MPI_RGN_DetachFromChn(RgnHdl, &stChn); + if (s32Ret != HI_SUCCESS) { + SAMPLE_PRT("HI_MPI_RGN_DetachFromChn fail,RgnHdl[%d] stChn[%d,%d,%d] Error Code: [0x%08X]\n", + RgnHdl, stChn.enModId, stChn.s32DevId, stChn.s32ChnId, s32Ret); + return s32Ret; + } + + return HI_SUCCESS; +} + +static HI_S32 OSD_DestroyRGN(RGN_HANDLE RgnHdl, const HI_OSD_ATTR_S* pstAttr) +{ + HI_S32 s32Ret = HI_SUCCESS; + HI_S32 s32DispIdx = 0; + + for (s32DispIdx = 0; s32DispIdx < pstAttr->u32DispNum ; ++s32DispIdx) { + if (pstAttr->astDispAttr[s32DispIdx].bShow) { + OSD_RGNDetach(RgnHdl, &pstAttr->astDispAttr[s32DispIdx]); + } + } + + s32Ret = HI_MPI_RGN_Destroy(RgnHdl); + if (s32Ret != HI_SUCCESS) { + SAMPLE_PRT("HI_MPI_RGN_Destroy fail, RgnHdl[%d] Error Code: [0x%08X]\n", RgnHdl, s32Ret); + return s32Ret; + } + + return HI_SUCCESS; +} + +/* + * 在OsdSet中创建区域 + * Create a region in OsdSet + */ +int OsdsCreateRgn(OsdSet* self) +{ + HI_ASSERT(self); + int ret = -1; + + MutexLock(&g_osdMutex); + for (int i = 0; i < HI_OSD_MAX_CNT; i++) { + if (!g_osdHndPool[i]) { + g_osdHndPool[i] = self; + ret = i; + break; + } + } + MutexUnlock(&g_osdMutex); + return ret; +} + +static HI_S32 OSD_Stop(HI_S32 s32OsdIdx) +{ + HI_S32 s32Ret = HI_SUCCESS; + OSD_PARAM_S* pstOsdParam = &s_stOSDParam[s32OsdIdx]; + + if (!pstOsdParam->bOn) { + return HI_SUCCESS; + } + + s32Ret = OSD_DestroyRGN(s32OsdIdx, &pstOsdParam->stAttr); + if (s32Ret != HI_SUCCESS) { + SAMPLE_PRT("OSD_DestroyRGN s32OsdIdx[%d] failed:[0x%08X]\n", s32OsdIdx, s32Ret); + return s32Ret; + } + + pstOsdParam->bOn = HI_FALSE; + return HI_SUCCESS; +} + +/* + * @brief 按索引停止osd + * @param[in] s32OsdIdx:osd 索引,范围[0,HI_OSD_MAX_CNT) + * @return 0 成功,非零错误码 + * + * @brief stop osd by index. + * @param[in] s32OsdIdx:osd index, range[0,HI_OSD_MAX_CNT) + * @return 0 success,non-zero error code. + */ +HI_S32 HI_OSD_Stop(HI_S32 s32OsdIdx) +{ + /* + * 检查模块初始化与否 + * Check Module Init or not + */ + HI_ASSERT(HI_TRUE == s_bOSDInitFlg); + /* + * 检查输入参数 + * Check Input Param + */ + HI_ASSERT(s32OsdIdx >= 0); + HI_ASSERT(HI_OSD_MAX_CNT > s32OsdIdx); + + HI_S32 s32Ret = HI_SUCCESS; + OSD_PARAM_S* pstOsdParam = &s_stOSDParam[s32OsdIdx]; + + pthread_mutex_lock(&pstOsdParam->mutexLock); + + /* + * 检查OSD Attrbute是否初始化 + * Check OSD Attrbute init or not + */ + if (!pstOsdParam->bInit) { + pthread_mutex_unlock(&pstOsdParam->mutexLock); + return HI_SUCCESS; + } + + /* + * 检查OSD是否停止 + * Check OSD stop or not + */ + if (!pstOsdParam->bOn) { + pthread_mutex_unlock(&pstOsdParam->mutexLock); + return HI_SUCCESS; + } + + s32Ret = OSD_Stop(s32OsdIdx); + pstOsdParam->stMaxSize.u32Width = 0; + pstOsdParam->stMaxSize.u32Height= 0; + pthread_mutex_unlock(&pstOsdParam->mutexLock); + return s32Ret; +} + +/* + * 销毁OsdSet中指定的区域 + * Destroy the region specified in the OsdSet + */ +void OsdsDestroyRgn(OsdSet* self, int rgnHnd) +{ + HI_ASSERT(self); + HI_ASSERT(rgnHnd >= 0 && rgnHnd < HI_OSD_MAX_CNT); + + MutexLock(&g_osdMutex); + HI_ASSERT(g_osdHndPool[rgnHnd] && g_osdHndPool[rgnHnd] == (void*)self); + g_osdHndPool[rgnHnd] = NULL; + MutexUnlock(&g_osdMutex); + + HI_OSD_Stop(rgnHnd); +} + +/* + * 销毁OsdSet中的所有区域 + * Destroy all regions in OsdSet + */ +void OsdsClear(OsdSet* self) +{ + MutexLock(&g_osdMutex); + for (int i = 0; i < HI_OSD_MAX_CNT; i++) { + if (g_osdHndPool[i] && g_osdHndPool[i] == (void*)self) { + OsdsDestroyRgn(self, i); + } + } + MutexUnlock(&g_osdMutex); +} + +/* + * 销毁OsdSet + * Destory OsdSet + */ +void OsdsDestroy(OsdSet* self) +{ + HI_ASSERT(self); + OsdsClear(self); + free(self); +} + +/* + * 设置文本区域的属性值 + * Set the attribute value of the text region + */ +int TxtRgnInit(HI_OSD_ATTR_S* rgnAttr, const char* str, uint32_t begX, uint32_t begY, uint32_t color) +{ + HI_ASSERT(rgnAttr); + if (!str) { + HI_ASSERT(0); + } + // 64:[0,128], the transparency of the text background block, the larger the background block color, + // the darker the background block color, 0 means no background block, that is, completely transparent + static const uint32_t bgAlpha = 64; + // 128:[0,128], the brightness of the text, the larger the value, the brighter the text + static const uint32_t fgAlpha = 128; + + if (memset_s(rgnAttr, sizeof(*rgnAttr), 0, sizeof(*rgnAttr)) != EOK) { + HI_ASSERT(0); + } + rgnAttr->u32DispNum = 1; + rgnAttr->astDispAttr[0].bShow = (str && *str) ? HI_TRUE : HI_FALSE; + rgnAttr->astDispAttr[0].enBindedMod = HI_OSD_BINDMOD_BUTT; + rgnAttr->astDispAttr[0].ChnHdl = UINT32_MAX; + rgnAttr->astDispAttr[0].u32BgAlpha = bgAlpha; + rgnAttr->astDispAttr[0].u32FgAlpha = fgAlpha; + rgnAttr->astDispAttr[0].enCoordinate = HI_OSD_COORDINATE_ABS_COOR; + rgnAttr->astDispAttr[0].stStartPos.s32X = begX; + rgnAttr->astDispAttr[0].stStartPos.s32Y = begY; + rgnAttr->astDispAttr[0].enAttachDest = ATTACH_JPEG_MAIN; + rgnAttr->stContent.enType = HI_OSD_TYPE_STRING; + rgnAttr->stContent.u32Color = color; // ARGB #FFFF0000 Red + HiStrxfrm(rgnAttr->stContent.szStr, str, sizeof(rgnAttr->stContent.szStr)); + rgnAttr->stContent.stFontSize.u32Width = OSD_FONT_WIDTH_DEF; + rgnAttr->stContent.stFontSize.u32Height = OSD_FONT_HEIGHT_DEF; + return 0; +} + +static HI_S32 OSD_Ratio2Absolute(MPP_CHN_S stChn, const POINT_S* pstRatioCoor, POINT_S* pstAbsCoor) +{ + HI_S32 s32Ret = HI_SUCCESS; + SIZE_S stImageSize; + + if (pstRatioCoor->s32X < 0 || pstRatioCoor->s32X > X_COORDINATE || + pstRatioCoor->s32Y < 0 || pstRatioCoor->s32Y > Y_COORDINATE) { + SAMPLE_PRT("invalide Ratio coordinate(%d,%d)\n", pstRatioCoor->s32X, pstRatioCoor->s32Y); + return HI_EINVAL; + } + switch (stChn.enModId) { + case HI_ID_VI: { + VI_CHN_ATTR_S stChnAttr; + s32Ret = HI_MPI_VI_GetChnAttr(stChn.s32DevId, stChn.s32ChnId, &stChnAttr); + if (s32Ret != HI_SUCCESS) { + SAMPLE_PRT("HI_MPI_VI_GetChnAttr(%d,%d) fail,Error Code: [0x%08X]\n", + stChn.s32DevId, stChn.s32ChnId, s32Ret); + return s32Ret; + } + stImageSize = stChnAttr.stSize; + break; + } + case HI_ID_VPSS: { + VPSS_CHN_ATTR_S stChnAttr; + s32Ret = HI_MPI_VPSS_GetChnAttr(stChn.s32DevId, stChn.s32ChnId, &stChnAttr); + if (s32Ret != HI_SUCCESS) { + SAMPLE_PRT("HI_MPI_VPSS_GetChnAttr(%d,%d) fail, Error Code: [0x%08X]\n", + stChn.s32DevId, stChn.s32ChnId, s32Ret); + return s32Ret; + } + stImageSize.u32Width = stChnAttr.u32Width; + stImageSize.u32Height = stChnAttr.u32Height; + break; + } + case HI_ID_VO: { + VO_CHN_ATTR_S stChnAttr; + s32Ret = HI_MPI_VO_GetChnAttr(stChn.s32DevId, stChn.s32ChnId, &stChnAttr); + if (s32Ret != HI_SUCCESS) { + SAMPLE_PRT("HI_MPI_VO_GetChnAttr(%d,%d) fail,Error Code: [0x%08X]\n", + stChn.s32DevId, stChn.s32ChnId, s32Ret); + return s32Ret; + } + stImageSize.u32Width = stChnAttr.stRect.u32Width; + stImageSize.u32Height = stChnAttr.stRect.u32Height; + break; + } + default: + SAMPLE_PRT("invalide mode id [%d]\n", stChn.enModId); + return HI_EINVAL; + } + + // 2: HiAppcommAlign api base param + pstAbsCoor->s32X = HiAppcommAlign(stImageSize.u32Width * pstRatioCoor->s32X / MULTIPLE_NUM, 2); + // 2: HiAppcommAlign api base param + pstAbsCoor->s32Y = HiAppcommAlign(stImageSize.u32Height * pstRatioCoor->s32Y / MULTIPLE_NUM, 2); + return HI_SUCCESS; +} + +static HI_S32 OSD_Update(RGN_HANDLE RgnHdl, const HI_OSD_ATTR_S* pstAttr) +{ + HI_S32 s32Ret = HI_SUCCESS; + HI_S32 s32DispIdx = 0; + RGN_CHN_ATTR_S stRgnChnAttr; + MPP_CHN_S stChn; + + for (s32DispIdx = 0; s32DispIdx < pstAttr->u32DispNum ; ++s32DispIdx) { + if (!pstAttr->astDispAttr[s32DispIdx].bShow) { + continue; + } + + stChn.s32DevId = pstAttr->astDispAttr[s32DispIdx].ModHdl; + stChn.s32ChnId = pstAttr->astDispAttr[s32DispIdx].ChnHdl; + switch (pstAttr->astDispAttr[s32DispIdx].enBindedMod) { + case HI_OSD_BINDMOD_VI: + stChn.enModId = HI_ID_VI; + break; + case HI_OSD_BINDMOD_VPSS: + stChn.enModId = HI_ID_VPSS; + break; + case HI_OSD_BINDMOD_VO: + stChn.enModId = HI_ID_VO; + break; + default: + SAMPLE_PRT("invalide bind mode [%d]\n", pstAttr->astDispAttr[s32DispIdx].enBindedMod); + return HI_EINVAL; + } + /* + * 获取区域的通道显示属性 + * Get the channel display properties of the zone + */ + s32Ret = HI_MPI_RGN_GetDisplayAttr(RgnHdl, &stChn, &stRgnChnAttr); + SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "GetDisplayAttr fail, s32Ret:[0x%08X]\n", s32Ret); + + stRgnChnAttr.bShow = pstAttr->astDispAttr[s32DispIdx].bShow; + POINT_S stStartPos; + if (pstAttr->astDispAttr[s32DispIdx].enCoordinate == HI_OSD_COORDINATE_RATIO_COOR) { + s32Ret = OSD_Ratio2Absolute(stChn, &pstAttr->astDispAttr[s32DispIdx].stStartPos, &stStartPos); + SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "Ratio2Absolute fail, s32Ret:[0x%08X]\n", s32Ret); + } else { + stStartPos = pstAttr->astDispAttr[s32DispIdx].stStartPos; + } + + if (stRgnChnAttr.enType == OVERLAYEX_RGN) { + stRgnChnAttr.unChnAttr.stOverlayExChn.stPoint.s32X = stStartPos.s32X; + stRgnChnAttr.unChnAttr.stOverlayExChn.stPoint.s32Y = stStartPos.s32Y; + stRgnChnAttr.unChnAttr.stOverlayExChn.u32BgAlpha = pstAttr->astDispAttr[s32DispIdx].u32BgAlpha; + stRgnChnAttr.unChnAttr.stOverlayExChn.u32FgAlpha = pstAttr->astDispAttr[s32DispIdx].u32FgAlpha; + } else { + stRgnChnAttr.unChnAttr.stOverlayChn.stPoint.s32X = stStartPos.s32X; + stRgnChnAttr.unChnAttr.stOverlayChn.stPoint.s32Y = stStartPos.s32Y; + stRgnChnAttr.unChnAttr.stOverlayChn.u32BgAlpha = pstAttr->astDispAttr[s32DispIdx].u32BgAlpha; + stRgnChnAttr.unChnAttr.stOverlayChn.u32FgAlpha = pstAttr->astDispAttr[s32DispIdx].u32FgAlpha; + } + /* + * 设置区域的通道显示属性 + * Sets the channel display properties for the zone + */ + s32Ret = HI_MPI_RGN_SetDisplayAttr(RgnHdl, &stChn, &stRgnChnAttr); + SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "SetDisplayAttr fail, s32Ret:[0x%08X]\n", s32Ret); + } + + return HI_SUCCESS; +} + +HI_VOID OSD_PuBmData_Cal(HI_OSD_CONTENT_S* pstContent, HI_U16* puBmData, HI_S32 s32HexOffset, + HI_S32 s32BmDataIdx, HI_S32 s32BitOffset) +{ + HI_U8 temp = FontMod[s32HexOffset]; + if ((temp >> ((BYTE_BITS - 1) - s32BitOffset)) & 0x1) { + puBmData[s32BmDataIdx] = (HI_U16)pstContent->u32Color; + } else { + puBmData[s32BmDataIdx] = (HI_U16)pstContent->u32BgColor; + } + + return; +} + +HI_S32 OSD_Bitmap_Cal(HI_OSD_CONTENT_S* pstContent, HI_S32 NonASCNum, HI_U16* puBmData) +{ + HI_S32 NonASCShow = 0; + for (s32BmCol = 0; s32BmCol < pstContent->stBitmap.u32Width; ++s32BmCol) { + /* + * 点的位图数据偏移 + * Bitmap Data Offset for the point + */ + HI_S32 s32BmDataIdx = s32BmRow * s_stOSDTextBitMap.stCanvasInfo.u32Stride / 2 + s32BmCol; + /* + * 文本字符串中的字符索引 + * Character Index in Text String + */ + HI_S32 s32CharIdx = s32BmCol / pstContent->stFontSize.u32Width; + HI_S32 s32StringIdx = s32CharIdx+NonASCShow * (NOASCII_CHARACTER_BYTES - 1); + if (NonASCNum > 0 && s32CharIdx > 0) { + NonASCShow = OSD_GetNonASCNum(pstContent->szStr, s32StringIdx); + s32StringIdx = s32CharIdx+NonASCShow * (NOASCII_CHARACTER_BYTES - 1); + } + /* + * 字符中的点行/列索引 + * Point Row/Col Index in Character + */ + HI_S32 s32CharCol = (s32BmCol - (pstContent->stFontSize.u32Width * s32CharIdx)) * + OSD_LIB_FONT_W / pstContent->stFontSize.u32Width; + HI_S32 s32CharRow = s32BmRow * OSD_LIB_FONT_H / pstContent->stFontSize.u32Height; + HI_S32 s32HexOffset = s32CharRow * OSD_LIB_FONT_W / BYTE_BITS + s32CharCol / BYTE_BITS; + HI_S32 s32BitOffset = s32CharCol % BYTE_BITS; + + if (s_stOSDFonts.pfnGetFontMod(&pstContent->szStr[s32StringIdx], &FontMod, &FontModLen) + == HI_SUCCESS) { + if (FontMod != NULL && s32HexOffset < FontModLen) { + OSD_PuBmData_Cal(pstContent, puBmData, s32HexOffset, s32BmDataIdx, s32BitOffset); + continue; + } + } + SAMPLE_PRT("GetFontMod Fail\n"); + return HI_FAILURE; + } +} + +HI_S32 OSD_Generate_Bitmap(RGN_HANDLE RgnHdl, HI_OSD_CONTENT_S* pstContent) +{ + HI_S32 s32Ret; + HI_S32 s32StrLen = strnlen(pstContent->szStr, HI_OSD_MAX_STR_LEN); + HI_S32 NonASCNum = OSD_GetNonASCNum(pstContent->szStr, s32StrLen); + + s32Ret = HI_MPI_RGN_GetCanvasInfo(RgnHdl, &s_stOSDTextBitMap.stCanvasInfo); + SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "RGN_GetCanvasInfo FAIL, s32Ret=%x\n", s32Ret); + + /* + * 生成位图 + * Generate Bitmap + */ + pstContent->stBitmap.u32Width = pstContent->stFontSize.u32Width * + (s32StrLen - NonASCNum * (NOASCII_CHARACTER_BYTES - 1)); + pstContent->stBitmap.u32Height = pstContent->stFontSize.u32Height; + HI_U16* puBmData = (HI_U16*)(HI_UL)s_stOSDTextBitMap.stCanvasInfo.u64VirtAddr; + + for (s32BmRow = 0; s32BmRow < pstContent->stBitmap.u32Height; ++s32BmRow) { + OSD_Bitmap_Cal(pstContent, NonASCNum, puBmData); + for (s32BmCol = pstContent->stBitmap.u32Width; + s32BmCol < s_stOSDParam[RgnHdl].stMaxSize.u32Width; ++s32BmCol) { + HI_S32 s32BmDataIdx = s32BmRow * s_stOSDTextBitMap.stCanvasInfo.u32Stride / 2 + s32BmCol; + puBmData[s32BmDataIdx] = 0; + } + } + + for (s32BmRow = pstContent->stBitmap.u32Height; + s32BmRow < s_stOSDParam[RgnHdl].stMaxSize.u32Height; ++s32BmRow) { + for (s32BmCol = 0; s32BmCol < s_stOSDParam[RgnHdl].stMaxSize.u32Width; ++s32BmCol) { + HI_S32 s32BmDataIdx = s32BmRow * s_stOSDTextBitMap.stCanvasInfo.u32Stride / 2 + s32BmCol; + puBmData[s32BmDataIdx] = 0; + } + } + + return s32Ret; +} + +static HI_S32 OSD_UpdateTextBitmap(RGN_HANDLE RgnHdl, HI_OSD_CONTENT_S* pstContent) +{ + HI_S32 s32Ret = HI_SUCCESS; + + OSD_Generate_Bitmap(RgnHdl, pstContent); + s_stOSDTextBitMap.stCanvasInfo.enPixelFmt = PIXEL_FORMAT_ARGB_1555; + s_stOSDTextBitMap.stCanvasInfo.stSize.u32Width = pstContent->stBitmap.u32Width; + s_stOSDTextBitMap.stCanvasInfo.stSize.u32Height = pstContent->stBitmap.u32Height; + + s32Ret = HI_MPI_RGN_UpdateCanvas(RgnHdl); + SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "RGN_UpdateCanvas FAIL, s32Ret=%x\n", s32Ret); + + return s32Ret; +} + +static HI_S32 OSD_RGNAttach(RGN_HANDLE RgnHdl, const HI_OSD_DISP_ATTR_S* pstDispAttr) +{ + HI_S32 s32Ret = HI_SUCCESS; + RGN_CHN_ATTR_S stRgnChnAttr; + MPP_CHN_S stChn; + + stChn.s32DevId = pstDispAttr->ModHdl; + stChn.s32ChnId = pstDispAttr->ChnHdl; + memset_s(&stRgnChnAttr, sizeof(RGN_CHN_ATTR_S), 0x0, sizeof(RGN_CHN_ATTR_S)); + stRgnChnAttr.bShow = pstDispAttr->bShow; + stRgnChnAttr.enType = OVERLAYEX_RGN; + switch (pstDispAttr->enBindedMod) { + case HI_OSD_BINDMOD_VI: + stChn.enModId = HI_ID_VI; + break; + case HI_OSD_BINDMOD_VPSS: + stChn.enModId = HI_ID_VPSS; + break; + case HI_OSD_BINDMOD_VO: + stChn.enModId = HI_ID_VO; + break; + default: + SAMPLE_PRT("RgnHdl[%d] invalide bind mode [%d]\n", RgnHdl, pstDispAttr->enBindedMod); + return HI_EINVAL; + } + + POINT_S stStartPos; + if (pstDispAttr->enCoordinate == HI_OSD_COORDINATE_RATIO_COOR) { + s32Ret = OSD_Ratio2Absolute(stChn, &pstDispAttr->stStartPos, &stStartPos); + SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "Ratio2Absolute FAIL, s32Ret=%x\n", s32Ret); + } else { + stStartPos = pstDispAttr->stStartPos; + } + + if (stRgnChnAttr.enType == OVERLAYEX_RGN) { + stRgnChnAttr.unChnAttr.stOverlayExChn.stPoint.s32X = stStartPos.s32X; + stRgnChnAttr.unChnAttr.stOverlayExChn.stPoint.s32Y = stStartPos.s32Y; + stRgnChnAttr.unChnAttr.stOverlayExChn.u32BgAlpha = pstDispAttr->u32BgAlpha; + stRgnChnAttr.unChnAttr.stOverlayExChn.u32FgAlpha = pstDispAttr->u32FgAlpha; + stRgnChnAttr.unChnAttr.stOverlayExChn.u32Layer = 0; + } else { + stRgnChnAttr.unChnAttr.stOverlayChn.stPoint.s32X = stStartPos.s32X; + stRgnChnAttr.unChnAttr.stOverlayChn.stPoint.s32Y = stStartPos.s32Y; + stRgnChnAttr.unChnAttr.stOverlayChn.u32BgAlpha = pstDispAttr->u32BgAlpha; + stRgnChnAttr.unChnAttr.stOverlayChn.u32FgAlpha = pstDispAttr->u32FgAlpha; + stRgnChnAttr.unChnAttr.stOverlayChn.u32Layer = 0; + } + + s32Ret = HI_MPI_RGN_AttachToChn(RgnHdl, &stChn, &stRgnChnAttr); + SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "RGN_AttachToChn FAIL, s32Ret=%x\n", s32Ret); + + return HI_SUCCESS; +} + +static HI_S32 OSD_CreateRGN(RGN_HANDLE RgnHdl, const HI_OSD_ATTR_S* pstAttr) +{ + HI_S32 s32Ret = HI_SUCCESS; + HI_S32 s32DispIdx = 0; + RGN_ATTR_S stRgnAttr; + stRgnAttr.enType = OVERLAY_RGN; + + for (s32DispIdx = 0; s32DispIdx < pstAttr->u32DispNum ; ++s32DispIdx) { + if (pstAttr->astDispAttr[s32DispIdx].enBindedMod != HI_OSD_BINDMOD_VENC) { + stRgnAttr.enType = OVERLAYEX_RGN; + break; + } + } + + if (stRgnAttr.enType == OVERLAYEX_RGN) { + stRgnAttr.unAttr.stOverlayEx.enPixelFmt = PIXEL_FORMAT_ARGB_1555; + stRgnAttr.unAttr.stOverlayEx.u32BgColor = pstAttr->stContent.u32Color; + stRgnAttr.unAttr.stOverlayEx.stSize.u32Width = pstAttr->stContent.stBitmap.u32Width; + stRgnAttr.unAttr.stOverlayEx.stSize.u32Height = pstAttr->stContent.stBitmap.u32Height; + stRgnAttr.unAttr.stOverlayEx.u32CanvasNum = + (HI_OSD_TYPE_BITMAP == pstAttr->stContent.enType) ? 1 : 2; // 2: u32CanvasNum + } else { + stRgnAttr.unAttr.stOverlay.enPixelFmt = PIXEL_FORMAT_ARGB_1555; + stRgnAttr.unAttr.stOverlay.u32BgColor = pstAttr->stContent.u32Color; + stRgnAttr.unAttr.stOverlay.stSize.u32Width = pstAttr->stContent.stBitmap.u32Width; + stRgnAttr.unAttr.stOverlay.stSize.u32Height = pstAttr->stContent.stBitmap.u32Height; + stRgnAttr.unAttr.stOverlay.u32CanvasNum = + (HI_OSD_TYPE_BITMAP == pstAttr->stContent.enType) ? 1 : 2; // 2: u32CanvasNum + } + + s32Ret = HI_MPI_RGN_Create(RgnHdl, &stRgnAttr); + SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, + "HI_MPI_RGN_Create fail,RgnHdl[%d] Error Code: [0x%08X]\n", RgnHdl, s32Ret); + + if (pstAttr->stContent.enType == HI_OSD_TYPE_BITMAP) { + BITMAP_S stBitmap; + stBitmap.enPixelFormat = PIXEL_FORMAT_ARGB_1555; + stBitmap.u32Width = pstAttr->stContent.stBitmap.u32Width; + stBitmap.u32Height = pstAttr->stContent.stBitmap.u32Height; + stBitmap.pData = pstAttr->stContent.stBitmap.pvData; + s32Ret = HI_MPI_RGN_SetBitMap(RgnHdl, &stBitmap); + SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, + "HI_MPI_RGN_SetBitMap fail,RgnHdl[%d] Error Code: [0x%08X]\n", RgnHdl, s32Ret); + } else { + s32Ret = OSD_UpdateTextBitmap(RgnHdl, (HI_OSD_CONTENT_S*)&pstAttr->stContent); + SAMPLE_CHECK_EXPR_RET(s32Ret != HI_SUCCESS, s32Ret, "UpdateTextBitmap fail, ret=%x\n", s32Ret); + } + + for (s32DispIdx = 0; s32DispIdx < pstAttr->u32DispNum; ++s32DispIdx) { + if (pstAttr->astDispAttr[s32DispIdx].bShow) { + OSD_RGNAttach(RgnHdl, &pstAttr->astDispAttr[s32DispIdx]); + } + } + + return HI_SUCCESS; +} + +HI_VOID OSD_Update_Relate_Info(HI_S32 s32OsdIdx) +{ + HI_S32 s32Ret = 0; + + for (s32OsdIdx = 0; s32OsdIdx < HI_OSD_MAX_CNT; ++s32OsdIdx) { + pthread_mutex_lock(&s_stOSDParam[s32OsdIdx].mutexLock); + if (s_stOSDParam[s32OsdIdx].stAttr.stContent.enType == + HI_OSD_TYPE_TIME && s_stOSDParam[s32OsdIdx].bOn) { + /* + * 更新OSD时间字符串 + * Update OSD Time String + */ + OSD_GetTimeStr(&stTime, + s_stOSDParam[s32OsdIdx].stAttr.stContent.szStr, HI_OSD_MAX_STR_LEN); + /* + * 更新OSD文本位图 + * Update OSD Text Bitmap + */ + s32Ret = OSD_UpdateTextBitmap(s32OsdIdx, &s_stOSDParam[s32OsdIdx].stAttr.stContent); + if (HI_SUCCESS != s32Ret) { + pthread_mutex_unlock(&s_stOSDParam[s32OsdIdx].mutexLock); + SAMPLE_PRT("Update Text Bitmap failed\n"); + continue; + } + /* + * 更新OSD属性 + * Update OSD Attribute + */ + s32Ret = OSD_Update(s32OsdIdx, &s_stOSDParam[s32OsdIdx].stAttr); + if (HI_SUCCESS != s32Ret) { + SAMPLE_PRT("Update Attribute failed\n"); + } + } + pthread_mutex_unlock(&s_stOSDParam[s32OsdIdx].mutexLock); + } + + return; +} + +/* + * @brief 时间 osd 更新任务 + * @param[in]pvParam : 不使用 + * @return 0 成功,非零错误码 + * + * @brief time osd update task + * @param[in]pvParam : nonuse + * @return 0 success, non-zero error code. + */ +static HI_VOID* OSD_TimeUpdate(HI_VOID* pvParam) +{ + HI_S32 s32Ret = 0; + HI_S32 s32OsdIdx = 0; + time_t nowTime = 0; + time_t lastTime = 0; + prctl(PR_SET_NAME, __FUNCTION__, 0, 0, 0); + + while (s_bOSDTimeRun) { + nowTime = time(NULL); // also means time(&nowTime) + if (nowTime == lastTime) { + usleep(10000); // 10000:usleep time + continue; + } else { + localtime_r(&nowTime, &stTime); + OSD_Update_Relate_Info(s32OsdIdx); + lastTime = nowTime; /* update time */ + } + usleep(500000); // 500000: usleep time + } + + return NULL; +} + +/* + * @brief osd模块初始化,例如:创建时间OSD更新任务 + * @param[in] pstFonts:osd 字体库 + * @return 0 成功,非零表示错误码 + * + * @brief osd module initialization, eg. create time osd update task. + * @param[in] pstFonts:osd fonts lib + * @return 0 success, non-zero error code. + */ +HI_S32 HI_OSD_Init(const HI_OSD_FONTS_S* pstFonts) +{ + if (!(HI_TRUE != s_bOSDInitFlg)) { + return HI_EINITIALIZED; + } + if (pstFonts != NULL) { + if (!pstFonts->pfnGetFontMod) { + return HI_EINVAL; + } + if (pstFonts->u32FontWidth % BYTE_BITS) { + SAMPLE_PRT("FontWidth must be a multiple of %d.", BYTE_BITS); + return HI_EINVAL; + } + memcpy_s(&s_stOSDFonts, sizeof(HI_OSD_FONTS_S), pstFonts, sizeof(HI_OSD_FONTS_S)); + } else { + memset_s(&s_stOSDFonts, sizeof(HI_OSD_FONTS_S), 0, sizeof(HI_OSD_FONTS_S)); + } + HI_S32 s32Idx = 0; + HI_S32 s32Ret = HI_SUCCESS; + + /* + * 初始化OSD参数 + * Init OSD Param + */ + for (s32Idx = 0; s32Idx < HI_OSD_MAX_CNT; ++s32Idx) { + pthread_mutex_init(&s_stOSDParam[s32Idx].mutexLock, NULL); + pthread_mutex_lock(&s_stOSDParam[s32Idx].mutexLock); + memset_s(&s_stOSDParam[s32Idx], sizeof(OSD_PARAM_S), 0, sizeof(OSD_PARAM_S)); + pthread_mutex_unlock(&s_stOSDParam[s32Idx].mutexLock); + } + + if (pstFonts != NULL) { + /* + * 创建时间OSD更新线程 + * Create Time OSD Update Thread + */ + s_bOSDTimeRun = HI_TRUE; + s32Ret = pthread_create(&s_OSDTimeTskId, NULL, OSD_TimeUpdate, NULL); + if (HI_SUCCESS != s32Ret) { + SAMPLE_PRT("create OSD_TimeUpdate failed:%s\n", strerror(errno)); + return HI_ENORES; + } + } + + s_bOSDInitFlg = HI_TRUE; + return HI_SUCCESS; +} + +/* + * 初始化OSD字体 + * Initialize OSD font + */ +static int OsdInitFont(HI_CHAR *character, HI_U8 **fontMod, HI_S32 *fontModLen) +{ + static const HI_CHAR baseChar = 0x20; + + /* + * 获取ASCII字体库中的字体模组 + * Get Font Mod in ASCII Fontlib + */ + if (!character || !fontMod || !fontModLen) { + return HI_FAILURE; + } + /* + * 如果参数是ASCII字符则返回true,否则返回NULL(0) + * Return true if the parameter is an ASCII character, otherwise NULL (0) + */ + if (!IsAscii(character[0])) { + return HI_FAILURE; + } + HI_U32 offset = (character[0] - baseChar) * (OSD_FONT_MOD_H * OSD_FONT_MOD_W / HI_BYTE_BITS); + *fontMod = (HI_U8 *)G_FONT_LIB + offset; + *fontModLen = OSD_FONT_MOD_H * OSD_FONT_MOD_W / HI_BYTE_BITS; + return HI_SUCCESS; +} + +/* + * 初始化OsdSet库 + * Initialize OsdSet lib + */ +int OsdLibInit(void) +{ + RecurMutexInit(&g_osdMutex); + +# if defined(OSD_FONT_HZK) || defined(OSD_FONT_ASC) + SAMPLE_PRT("==================success=================\n"); + HI_OSD_FONTS_S stOsdFonts; + stOsdFonts.u32FontWidth = OSD_FONT_MOD_W; + stOsdFonts.u32FontHeight = OSD_FONT_MOD_H; + stOsdFonts.pfnGetFontMod = OsdInitFont; + return HI_OSD_Init(&stOsdFonts); +# else + SAMPLE_PRT("##################success##################\n"); + return HI_OSD_Init(NULL); +# endif +} + +HI_VOID Osd_Param_Config(const HI_OSD_ATTR_S* pstAttr, OSD_PARAM_S* pstOsdParam) +{ + /* + * 更新属性 + * Update Attribute + */ + pstOsdParam->stAttr.stContent.u32Color = pstAttr->stContent.u32Color; + pstOsdParam->stAttr.stContent.u32BgColor = pstAttr->stContent.u32BgColor; + + if (HI_OSD_TYPE_BITMAP != pstAttr->stContent.enType) { + if (HI_OSD_TYPE_TIME == pstAttr->stContent.enType) { + /* + * 时间类型:更新时间字符串 + * Time Type: Update time string + */ + pstOsdParam->stAttr.stContent.enTimeFmt = pstAttr->stContent.enTimeFmt; + OSD_GetTimeStr(NULL, ((HI_OSD_ATTR_S*)pstAttr)->stContent.szStr, HI_OSD_MAX_STR_LEN); + } + + /* + * 更新字符串 + * Update string + */ + if (snprintf_s(pstOsdParam->stAttr.stContent.szStr, HI_OSD_MAX_STR_LEN, + HI_OSD_MAX_STR_LEN - 1, "%s", pstAttr->stContent.szStr) < 0) { + HI_ASSERT(0); + } + + pstOsdParam->stAttr.stContent.stBitmap.enPixelFormat = PIXEL_FORMAT_ARGB_1555; + ((HI_OSD_ATTR_S*)pstAttr)->stContent.stBitmap.u32Width = + pstAttr->stContent.stFontSize.u32Width * strnlen(pstOsdParam->stAttr.stContent.szStr, HI_OSD_MAX_STR_LEN); + ((HI_OSD_ATTR_S*)pstAttr)->stContent.stBitmap.u32Height= pstAttr->stContent.stFontSize.u32Height; + pstOsdParam->stAttr.stContent.stFontSize = pstAttr->stContent.stFontSize; + } else { + pstOsdParam->stAttr.stContent.stBitmap.enPixelFormat = pstAttr->stContent.stBitmap.enPixelFormat; + pstOsdParam->stAttr.stContent.stBitmap.u64PhyAddr = pstAttr->stContent.stBitmap.u64PhyAddr; + pstOsdParam->stAttr.stContent.stBitmap.pvData = pstAttr->stContent.stBitmap.pvData; + } + pstOsdParam->stAttr.stContent.stBitmap.u32Width = pstAttr->stContent.stBitmap.u32Width; + pstOsdParam->stAttr.stContent.stBitmap.u32Height = pstAttr->stContent.stBitmap.u32Height; + pstOsdParam->stAttr.stContent.enType = pstAttr->stContent.enType; + + return; +} + +static HI_S32 OSD_Update_RGN_Content(const HI_OSD_ATTR_S* pstAttr, OSD_PARAM_S* pstOsdParam, HI_S32 s32OsdIdx) +{ + HI_S32 s32Ret = HI_SUCCESS; + /* + * 更新RGN内容 + * Update RGN Content + */ + if (pstAttr->stContent.enType == HI_OSD_TYPE_BITMAP) { + BITMAP_S stBitmap; + stBitmap.enPixelFormat = PIXEL_FORMAT_ARGB_1555; + stBitmap.u32Width = pstAttr->stContent.stBitmap.u32Width; + stBitmap.u32Height = pstAttr->stContent.stBitmap.u32Height; + stBitmap.pData = pstAttr->stContent.stBitmap.pvData; + /* + * 设置区域位图,即对区域进行位图填充 + * Set the area bitmap, that is, fill the area with a bitmap + */ + s32Ret = HI_MPI_RGN_SetBitMap(s32OsdIdx, &stBitmap); + SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, FAIL, "HI_MPI_RGN_SetBitMap. s32Ret: 0x%x\n", s32Ret); + } else { + /* + * 时间/字符串类型:更新文本位图 + * Time/String Type: Update text bitmap + */ + s32Ret = OSD_UpdateTextBitmap(s32OsdIdx, (HI_OSD_CONTENT_S*)&pstOsdParam->stAttr.stContent); + SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, FAIL, "OSD_UpdateTextBitmap fail, err(%#x)\n", s32Ret); + } + + HI_S32 s32DispIdx = 0; + for (s32DispIdx = 0; s32DispIdx < pstAttr->u32DispNum ; ++s32DispIdx) { + if (HI_TRUE == pstAttr->astDispAttr[s32DispIdx].bShow && HI_FALSE == + pstOsdParam->stAttr.astDispAttr[s32DispIdx].bShow) { + OSD_RGNAttach(s32OsdIdx, &pstAttr->astDispAttr[s32DispIdx]); + } else if (HI_FALSE == pstAttr->astDispAttr[s32DispIdx].bShow && HI_TRUE == + pstOsdParam->stAttr.astDispAttr[s32DispIdx].bShow) { + OSD_RGNDetach(s32OsdIdx, &pstOsdParam->stAttr.astDispAttr[s32DispIdx]); + } + } + s32Ret = OSD_Update(s32OsdIdx, pstAttr); + SAMPLE_CHECK_EXPR_GOTO(s32Ret != HI_SUCCESS, FAIL, "OSD_Update fail, err(%#x)\n", s32Ret); + + return s32Ret; + +FAIL: + pthread_mutex_unlock(&pstOsdParam->mutexLock); + return s32Ret; +} + +/* + * @brief 设置osd属性 + * @param[in] s32OsdIdx:osd索引,范围[0,HI_OSD_MAX_CNT) + * @param[in] pstAttr:osd配置属性 + * @return 0 成功,非零错误码 + * + * @brief set osd attribute. + * @param[in] s32OsdIdx:osd index, range[0,HI_OSD_MAX_CNT) + * @param[in] pstAttr:osd configure attribute + * @return 0 success,non-zero error code. + */ +HI_S32 HI_OSD_SetAttr(HI_S32 s32OsdIdx, const HI_OSD_ATTR_S* pstAttr) +{ + /* + * 检查模块是否初始化成功 + * Check Module Init or not + */ + HI_ASSERT(HI_TRUE == s_bOSDInitFlg); + /* + * 检查输入的参数 + * Check Input Param + */ + HI_ASSERT(s32OsdIdx >= 0); + HI_ASSERT(HI_OSD_MAX_CNT > s32OsdIdx); + HI_ASSERT(pstAttr); + HI_ASSERT(HI_OSD_MAX_DISP_CNT >= pstAttr->u32DispNum); + + if (HI_OSD_TYPE_BITMAP == pstAttr->stContent.enType) { + if (!pstAttr->stContent.stBitmap.pvData) { + return HI_FAILURE; + } + } else { + if (s_stOSDFonts.pfnGetFontMod == NULL) { + SAMPLE_PRT("The font library is not registered,only support bitmaps OSD\n"); + return HI_FAILURE; + } + } + + HI_S32 s32Ret = HI_SUCCESS; + OSD_PARAM_S* pstOsdParam = &s_stOSDParam[s32OsdIdx]; + pthread_mutex_lock(&pstOsdParam->mutexLock); + HI_BOOL bOn = pstOsdParam->bOn; + + /* + * 更新属性 + * Update Attribute + */ + Osd_Param_Config(pstAttr, pstOsdParam); + if (bOn) { + if (pstOsdParam->stMaxSize.u32Width < pstOsdParam->stAttr.stContent.stBitmap.u32Width + || pstOsdParam->stMaxSize.u32Height < pstOsdParam->stAttr.stContent.stBitmap.u32Height) { + SAMPLE_PRT("RGN(%d) size increase[%d,%d->%d,%d], rebuild\n", s32OsdIdx, + pstOsdParam->stMaxSize.u32Width, pstOsdParam->stMaxSize.u32Height, + pstAttr->stContent.stBitmap.u32Width, pstAttr->stContent.stBitmap.u32Height); + /* + * 销毁区域 + * Destory region + */ + s32Ret = OSD_DestroyRGN(s32OsdIdx, &pstOsdParam->stAttr); + if (s32Ret != HI_SUCCESS) { + pthread_mutex_unlock(&pstOsdParam->mutexLock); + return s32Ret; + } + + s32Ret = OSD_CreateRGN(s32OsdIdx, pstAttr); + if (s32Ret != HI_SUCCESS) { + pthread_mutex_unlock(&pstOsdParam->mutexLock); + return s32Ret; + } + } else { + OSD_Update_RGN_Content(pstAttr, pstOsdParam, s32OsdIdx); + } + } + + memcpy_s(pstOsdParam->stAttr.astDispAttr, sizeof(HI_OSD_DISP_ATTR_S) * HI_OSD_MAX_DISP_CNT, + pstAttr->astDispAttr, sizeof(HI_OSD_DISP_ATTR_S) * HI_OSD_MAX_DISP_CNT); + pstOsdParam->stAttr.u32DispNum = pstAttr->u32DispNum; + pstOsdParam->stMaxSize.u32Width = + max(pstOsdParam->stMaxSize.u32Width, pstOsdParam->stAttr.stContent.stBitmap.u32Width); + pstOsdParam->stMaxSize.u32Height= + max(pstOsdParam->stMaxSize.u32Height, pstOsdParam->stAttr.stContent.stBitmap.u32Height); + pstOsdParam->bInit = HI_TRUE; + pthread_mutex_unlock(&pstOsdParam->mutexLock); + + return HI_SUCCESS; +} + +static HI_S32 OSD_Start(HI_S32 s32OsdIdx) +{ + HI_S32 s32Ret = HI_SUCCESS; + OSD_PARAM_S* pstOsdParam = &s_stOSDParam[s32OsdIdx]; + + /* + * 时间OSD:更新时间字符串和位图 + * Time OSD: Update time string and bitmap + */ + if (HI_OSD_TYPE_TIME == pstOsdParam->stAttr.stContent.enType) { + OSD_GetTimeStr(NULL, pstOsdParam->stAttr.stContent.szStr, HI_OSD_MAX_STR_LEN); + } + + s32Ret = OSD_CreateRGN(s32OsdIdx, &pstOsdParam->stAttr); + if (HI_SUCCESS != s32Ret) { + SAMPLE_PRT("OSD_CreateRGN s32OsdIdx[%d] failed:[0x%08X]\n", s32OsdIdx, s32Ret); + return s32Ret; + } + pstOsdParam->bOn = HI_TRUE; + return HI_SUCCESS; +} + +/* + * @brief 按索引启动 osd + * @param[in] s32OsdIdx:osd 索引,范围[0,HI_OSD_MAX_CNT) + * @return 0 成功,非零错误码 + * + * @brief start osd by index. + * @param[in] s32OsdIdx:osd index, range[0,HI_OSD_MAX_CNT) + * @return 0 success,non-zero error code. + */ +HI_S32 HI_OSD_Start(HI_S32 s32OsdIdx) +{ + /* + * 检查模块是否初始化成功 + * Check Module Init or not + */ + HI_ASSERT(HI_TRUE == s_bOSDInitFlg); + /* + * 检查输入的参数 + * Check Input Param + */ + HI_ASSERT(s32OsdIdx >= 0); + HI_ASSERT(HI_OSD_MAX_CNT > s32OsdIdx); + + HI_S32 s32Ret = HI_SUCCESS; + OSD_PARAM_S* pstOsdParam = &s_stOSDParam[s32OsdIdx]; + + pthread_mutex_lock(&pstOsdParam->mutexLock); + + /* + * 检查OSD属性是否初始化 + * Check OSD Attrbute init or not + */ + if (!pstOsdParam->bInit) { + pthread_mutex_unlock(&pstOsdParam->mutexLock); + SAMPLE_PRT("OSD[%d] not init yet!\n", s32OsdIdx); + return HI_EINVAL; + } + + /* + * 检查OSD是否停止 + * Check OSD stop or not + */ + if (pstOsdParam->bOn) { + pthread_mutex_unlock(&pstOsdParam->mutexLock); + SAMPLE_PRT("OSD[%d] has already started!\n", s32OsdIdx); + return HI_SUCCESS; + } + + s32Ret = OSD_Start(s32OsdIdx); + pthread_mutex_unlock(&pstOsdParam->mutexLock); + return s32Ret; +} + +/* + * 在OsdSet中设置指定区域的属性 + * Set attributes for the specified region in OsdSet + */ +int OsdsSetRgn(OsdSet* self, int rgnHnd, const HI_OSD_ATTR_S* rgnAttr) +{ + HI_ASSERT(self); + HI_ASSERT(rgnHnd >= 0 && rgnHnd < HI_OSD_MAX_CNT); + HI_ASSERT(g_osdHndPool[rgnHnd] && g_osdHndPool[rgnHnd] == (void*)self); // not need lock + HI_OSD_ATTR_S attr; + int ret; + + if (!rgnAttr) { // hidden the region + if (memset_s(&attr, sizeof(attr), 0, sizeof(attr)) != EOK) { + HI_ASSERT(0); + } + attr.u32DispNum = 1; + attr.astDispAttr[0].bShow = HI_FALSE; + } else { + attr = *rgnAttr; + } + + attr.astDispAttr[0].enBindedMod = self->bindMod; + attr.astDispAttr[0].ModHdl = self->modHnd; + attr.astDispAttr[0].ChnHdl = self->chnHnd; + + ret = HI_OSD_SetAttr(rgnHnd, &attr); + SAMPLE_CHECK_EXPR_RET(ret, "HI_OSD_SetAttr FAIL, ret=%d\n", ret); + + ret = HI_OSD_Start(rgnHnd); + SAMPLE_CHECK_EXPR_RET(ret, "HI_OSD_Start FAIL, ret=%d\n", ret); + return 0; +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ \ No newline at end of file diff --git a/src/modules/isp/mpp/osd_img.h b/src/modules/isp/mpp/osd_img.h new file mode 100755 index 0000000..fee49de --- /dev/null +++ b/src/modules/isp/mpp/osd_img.h @@ -0,0 +1,287 @@ +/* + * Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED. + * 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. + */ + +#ifndef OSD_IMG_H +#define OSD_IMG_H + +#include +#include +#include +#include "hi_comm_region.h" +#include "hi_common.h" + +#if __cplusplus +extern "C" { +#endif + +#define HI_OSD_MAX_CNT (16) // Maximum OSD Count +#define HI_OSD_MAX_DISP_CNT (2) // Maximum Display Count for Each OSD +#define HI_OSD_MAX_STR_LEN (64) // String OSD Maximum Length + +typedef HI_S32 HI_ERRNO; + +/* + * 常见的错误码 + * Common error code + */ +#define HI_ERRNO_COMMON_BASE 0 +#define HI_ERRNO_COMMON_COUNT 256 + +#define HI_EUNKNOWN (HI_ERRNO)(HI_ERRNO_COMMON_BASE + 1) +#define HI_EOTHER (HI_ERRNO)(HI_ERRNO_COMMON_BASE + 2) +#define HI_EINTER (HI_ERRNO)(HI_ERRNO_COMMON_BASE + 3) +#define HI_EVERSION (HI_ERRNO)(HI_ERRNO_COMMON_BASE + 4) +#define HI_EPAERM (HI_ERRNO)(HI_ERRNO_COMMON_BASE + 5) +#define HI_EINVAL (HI_ERRNO)(HI_ERRNO_COMMON_BASE + 6) +#define HI_ENOINIT (HI_ERRNO)(HI_ERRNO_COMMON_BASE + 7) +#define HI_ENOTREADY (HI_ERRNO)(HI_ERRNO_COMMON_BASE + 8) +#define HI_ENORES (HI_ERRNO)(HI_ERRNO_COMMON_BASE + 9) +#define HI_EEXIST (HI_ERRNO)(HI_ERRNO_COMMON_BASE + 10) +#define HI_ELOST (HI_ERRNO)(HI_ERRNO_COMMON_BASE + 11) +#define HI_ENOOP (HI_ERRNO)(HI_ERRNO_COMMON_BASE + 12) +#define HI_EBUSY (HI_ERRNO)(HI_ERRNO_COMMON_BASE + 13) +#define HI_EIDLE (HI_ERRNO)(HI_ERRNO_COMMON_BASE + 14) +#define HI_EFULL (HI_ERRNO)(HI_ERRNO_COMMON_BASE + 15) +#define HI_EEMPTY (HI_ERRNO)(HI_ERRNO_COMMON_BASE + 16) +#define HI_EUNDERFLOW (HI_ERRNO)(HI_ERRNO_COMMON_BASE + 17) +#define HI_EOVERFLOW (HI_ERRNO)(HI_ERRNO_COMMON_BASE + 18) +#define HI_EACCES (HI_ERRNO)(HI_ERRNO_COMMON_BASE + 19) +#define HI_EINTR (HI_ERRNO)(HI_ERRNO_COMMON_BASE + 20) +#define HI_ECONTINUE (HI_ERRNO)(HI_ERRNO_COMMON_BASE + 21) +#define HI_EOVER (HI_ERRNO)(HI_ERRNO_COMMON_BASE + 22) +#define HI_ERRNO_COMMON_BOTTOM (HI_ERRNO)(HI_ERRNO_COMMON_BASE + 23) + +/* + * 自定义错误码 + * Custom error code + */ +#define HI_ERRNO_BASE (HI_ERRNO)(HI_ERRNO_COMMON_BASE + HI_ERRNO_COMMON_COUNT) +#define HI_EINITIALIZED (HI_ERRNO)(HI_ERRNO_BASE + 1) // Repeated initialization +#define HI_ERRNO_CUSTOM_BOTTOM (HI_ERRNO)(HI_ERRNO_BASE + 2) // Number of error numbers that have been defined + +/* + * pthread互斥锁 + * pthread mutex lock + */ +static inline void MutexLock(pthread_mutex_t* mutex) +{ + if (pthread_mutex_lock(mutex) != 0) { + HI_ASSERT(0); + } +} + +/* + * 解除锁定mutex所指向的互斥锁 + * pthread mutex unlock + */ +static inline void MutexUnlock(pthread_mutex_t* mutex) +{ + if (pthread_mutex_unlock(mutex) != 0) { + HI_ASSERT(0); + } +} + +typedef HI_S32 (*HI_OSD_GETFONTMOD_CALLBACK_FN_PTR)(HI_CHAR* Character, HI_U8** FontMod, HI_S32* FontModLen); + +/* + * OSD字体库 + * OSD Fonts Lib + */ +typedef struct hiOSD_FONTS_S { + /* OSD Lib Font Size, in pixel */ + HI_U32 u32FontWidth; + HI_U32 u32FontHeight; + HI_OSD_GETFONTMOD_CALLBACK_FN_PTR pfnGetFontMod; +} HI_OSD_FONTS_S; + +/* + * OSD像素格式枚举 + * OSD pixel format enum + */ +typedef enum hiOSD_PIXEL_FMT_E { + HI_OSD_PIXEL_FMT_RGB1555 = 0, + HI_OSD_PIXEL_FMT_BUTT +} HI_OSD_PIXEL_FMT_E; + +/* + * OSD位图属性 + * OSD Bitmap Attribute + */ +typedef struct hiOSD_BITMAP_ATTR_S { + HI_OSD_PIXEL_FMT_E enPixelFormat; + HI_U32 u32Width; + HI_U32 u32Height; + HI_U64 u64PhyAddr; + HI_VOID* pvData; +} HI_OSD_BITMAP_ATTR_S; + +/* + * OSD类型枚举 + * OSD Type Enum + */ +typedef enum hiOSD_TYPE_E { + HI_OSD_TYPE_TIME = 0, + HI_OSD_TYPE_STRING, + HI_OSD_TYPE_BITMAP, + HI_OSD_TYPE_BUTT +} HI_OSD_TYPE_E; + +/* + * OSD时间格式枚举 + * OSD Time Format Enum + */ +typedef enum hiOSD_TIMEFMT_E { + HI_OSD_TIMEFMT_YMD24H = 0, // eg. 2017-03-10 23:00:59 + HI_OSD_TIMEFMT_BUTT +} HI_OSD_TIMEFMT_E; + +/* + * OSD绑定模块枚举 + * OSD Binded Module enum + */ +typedef enum hiOSD_BIND_MOD_E { + HI_OSD_BINDMOD_VI = 0, + HI_OSD_BINDMOD_VPSS, + HI_OSD_BINDMOD_AVS, + HI_OSD_BINDMOD_VENC, + HI_OSD_BINDMOD_VO, + HI_OSD_BINDMOD_BUTT +} HI_OSD_BIND_MOD_E; + +typedef enum hiOSD_COORDINATE_E { + HI_OSD_COORDINATE_RATIO_COOR = 0, + HI_OSD_COORDINATE_ABS_COOR +} HI_OSD_COORDINATE_E; + +/* + * OSD显示属性 + * OSD Display Attribute + */ +typedef struct hiOSD_DISP_ATTR_S { + HI_BOOL bShow; + HI_OSD_BIND_MOD_E enBindedMod; + HI_HANDLE ModHdl; + HI_HANDLE ChnHdl; + HI_U32 u32FgAlpha; + HI_U32 u32BgAlpha; + HI_OSD_COORDINATE_E enCoordinate; // Coordinate mode of the osd start Position + POINT_S stStartPos; // OSD Start Position + ATTACH_DEST_E enAttachDest; // only for venc + HI_S32 s32Batch; +} HI_OSD_DISP_ATTR_S; + +/* + * OSD内容 + * OSD Content + */ +typedef struct hiOSD_CONTENT_S { + HI_OSD_TYPE_E enType; + HI_OSD_TIMEFMT_E enTimeFmt; + HI_U32 u32Color; // string color + HI_U32 u32BgColor; + HI_CHAR szStr[HI_OSD_MAX_STR_LEN]; + SIZE_S stFontSize; + HI_OSD_BITMAP_ATTR_S stBitmap; // Pixel Format: Only Support RGB1555 for now +} HI_OSD_CONTENT_S; + +/* + * OSD属性 + * OSD attribution + */ +typedef struct hiOSD_ATTR_S { + HI_U32 u32DispNum; /* 1Binded Display Number for this OSD */ + HI_OSD_DISP_ATTR_S astDispAttr[HI_OSD_MAX_DISP_CNT]; + HI_OSD_CONTENT_S stContent; +} HI_OSD_ATTR_S; + +/* + * OSD参数 + * OSD Parameter + */ +typedef struct tagOSD_PARAM_S { + HI_OSD_ATTR_S stAttr; + SIZE_S stMaxSize; + pthread_mutex_t mutexLock; + HI_BOOL bInit; /* OSD Attribute Set or not, Canbe modified only HI_OSD_SetAttr */ + HI_BOOL bOn; /* OSD On/Off Flag, Canbe modified only by HI_OSD_Start/HI_OSD_Stop */ +} OSD_PARAM_S; + +typedef struct hiOSD_TEXTBITMAP_S { + RGN_HANDLE rgnHdl; + HI_OSD_CONTENT_S pstContent; + RGN_CANVAS_INFO_S stCanvasInfo; +} HI_OSD_TEXTBITMAP_S; + +/* + * OSD区域设置 + * OSD region set + */ +struct OsdSet { + // OSD Binded Module: Static + HI_OSD_BIND_MOD_E bindMod; + // Binded Module Handle: Static eg.VcapPipeHdl, VpssHdl, StitchHdl, DispHdl, 0 + HI_U32 modHnd; + // Binded Channel Handle: Static eg.PipeChnHdl, VPortHdl, StitchPortHdl, WndHdl, VencHdl + HI_U32 chnHnd; +}; + +typedef struct OsdSet OsdSet; + +/* + * 在OsdSet中创建区域 + * Create a region in OsdSet + */ +int OsdsCreateRgn(OsdSet* self); + +/* + * 设置文本区域的属性值 + * Set the attribute value of the text region + */ +int TxtRgnInit(HI_OSD_ATTR_S* rgnAttr, const char* str, uint32_t begX, uint32_t begY, uint32_t color); + +/* + * 销毁OsdSet中的所有区域 + * Destroy all regions in OsdSet + */ +void OsdsClear(OsdSet* self); + +/* + * 在OsdSet中设置指定区域的属性 + * Set attributes for the specified region in OsdSet + */ +int OsdsSetRgn(OsdSet* self, int rgnHnd, const HI_OSD_ATTR_S* rgnAttr); + +/* + * 创建OsdSet + * Creat OsdSet + */ +OsdSet* OsdsCreate(HI_OSD_BIND_MOD_E bindMod, HI_U32 modHnd, HI_U32 chnHnd); + +/* + * 销毁OsdSet + * Destory OsdSet + */ +void OsdsDestroy(OsdSet* self); + +/* + * 初始化OsdSet库 + * Initialize OsdSet lib + */ +int OsdLibInit(void); + +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/src/modules/isp/mpp/sample_comm_ive.c b/src/modules/isp/mpp/sample_comm_ive.c new file mode 100755 index 0000000..478cb3b --- /dev/null +++ b/src/modules/isp/mpp/sample_comm_ive.c @@ -0,0 +1,1143 @@ +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "hi_common.h" +#include "hi_comm_video.h" +#include "hi_comm_sys.h" +#include "hi_comm_vgs.h" +#include "hi_comm_vi.h" +#include "hi_comm_vo.h" +#include "mpi_vb.h" +#include "mpi_sys.h" +#include "mpi_vi.h" +#include "mpi_vo.h" +#include "mpi_vgs.h" + +#include "sample_comm_ive.h" + +static HI_BOOL bMpiInit = HI_FALSE; + +HI_U16 SAMPLE_COMM_IVE_CalcStride(HI_U32 u32Width, HI_U8 u8Align) +{ + return (u32Width + (u8Align - u32Width % u8Align) % u8Align); +} + +static HI_S32 SAMPLE_IVE_MPI_Init(HI_VOID) +{ + HI_S32 s32Ret; + + HI_MPI_SYS_Exit(); + + s32Ret = HI_MPI_SYS_Init(); + if (HI_SUCCESS != s32Ret) + { + SAMPLE_PRT("HI_MPI_SYS_Init fail,Error(%#x)\n", s32Ret); + return s32Ret; + } + + return HI_SUCCESS; +} + + +HI_VOID SAMPLE_COMM_IVE_CheckIveMpiInit(HI_VOID) +{ + if (HI_FALSE == bMpiInit) + { + if (SAMPLE_IVE_MPI_Init()) + { + SAMPLE_PRT("Ive mpi init failed!\n"); + exit(-1); + } + bMpiInit = HI_TRUE; + } +} +HI_S32 SAMPLE_COMM_IVE_IveMpiExit(HI_VOID) +{ + bMpiInit = HI_FALSE; + if (HI_MPI_SYS_Exit()) + { + SAMPLE_PRT("Sys exit failed!\n"); + return HI_FAILURE; + } + + return HI_SUCCESS; +} + +HI_S32 SAMPLE_COMM_VGS_FillRect(VIDEO_FRAME_INFO_S* pstFrmInfo, SAMPLE_RECT_ARRAY_S* pstRect, HI_U32 u32Color) +{ + VGS_HANDLE VgsHandle = -1; + HI_S32 s32Ret = HI_SUCCESS; + HI_U16 i; + VGS_TASK_ATTR_S stVgsTask; + VGS_ADD_COVER_S stVgsAddCover; + + if (0 == pstRect->u16Num) + { + return s32Ret; + } + s32Ret = HI_MPI_VGS_BeginJob(&VgsHandle); + if (s32Ret != HI_SUCCESS) + { + SAMPLE_PRT("Vgs begin job fail,Error(%#x)\n", s32Ret); + return s32Ret; + } + + memcpy(&stVgsTask.stImgIn, pstFrmInfo, sizeof(VIDEO_FRAME_INFO_S)); + memcpy(&stVgsTask.stImgOut, pstFrmInfo, sizeof(VIDEO_FRAME_INFO_S)); + + stVgsAddCover.enCoverType = COVER_QUAD_RANGLE; + stVgsAddCover.u32Color = u32Color; + for (i = 0; i < pstRect->u16Num; i++) + { + stVgsAddCover.stQuadRangle.bSolid = HI_FALSE; + stVgsAddCover.stQuadRangle.u32Thick = 2; + memcpy(stVgsAddCover.stQuadRangle.stPoint, pstRect->astRect[i].astPoint, sizeof(pstRect->astRect[i].astPoint)); + s32Ret = HI_MPI_VGS_AddCoverTask(VgsHandle, &stVgsTask, &stVgsAddCover); + if (s32Ret != HI_SUCCESS) + { + SAMPLE_PRT("HI_MPI_VGS_AddCoverTask fail,Error(%#x)\n", s32Ret); + HI_MPI_VGS_CancelJob(VgsHandle); + return s32Ret; + } + } + + s32Ret = HI_MPI_VGS_EndJob(VgsHandle); + if (s32Ret != HI_SUCCESS) + { + SAMPLE_PRT("HI_MPI_VGS_EndJob fail,Error(%#x)\n", s32Ret); + HI_MPI_VGS_CancelJob(VgsHandle); + return s32Ret; + } + + return s32Ret; + +} + +HI_S32 SAMPLE_COMM_IVE_ReadFile(IVE_IMAGE_S* pstImg, FILE* pFp) +{ + HI_U16 y; + HI_U8* pU8; + HI_U16 height; + HI_U16 width; + HI_U16 loop; + HI_S32 s32Ret; + + (HI_VOID)fgetc(pFp); + if (feof(pFp)) + { + SAMPLE_PRT("end of file!\n"); + s32Ret = fseek(pFp, 0 , SEEK_SET ); + if (0 != s32Ret) + { + SAMPLE_PRT("fseek failed!\n"); + return s32Ret; + } + + } + else + { + s32Ret = fseek(pFp, -1 , SEEK_CUR ); + if (0 != s32Ret) + { + SAMPLE_PRT("fseek failed!\n"); + return s32Ret; + } + } + + //if (feof(pFp)) + //{ + // SAMPLE_PRT("end of file!\n"); + // fseek(pFp, 0 , SEEK_SET); + //} + + height = pstImg->u32Height; + width = pstImg->u32Width; + + switch (pstImg->enType) + { + case IVE_IMAGE_TYPE_U8C1: + { + pU8 = (HI_U8 *)(HI_UL)pstImg->au64VirAddr[0]; + for (y = 0; y < height; y++) + { + if ( 1 != fread(pU8, width, 1, pFp)) + { + SAMPLE_PRT("Read file fail\n"); + return HI_FAILURE; + } + + pU8 += pstImg->au32Stride[0]; + } + } + break; + case IVE_IMAGE_TYPE_YUV420SP: + { + pU8 = (HI_U8 *)(HI_UL)pstImg->au64VirAddr[0]; + for (y = 0; y < height; y++) + { + if ( 1 != fread(pU8, width, 1, pFp)) + { + SAMPLE_PRT("Read file fail\n"); + return HI_FAILURE; + } + + pU8 += pstImg->au32Stride[0]; + } + + pU8 = (HI_U8 *)(HI_UL)pstImg->au64VirAddr[1]; + for (y = 0; y < height / 2; y++) + { + if ( 1 != fread(pU8, width, 1, pFp)) + { + SAMPLE_PRT("Read file fail\n"); + return HI_FAILURE; + } + + pU8 += pstImg->au32Stride[1]; + } + } + break; + case IVE_IMAGE_TYPE_YUV422SP: + { + pU8 = (HI_U8 *)(HI_UL)pstImg->au64VirAddr[0]; + for (y = 0; y < height; y++) + { + if ( 1 != fread(pU8, width, 1, pFp)) + { + SAMPLE_PRT("Read file fail\n"); + return HI_FAILURE; + } + + pU8 += pstImg->au32Stride[0]; + } + + pU8 = (HI_U8 *)(HI_UL)pstImg->au64VirAddr[1]; + for (y = 0; y < height; y++) + { + if ( 1 != fread(pU8, width, 1, pFp)) + { + SAMPLE_PRT("Read file fail\n"); + return HI_FAILURE; + } + + pU8 += pstImg->au32Stride[1]; + } + } + break; + case IVE_IMAGE_TYPE_U8C3_PACKAGE: + { + pU8 = (HI_U8 *)(HI_UL)pstImg->au64VirAddr[0]; + for (y = 0; y < height; y++) + { + if ( 1 != fread(pU8, width * 3, 1, pFp)) + { + SAMPLE_PRT("Read file fail\n"); + return HI_FAILURE; + } + + pU8 += pstImg->au32Stride[0] * 3; + } + + } + break; + case IVE_IMAGE_TYPE_U8C3_PLANAR: + { + for (loop = 0; loop < 3; loop++) + { + pU8 = (HI_U8 *)(HI_UL)pstImg->au64VirAddr[loop]; + for (y = 0; y < height; y++) + { + if ( 1 != fread(pU8, width, 1, pFp)) + { + SAMPLE_PRT("Read file fail\n"); + return HI_FAILURE; + } + + pU8 += pstImg->au32Stride[loop]; + } + } + + } + break; + case IVE_IMAGE_TYPE_S16C1: + case IVE_IMAGE_TYPE_U16C1: + { + pU8 = (HI_U8 *)(HI_UL)pstImg->au64VirAddr[0]; + for ( y = 0; y < height; y++ ) + { + if ( sizeof(HI_U16) != fread(pU8, width, sizeof(HI_U16), pFp) ) + { + SAMPLE_PRT("Read file fail\n"); + return HI_FAILURE; + } + + pU8 += pstImg->au32Stride[0] * 2; + } + } + break; + default: + break; + } + + return HI_SUCCESS; +} + +HI_S32 SAMPLE_COMM_IVE_WriteFile(IVE_IMAGE_S* pstImg, FILE* pFp) +{ + HI_U16 y; + HI_U8* pU8; + HI_U16 height; + HI_U16 width; + + height = pstImg->u32Height; + width = pstImg->u32Width; + + switch (pstImg->enType) + { + case IVE_IMAGE_TYPE_U8C1: + case IVE_IMAGE_TYPE_S8C1: + { + pU8 = (HI_U8 *)(HI_UL)pstImg->au64VirAddr[0]; + for (y = 0; y < height; y++) + { + if ( 1 != fwrite(pU8, width, 1, pFp)) + { + SAMPLE_PRT("Write file fail\n"); + return HI_FAILURE; + } + + pU8 += pstImg->au32Stride[0]; + } + } + break; + case IVE_IMAGE_TYPE_YUV420SP: + { + pU8 = (HI_U8 *)(HI_UL)pstImg->au64VirAddr[0]; + for (y = 0; y < height; y++) + { + if ( width != fwrite(pU8, 1, width, pFp)) + { + SAMPLE_PRT("Write file fail\n"); + return HI_FAILURE; + } + + pU8 += pstImg->au32Stride[0]; + } + + pU8 = (HI_U8 *)(HI_UL)pstImg->au64VirAddr[1]; + for (y = 0; y < height / 2; y++) + { + if ( width != fwrite(pU8, 1, width, pFp)) + { + SAMPLE_PRT("Write file fail\n"); + return HI_FAILURE; + } + + pU8 += pstImg->au32Stride[1]; + } + } + break; + case IVE_IMAGE_TYPE_YUV422SP: + { + pU8 = (HI_U8 *)(HI_UL)pstImg->au64VirAddr[0]; + for (y = 0; y < height; y++) + { + if ( width != fwrite(pU8, 1, width, pFp)) + { + SAMPLE_PRT("Write file fail\n"); + return HI_FAILURE; + } + + pU8 += pstImg->au32Stride[0]; + } + + pU8 = (HI_U8 *)(HI_UL)pstImg->au64VirAddr[1]; + for (y = 0; y < height; y++) + { + if ( width != fwrite(pU8, 1, width, pFp)) + { + SAMPLE_PRT("Write file fail\n"); + return HI_FAILURE; + } + + pU8 += pstImg->au32Stride[1]; + } + } + break; + case IVE_IMAGE_TYPE_S16C1: + case IVE_IMAGE_TYPE_U16C1: + { + pU8 = (HI_U8 *)(HI_UL)pstImg->au64VirAddr[0]; + for ( y = 0; y < height; y++ ) + { + if ( sizeof(HI_U16) != fwrite(pU8, width, sizeof(HI_U16), pFp) ) + { + SAMPLE_PRT("Write file fail\n"); + return HI_FAILURE; + } + + pU8 += pstImg->au32Stride[0] * 2; + } + } + break; + case IVE_IMAGE_TYPE_U32C1: + { + + pU8 = (HI_U8 *)(HI_UL)pstImg->au64VirAddr[0]; + for ( y = 0; y < height; y++ ) + { + if ( width != fwrite(pU8, sizeof(HI_U32), width, pFp) ) + { + SAMPLE_PRT("Write file fail\n"); + return HI_FAILURE; + } + + pU8 += pstImg->au32Stride[0] * 4; + } + break; + } + + default: + break; + } + + return HI_SUCCESS; +} + +HI_VOID SAMPLE_COMM_IVE_BlobToRect(IVE_CCBLOB_S *pstBlob, SAMPLE_RECT_ARRAY_S *pstRect, + HI_U16 u16RectMaxNum,HI_U16 u16AreaThrStep, + HI_U32 u32SrcWidth, HI_U32 u32SrcHeight, + HI_U32 u32DstWidth,HI_U32 u32DstHeight) +{ + HI_U16 u16Num; + HI_U16 i,j,k; + HI_U16 u16Thr= 0; + HI_BOOL bValid; + + if(pstBlob->u8RegionNum > u16RectMaxNum) + { + u16Thr = pstBlob->u16CurAreaThr; + do + { + u16Num = 0; + u16Thr += u16AreaThrStep; + for(i = 0;i < 254;i++) + { + if(pstBlob->astRegion[i].u32Area > u16Thr) + { + u16Num++; + } + } + }while(u16Num > u16RectMaxNum); + } + + u16Num = 0; + + for(i = 0;i < 254;i++) + { + if(pstBlob->astRegion[i].u32Area > u16Thr) + { + pstRect->astRect[u16Num].astPoint[0].s32X = (HI_U32)((HI_FLOAT)pstBlob->astRegion[i].u16Left / (HI_FLOAT)u32SrcWidth * (HI_FLOAT)u32DstWidth) & (~1) ; + pstRect->astRect[u16Num].astPoint[0].s32Y = (HI_U32)((HI_FLOAT)pstBlob->astRegion[i].u16Top / (HI_FLOAT)u32SrcHeight * (HI_FLOAT)u32DstHeight) & (~1); + + pstRect->astRect[u16Num].astPoint[1].s32X = (HI_U32)((HI_FLOAT)pstBlob->astRegion[i].u16Right/ (HI_FLOAT)u32SrcWidth * (HI_FLOAT)u32DstWidth) & (~1); + pstRect->astRect[u16Num].astPoint[1].s32Y = (HI_U32)((HI_FLOAT)pstBlob->astRegion[i].u16Top / (HI_FLOAT)u32SrcHeight * (HI_FLOAT)u32DstHeight) & (~1); + + pstRect->astRect[u16Num].astPoint[2].s32X = (HI_U32)((HI_FLOAT)pstBlob->astRegion[i].u16Right / (HI_FLOAT)u32SrcWidth * (HI_FLOAT)u32DstWidth) & (~1); + pstRect->astRect[u16Num].astPoint[2].s32Y = (HI_U32)((HI_FLOAT)pstBlob->astRegion[i].u16Bottom / (HI_FLOAT)u32SrcHeight * (HI_FLOAT)u32DstHeight) & (~1); + + pstRect->astRect[u16Num].astPoint[3].s32X = (HI_U32)((HI_FLOAT)pstBlob->astRegion[i].u16Left / (HI_FLOAT)u32SrcWidth * (HI_FLOAT)u32DstWidth) & (~1); + pstRect->astRect[u16Num].astPoint[3].s32Y = (HI_U32)((HI_FLOAT)pstBlob->astRegion[i].u16Bottom / (HI_FLOAT)u32SrcHeight * (HI_FLOAT)u32DstHeight) & (~1); + + bValid = HI_TRUE; + for(j = 0; j < 3;j++) + { + for (k = j + 1; k < 4;k++) + { + if ((pstRect->astRect[u16Num].astPoint[j].s32X == pstRect->astRect[u16Num].astPoint[k].s32X) + &&(pstRect->astRect[u16Num].astPoint[j].s32Y == pstRect->astRect[u16Num].astPoint[k].s32Y)) + { + bValid = HI_FALSE; + break; + } + } + } + if (HI_TRUE == bValid) + { + u16Num++; + } + } + } + + pstRect->u16Num = u16Num; +} + +/****************************************************************************** +* function : Create ive image +******************************************************************************/ +HI_S32 SAMPLE_COMM_IVE_CreateImage(IVE_IMAGE_S* pstImg, IVE_IMAGE_TYPE_E enType, HI_U32 u32Width, HI_U32 u32Height) +{ + HI_U32 u32Size = 0; + HI_S32 s32Ret; + if (NULL == pstImg) + { + SAMPLE_PRT("pstImg is null\n"); + return HI_FAILURE; + } + + pstImg->enType = enType; + pstImg->u32Width = u32Width; + pstImg->u32Height = u32Height; + pstImg->au32Stride[0] = SAMPLE_COMM_IVE_CalcStride(pstImg->u32Width, IVE_ALIGN); + + switch (enType) + { + case IVE_IMAGE_TYPE_U8C1: + case IVE_IMAGE_TYPE_S8C1: + { + u32Size = pstImg->au32Stride[0] * pstImg->u32Height; + s32Ret = HI_MPI_SYS_MmzAlloc(&pstImg->au64PhyAddr[0], (HI_VOID**)&pstImg->au64VirAddr[0], NULL, HI_NULL, u32Size); + if (s32Ret != HI_SUCCESS) + { + SAMPLE_PRT("Mmz Alloc fail,Error(%#x)\n", s32Ret); + return s32Ret; + } + } + break; + case IVE_IMAGE_TYPE_YUV420SP: + { + u32Size = pstImg->au32Stride[0] * pstImg->u32Height * 3 / 2; + s32Ret = HI_MPI_SYS_MmzAlloc(&pstImg->au64PhyAddr[0], (HI_VOID**)&pstImg->au64VirAddr[0], NULL, HI_NULL, u32Size); + if (s32Ret != HI_SUCCESS) + { + SAMPLE_PRT("Mmz Alloc fail,Error(%#x)\n", s32Ret); + return s32Ret; + } + pstImg->au32Stride[1] = pstImg->au32Stride[0]; + pstImg->au64PhyAddr[1] = pstImg->au64PhyAddr[0] + pstImg->au32Stride[0] * pstImg->u32Height; + pstImg->au64VirAddr[1] = pstImg->au64VirAddr[0] + pstImg->au32Stride[0] * pstImg->u32Height; + + } + break; + case IVE_IMAGE_TYPE_YUV422SP: + { + u32Size = pstImg->au32Stride[0] * pstImg->u32Height * 2; + s32Ret = HI_MPI_SYS_MmzAlloc(&pstImg->au64PhyAddr[0], (HI_VOID**)&pstImg->au64VirAddr[0], NULL, HI_NULL, u32Size); + if (s32Ret != HI_SUCCESS) + { + SAMPLE_PRT("Mmz Alloc fail,Error(%#x)\n", s32Ret); + return s32Ret; + } + pstImg->au32Stride[1] = pstImg->au32Stride[0]; + pstImg->au64PhyAddr[1] = pstImg->au64PhyAddr[0] + pstImg->au32Stride[0] * pstImg->u32Height; + pstImg->au64VirAddr[1] = pstImg->au64VirAddr[0] + pstImg->au32Stride[0] * pstImg->u32Height; + + } + break; + case IVE_IMAGE_TYPE_YUV420P: + break; + case IVE_IMAGE_TYPE_YUV422P: + break; + case IVE_IMAGE_TYPE_S8C2_PACKAGE: + break; + case IVE_IMAGE_TYPE_S8C2_PLANAR: + break; + case IVE_IMAGE_TYPE_S16C1: + case IVE_IMAGE_TYPE_U16C1: + { + + u32Size = pstImg->au32Stride[0] * pstImg->u32Height * sizeof(HI_U16); + s32Ret = HI_MPI_SYS_MmzAlloc(&pstImg->au64PhyAddr[0], (HI_VOID**)&pstImg->au64VirAddr[0], NULL, HI_NULL, u32Size); + if (s32Ret != HI_SUCCESS) + { + SAMPLE_PRT("Mmz Alloc fail,Error(%#x)\n", s32Ret); + return s32Ret; + } + } + break; + case IVE_IMAGE_TYPE_U8C3_PACKAGE: + { + u32Size = pstImg->au32Stride[0] * pstImg->u32Height * 3; + s32Ret = HI_MPI_SYS_MmzAlloc(&pstImg->au64PhyAddr[0], (HI_VOID**)&pstImg->au64VirAddr[0], NULL, HI_NULL, u32Size); + if (s32Ret != HI_SUCCESS) + { + SAMPLE_PRT("Mmz Alloc fail,Error(%#x)\n", s32Ret); + return s32Ret; + } + pstImg->au64VirAddr[1] = pstImg->au64VirAddr[0] + 1; + pstImg->au64VirAddr[2] = pstImg->au64VirAddr[1] + 1; + pstImg->au64PhyAddr[1] = pstImg->au64PhyAddr[0] + 1; + pstImg->au64PhyAddr[2] = pstImg->au64PhyAddr[1] + 1; + pstImg->au32Stride[1] = pstImg->au32Stride[0]; + pstImg->au32Stride[2] = pstImg->au32Stride[0]; + } + break; + case IVE_IMAGE_TYPE_U8C3_PLANAR: + break; + case IVE_IMAGE_TYPE_S32C1: + case IVE_IMAGE_TYPE_U32C1: + { + u32Size = pstImg->au32Stride[0] * pstImg->u32Height * sizeof(HI_U32); + s32Ret = HI_MPI_SYS_MmzAlloc(&pstImg->au64PhyAddr[0], (HI_VOID**)&pstImg->au64VirAddr[0], NULL, HI_NULL, u32Size); + if (s32Ret != HI_SUCCESS) + { + SAMPLE_PRT("Mmz Alloc fail,Error(%#x)\n", s32Ret); + return s32Ret; + } + } + break; + case IVE_IMAGE_TYPE_S64C1: + case IVE_IMAGE_TYPE_U64C1: + { + + u32Size = pstImg->au32Stride[0] * pstImg->u32Height * sizeof(HI_U64); + s32Ret = HI_MPI_SYS_MmzAlloc(&pstImg->au64PhyAddr[0], (HI_VOID**)&pstImg->au64VirAddr[0], NULL, HI_NULL, u32Size); + if (s32Ret != HI_SUCCESS) + { + SAMPLE_PRT("Mmz Alloc fail,Error(%#x)\n", s32Ret); + return s32Ret; + } + } + break; + default: + break; + + } + + return HI_SUCCESS; +} +/****************************************************************************** +* function : Create memory info +******************************************************************************/ +HI_S32 SAMPLE_COMM_IVE_CreateMemInfo(IVE_MEM_INFO_S* pstMemInfo, HI_U32 u32Size) +{ + HI_S32 s32Ret; + + if (NULL == pstMemInfo) + { + SAMPLE_PRT("pstMemInfo is null\n"); + return HI_FAILURE; + } + pstMemInfo->u32Size = u32Size; + s32Ret = HI_MPI_SYS_MmzAlloc(&pstMemInfo->u64PhyAddr, (HI_VOID**)&pstMemInfo->u64VirAddr, NULL, HI_NULL, u32Size); + if (s32Ret != HI_SUCCESS) + { + SAMPLE_PRT("Mmz Alloc fail,Error(%#x)\n", s32Ret); + return HI_FAILURE; + } + + return HI_SUCCESS; +} +/****************************************************************************** +* function : Create ive image by cached +******************************************************************************/ +HI_S32 SAMPLE_COMM_IVE_CreateImageByCached(IVE_IMAGE_S* pstImg, + IVE_IMAGE_TYPE_E enType, HI_U32 u32Width, HI_U32 u32Height) +{ + HI_U32 u32Size = 0; + HI_S32 s32Ret; + if (NULL == pstImg) + { + SAMPLE_PRT("pstImg is null\n"); + return HI_FAILURE; + } + + pstImg->enType = enType; + pstImg->u32Width = u32Width; + pstImg->u32Height = u32Height; + pstImg->au32Stride[0] = SAMPLE_COMM_IVE_CalcStride(pstImg->u32Width, IVE_ALIGN); + + switch (enType) + { + case IVE_IMAGE_TYPE_U8C1: + case IVE_IMAGE_TYPE_S8C1: + { + u32Size = pstImg->au32Stride[0] * pstImg->u32Height; + s32Ret = HI_MPI_SYS_MmzAlloc_Cached(&pstImg->au64PhyAddr[0], (HI_VOID**)&pstImg->au64VirAddr[0], NULL, HI_NULL, u32Size); + if (s32Ret != HI_SUCCESS) + { + SAMPLE_PRT("Mmz Alloc fail,Error(%#x)\n", s32Ret); + return s32Ret; + } + } + break; + case IVE_IMAGE_TYPE_YUV420SP: + break; + case IVE_IMAGE_TYPE_YUV422SP: + break; + case IVE_IMAGE_TYPE_YUV420P: + break; + case IVE_IMAGE_TYPE_YUV422P: + break; + case IVE_IMAGE_TYPE_S8C2_PACKAGE: + break; + case IVE_IMAGE_TYPE_S8C2_PLANAR: + break; + case IVE_IMAGE_TYPE_S16C1: + case IVE_IMAGE_TYPE_U16C1: + { + + u32Size = pstImg->au32Stride[0] * pstImg->u32Height * sizeof(HI_U16); + s32Ret = HI_MPI_SYS_MmzAlloc_Cached(&pstImg->au64PhyAddr[0], (HI_VOID**)&pstImg->au64VirAddr[0], NULL, HI_NULL, u32Size); + if (s32Ret != HI_SUCCESS) + { + SAMPLE_PRT("Mmz Alloc fail,Error(%#x)\n", s32Ret); + return s32Ret; + } + } + break; + case IVE_IMAGE_TYPE_U8C3_PACKAGE: + break; + case IVE_IMAGE_TYPE_U8C3_PLANAR: + break; + case IVE_IMAGE_TYPE_S32C1: + case IVE_IMAGE_TYPE_U32C1: + { + u32Size = pstImg->au32Stride[0] * pstImg->u32Height * sizeof(HI_U32); + s32Ret = HI_MPI_SYS_MmzAlloc_Cached(&pstImg->au64PhyAddr[0], (HI_VOID**)&pstImg->au64VirAddr[0], NULL, HI_NULL, u32Size); + if (s32Ret != HI_SUCCESS) + { + SAMPLE_PRT("Mmz Alloc fail,Error(%#x)\n", s32Ret); + return s32Ret; + } + } + break; + case IVE_IMAGE_TYPE_S64C1: + case IVE_IMAGE_TYPE_U64C1: + { + + u32Size = pstImg->au32Stride[0] * pstImg->u32Height * sizeof(HI_U64); + s32Ret = HI_MPI_SYS_MmzAlloc_Cached(&pstImg->au64PhyAddr[0], (HI_VOID**)&pstImg->au64VirAddr[0], NULL, HI_NULL, u32Size); + if (s32Ret != HI_SUCCESS) + { + SAMPLE_PRT("Mmz Alloc fail,Error(%#x)\n", s32Ret); + return s32Ret; + } + } + break; + default: + break; + } + + return HI_SUCCESS; +} + +HI_S32 SAMPLE_COMM_IVE_CreateData(IVE_DATA_S* pstData,HI_U32 u32Width, HI_U32 u32Height) +{ + HI_S32 s32Ret; + HI_U32 u32Size; + + if (NULL == pstData) + { + SAMPLE_PRT("pstData is null\n"); + return HI_FAILURE; + } + pstData->u32Width = u32Width; + pstData->u32Height = u32Height; + pstData->u32Stride = SAMPLE_COMM_IVE_CalcStride(pstData->u32Width, IVE_ALIGN); + u32Size = pstData->u32Stride * pstData->u32Height; + s32Ret = HI_MPI_SYS_MmzAlloc(&pstData->u64PhyAddr, (HI_VOID**)&pstData->u64VirAddr, NULL, HI_NULL, u32Size); + if (s32Ret != HI_SUCCESS) + { + SAMPLE_PRT("Mmz Alloc fail,Error(%#x)\n", s32Ret); + return HI_FAILURE; + } + + return HI_SUCCESS; +} +/****************************************************************************** +* function : Init Vb +******************************************************************************/ +HI_S32 SAMPLE_COMM_IVE_VbInit(PIC_SIZE_E *paenSize,SIZE_S *pastSize,HI_U32 u32VpssChnNum) +{ + HI_S32 s32Ret; + HI_U32 i; + HI_U64 u64BlkSize; + VB_CONFIG_S stVbConf; + + memset(&stVbConf, 0, sizeof(VB_CONFIG_S)); + stVbConf.u32MaxPoolCnt = 128; + + for (i = 0; i < u32VpssChnNum; i++) + { + s32Ret = SAMPLE_COMM_SYS_GetPicSize(paenSize[i], &pastSize[i]); + SAMPLE_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret, VB_FAIL_0, + "SAMPLE_COMM_SYS_GetPicSize failed,Error(%#x)!\n",s32Ret); + + u64BlkSize = COMMON_GetPicBufferSize(pastSize[i].u32Width, pastSize[i].u32Height, + SAMPLE_PIXEL_FORMAT, DATA_BITWIDTH_8, COMPRESS_MODE_NONE, DEFAULT_ALIGN); + /* comm video buffer */ + stVbConf.astCommPool[i].u64BlkSize = u64BlkSize; + stVbConf.astCommPool[i].u32BlkCnt = 16; + } + + s32Ret = SAMPLE_COMM_SYS_Init(&stVbConf); + SAMPLE_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret, VB_FAIL_1, + "SAMPLE_COMM_SYS_Init failed,Error(%#x)!\n", s32Ret); + + return s32Ret; +VB_FAIL_1: + SAMPLE_COMM_SYS_Exit(); +VB_FAIL_0: + + return s32Ret; +} + +/****************************************************************************** +* function : Dma frame info to ive image +******************************************************************************/ +HI_S32 SAMPLE_COMM_IVE_DmaImage(VIDEO_FRAME_INFO_S *pstFrameInfo,IVE_DST_IMAGE_S *pstDst,HI_BOOL bInstant) +{ + HI_S32 s32Ret; + IVE_HANDLE hIveHandle; + IVE_SRC_DATA_S stSrcData; + IVE_DST_DATA_S stDstData; + IVE_DMA_CTRL_S stCtrl = {IVE_DMA_MODE_DIRECT_COPY,0}; + HI_BOOL bFinish = HI_FALSE; + HI_BOOL bBlock = HI_TRUE; + + //fill src + //stSrcData.u64VirAddr = pstFrameInfo->stVFrame.u64VirAddr[0]; + stSrcData.u64PhyAddr = pstFrameInfo->stVFrame.u64PhyAddr[0]; + stSrcData.u32Width = pstFrameInfo->stVFrame.u32Width; + stSrcData.u32Height = pstFrameInfo->stVFrame.u32Height; + stSrcData.u32Stride = pstFrameInfo->stVFrame.u32Stride[0]; + + //fill dst + //stDstData.u64VirAddr = pstDst->au64VirAddr[0]; + stDstData.u64PhyAddr = pstDst->au64PhyAddr[0]; + stDstData.u32Width = pstDst->u32Width; + stDstData.u32Height = pstDst->u32Height; + stDstData.u32Stride = pstDst->au32Stride[0]; + + s32Ret = HI_MPI_IVE_DMA(&hIveHandle,&stSrcData,&stDstData,&stCtrl,bInstant); + SAMPLE_CHECK_EXPR_RET(HI_SUCCESS != s32Ret,s32Ret,"Error(%#x),HI_MPI_IVE_DMA failed!\n",s32Ret); + + if (HI_TRUE == bInstant) + { + s32Ret = HI_MPI_IVE_Query(hIveHandle,&bFinish,bBlock); + while(HI_ERR_IVE_QUERY_TIMEOUT == s32Ret) + { + usleep(100); + s32Ret = HI_MPI_IVE_Query(hIveHandle,&bFinish,bBlock); + } + SAMPLE_CHECK_EXPR_RET(HI_SUCCESS != s32Ret,s32Ret,"Error(%#x),HI_MPI_IVE_Query failed!\n",s32Ret); + } + + return HI_SUCCESS; +} + +/****************************************************************************** +* function : Start Vpss +******************************************************************************/ +HI_S32 SAMPLE_COMM_IVE_StartVpss(SIZE_S *pastSize,HI_U32 u32VpssChnNum) +{ + HI_S32 i; + VPSS_CHN_ATTR_S astVpssChnAttr[VPSS_MAX_CHN_NUM]; + VPSS_GRP_ATTR_S stVpssGrpAttr; + HI_BOOL abChnEnable[VPSS_MAX_CHN_NUM] = {HI_FALSE, HI_FALSE, HI_FALSE, HI_FALSE}; + VPSS_GRP VpssGrp = 0; + + stVpssGrpAttr.u32MaxW = 1920; + stVpssGrpAttr.u32MaxH = 1080; + stVpssGrpAttr.stFrameRate.s32SrcFrameRate = -1; + stVpssGrpAttr.stFrameRate.s32DstFrameRate = -1; + stVpssGrpAttr.enDynamicRange = DYNAMIC_RANGE_SDR8; + stVpssGrpAttr.enPixelFormat = PIXEL_FORMAT_YVU_SEMIPLANAR_420; + stVpssGrpAttr.bNrEn = HI_FALSE; + + for (i = 0; i < u32VpssChnNum; i++) + { + abChnEnable[i] = HI_TRUE; + } + + for(i = 0; i < VPSS_MAX_CHN_NUM; i++) + { + astVpssChnAttr[i].u32Width = pastSize[i].u32Width; + astVpssChnAttr[i].u32Height = pastSize[i].u32Height; + astVpssChnAttr[i].enChnMode = VPSS_CHN_MODE_USER; + astVpssChnAttr[i].enCompressMode = COMPRESS_MODE_NONE; + astVpssChnAttr[i].enDynamicRange = DYNAMIC_RANGE_SDR8; + astVpssChnAttr[i].enVideoFormat = VIDEO_FORMAT_LINEAR; + astVpssChnAttr[i].enPixelFormat = PIXEL_FORMAT_YVU_SEMIPLANAR_420; + astVpssChnAttr[i].stFrameRate.s32SrcFrameRate = -1; + astVpssChnAttr[i].stFrameRate.s32DstFrameRate = -1; + astVpssChnAttr[i].u32Depth = 1; + astVpssChnAttr[i].bMirror = HI_FALSE; + astVpssChnAttr[i].bFlip = HI_FALSE; + astVpssChnAttr[i].stAspectRatio.enMode = ASPECT_RATIO_NONE; + } + + return SAMPLE_COMM_VPSS_Start(VpssGrp, abChnEnable, &stVpssGrpAttr, &astVpssChnAttr[0]); + +} +/****************************************************************************** +* function : Stop Vpss +******************************************************************************/ +HI_VOID SAMPLE_COMM_IVE_StopVpss(HI_U32 u32VpssChnNum) +{ + VPSS_GRP VpssGrp = 0; + HI_BOOL abChnEnable[VPSS_MAX_CHN_NUM] = {HI_FALSE, HI_FALSE, HI_FALSE, HI_FALSE}; + HI_S32 i = 0; + + for (i = 0; i < u32VpssChnNum; i++) + { + abChnEnable[i] = HI_TRUE; + } + + (HI_VOID)SAMPLE_COMM_VPSS_Stop(VpssGrp, abChnEnable); + + return; +} + +/****************************************************************************** +* function : Start Vo +******************************************************************************/ +HI_S32 SAMPLE_COMM_IVE_StartVo(HI_VOID) +{ + HI_S32 s32Ret; + VO_DEV VoDev = SAMPLE_VO_DEV_DHD0; + VO_LAYER VoLayer = 0; + VO_PUB_ATTR_S stVoPubAttr; + VO_VIDEO_LAYER_ATTR_S stLayerAttr; + SAMPLE_VO_MODE_E enVoMode = VO_MODE_1MUX; + HI_U32 u32DisBufLen = 3; + + stVoPubAttr.enIntfSync = VO_OUTPUT_1080P30; + stVoPubAttr.enIntfType = VO_INTF_HDMI; + stVoPubAttr.u32BgColor = COLOR_RGB_BLUE; + s32Ret = SAMPLE_COMM_VO_StartDev(VoDev, &stVoPubAttr); + SAMPLE_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret, VO_FAIL_0, + "SAMPLE_COMM_VO_StartDev failed,Error(%#x)!\n",s32Ret); + + s32Ret = SAMPLE_COMM_VO_HdmiStart(stVoPubAttr.enIntfSync); + SAMPLE_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret, VO_FAIL_1, + "SAMPLE_COMM_VO_HdmiStart failed,Error(%#x)!\n",s32Ret); + + s32Ret = SAMPLE_COMM_VO_GetWH(stVoPubAttr.enIntfSync,&stLayerAttr.stDispRect.u32Width, + &stLayerAttr.stDispRect.u32Height, &stLayerAttr.u32DispFrmRt); + SAMPLE_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret, VO_FAIL_2, + "SAMPLE_COMM_VO_GetWH failed,Error(%#x)!\n",s32Ret); + + s32Ret = HI_MPI_VO_SetDisplayBufLen(VoLayer, u32DisBufLen); + SAMPLE_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret, VO_FAIL_2, + "HI_MPI_VO_SetDisplayBufLen failed,Error(%#x)!\n",s32Ret); + + stLayerAttr.stDispRect.s32X = 0; + stLayerAttr.stDispRect.s32Y = 0; + stLayerAttr.stImageSize.u32Width = stLayerAttr.stDispRect.u32Width; + stLayerAttr.stImageSize.u32Height = stLayerAttr.stDispRect.u32Height; + stLayerAttr.bDoubleFrame = HI_FALSE; + stLayerAttr.bClusterMode = HI_FALSE; + stLayerAttr.enPixFormat = PIXEL_FORMAT_YVU_SEMIPLANAR_420; + stLayerAttr.enDstDynamicRange = DYNAMIC_RANGE_SDR8; + + s32Ret = SAMPLE_COMM_VO_StartLayer(VoLayer, &stLayerAttr); + SAMPLE_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret, VO_FAIL_2, + "SAMPLE_COMM_VO_StartLayer failed,Error(%#x)!\n",s32Ret); + + s32Ret = SAMPLE_COMM_VO_StartChn(VoLayer, enVoMode); + SAMPLE_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret, VO_FAIL_3, + "SAMPLE_COMM_VO_StartChn failed,Error(%#x)!\n",s32Ret); + + return s32Ret; +VO_FAIL_3: + SAMPLE_COMM_VO_StopLayer(VoLayer); +VO_FAIL_2: + SAMPLE_COMM_VO_HdmiStop(); +VO_FAIL_1: + SAMPLE_COMM_VO_StopDev(VoDev); +VO_FAIL_0: + return s32Ret; +} +/****************************************************************************** +* function : Stop Vo +******************************************************************************/ +HI_VOID SAMPLE_COMM_IVE_StopVo(HI_VOID) +{ + VO_DEV VoDev = SAMPLE_VO_DEV_DHD0; + VO_LAYER VoLayer = 0; + SAMPLE_VO_MODE_E enVoMode = VO_MODE_1MUX; + + (HI_VOID)SAMPLE_COMM_VO_StopChn(VoDev, enVoMode); + (HI_VOID)SAMPLE_COMM_VO_StopLayer(VoLayer); + SAMPLE_COMM_VO_HdmiStop(); + (HI_VOID)SAMPLE_COMM_VO_StopDev(VoDev); +} +/****************************************************************************** +* function : Start Vi/Vpss/Venc/Vo +******************************************************************************/ +HI_S32 SAMPLE_COMM_IVE_StartViVpssVencVo(SAMPLE_VI_CONFIG_S *pstViConfig, + SAMPLE_IVE_SWITCH_S *pstSwitch,PIC_SIZE_E *penExtPicSize) +{ + SIZE_S astSize[VPSS_CHN_NUM]; + PIC_SIZE_E aenSize[VPSS_CHN_NUM]; + VI_CHN_ATTR_S stViChnAttr; + SAMPLE_RC_E enRcMode = SAMPLE_RC_CBR; + PAYLOAD_TYPE_E enStreamType = PT_H264; + HI_BOOL bRcnRefShareBuf=HI_FALSE; + VENC_GOP_ATTR_S stGopAttr; + VI_DEV ViDev0 = 0; + VI_PIPE ViPipe0 = 0; + VI_CHN ViChn = 0; + HI_S32 s32ViCnt = 1; + HI_S32 s32WorkSnsId = 0; + VPSS_GRP VpssGrp = 0; + HI_S32 s32Ret = HI_SUCCESS; + VENC_CHN VeH264Chn = 0; + WDR_MODE_E enWDRMode = WDR_MODE_NONE; + DYNAMIC_RANGE_E enDynamicRange = DYNAMIC_RANGE_SDR8; + PIXEL_FORMAT_E enPixFormat = PIXEL_FORMAT_YVU_SEMIPLANAR_420; + VIDEO_FORMAT_E enVideoFormat = VIDEO_FORMAT_LINEAR; + COMPRESS_MODE_E enCompressMode = COMPRESS_MODE_NONE; + VI_VPSS_MODE_E enMastPipeMode = VI_ONLINE_VPSS_OFFLINE; + + memset(pstViConfig,0,sizeof(*pstViConfig)); + + SAMPLE_COMM_VI_GetSensorInfo(pstViConfig); + pstViConfig->s32WorkingViNum = s32ViCnt; + + pstViConfig->as32WorkingViId[0] = 0; + pstViConfig->astViInfo[0].stSnsInfo.MipiDev = SAMPLE_COMM_VI_GetComboDevBySensor(pstViConfig->astViInfo[0].stSnsInfo.enSnsType, 0); + pstViConfig->astViInfo[0].stSnsInfo.s32BusId = 0; + + pstViConfig->astViInfo[0].stDevInfo.ViDev = ViDev0; + pstViConfig->astViInfo[0].stDevInfo.enWDRMode = enWDRMode; + + pstViConfig->astViInfo[0].stPipeInfo.enMastPipeMode = enMastPipeMode; + pstViConfig->astViInfo[0].stPipeInfo.aPipe[0] = ViPipe0; + pstViConfig->astViInfo[0].stPipeInfo.aPipe[1] = -1; + pstViConfig->astViInfo[0].stPipeInfo.aPipe[2] = -1; + pstViConfig->astViInfo[0].stPipeInfo.aPipe[3] = -1; + + pstViConfig->astViInfo[0].stChnInfo.ViChn = ViChn; + pstViConfig->astViInfo[0].stChnInfo.enPixFormat = enPixFormat; + pstViConfig->astViInfo[0].stChnInfo.enDynamicRange = enDynamicRange; + pstViConfig->astViInfo[0].stChnInfo.enVideoFormat = enVideoFormat; + pstViConfig->astViInfo[0].stChnInfo.enCompressMode = enCompressMode; + + s32Ret = SAMPLE_COMM_VI_GetSizeBySensor(pstViConfig->astViInfo[s32WorkSnsId].stSnsInfo.enSnsType, &aenSize[0]); + SAMPLE_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret, END_INIT_0, + "Error(%#x),SAMPLE_COMM_VI_GetSizeBySensor failed!\n",s32Ret); + aenSize[1] = *penExtPicSize; + + /****************************************** + step 1: Init vb + ******************************************/ + s32Ret = SAMPLE_COMM_IVE_VbInit(aenSize,astSize,VPSS_CHN_NUM); + SAMPLE_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret, END_INIT_0, + "Error(%#x),SAMPLE_COMM_IVE_VbInit failed!\n",s32Ret); + /****************************************** + step 2: Start vi + ******************************************/ + s32Ret = SAMPLE_COMM_VI_SetParam(pstViConfig); + SAMPLE_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret, END_INIT_1, + "Error(%#x),SAMPLE_COMM_VI_SetParam failed!\n",s32Ret); + + s32Ret = SAMPLE_COMM_VI_StartVi(pstViConfig); + SAMPLE_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret, END_INIT_1, + "Error(%#x),SAMPLE_COMM_VI_StartVi failed!\n",s32Ret); + /****************************************** + step 3: Start vpss + ******************************************/ + s32Ret = SAMPLE_COMM_IVE_StartVpss(astSize,VPSS_CHN_NUM); + SAMPLE_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret, END_INIT_2, + "Error(%#x),SAMPLE_IVS_StartVpss failed!\n",s32Ret); + /****************************************** + step 4: Bind vpss to vi + ******************************************/ + s32Ret = SAMPLE_COMM_VI_Bind_VPSS(ViPipe0, ViChn, VpssGrp); + SAMPLE_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret, END_INIT_3, + "Error(%#x),SAMPLE_COMM_VI_BindVpss failed!\n",s32Ret); + //Set vi frame + s32Ret = HI_MPI_VI_GetChnAttr(ViPipe0, ViChn,&stViChnAttr); + SAMPLE_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret, END_INIT_4, + "Error(%#x),HI_MPI_VI_GetChnAttr failed!\n",s32Ret); + + s32Ret = HI_MPI_VI_SetChnAttr(ViPipe0, ViChn,&stViChnAttr); + SAMPLE_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret, END_INIT_4, + "Error(%#x),HI_MPI_VI_SetChnAttr failed!\n",s32Ret); + /****************************************** + step 5: Start Vo + ******************************************/ + if (HI_TRUE == pstSwitch->bVo) + { + s32Ret = SAMPLE_COMM_IVE_StartVo(); + SAMPLE_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret, END_INIT_4, + "Error(%#x),SAMPLE_COMM_IVE_StartVo failed!\n", s32Ret); + } + /****************************************** + step 6: Start Venc + ******************************************/ + if (HI_TRUE == pstSwitch->bVenc) + { + s32Ret = SAMPLE_COMM_VENC_GetGopAttr(VENC_GOPMODE_NORMALP,&stGopAttr); + SAMPLE_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret, END_INIT_5, + "Error(%#x),SAMPLE_COMM_VENC_GetGopAttr failed!\n",s32Ret); + s32Ret = SAMPLE_COMM_VENC_Start(VeH264Chn, enStreamType,aenSize[0],enRcMode,0,bRcnRefShareBuf,&stGopAttr); + SAMPLE_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret, END_INIT_5, + "Error(%#x),SAMPLE_COMM_VENC_Start failed!\n",s32Ret); + s32Ret = SAMPLE_COMM_VENC_StartGetStream(&VeH264Chn, 1); + SAMPLE_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret, END_INIT_6, + "Error(%#x),SAMPLE_COMM_VENC_StartGetStream failed!\n",s32Ret); + } + + return HI_SUCCESS; + +END_INIT_6: + if (HI_TRUE == pstSwitch->bVenc) + { + SAMPLE_COMM_VENC_Stop(VeH264Chn); + } +END_INIT_5: + if (HI_TRUE == pstSwitch->bVo) + { + SAMPLE_COMM_IVE_StopVo(); + } +END_INIT_4: + SAMPLE_COMM_VI_UnBind_VPSS(ViPipe0, ViChn, VpssGrp); +END_INIT_3: + SAMPLE_COMM_IVE_StopVpss(VPSS_CHN_NUM); +END_INIT_2: + SAMPLE_COMM_VI_StopVi(pstViConfig); +END_INIT_1: //system exit + SAMPLE_COMM_SYS_Exit(); + memset(pstViConfig,0,sizeof(*pstViConfig)); +END_INIT_0: + + return s32Ret; +} +/****************************************************************************** +* function : Stop Vi/Vpss/Venc/Vo +******************************************************************************/ +HI_VOID SAMPLE_COMM_IVE_StopViVpssVencVo(SAMPLE_VI_CONFIG_S *pstViConfig,SAMPLE_IVE_SWITCH_S *pstSwitch) +{ + if (HI_TRUE == pstSwitch->bVenc) + { + SAMPLE_COMM_VENC_StopGetStream(); + SAMPLE_COMM_VENC_Stop(0); + } + if (HI_TRUE == pstSwitch->bVo) + { + SAMPLE_COMM_IVE_StopVo(); + } + + SAMPLE_COMM_VI_UnBind_VPSS(pstViConfig->astViInfo[0].stPipeInfo.aPipe[0], + pstViConfig->astViInfo[0].stChnInfo.ViChn, 0); + SAMPLE_COMM_IVE_StopVpss(VPSS_CHN_NUM); + SAMPLE_COMM_VI_StopVi(pstViConfig); + SAMPLE_COMM_SYS_Exit(); + + memset(pstViConfig,0,sizeof(*pstViConfig)); +} + + diff --git a/src/modules/isp/mpp/sample_comm_ive.h b/src/modules/isp/mpp/sample_comm_ive.h new file mode 100755 index 0000000..a5149c4 --- /dev/null +++ b/src/modules/isp/mpp/sample_comm_ive.h @@ -0,0 +1,194 @@ +#ifndef __SAMPLE_COMM_IVE_H__ +#define __SAMPLE_COMM_IVE_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "hi_debug.h" +#include "hi_comm_ive.h" +#include "mpi_ive.h" +#include "sample_comm.h" + +#define VIDEO_WIDTH 352 +#define VIDEO_HEIGHT 288 +#define IVE_ALIGN 16 +#define IVE_CHAR_CALW 8 +#define IVE_CHAR_CALH 8 +#define IVE_CHAR_NUM (IVE_CHAR_CALW *IVE_CHAR_CALH) +#define IVE_FILE_NAME_LEN 256 +#define IVE_RECT_NUM 64 +#define VPSS_CHN_NUM 2 + +#define SAMPLE_ALIGN_BACK(x, a) ((a) * (((x) / (a)))) + +typedef struct hiSAMPLE_IVE_SWITCH_S +{ + HI_BOOL bVenc; + HI_BOOL bVo; +}SAMPLE_IVE_SWITCH_S; + +typedef struct hiSAMPLE_IVE_RECT_S +{ + POINT_S astPoint[4]; +} SAMPLE_IVE_RECT_S; + +typedef struct hiSAMPLE_RECT_ARRAY_S +{ + HI_U16 u16Num; + SAMPLE_IVE_RECT_S astRect[IVE_RECT_NUM]; +} SAMPLE_RECT_ARRAY_S; + +typedef struct hiIVE_LINEAR_DATA_S +{ + HI_S32 s32LinearNum; + HI_S32 s32ThreshNum; + POINT_S* pstLinearPoint; +} IVE_LINEAR_DATA_S; + +typedef struct hiSAMPLE_IVE_DRAW_RECT_MSG_S +{ + VIDEO_FRAME_INFO_S stFrameInfo; + SAMPLE_RECT_ARRAY_S stRegion; +} SAMPLE_IVE_DRAW_RECT_MSG_S; + +//free mmz +#define IVE_MMZ_FREE(phy,vir)\ + do{\ + if ((0 != (phy)) && (0 != (vir)))\ + {\ + HI_MPI_SYS_MmzFree((phy),(HI_VOID *)(HI_UL)(vir));\ + (phy) = 0;\ + (vir) = 0;\ + }\ + }while(0) + +#define IVE_CLOSE_FILE(fp)\ + do{\ + if (NULL != (fp))\ + {\ + fclose((fp));\ + (fp) = NULL;\ + }\ + }while(0) + +#define SAMPLE_PAUSE()\ + do {\ + printf("---------------press Enter key to exit!---------------\n");\ + (void)getchar();\ + } while (0) +#define SAMPLE_CHECK_EXPR_RET(expr, ret, fmt...)\ +do\ +{\ + if(expr)\ + {\ + SAMPLE_PRT(fmt);\ + return (ret);\ + }\ +}while(0) +#define SAMPLE_CHECK_EXPR_GOTO(expr, label, fmt...)\ +do\ +{\ + if(expr)\ + {\ + SAMPLE_PRT(fmt);\ + goto label;\ + }\ +}while(0) + +#define SAMPLE_COMM_IVE_CONVERT_64BIT_ADDR(Type,Addr) (Type*)(HI_UL)(Addr) + +/****************************************************************************** +* function : Mpi init +******************************************************************************/ +HI_VOID SAMPLE_COMM_IVE_CheckIveMpiInit(HI_VOID); +/****************************************************************************** +* function : Mpi exit +******************************************************************************/ +HI_S32 SAMPLE_COMM_IVE_IveMpiExit(HI_VOID); +/****************************************************************************** +* function :Read file +******************************************************************************/ +HI_S32 SAMPLE_COMM_IVE_ReadFile(IVE_IMAGE_S* pstImg, FILE* pFp); +/****************************************************************************** +* function :Write file +******************************************************************************/ +HI_S32 SAMPLE_COMM_IVE_WriteFile(IVE_IMAGE_S* pstImg, FILE* pFp); +/****************************************************************************** +* function :Calc stride +******************************************************************************/ +HI_U16 SAMPLE_COMM_IVE_CalcStride(HI_U32 u32Width, HI_U8 u8Align); +/****************************************************************************** +* function : Copy blob to rect +******************************************************************************/ +HI_VOID SAMPLE_COMM_IVE_BlobToRect(IVE_CCBLOB_S *pstBlob, SAMPLE_RECT_ARRAY_S *pstRect, + HI_U16 u16RectMaxNum,HI_U16 u16AreaThrStep, + HI_U32 u32SrcWidth, HI_U32 u32SrcHeight, + HI_U32 u32DstWidth,HI_U32 u32DstHeight); +/****************************************************************************** +* function : Create ive image +******************************************************************************/ +HI_S32 SAMPLE_COMM_IVE_CreateImage(IVE_IMAGE_S* pstImg, IVE_IMAGE_TYPE_E enType, + HI_U32 u32Width, HI_U32 u32Height); +/****************************************************************************** +* function : Create memory info +******************************************************************************/ +HI_S32 SAMPLE_COMM_IVE_CreateMemInfo(IVE_MEM_INFO_S* pstMemInfo, HI_U32 u32Size); +/****************************************************************************** +* function : Create ive image by cached +******************************************************************************/ +HI_S32 SAMPLE_COMM_IVE_CreateImageByCached(IVE_IMAGE_S* pstImg, + IVE_IMAGE_TYPE_E enType, HI_U32 u32Width, HI_U32 u32Height); +/****************************************************************************** +* function : Create IVE_DATA_S +******************************************************************************/ +HI_S32 SAMPLE_COMM_IVE_CreateData(IVE_DATA_S* pstData,HI_U32 u32Width, HI_U32 u32Height); +/****************************************************************************** +* function : Init Vb +******************************************************************************/ +HI_S32 SAMPLE_COMM_IVE_VbInit(PIC_SIZE_E *paenSize,SIZE_S *pastSize,HI_U32 u32VpssChnNum); +/****************************************************************************** +* function : Dma frame info to ive image +******************************************************************************/ +HI_S32 SAMPLE_COMM_IVE_DmaImage(VIDEO_FRAME_INFO_S *pstFrameInfo,IVE_DST_IMAGE_S *pstDst,HI_BOOL bInstant); + +/****************************************************************************** +* function : Call vgs to fill rect +******************************************************************************/ +HI_S32 SAMPLE_COMM_VGS_FillRect(VIDEO_FRAME_INFO_S* pstFrmInfo, SAMPLE_RECT_ARRAY_S* pstRect, HI_U32 u32Color); + +/****************************************************************************** +* function : Start Vpss +******************************************************************************/ +HI_S32 SAMPLE_COMM_IVE_StartVpss(SIZE_S *pastSize,HI_U32 u32VpssChnNum); +/****************************************************************************** +* function : Stop Vpss +******************************************************************************/ +HI_VOID SAMPLE_COMM_IVE_StopVpss(HI_U32 u32VpssChnNum); +/****************************************************************************** +* function : Start Vo +******************************************************************************/ +HI_S32 SAMPLE_COMM_IVE_StartVo(HI_VOID); +/****************************************************************************** +* function : Stop Vo +******************************************************************************/ +HI_VOID SAMPLE_COMM_IVE_StopVo(HI_VOID); +/****************************************************************************** +* function : Start Vi/Vpss/Venc/Vo +******************************************************************************/ +HI_S32 SAMPLE_COMM_IVE_StartViVpssVencVo(SAMPLE_VI_CONFIG_S *pstViConfig,SAMPLE_IVE_SWITCH_S *pstSwitch,PIC_SIZE_E *penExtPicSize); +/****************************************************************************** +* function : Stop Vi/Vpss/Venc/Vo +******************************************************************************/ +HI_VOID SAMPLE_COMM_IVE_StopViVpssVencVo(SAMPLE_VI_CONFIG_S *pstViConfig,SAMPLE_IVE_SWITCH_S *pstSwitch); + +#endif + + diff --git a/src/modules/isp/mpp/simsunb_16x32.txt b/src/modules/isp/mpp/simsunb_16x32.txt new file mode 100644 index 0000000..b4ec6a3 --- /dev/null +++ b/src/modules/isp/mpp/simsunb_16x32.txt @@ -0,0 +1,380 @@ +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x01 ,0x00 ,0x03 ,0x80 ,0x03 ,0x80 ,0x03 ,0x80 ,0x03 ,0x80 , +0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00 , +0x01 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x01 ,0x80 ,0x03 ,0x80 , +0x03 ,0x80 ,0x01 ,0x80 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x06 ,0x70 ,0x06 ,0x70 ,0x06 ,0x70 ,0x06 ,0x60 ,0x06 ,0x60 ,0x06 ,0x60 ,0x06 ,0x60 , +0x06 ,0x20 ,0x04 ,0x40 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x04 ,0x18 ,0x0c ,0x18 ,0x0c ,0x10 ,0x08 ,0x10 , +0x08 ,0x10 ,0x7f ,0xfe ,0x7f ,0xfe ,0x08 ,0x10 ,0x08 ,0x10 ,0x08 ,0x10 ,0x08 ,0x10 ,0x08 ,0x10 , +0x08 ,0x30 ,0x08 ,0x30 ,0x7f ,0xfe ,0x7f ,0xfe ,0x10 ,0x20 ,0x10 ,0x20 ,0x10 ,0x20 ,0x10 ,0x20 , +0x10 ,0x20 ,0x10 ,0x20 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x01 ,0x80 ,0x01 ,0x80 ,0x07 ,0xe0 ,0x0d ,0xb0 ,0x19 ,0x98 ,0x19 ,0x98 , +0x19 ,0xb8 ,0x19 ,0xb0 ,0x19 ,0x80 ,0x1d ,0x80 ,0x0f ,0x80 ,0x07 ,0x80 ,0x01 ,0xc0 ,0x01 ,0xe0 , +0x01 ,0xf0 ,0x01 ,0xb8 ,0x01 ,0x98 ,0x19 ,0x98 ,0x39 ,0x98 ,0x39 ,0x98 ,0x31 ,0x98 ,0x11 ,0x90 , +0x0d ,0xe0 ,0x03 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x38 ,0x10 ,0x44 ,0x10 ,0x46 ,0x20 ,0xc6 ,0x20 , +0xc6 ,0x20 ,0xc6 ,0x40 ,0xc6 ,0x40 ,0xc6 ,0x80 ,0x46 ,0x80 ,0x44 ,0x80 ,0x3d ,0x18 ,0x01 ,0x64 , +0x02 ,0x46 ,0x02 ,0x46 ,0x04 ,0xc6 ,0x04 ,0xc6 ,0x04 ,0xc6 ,0x08 ,0xc6 ,0x08 ,0x46 ,0x10 ,0x46 , +0x10 ,0x2c ,0x10 ,0x10 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x0f ,0x80 ,0x18 ,0x80 ,0x10 ,0xc0 ,0x10 ,0xc0 , +0x10 ,0xc0 ,0x10 ,0x80 ,0x19 ,0x80 ,0x19 ,0x00 ,0x1a ,0x00 ,0x1c ,0x7c ,0x1c ,0x18 ,0x2c ,0x10 , +0x66 ,0x10 ,0x46 ,0x10 ,0xc7 ,0x20 ,0xc3 ,0x20 ,0xc1 ,0xa0 ,0xc1 ,0xc0 ,0x60 ,0xe0 ,0x70 ,0xf2 , +0x3f ,0x3e ,0x0c ,0x18 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x03 ,0x00 ,0x03 ,0x80 ,0x03 ,0x00 ,0x03 ,0x00 ,0x03 ,0x00 ,0x03 ,0x00 ,0x03 ,0x00 ,0x02 ,0x00 , +0x02 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x04 ,0x00 ,0x0c ,0x00 ,0x18 ,0x00 ,0x10 ,0x00 ,0x20 ,0x00 ,0x60 ,0x00 ,0x40 ,0x00 ,0xc0 , +0x00 ,0xc0 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 , +0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x00 ,0x80 ,0x00 ,0xc0 ,0x00 ,0xc0 ,0x00 ,0x40 ,0x00 ,0x60 , +0x00 ,0x30 ,0x00 ,0x10 ,0x00 ,0x08 ,0x00 ,0x04 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x40 ,0x00 ,0x20 ,0x00 ,0x10 ,0x00 ,0x18 ,0x00 ,0x0c ,0x00 ,0x04 ,0x00 ,0x06 ,0x00 ,0x02 ,0x00 , +0x03 ,0x00 ,0x03 ,0x00 ,0x01 ,0x00 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 , +0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x00 ,0x03 ,0x00 ,0x03 ,0x00 ,0x02 ,0x00 ,0x06 ,0x00 ,0x04 ,0x00 , +0x0c ,0x00 ,0x18 ,0x00 ,0x10 ,0x00 ,0x20 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x01 ,0x80 , +0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x79 ,0x8e ,0x3d ,0xbe ,0x1e ,0xf0 ,0x01 ,0x80 ,0x03 ,0xc0 , +0x06 ,0x70 ,0x0c ,0x38 ,0x1c ,0x1c ,0x38 ,0x0c ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x01 ,0x80 ,0x01 ,0x80 , +0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x7f ,0xfe ,0x01 ,0x80 , +0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x1c ,0x00 ,0x1e ,0x00 , +0x0e ,0x00 ,0x06 ,0x00 ,0x06 ,0x00 ,0x0c ,0x00 ,0x18 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x7f ,0xfe ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x18 ,0x00 ,0x3c ,0x00 , +0x3c ,0x00 ,0x18 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x02 ,0x00 ,0x04 ,0x00 ,0x04 ,0x00 ,0x08 ,0x00 ,0x08 ,0x00 ,0x10 ,0x00 ,0x10 , +0x00 ,0x20 ,0x00 ,0x20 ,0x00 ,0x40 ,0x00 ,0x40 ,0x00 ,0x80 ,0x00 ,0x80 ,0x01 ,0x00 ,0x01 ,0x00 , +0x02 ,0x00 ,0x02 ,0x00 ,0x06 ,0x00 ,0x04 ,0x00 ,0x0c ,0x00 ,0x08 ,0x00 ,0x18 ,0x00 ,0x10 ,0x00 , +0x10 ,0x00 ,0x20 ,0x00 ,0x20 ,0x00 ,0x40 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x07 ,0xc0 ,0x0c ,0x30 ,0x18 ,0x30 ,0x18 ,0x18 , +0x38 ,0x18 ,0x30 ,0x1c ,0x30 ,0x0c ,0x30 ,0x0c ,0x70 ,0x0c ,0x70 ,0x0c ,0x70 ,0x0c ,0x70 ,0x0c , +0x70 ,0x0c ,0x30 ,0x0c ,0x30 ,0x0c ,0x30 ,0x1c ,0x30 ,0x18 ,0x18 ,0x18 ,0x18 ,0x18 ,0x0c ,0x30 , +0x06 ,0x60 ,0x01 ,0x80 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x80 ,0x03 ,0x80 ,0x07 ,0x80 ,0x01 ,0x80 , +0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 , +0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 , +0x07 ,0xf0 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x07 ,0xe0 ,0x18 ,0x30 ,0x10 ,0x18 ,0x30 ,0x18 , +0x30 ,0x1c ,0x38 ,0x1c ,0x38 ,0x18 ,0x00 ,0x18 ,0x00 ,0x18 ,0x00 ,0x30 ,0x00 ,0x60 ,0x00 ,0x40 , +0x00 ,0x80 ,0x01 ,0x00 ,0x02 ,0x00 ,0x04 ,0x00 ,0x08 ,0x04 ,0x10 ,0x04 ,0x30 ,0x0c ,0x20 ,0x38 , +0x3f ,0xf8 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x0f ,0xc0 ,0x18 ,0x30 ,0x30 ,0x30 ,0x30 ,0x18 , +0x38 ,0x18 ,0x10 ,0x18 ,0x00 ,0x18 ,0x00 ,0x30 ,0x00 ,0x60 ,0x03 ,0xc0 ,0x01 ,0xe0 ,0x00 ,0x30 , +0x00 ,0x18 ,0x00 ,0x18 ,0x00 ,0x0c ,0x00 ,0x0c ,0x30 ,0x0c ,0x38 ,0x1c ,0x30 ,0x18 ,0x30 ,0x30 , +0x0c ,0x60 ,0x03 ,0x80 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x20 ,0x00 ,0x60 ,0x00 ,0xe0 ,0x00 ,0xe0 , +0x01 ,0x60 ,0x03 ,0x60 ,0x02 ,0x60 ,0x04 ,0x60 ,0x04 ,0x60 ,0x08 ,0x60 ,0x10 ,0x60 ,0x10 ,0x60 , +0x20 ,0x60 ,0x60 ,0x60 ,0x7f ,0xfe ,0x00 ,0x60 ,0x00 ,0x60 ,0x00 ,0x60 ,0x00 ,0x60 ,0x00 ,0x60 , +0x01 ,0xfc ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x1f ,0xf8 ,0x1f ,0xf8 ,0x10 ,0x00 ,0x10 ,0x00 , +0x10 ,0x00 ,0x10 ,0x00 ,0x10 ,0x00 ,0x10 ,0x00 ,0x17 ,0xe0 ,0x18 ,0x30 ,0x10 ,0x18 ,0x00 ,0x18 , +0x00 ,0x0c ,0x00 ,0x0c ,0x00 ,0x0c ,0x10 ,0x0c ,0x38 ,0x0c ,0x30 ,0x18 ,0x30 ,0x18 ,0x10 ,0x30 , +0x0c ,0x60 ,0x03 ,0x80 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x03 ,0xf0 ,0x04 ,0x18 ,0x08 ,0x18 ,0x18 ,0x18 , +0x10 ,0x00 ,0x30 ,0x00 ,0x30 ,0x00 ,0x30 ,0x00 ,0x33 ,0xf0 ,0x74 ,0x38 ,0x78 ,0x18 ,0x70 ,0x0c , +0x70 ,0x0c ,0x70 ,0x0c ,0x30 ,0x0c ,0x30 ,0x0c ,0x30 ,0x0c ,0x30 ,0x0c ,0x18 ,0x08 ,0x1c ,0x18 , +0x0e ,0x70 ,0x01 ,0x80 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x1f ,0xfc ,0x3f ,0xfc ,0x30 ,0x08 ,0x20 ,0x10 , +0x20 ,0x10 ,0x00 ,0x20 ,0x00 ,0x20 ,0x00 ,0x60 ,0x00 ,0x40 ,0x00 ,0xc0 ,0x00 ,0x80 ,0x01 ,0x80 , +0x01 ,0x80 ,0x01 ,0x80 ,0x03 ,0x00 ,0x03 ,0x00 ,0x03 ,0x00 ,0x03 ,0x00 ,0x03 ,0x00 ,0x07 ,0x00 , +0x03 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x0f ,0xe0 ,0x18 ,0x10 ,0x30 ,0x18 ,0x30 ,0x0c , +0x30 ,0x0c ,0x30 ,0x0c ,0x30 ,0x08 ,0x38 ,0x18 ,0x1e ,0x30 ,0x0f ,0xe0 ,0x07 ,0xe0 ,0x18 ,0xf0 , +0x30 ,0x38 ,0x30 ,0x18 ,0x60 ,0x0c ,0x60 ,0x0c ,0x60 ,0x0c ,0x60 ,0x0c ,0x30 ,0x08 ,0x10 ,0x18 , +0x0c ,0x70 ,0x03 ,0x80 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x0f ,0xc0 ,0x18 ,0x30 ,0x30 ,0x18 ,0x30 ,0x18 , +0x70 ,0x18 ,0x60 ,0x0c ,0x60 ,0x0c ,0x60 ,0x0c ,0x70 ,0x0c ,0x30 ,0x1c ,0x30 ,0x2c ,0x38 ,0x6c , +0x0f ,0xcc ,0x00 ,0x1c ,0x00 ,0x1c ,0x00 ,0x18 ,0x00 ,0x18 ,0x10 ,0x30 ,0x38 ,0x30 ,0x38 ,0x60 , +0x18 ,0xc0 ,0x07 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x03 ,0x80 ,0x03 ,0x80 ,0x03 ,0x80 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x01 ,0x80 ,0x03 ,0x80 , +0x03 ,0x80 ,0x01 ,0x80 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x03 ,0x80 ,0x03 ,0x80 ,0x03 ,0x80 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x03 ,0x80 , +0x03 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x00 ,0x03 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x08 ,0x00 ,0x10 ,0x00 ,0x20 ,0x00 ,0x40 , +0x00 ,0x80 ,0x01 ,0x00 ,0x02 ,0x00 ,0x04 ,0x00 ,0x08 ,0x00 ,0x10 ,0x00 ,0x30 ,0x00 ,0x18 ,0x00 , +0x0c ,0x00 ,0x06 ,0x00 ,0x03 ,0x00 ,0x01 ,0x80 ,0x00 ,0xc0 ,0x00 ,0x60 ,0x00 ,0x30 ,0x00 ,0x18 , +0x00 ,0x0c ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x7f ,0xfe ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x7f ,0xfe ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x20 ,0x00 ,0x30 ,0x00 ,0x18 ,0x00 ,0x0c ,0x00 ,0x06 ,0x00 , +0x03 ,0x00 ,0x01 ,0x80 ,0x00 ,0xc0 ,0x00 ,0x60 ,0x00 ,0x30 ,0x00 ,0x18 ,0x00 ,0x0c ,0x00 ,0x18 , +0x00 ,0x30 ,0x00 ,0x60 ,0x00 ,0xc0 ,0x01 ,0x80 ,0x03 ,0x00 ,0x06 ,0x00 ,0x0c ,0x00 ,0x18 ,0x00 , +0x30 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x01 ,0x80 ,0x0f ,0xf0 ,0x10 ,0x18 ,0x30 ,0x1c ,0x20 ,0x0c , +0x20 ,0x0c ,0x30 ,0x0c ,0x38 ,0x0c ,0x10 ,0x1c ,0x00 ,0x18 ,0x00 ,0x30 ,0x00 ,0xe0 ,0x01 ,0x80 , +0x01 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x01 ,0x80 ,0x03 ,0x80 , +0x03 ,0x80 ,0x01 ,0x80 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x03 ,0xf0 ,0x0c ,0x18 ,0x08 ,0x04 ,0x10 ,0x04 , +0x30 ,0xf2 ,0x21 ,0x12 ,0x23 ,0x32 ,0x62 ,0x32 ,0x66 ,0x32 ,0x66 ,0x32 ,0x64 ,0x22 ,0x64 ,0x22 , +0x64 ,0x22 ,0x64 ,0x64 ,0x64 ,0x64 ,0x26 ,0xb8 ,0x33 ,0x10 ,0x10 ,0x02 ,0x18 ,0x04 ,0x08 ,0x08 , +0x06 ,0x70 ,0x01 ,0x80 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x01 ,0x80 ,0x03 ,0x80 ,0x03 ,0x80 ,0x02 ,0xc0 , +0x02 ,0xc0 ,0x04 ,0xc0 ,0x04 ,0xc0 ,0x04 ,0x60 ,0x04 ,0x60 ,0x08 ,0x60 ,0x08 ,0x60 ,0x08 ,0x30 , +0x08 ,0x30 ,0x17 ,0xf0 ,0x10 ,0x30 ,0x10 ,0x30 ,0x10 ,0x18 ,0x20 ,0x18 ,0x20 ,0x18 ,0x20 ,0x18 , +0x70 ,0x3e ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x7f ,0xe0 ,0x38 ,0x38 ,0x38 ,0x18 ,0x38 ,0x1c , +0x38 ,0x0c ,0x38 ,0x0c ,0x38 ,0x1c ,0x38 ,0x18 ,0x38 ,0x30 ,0x3f ,0xc0 ,0x38 ,0x70 ,0x38 ,0x18 , +0x38 ,0x0c ,0x38 ,0x0c ,0x38 ,0x0e ,0x38 ,0x0e ,0x38 ,0x0e ,0x38 ,0x0e ,0x38 ,0x0c ,0x38 ,0x18 , +0x7f ,0xf0 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x03 ,0xfc ,0x0c ,0x0c ,0x18 ,0x04 ,0x18 ,0x04 , +0x30 ,0x02 ,0x30 ,0x00 ,0x70 ,0x00 ,0x60 ,0x00 ,0x60 ,0x00 ,0x60 ,0x00 ,0x60 ,0x00 ,0x60 ,0x00 , +0x60 ,0x00 ,0x60 ,0x00 ,0x70 ,0x00 ,0x70 ,0x02 ,0x30 ,0x02 ,0x30 ,0x04 ,0x18 ,0x04 ,0x1c ,0x08 , +0x07 ,0xf0 ,0x01 ,0x80 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x7f ,0x80 ,0x38 ,0x60 ,0x38 ,0x30 ,0x38 ,0x18 , +0x38 ,0x0c ,0x38 ,0x0c ,0x38 ,0x0c ,0x38 ,0x0e ,0x38 ,0x0e ,0x38 ,0x0e ,0x38 ,0x0e ,0x38 ,0x0e , +0x38 ,0x0e ,0x38 ,0x0e ,0x38 ,0x0c ,0x38 ,0x0c ,0x38 ,0x0c ,0x38 ,0x18 ,0x38 ,0x18 ,0x38 ,0x70 , +0x3f ,0xc0 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x7f ,0xf8 ,0x18 ,0x1c ,0x18 ,0x04 ,0x18 ,0x04 , +0x18 ,0x00 ,0x18 ,0x00 ,0x18 ,0x00 ,0x18 ,0x20 ,0x18 ,0x20 ,0x1f ,0xe0 ,0x18 ,0x60 ,0x18 ,0x20 , +0x18 ,0x20 ,0x18 ,0x00 ,0x18 ,0x00 ,0x18 ,0x00 ,0x18 ,0x02 ,0x18 ,0x02 ,0x18 ,0x04 ,0x18 ,0x0c , +0x7f ,0xfc ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x7f ,0xfc ,0x18 ,0x0c ,0x18 ,0x06 ,0x18 ,0x02 , +0x18 ,0x02 ,0x18 ,0x00 ,0x18 ,0x00 ,0x18 ,0x10 ,0x18 ,0x10 ,0x18 ,0x30 ,0x1f ,0xf0 ,0x18 ,0x10 , +0x18 ,0x10 ,0x18 ,0x10 ,0x18 ,0x00 ,0x18 ,0x00 ,0x18 ,0x00 ,0x18 ,0x00 ,0x18 ,0x00 ,0x18 ,0x00 , +0x7c ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x07 ,0xf8 ,0x0c ,0x38 ,0x18 ,0x18 ,0x10 ,0x08 , +0x30 ,0x08 ,0x30 ,0x00 ,0x60 ,0x00 ,0x60 ,0x00 ,0x60 ,0x00 ,0x60 ,0x00 ,0x60 ,0x00 ,0x60 ,0x00 , +0x60 ,0x7e ,0x60 ,0x18 ,0x60 ,0x18 ,0x70 ,0x18 ,0x30 ,0x18 ,0x30 ,0x18 ,0x18 ,0x18 ,0x18 ,0x18 , +0x0e ,0x20 ,0x01 ,0xc0 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0xfc ,0x3e ,0x30 ,0x1c ,0x30 ,0x1c ,0x30 ,0x1c , +0x30 ,0x1c ,0x30 ,0x1c ,0x30 ,0x1c ,0x30 ,0x1c ,0x30 ,0x1c ,0x30 ,0x1c ,0x3f ,0xfc ,0x30 ,0x1c , +0x30 ,0x1c ,0x30 ,0x1c ,0x30 ,0x1c ,0x30 ,0x1c ,0x30 ,0x1c ,0x30 ,0x1c ,0x30 ,0x1c ,0x30 ,0x1c , +0x78 ,0x3e ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x1f ,0xf8 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 , +0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 , +0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 , +0x1f ,0xf0 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x07 ,0xfe ,0x00 ,0x60 ,0x00 ,0x60 ,0x00 ,0x60 , +0x00 ,0x60 ,0x00 ,0x60 ,0x00 ,0x60 ,0x00 ,0x60 ,0x00 ,0x60 ,0x00 ,0x60 ,0x00 ,0x60 ,0x00 ,0x60 , +0x00 ,0x60 ,0x00 ,0x60 ,0x00 ,0x60 ,0x00 ,0x60 ,0x00 ,0x60 ,0x00 ,0x60 ,0x30 ,0x40 ,0x30 ,0xc0 , +0x3f ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x7c ,0x7e ,0x38 ,0x18 ,0x38 ,0x30 ,0x38 ,0x20 , +0x38 ,0x40 ,0x38 ,0x80 ,0x38 ,0x80 ,0x39 ,0x00 ,0x3b ,0x00 ,0x3f ,0x80 ,0x3d ,0x80 ,0x39 ,0x80 , +0x38 ,0xc0 ,0x38 ,0xc0 ,0x38 ,0x60 ,0x38 ,0x60 ,0x38 ,0x30 ,0x38 ,0x30 ,0x38 ,0x18 ,0x38 ,0x18 , +0x7c ,0x3e ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x7e ,0x00 ,0x18 ,0x00 ,0x18 ,0x00 ,0x18 ,0x00 , +0x18 ,0x00 ,0x18 ,0x00 ,0x18 ,0x00 ,0x18 ,0x00 ,0x18 ,0x00 ,0x18 ,0x00 ,0x18 ,0x00 ,0x18 ,0x00 , +0x18 ,0x00 ,0x18 ,0x00 ,0x18 ,0x00 ,0x18 ,0x00 ,0x18 ,0x02 ,0x18 ,0x02 ,0x18 ,0x04 ,0x18 ,0x0c , +0x7f ,0xfc ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0xf0 ,0x1f ,0x30 ,0x1c ,0x30 ,0x1c ,0x38 ,0x1c , +0x38 ,0x2c ,0x38 ,0x2c ,0x38 ,0x2c ,0x28 ,0x2c ,0x2c ,0x4c ,0x2c ,0x4c ,0x2c ,0x4c ,0x2c ,0x4c , +0x24 ,0x8c ,0x26 ,0x8c ,0x26 ,0x8c ,0x26 ,0x8c ,0x22 ,0x8c ,0x23 ,0x0c ,0x23 ,0x0c ,0x23 ,0x0c , +0x73 ,0x1e ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0xf0 ,0x1f ,0x38 ,0x04 ,0x38 ,0x04 ,0x2c ,0x04 , +0x2c ,0x04 ,0x26 ,0x04 ,0x26 ,0x04 ,0x23 ,0x04 ,0x23 ,0x04 ,0x21 ,0x84 ,0x21 ,0x84 ,0x20 ,0xc4 , +0x20 ,0xc4 ,0x20 ,0x64 ,0x20 ,0x74 ,0x20 ,0x34 ,0x20 ,0x3c ,0x20 ,0x1c ,0x20 ,0x1c ,0x20 ,0x0c , +0x78 ,0x0c ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x07 ,0xe0 ,0x0c ,0x30 ,0x18 ,0x18 ,0x30 ,0x08 , +0x30 ,0x0c ,0x30 ,0x0c ,0x70 ,0x0e ,0x70 ,0x0e ,0x60 ,0x06 ,0x60 ,0x06 ,0x60 ,0x06 ,0x60 ,0x06 , +0x60 ,0x06 ,0x60 ,0x06 ,0x70 ,0x0e ,0x30 ,0x0c ,0x30 ,0x0c ,0x30 ,0x0c ,0x18 ,0x18 ,0x08 ,0x10 , +0x06 ,0x60 ,0x01 ,0x80 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x7f ,0xe0 ,0x18 ,0x18 ,0x18 ,0x0c ,0x18 ,0x0c , +0x18 ,0x0e ,0x18 ,0x0e ,0x18 ,0x0e ,0x18 ,0x0c ,0x18 ,0x0c ,0x18 ,0x18 ,0x18 ,0x70 ,0x1f ,0x80 , +0x18 ,0x00 ,0x18 ,0x00 ,0x18 ,0x00 ,0x18 ,0x00 ,0x18 ,0x00 ,0x18 ,0x00 ,0x18 ,0x00 ,0x18 ,0x00 , +0x7c ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x07 ,0xe0 ,0x0c ,0x30 ,0x18 ,0x18 ,0x30 ,0x08 , +0x30 ,0x0c ,0x30 ,0x0c ,0x70 ,0x0c ,0x60 ,0x0e ,0x60 ,0x0e ,0x60 ,0x0e ,0x60 ,0x0e ,0x60 ,0x0e , +0x60 ,0x0e ,0x60 ,0x0e ,0x60 ,0x0e ,0x77 ,0x8c ,0x3d ,0xcc ,0x38 ,0xcc ,0x18 ,0x58 ,0x18 ,0x70 , +0x06 ,0x60 ,0x01 ,0xf0 ,0x00 ,0x3c ,0x00 ,0x3c ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x7f ,0xe0 ,0x18 ,0x38 ,0x18 ,0x18 ,0x18 ,0x0c , +0x18 ,0x0c ,0x18 ,0x0c ,0x18 ,0x0c ,0x18 ,0x1c ,0x18 ,0x18 ,0x18 ,0x70 ,0x1f ,0xc0 ,0x18 ,0xc0 , +0x18 ,0xc0 ,0x18 ,0x60 ,0x18 ,0x60 ,0x18 ,0x30 ,0x18 ,0x30 ,0x18 ,0x30 ,0x18 ,0x18 ,0x18 ,0x18 , +0x7c ,0x1e ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x0f ,0xe8 ,0x10 ,0x38 ,0x30 ,0x18 ,0x20 ,0x08 , +0x20 ,0x08 ,0x20 ,0x00 ,0x30 ,0x00 ,0x38 ,0x00 ,0x1c ,0x00 ,0x0f ,0x80 ,0x03 ,0xe0 ,0x00 ,0xf0 , +0x00 ,0x38 ,0x00 ,0x18 ,0x00 ,0x0c ,0x40 ,0x0c ,0x40 ,0x0c ,0x20 ,0x0c ,0x20 ,0x08 ,0x30 ,0x18 , +0x3c ,0x70 ,0x03 ,0x80 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x3f ,0xfc ,0x21 ,0x8c ,0x61 ,0x84 ,0x41 ,0x84 , +0x41 ,0x82 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 , +0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 , +0x07 ,0xe0 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0xfc ,0x1e ,0x30 ,0x08 ,0x30 ,0x08 ,0x30 ,0x08 , +0x30 ,0x08 ,0x30 ,0x08 ,0x30 ,0x08 ,0x30 ,0x08 ,0x30 ,0x08 ,0x30 ,0x08 ,0x30 ,0x08 ,0x30 ,0x08 , +0x30 ,0x08 ,0x30 ,0x08 ,0x30 ,0x08 ,0x30 ,0x08 ,0x30 ,0x08 ,0x30 ,0x08 ,0x30 ,0x08 ,0x18 ,0x10 , +0x0e ,0x60 ,0x01 ,0x80 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0xfc ,0x3e ,0x30 ,0x08 ,0x30 ,0x08 ,0x18 ,0x08 , +0x18 ,0x10 ,0x18 ,0x10 ,0x18 ,0x10 ,0x0c ,0x10 ,0x0c ,0x20 ,0x0c ,0x20 ,0x0c ,0x20 ,0x06 ,0x40 , +0x06 ,0x40 ,0x06 ,0x40 ,0x06 ,0x40 ,0x03 ,0x80 ,0x03 ,0x80 ,0x03 ,0x80 ,0x03 ,0x80 ,0x01 ,0x00 , +0x01 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0xfb ,0xcf ,0x61 ,0x84 ,0x61 ,0x84 ,0x21 ,0x84 , +0x31 ,0x84 ,0x31 ,0x84 ,0x31 ,0xc8 ,0x31 ,0xc8 ,0x31 ,0xc8 ,0x12 ,0xc8 ,0x12 ,0xc8 ,0x1a ,0x50 , +0x1a ,0x50 ,0x1a ,0x70 ,0x1c ,0x70 ,0x1c ,0x70 ,0x0c ,0x70 ,0x0c ,0x60 ,0x0c ,0x20 ,0x0c ,0x20 , +0x08 ,0x20 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x7c ,0x3e ,0x18 ,0x18 ,0x18 ,0x10 ,0x0c ,0x10 , +0x0c ,0x20 ,0x06 ,0x20 ,0x06 ,0x40 ,0x02 ,0x40 ,0x03 ,0x80 ,0x03 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 , +0x02 ,0xc0 ,0x02 ,0xc0 ,0x04 ,0x60 ,0x04 ,0x60 ,0x0c ,0x30 ,0x08 ,0x30 ,0x08 ,0x18 ,0x10 ,0x18 , +0x78 ,0x3e ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x7c ,0x3e ,0x30 ,0x08 ,0x18 ,0x08 ,0x18 ,0x10 , +0x18 ,0x10 ,0x0c ,0x20 ,0x0c ,0x20 ,0x06 ,0x20 ,0x06 ,0x40 ,0x06 ,0x40 ,0x03 ,0x40 ,0x03 ,0x80 , +0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 , +0x07 ,0xe0 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x1f ,0xfc ,0x18 ,0x0c ,0x30 ,0x18 ,0x20 ,0x18 , +0x00 ,0x30 ,0x00 ,0x70 ,0x00 ,0x60 ,0x00 ,0xe0 ,0x00 ,0xc0 ,0x01 ,0x80 ,0x01 ,0x80 ,0x03 ,0x00 , +0x03 ,0x00 ,0x06 ,0x00 ,0x06 ,0x00 ,0x0c ,0x00 ,0x0c ,0x00 ,0x18 ,0x04 ,0x18 ,0x04 ,0x30 ,0x0c , +0x7f ,0xf8 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x03 ,0xfc ,0x03 ,0xfc ,0x02 ,0x00 ,0x02 ,0x00 ,0x02 ,0x00 ,0x02 ,0x00 ,0x02 ,0x00 ,0x02 ,0x00 , +0x02 ,0x00 ,0x02 ,0x00 ,0x02 ,0x00 ,0x02 ,0x00 ,0x02 ,0x00 ,0x02 ,0x00 ,0x02 ,0x00 ,0x02 ,0x00 , +0x02 ,0x00 ,0x02 ,0x00 ,0x02 ,0x00 ,0x02 ,0x00 ,0x02 ,0x00 ,0x02 ,0x00 ,0x02 ,0x00 ,0x02 ,0x00 , +0x02 ,0x00 ,0x02 ,0x00 ,0x02 ,0x00 ,0x03 ,0xfc ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x10 ,0x00 ,0x10 ,0x00 ,0x18 ,0x00 ,0x08 ,0x00 ,0x0c ,0x00 , +0x04 ,0x00 ,0x04 ,0x00 ,0x06 ,0x00 ,0x02 ,0x00 ,0x03 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00 ,0x01 ,0x80 , +0x00 ,0x80 ,0x00 ,0xc0 ,0x00 ,0x40 ,0x00 ,0x40 ,0x00 ,0x60 ,0x00 ,0x20 ,0x00 ,0x30 ,0x00 ,0x10 , +0x00 ,0x10 ,0x00 ,0x18 ,0x00 ,0x08 ,0x00 ,0x0c ,0x00 ,0x04 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x3f ,0xc0 ,0x3f ,0xc0 ,0x00 ,0xc0 ,0x00 ,0xc0 ,0x00 ,0xc0 ,0x00 ,0xc0 ,0x00 ,0xc0 ,0x00 ,0xc0 , +0x00 ,0xc0 ,0x00 ,0xc0 ,0x00 ,0xc0 ,0x00 ,0xc0 ,0x00 ,0xc0 ,0x00 ,0xc0 ,0x00 ,0xc0 ,0x00 ,0xc0 , +0x00 ,0xc0 ,0x00 ,0xc0 ,0x00 ,0xc0 ,0x00 ,0xc0 ,0x00 ,0xc0 ,0x00 ,0xc0 ,0x00 ,0xc0 ,0x00 ,0xc0 , +0x00 ,0xc0 ,0x00 ,0xc0 ,0x00 ,0xc0 ,0x3f ,0xc0 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x03 ,0xc0 ,0x06 ,0xe0 ,0x0c ,0x20 ,0x00 ,0x10 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0xff ,0xff ,0x00 ,0x00 ,0x00 ,0x00 , +0x1e ,0x00 ,0x07 ,0x00 ,0x01 ,0x80 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x07 ,0xc0 ,0x18 ,0x30 ,0x30 ,0x10 ,0x30 ,0x18 ,0x00 ,0x18 , +0x00 ,0x78 ,0x07 ,0x98 ,0x18 ,0x18 ,0x30 ,0x18 ,0x70 ,0x18 ,0x60 ,0x18 ,0x60 ,0x18 ,0x30 ,0x3a , +0x1f ,0xde ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x10 ,0x00 ,0x70 ,0x00 ,0x30 ,0x00 ,0x30 ,0x00 ,0x30 ,0x00 , +0x30 ,0x00 ,0x30 ,0x00 ,0x30 ,0x00 ,0x31 ,0xc0 ,0x32 ,0x30 ,0x34 ,0x18 ,0x38 ,0x0c ,0x38 ,0x0c , +0x30 ,0x0c ,0x30 ,0x0c ,0x30 ,0x0c ,0x30 ,0x0c ,0x30 ,0x0c ,0x30 ,0x0c ,0x30 ,0x18 ,0x38 ,0x18 , +0x37 ,0xf0 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x03 ,0xe0 ,0x0c ,0x30 ,0x18 ,0x18 ,0x18 ,0x18 ,0x30 ,0x18 , +0x30 ,0x00 ,0x30 ,0x00 ,0x30 ,0x00 ,0x30 ,0x00 ,0x30 ,0x00 ,0x30 ,0x04 ,0x18 ,0x08 ,0x18 ,0x08 , +0x0f ,0x70 ,0x00 ,0xc0 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x08 ,0x00 ,0x78 ,0x00 ,0x18 ,0x00 ,0x18 ,0x00 ,0x18 , +0x00 ,0x18 ,0x00 ,0x18 ,0x00 ,0x18 ,0x03 ,0x98 ,0x0e ,0x78 ,0x18 ,0x18 ,0x18 ,0x18 ,0x30 ,0x18 , +0x30 ,0x18 ,0x30 ,0x18 ,0x30 ,0x18 ,0x30 ,0x18 ,0x30 ,0x18 ,0x30 ,0x18 ,0x10 ,0x18 ,0x18 ,0x38 , +0x0f ,0xde ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x03 ,0xc0 ,0x0c ,0x30 ,0x18 ,0x18 ,0x10 ,0x18 ,0x30 ,0x0c , +0x30 ,0x0c ,0x30 ,0x0c ,0x3f ,0xf0 ,0x30 ,0x00 ,0x30 ,0x00 ,0x30 ,0x00 ,0x18 ,0x08 ,0x18 ,0x08 , +0x07 ,0x70 ,0x00 ,0xc0 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0xf8 ,0x01 ,0x06 ,0x03 ,0x06 ,0x02 ,0x04 , +0x02 ,0x00 ,0x06 ,0x00 ,0x06 ,0x00 ,0x3f ,0xf8 ,0x06 ,0x00 ,0x06 ,0x00 ,0x06 ,0x00 ,0x06 ,0x00 , +0x06 ,0x00 ,0x06 ,0x00 ,0x06 ,0x00 ,0x06 ,0x00 ,0x06 ,0x00 ,0x06 ,0x00 ,0x06 ,0x00 ,0x06 ,0x00 , +0x1f ,0xe0 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x03 ,0x8e ,0x0c ,0x76 ,0x18 ,0x30 ,0x10 ,0x10 ,0x10 ,0x10 , +0x10 ,0x10 ,0x18 ,0x10 ,0x08 ,0x30 ,0x0e ,0xe0 ,0x11 ,0x00 ,0x10 ,0x00 ,0x1f ,0x80 ,0x0f ,0xf8 , +0x10 ,0x3c ,0x20 ,0x0c ,0x20 ,0x0c ,0x20 ,0x0c ,0x10 ,0x18 ,0x0f ,0xf0 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x10 ,0x00 ,0x70 ,0x00 ,0x10 ,0x00 ,0x10 ,0x00 ,0x10 ,0x00 , +0x10 ,0x00 ,0x10 ,0x00 ,0x10 ,0x00 ,0x11 ,0xe0 ,0x17 ,0x30 ,0x1c ,0x18 ,0x18 ,0x18 ,0x10 ,0x18 , +0x10 ,0x18 ,0x10 ,0x18 ,0x10 ,0x18 ,0x10 ,0x18 ,0x10 ,0x18 ,0x10 ,0x18 ,0x10 ,0x18 ,0x10 ,0x18 , +0x7c ,0x3c ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x01 ,0x80 ,0x03 ,0xc0 ,0x01 ,0x80 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x80 ,0x1f ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 , +0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 , +0x0f ,0xf0 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x38 ,0x00 ,0x38 ,0x00 ,0x30 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x01 ,0xf0 ,0x00 ,0x30 ,0x00 ,0x30 ,0x00 ,0x30 ,0x00 ,0x30 , +0x00 ,0x30 ,0x00 ,0x30 ,0x00 ,0x30 ,0x00 ,0x30 ,0x00 ,0x30 ,0x00 ,0x30 ,0x00 ,0x30 ,0x00 ,0x30 , +0x00 ,0x30 ,0x00 ,0x30 ,0x00 ,0x30 ,0x38 ,0x20 ,0x18 ,0x60 ,0x0f ,0x80 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x08 ,0x00 ,0x78 ,0x00 ,0x18 ,0x00 ,0x18 ,0x00 ,0x18 ,0x00 , +0x18 ,0x00 ,0x18 ,0x00 ,0x18 ,0x00 ,0x18 ,0x7c ,0x18 ,0x30 ,0x18 ,0x60 ,0x18 ,0x40 ,0x18 ,0x80 , +0x19 ,0x00 ,0x1b ,0x80 ,0x1c ,0xc0 ,0x18 ,0xc0 ,0x18 ,0x60 ,0x18 ,0x70 ,0x18 ,0x30 ,0x18 ,0x18 , +0x7c ,0x3c ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x01 ,0x80 ,0x1f ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 , +0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 , +0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 , +0x1f ,0xf0 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0xe7 ,0x38 ,0x69 ,0xcc ,0x71 ,0x84 ,0x61 ,0x86 ,0x61 ,0x86 , +0x61 ,0x86 ,0x61 ,0x86 ,0x61 ,0x86 ,0x61 ,0x86 ,0x61 ,0x86 ,0x61 ,0x86 ,0x61 ,0x86 ,0x61 ,0x86 , +0x73 ,0xce ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x71 ,0xe0 ,0x12 ,0x30 ,0x1c ,0x18 ,0x18 ,0x18 ,0x10 ,0x18 , +0x10 ,0x18 ,0x10 ,0x18 ,0x10 ,0x18 ,0x10 ,0x18 ,0x10 ,0x18 ,0x10 ,0x18 ,0x10 ,0x18 ,0x10 ,0x18 , +0x7c ,0x3c ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x03 ,0xc0 ,0x0c ,0x30 ,0x18 ,0x18 ,0x30 ,0x08 ,0x30 ,0x0c , +0x30 ,0x0c ,0x60 ,0x0c ,0x60 ,0x0c ,0x60 ,0x0c ,0x30 ,0x0c ,0x30 ,0x0c ,0x30 ,0x08 ,0x18 ,0x18 , +0x0c ,0x20 ,0x03 ,0xc0 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x71 ,0xc0 ,0x36 ,0x30 ,0x14 ,0x18 ,0x18 ,0x0c ,0x10 ,0x0c , +0x10 ,0x0c ,0x10 ,0x0c ,0x10 ,0x0c ,0x10 ,0x0c ,0x10 ,0x0c ,0x10 ,0x0c ,0x18 ,0x18 ,0x18 ,0x18 , +0x16 ,0x70 ,0x11 ,0x80 ,0x10 ,0x00 ,0x10 ,0x00 ,0x10 ,0x00 ,0x7e ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x03 ,0x88 ,0x0c ,0x68 ,0x18 ,0x18 ,0x30 ,0x18 ,0x30 ,0x18 , +0x30 ,0x18 ,0x30 ,0x18 ,0x30 ,0x18 ,0x30 ,0x18 ,0x30 ,0x18 ,0x30 ,0x18 ,0x30 ,0x18 ,0x18 ,0x38 , +0x0f ,0xd8 ,0x00 ,0x18 ,0x00 ,0x18 ,0x00 ,0x18 ,0x00 ,0x18 ,0x00 ,0x7e ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x7c ,0x38 ,0x0c ,0x4c ,0x0c ,0x8c ,0x0d ,0x00 ,0x0e ,0x00 , +0x0c ,0x00 ,0x0c ,0x00 ,0x0c ,0x00 ,0x0c ,0x00 ,0x0c ,0x00 ,0x0c ,0x00 ,0x0c ,0x00 ,0x0c ,0x00 , +0x7f ,0xc0 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x03 ,0xc8 ,0x0c ,0x38 ,0x18 ,0x18 ,0x18 ,0x08 ,0x18 ,0x00 , +0x1c ,0x00 ,0x0f ,0x80 ,0x01 ,0xe0 ,0x00 ,0x78 ,0x00 ,0x18 ,0x10 ,0x0c ,0x10 ,0x08 ,0x18 ,0x08 , +0x1f ,0xf0 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x02 ,0x00 , +0x02 ,0x00 ,0x02 ,0x00 ,0x06 ,0x00 ,0x3f ,0xf0 ,0x02 ,0x00 ,0x02 ,0x00 ,0x02 ,0x00 ,0x02 ,0x00 , +0x02 ,0x00 ,0x02 ,0x00 ,0x02 ,0x00 ,0x02 ,0x00 ,0x02 ,0x00 ,0x02 ,0x04 ,0x02 ,0x08 ,0x03 ,0x08 , +0x01 ,0xf0 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x70 ,0x78 ,0x30 ,0x18 ,0x30 ,0x18 ,0x30 ,0x18 ,0x30 ,0x18 , +0x30 ,0x18 ,0x30 ,0x18 ,0x30 ,0x18 ,0x30 ,0x18 ,0x30 ,0x18 ,0x10 ,0x18 ,0x10 ,0x18 ,0x18 ,0x38 , +0x0f ,0xde ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x7c ,0x3e ,0x18 ,0x18 ,0x18 ,0x10 ,0x18 ,0x10 ,0x0c ,0x10 , +0x0c ,0x20 ,0x0c ,0x20 ,0x06 ,0x20 ,0x06 ,0x40 ,0x02 ,0x40 ,0x03 ,0x80 ,0x03 ,0x80 ,0x01 ,0x80 , +0x01 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0xfb ,0xdf ,0x61 ,0x84 ,0x21 ,0x84 ,0x31 ,0x84 ,0x31 ,0x88 , +0x31 ,0xc8 ,0x12 ,0xc8 ,0x12 ,0xc8 ,0x1a ,0x50 ,0x1a ,0x50 ,0x0c ,0x70 ,0x0c ,0x70 ,0x0c ,0x20 , +0x0c ,0x20 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x3e ,0x7c ,0x1c ,0x10 ,0x0c ,0x30 ,0x06 ,0x20 ,0x06 ,0x40 , +0x03 ,0xc0 ,0x01 ,0x80 ,0x01 ,0x80 ,0x03 ,0xc0 ,0x02 ,0x40 ,0x04 ,0x60 ,0x08 ,0x30 ,0x08 ,0x30 , +0x78 ,0x7c ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x7e ,0x7e ,0x18 ,0x18 ,0x18 ,0x10 ,0x0c ,0x10 ,0x0c ,0x30 , +0x0c ,0x20 ,0x06 ,0x20 ,0x06 ,0x60 ,0x02 ,0x40 ,0x03 ,0x40 ,0x03 ,0x80 ,0x01 ,0x80 ,0x01 ,0x80 , +0x01 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00 ,0x02 ,0x00 ,0x3e ,0x00 ,0x1c ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x1f ,0xf8 ,0x38 ,0x30 ,0x30 ,0x30 ,0x20 ,0x60 ,0x20 ,0xc0 , +0x00 ,0xc0 ,0x01 ,0x80 ,0x03 ,0x00 ,0x03 ,0x00 ,0x06 ,0x04 ,0x0c ,0x08 ,0x0c ,0x08 ,0x18 ,0x08 , +0x3f ,0xf8 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x0c ,0x00 ,0x30 ,0x00 ,0x20 ,0x00 ,0x60 ,0x00 ,0x60 ,0x00 ,0x60 ,0x00 ,0x60 ,0x00 ,0x60 , +0x00 ,0x60 ,0x00 ,0x60 ,0x00 ,0x60 ,0x00 ,0x40 ,0x00 ,0x40 ,0x00 ,0xc0 ,0x01 ,0x00 ,0x00 ,0xc0 , +0x00 ,0x40 ,0x00 ,0x40 ,0x00 ,0x60 ,0x00 ,0x60 ,0x00 ,0x60 ,0x00 ,0x60 ,0x00 ,0x60 ,0x00 ,0x60 , +0x00 ,0x60 ,0x00 ,0x20 ,0x00 ,0x20 ,0x00 ,0x38 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x01 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00 , +0x01 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00 , +0x01 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00 , +0x01 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x30 ,0x00 ,0x0c ,0x00 ,0x04 ,0x00 ,0x04 ,0x00 ,0x04 ,0x00 ,0x04 ,0x00 ,0x04 ,0x00 ,0x04 ,0x00 , +0x04 ,0x00 ,0x04 ,0x00 ,0x04 ,0x00 ,0x04 ,0x00 ,0x06 ,0x00 ,0x03 ,0x00 ,0x00 ,0x80 ,0x03 ,0x00 , +0x06 ,0x00 ,0x04 ,0x00 ,0x04 ,0x00 ,0x04 ,0x00 ,0x04 ,0x00 ,0x04 ,0x00 ,0x04 ,0x00 ,0x04 ,0x00 , +0x04 ,0x00 ,0x04 ,0x00 ,0x04 ,0x00 ,0x18 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x23 ,0x02 ,0x41 ,0x82 ,0x40 ,0xc4 ,0x00 ,0x6c ,0x00 ,0x30 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 , diff --git a/src/modules/isp/mpp/vgs_img.c b/src/modules/isp/mpp/vgs_img.c new file mode 100755 index 0000000..b4cde49 --- /dev/null +++ b/src/modules/isp/mpp/vgs_img.c @@ -0,0 +1,493 @@ +/* + * Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED. + * 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. + */ + +#include +#include +#include +#include + +#include "hi_comm_vb.h" +#include "hi_comm_vgs.h" +#include "hi_comm_region.h" +#include "sample_comm.h" +#include "mpi_sys.h" +#include "mpi_vgs.h" +#include "hi_buffer.h" + +#include "vgs_img.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* End of #ifdef __cplusplus */ + +#define VGS_MAX_LINE 100 // The maximum number of lines for a superimposed graphics operation +#define RECT_LINES 4 // The number of lines in a rectangle + +#define RECT_LINE1 1 +#define RECT_LINE2 2 +#define RECT_LINE3 3 + +/* + * 设置帧的buffer + * Set the buf of the frame + */ +static void MppFrmSetBuf(VIDEO_FRAME_INFO_S* frm, + const VB_CAL_CONFIG_S *vbCfg, HI_U64 phyAddr, uint8_t *virAddr) +{ + /* + * 目前只支持SP422/SP420,不支持SP444 + * Currently only SP422/SP420 is supported, SP444 is not supported + */ + frm->stVFrame.u32HeaderStride[0] = vbCfg->u32HeadStride; + frm->stVFrame.u32HeaderStride[1] = vbCfg->u32HeadStride; + frm->stVFrame.u32HeaderStride[2] = vbCfg->u32HeadStride; // 2: Array subscript, not out of bounds + frm->stVFrame.u64HeaderPhyAddr[0] = phyAddr; + frm->stVFrame.u64HeaderPhyAddr[1] = frm->stVFrame.u64HeaderPhyAddr[0] + vbCfg->u32HeadYSize; + frm->stVFrame.u64HeaderPhyAddr[2] = frm->stVFrame.u64HeaderPhyAddr[1]; // 2: Array subscript, not out of bounds + frm->stVFrame.u64HeaderVirAddr[0] = (HI_U64)(HI_UL)virAddr; + frm->stVFrame.u64HeaderVirAddr[1] = frm->stVFrame.u64HeaderVirAddr[0] + vbCfg->u32HeadYSize; + frm->stVFrame.u64HeaderVirAddr[2] = frm->stVFrame.u64HeaderVirAddr[1]; // 2: Array subscript, not out of bounds + + frm->stVFrame.u32Stride[0] = vbCfg->u32MainStride; + frm->stVFrame.u32Stride[1] = vbCfg->u32MainStride; + frm->stVFrame.u32Stride[2] = vbCfg->u32MainStride; // 2: Array subscript, not out of bounds + frm->stVFrame.u64PhyAddr[0] = frm->stVFrame.u64HeaderPhyAddr[0] + vbCfg->u32HeadSize; + frm->stVFrame.u64PhyAddr[1] = frm->stVFrame.u64PhyAddr[0] + vbCfg->u32MainYSize; + frm->stVFrame.u64PhyAddr[2] = frm->stVFrame.u64PhyAddr[1]; // 2: Array subscript, not out of bounds + frm->stVFrame.u64VirAddr[0] = frm->stVFrame.u64HeaderVirAddr[0] + vbCfg->u32HeadSize; + frm->stVFrame.u64VirAddr[1] = frm->stVFrame.u64VirAddr[0] + vbCfg->u32MainYSize; + frm->stVFrame.u64VirAddr[2] = frm->stVFrame.u64VirAddr[1]; // 2: Array subscript, not out of bounds +} + +/* + * 创建一个空的frame buf. + * 它根据参数的规格计算frame所需空间,为frame分配内存. + * @param frm[in|out]: 若成功,创建的frame信息会复制到frm. + * @param width[in]: frame width. + * @param height[in]: frame height. + * @param pixelFormat[in]: 置为-1表示取默认值PIXEL_FORMAT_YVU_SEMIPLANAR_420. + * @param bitWidth[in]: 置为-1表示取默认值DATA_BITWIDTH_8. + * @param compressMode[in]: 置为-1表示取默认值COMPRESS_MODE_NONE. + * @param align[in]: 对齐的字节长度. 置为-1表示取默认值'自动对齐'. + * + * Create an empty frame buf. + * It calculates the space required by the frame according to the parameter specification, + * and allocates memory for the frame. + * @param frm[in|out]: If successful, the created frame information will be copied to frm. + * @param width[in]: frame width. + * @param height[in]: frame height. + * @param pixelFormat[in]: Set to -1 means to take the default value PIXEL_FORMAT_YVU_SEMIPLANAR_420. + * @param bitWidth[in]: Set to -1 means to take the default value DATA_BITWIDTH_8. + * @param compressMode[in]: Set to -1 means to take the default value COMPRESS_MODE_NONE. + * @param align[in]: The byte length of the alignment. Set to -1 to take the default value 'automatic alignment'. + */ +int MppFrmCreate( + VIDEO_FRAME_INFO_S* frm, + int width, int height, + PIXEL_FORMAT_E pixelFormat, + DATA_BITWIDTH_E bitWidth, + COMPRESS_MODE_E compressMode, + int align) +{ + HI_ASSERT(frm); + VB_CAL_CONFIG_S vbCfg; + + if (memset_s(frm, sizeof(*frm), 0, sizeof(*frm)) != EOK) { + HI_ASSERT(0); + } + + HI_ASSERT(width > 0 && height > 0); + if ((int)pixelFormat < 0) { + pixelFormat = PIXEL_FORMAT_YVU_SEMIPLANAR_420; + } + if ((int)bitWidth < 0) { + bitWidth = DATA_BITWIDTH_8; + } + if ((int)compressMode < 0) { + compressMode = COMPRESS_MODE_NONE; + } + if (align < 0) { + HI_ASSERT(0); + } + + COMMON_GetPicBufferConfig(width, height, pixelFormat, bitWidth, compressMode, align, &vbCfg); + + HI_U64 u64VBSize = (HI_U64) vbCfg.u32VBSize; // HACK 不强转一下有问题, 可能是clang有bug吧 + VB_BLK vbHnd = HI_MPI_VB_GetBlock(VB_INVALID_POOLID, u64VBSize, NULL); + if (vbHnd == VB_INVALID_HANDLE) { + SAMPLE_PRT("HI_MPI_VB_GetBlock FAIL\n"); + return HI_FAILURE; + } + + HI_U64 phyAddr = HI_MPI_VB_Handle2PhysAddr(vbHnd); + HI_ASSERT(phyAddr); + uint8_t* virAddr = (uint8_t*)HI_MPI_SYS_Mmap(phyAddr, u64VBSize); + HI_ASSERT(virAddr); + + /* + * u64PrivateData用来存储映射的内存区长度和vbHnd,在destroy时会用到 + * + * u64PrivateData is used to store the length of the mapped memory area and vbHnd, + * which will be used when destroying + */ + frm->stVFrame.u64PrivateData = ((uint64_t)(uint32_t)vbHnd) << HI_INT32_BITS; + frm->stVFrame.u64PrivateData |= (uint64_t)u64VBSize; + + frm->enModId = HI_ID_VGS; + frm->u32PoolId = HI_MPI_VB_Handle2PoolId(vbHnd); + + frm->stVFrame.u32Width = width; + frm->stVFrame.u32Height = height; + frm->stVFrame.enField = VIDEO_FIELD_FRAME; + frm->stVFrame.enPixelFormat = pixelFormat; + frm->stVFrame.enVideoFormat = VIDEO_FORMAT_LINEAR; + frm->stVFrame.enCompressMode = compressMode; + frm->stVFrame.enDynamicRange = DYNAMIC_RANGE_SDR8; + frm->stVFrame.enColorGamut = COLOR_GAMUT_BT601; + + MppFrmSetBuf(frm, &vbCfg, phyAddr, virAddr); + return HI_SUCCESS; +} + +/* + * 判断frame是否可用, 即是否分配了内存 + * Determine whether the frame is available, That is, whether the memory is allocated + */ +bool MppFrmValid(const VIDEO_FRAME_INFO_S* frm) +{ + /* + * VPSS输出的frame默认没有映射虚地址 + * The frame output by VPSS does not map virtual addresses by default + */ + return frm->stVFrame.u64PhyAddr[0]; +} + +/* + * 销毁frame + * Destory frame + */ +void MppFrmDestroy(VIDEO_FRAME_INFO_S* frm) +{ + if (!MppFrmValid(frm)) { + return; + } + + /* + * u64PrivateData被用来存储映射的内存区长度和vbHnd,在创建时设置 + * u64PrivateData is used to store the length of the mapped memory area and vbHnd, which is set at create + */ + uint32_t memSize = (uint32_t)(frm->stVFrame.u64PrivateData); + uint32_t vbHnd = (uint32_t)(frm->stVFrame.u64PrivateData >> HI_INT32_BITS); + HI_S32 ret; + + ret = HI_MPI_SYS_Munmap((void*)(uintptr_t)frm->stVFrame.u64VirAddr[0], memSize); + HI_ASSERT(ret == HI_SUCCESS); + ret = HI_MPI_VB_ReleaseBlock(vbHnd); + HI_ASSERT(ret == HI_SUCCESS); + if (memset_s(frm, sizeof(*frm), 0, sizeof(*frm)) != EOK) { + HI_ASSERT(0); + } +} + +/* + * 执行一次VGS缩放 + * 每一次VGS resize的缩放倍数是有限制的. VGS支持对一幅图像进行缩放,最大支持图像 + * 宽高均放大16倍,缩小30 倍。支持单分量(Y)缩放 + * + * Perform a VGS resize. + * The zoom factor of each VGS resize is limited. VGS supports zooming of an image. + * The width and height are both enlarged by 16 times and reduced by 30 times.Support single-component (Y) scaling. + */ +static int VgsResizeOnce(const VIDEO_FRAME_INFO_S* src, VIDEO_FRAME_INFO_S* dst, uint32_t dstWidth, uint32_t dstHeight) +{ + HI_ASSERT(src && dst); + HI_ASSERT(dstWidth > 0 && dstHeight > 0); + VGS_HANDLE jobHnd = -1; + VGS_TASK_ATTR_S task; + int ret; + + ret = MppFrmCreate(dst, dstWidth, dstHeight, src->stVFrame.enPixelFormat, DATA_BITWIDTH_8, + src->stVFrame.enCompressMode, 0); + if (ret != 0) { + SAMPLE_PRT("frm resize FAIL, for create dstFrm FAIL\n"); + return ret; + } + + if (memset_s(&task, sizeof(task), 0, sizeof(task)) != EOK) { + HI_ASSERT(0); + } + task.stImgIn = *src; + task.stImgOut = *dst; + + ret = HI_MPI_VGS_BeginJob(&jobHnd); + if (ret != 0) { + SAMPLE_PRT("HI_MPI_VGS_BeginJob FAIL, ret=%08X\n", ret); + if (jobHnd >= 0 && HI_MPI_VGS_CancelJob(jobHnd) != HI_SUCCESS) { + HI_ASSERT(0); + } + MppFrmDestroy(dst); + return ret; + } + HI_ASSERT(jobHnd >= 0); + + ret = HI_MPI_VGS_AddScaleTask(jobHnd, &task, VGS_SCLCOEF_NORMAL); + if (ret != 0) { + SAMPLE_PRT("HI_MPI_VGS_AddScaleTask FAIL, ret=%08X\n", ret); + if (jobHnd >= 0 && HI_MPI_VGS_CancelJob(jobHnd) != HI_SUCCESS) { + HI_ASSERT(0); + } + MppFrmDestroy(dst); + return ret; + } + + ret = HI_MPI_VGS_EndJob(jobHnd); + if (ret != 0) { + SAMPLE_PRT("HI_MPI_VGS_EndJob FAIL, ret=%08X\n", ret); + if (jobHnd >= 0 && HI_MPI_VGS_CancelJob(jobHnd) != HI_SUCCESS) { + HI_ASSERT(0); + } + MppFrmDestroy(dst); + return ret; + } + return 0; +} + +/* + * 对一帧实现缩放 + * 多次调用vgs_resize以实现任意比例的缩放 + * 为简化实现,约定每次缩放最大14倍,此时宽、高仅需2像素对齐 + * 当两个方向缩放方向不同时,例如一向(如X)放大,另一向缩小倍,无需特别处理 + * 此时某个方向或两个方向缩放比例均超标,也不需要特别处理 + * + * resize frame. + * Call vgs_resize multiple times to achieve arbitrary scaling. + * In order to simplify the implementation, it is agreed that each zoom is up to 14 times, + * and at this time, the width and height only need to be aligned by 2 pixels. + * When the zooming direction of the two directions is different, for example, + * zooming in one direction (such as X) and zooming out in the other direction, no special processing is required + * At this time, the zoom ratio in one direction or both directions exceeds the standard, + * and no special treatment is required. + */ +int MppFrmResize( + const VIDEO_FRAME_INFO_S* src, + VIDEO_FRAME_INFO_S* dst, + uint32_t dstWidth, uint32_t dstHeight) +{ + static const double rateMax = 14.0; // Maximum magnification + static const double rateMin = 1.0 / rateMax; // The smallest magnification, that is, the largest reduction + + uint32_t srcWidth = src->stVFrame.u32Width; + uint32_t srcHeight = src->stVFrame.u32Height; + HI_ASSERT(srcWidth > 0 && srcHeight > 0); + HI_ASSERT(!(srcWidth % HI_OVEN_BASE) && !(srcHeight % HI_OVEN_BASE)); + HI_ASSERT(dstWidth > 0 && dstHeight > 0); + HI_ASSERT(!(dstWidth % HI_OVEN_BASE) && !(dstHeight % HI_OVEN_BASE)); + int ret; + + /* + * 放大倍数 + * magnification + */ + double widthRate = ((double)dstWidth) / (double)srcWidth; // >1 means zoom in, <1 means zoom out + double heightRate = ((double)dstHeight) / (double)srcHeight; // >1 means zoom in, <1 means zoom out + + /* + * 根据缩放倍数分别处理 + * Separate processing according to zoom factor + */ + if (widthRate > rateMax || widthRate < rateMin || + heightRate > rateMax || heightRate < rateMin) { + /* + * 缩放倍数超过一次VGS的最大值时,递归处理 ... + * When the zoom factor exceeds the maximum value of one VGS, recursive processing... + */ + uint32_t midWidth = (uint32_t)IntZoomTo((int)srcWidth, widthRate, rateMin, rateMax); + uint32_t midHeight = (uint32_t)IntZoomTo((int)srcHeight, heightRate, rateMin, rateMax); + /* + * 确保为偶数。为奇数时,放大则减一,否则加一 + * + * Make sure it is an even number. When it is an odd number, + * the zoom is reduced by one, otherwise it is increased by one + */ + if (midWidth % HI_OVEN_BASE) { + midWidth += widthRate > 1 ? -1 : 1; + } + if (midHeight % HI_OVEN_BASE) { + midHeight += heightRate > 1 ? -1 : 1; + } + + SAMPLE_PRT("@@@ multi-lev vgs resize, src={%u, %u}, mid={%u, %u}, dst={%u, %u}, rate={%.4f, %.4f}\n", + srcWidth, srcHeight, midWidth, midHeight, dstWidth, dstHeight, widthRate, heightRate); + + /* + * 缩放一次 + * Zoom once + */ + VIDEO_FRAME_INFO_S midFrm; + ret = VgsResizeOnce(src, &midFrm, midWidth, midHeight); + if (ret != 0) { + SAMPLE_PRT("VgsResizeOnce(dw=%u, dh=%u) FAIL\n", midWidth, midHeight); + return ret; + } + + /* + * 以midFrm为src递归调用 + * Recursively call with midFrm as src + */ + ret = MppFrmResize(&midFrm, dst, dstWidth, dstHeight); + MppFrmDestroy(&midFrm); + if (ret != 0) { + SAMPLE_PRT("sub call MppFrmResize(dw=%u, dh=%u) FAIL\n", dstWidth, dstHeight); + return ret; + } + } else { + /* + * 缩放倍数未超过一次VGS的最大值,直接完成 + * The zoom factor does not exceed the maximum value of VGS once, and it is done directly + */ + ret = VgsResizeOnce(src, dst, dstWidth, dstHeight); + if (ret != 0) { + SAMPLE_PRT("VgsResizeOnce(dw=%u, dh=%u) FAIL\n", dstWidth, dstHeight); + return ret; + } + } + return ret; +} + +/* + * 将整数向上修整为偶数 + * Round up integers to even numbers + */ +static inline int IntToOven(int x) +{ + if (x % HI_OVEN_BASE == 0) { + return x; + } else { + return x + 1; + } +} + +/* + * 创建并执行VGS画线任务 + * Create and execute VGS draw lines job + */ +static HI_S32 VgsDrawLines(VIDEO_FRAME_INFO_S *frm, const VGS_DRAW_LINE_S lines[], int lineNum) +{ + VGS_HANDLE jobHnd = -1; + VGS_TASK_ATTR_S task; + int ret; + + if (memset_s(&task, sizeof(task), 0, sizeof(task)) != EOK) { + HI_ASSERT(0); + } + task.stImgIn = *frm; + task.stImgOut = *frm; + + /* + * 启动一个job + * Start a job + */ + ret = HI_MPI_VGS_BeginJob(&jobHnd); + if (ret != 0) { + SAMPLE_PRT("HI_MPI_VGS_BeginJob FAIL, ret=%08X\n", ret); + if (jobHnd >= 0 && HI_MPI_VGS_CancelJob(jobHnd) != HI_SUCCESS) { + HI_ASSERT(0); + } + return ret; + } + HI_ASSERT(jobHnd >= 0); + + /* + * 往一个已经启动的job里添加批量画线task + * Add a batch line drawing task to an already started job + */ + ret = HI_MPI_VGS_AddDrawLineTaskArray(jobHnd, &task, lines, lineNum); + if (ret != 0) { + SAMPLE_PRT("HI_MPI_VGS_AddDrawLineTaskArray FAIL, ret=%08X\n", ret); + if (jobHnd >= 0 && HI_MPI_VGS_CancelJob(jobHnd) != HI_SUCCESS) { + HI_ASSERT(0); + } + return ret; + } + + /* + * 提交一个job + * Submit a job + */ + ret = HI_MPI_VGS_EndJob(jobHnd); + if (ret != 0) { + SAMPLE_PRT("HI_MPI_VGS_EndJob FAIL, ret=%08X\n", ret); + if (jobHnd >= 0 && HI_MPI_VGS_CancelJob(jobHnd) != HI_SUCCESS) { + HI_ASSERT(0); + } + return ret; + } + return 0; +} + +/* + * 在frame中叠加一个或多个矩形框 + * Superimpose one or more rectangular boxes in the frame + */ +int MppFrmDrawRects(VIDEO_FRAME_INFO_S *frm, + const RectBox *boxes, int boxesNum, uint32_t color, int thick) +{ + VGS_DRAW_LINE_S lines[VGS_MAX_LINE]; + int i; + + if (thick <= 0) { + HI_ASSERT(0); + } + + /* + * 将各矩形四边平面化为lines + * Planarize the four sides of each rectangle into lines + */ + for (i = 0; i < boxesNum; i++) { + lines[RECT_LINES * i].stStartPoint.s32X = IntToOven(boxes[i].xmin); + lines[RECT_LINES * i].stStartPoint.s32Y = IntToOven(boxes[i].ymin); + lines[RECT_LINES * i].stEndPoint.s32X = IntToOven(boxes[i].xmax); + lines[RECT_LINES * i].stEndPoint.s32Y = IntToOven(boxes[i].ymin); + lines[RECT_LINES * i].u32Color = color; + lines[RECT_LINES * i].u32Thick = thick; + lines[RECT_LINES * i + RECT_LINE1].stStartPoint.s32X = IntToOven(boxes[i].xmax); + lines[RECT_LINES * i + RECT_LINE1].stStartPoint.s32Y = IntToOven(boxes[i].ymin); + lines[RECT_LINES * i + RECT_LINE1].stEndPoint.s32X = IntToOven(boxes[i].xmax); + lines[RECT_LINES * i + RECT_LINE1].stEndPoint.s32Y = IntToOven(boxes[i].ymax); + lines[RECT_LINES * i + RECT_LINE1].u32Color = color; + lines[RECT_LINES * i + RECT_LINE1].u32Thick = thick; + lines[RECT_LINES * i + RECT_LINE2].stStartPoint.s32X = IntToOven(boxes[i].xmax); + lines[RECT_LINES * i + RECT_LINE2].stStartPoint.s32Y = IntToOven(boxes[i].ymax); + lines[RECT_LINES * i + RECT_LINE2].stEndPoint.s32X = IntToOven(boxes[i].xmin); + lines[RECT_LINES * i + RECT_LINE2].stEndPoint.s32Y = IntToOven(boxes[i].ymax); + lines[RECT_LINES * i + RECT_LINE2].u32Color = color; + lines[RECT_LINES * i + RECT_LINE2].u32Thick = thick; + lines[RECT_LINES * i + RECT_LINE3].stStartPoint.s32X = IntToOven(boxes[i].xmin); + lines[RECT_LINES * i + RECT_LINE3].stStartPoint.s32Y = IntToOven(boxes[i].ymax); + lines[RECT_LINES * i + RECT_LINE3].stEndPoint.s32X = IntToOven(boxes[i].xmin); + lines[RECT_LINES * i + RECT_LINE3].stEndPoint.s32Y = IntToOven(boxes[i].ymin); + lines[RECT_LINES * i + RECT_LINE3].u32Color = color; + lines[RECT_LINES * i + RECT_LINE3].u32Thick = thick; + } + return VgsDrawLines(frm, lines, i * RECT_LINES); +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ diff --git a/src/modules/isp/mpp/vgs_img.h b/src/modules/isp/mpp/vgs_img.h new file mode 100755 index 0000000..f2c249f --- /dev/null +++ b/src/modules/isp/mpp/vgs_img.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED. + * 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. + */ + +#ifndef VGS_IMG_H +#define VGS_IMG_H + +#include +#include + +#include "hi_common.h" +#include "hi_comm_video.h" +#include "hi_comm_venc.h" +#include "util.h" + +#if __cplusplus +extern "C" { +#endif + +/* + * 常用数字单位 + * Commonly used numerical units + */ +#define HI_KB 1024 +#define HI_MB (1024 * 1024) +#define HI_MS_OF_SEC 1000 // 1s in milliseconds +#define HI_NS_OF_MS 1000000 // Nanoseconds in 1ms +#define HI_BYTE_BITS 8 // Number of bits in 1 byte +#define HI_INT8_BITS 8 // 8-bit integer number of bits +#define HI_INT16_BITS 16 // 16-bit integer number of bits +#define HI_INT32_BITS 32 // 32-bit integer number of bits +#define HI_INT64_BITS 64 // The number of bits of a 64-bit integer + +/* + * 帧缩放 + * 多次调用vgs_resize以实现任意比例的缩放 + * 为简化实现,约定每次缩放最大14倍,此时宽、高仅需2像素对齐 + * 当两个方向缩放方向不同时,例如一向(如X)放大,另一向缩小倍,无需特别处理 + * 此时某个方向或两个方向缩放比例均超标,也不需要特别处理 + * + * resize frame. + * Call vgs_resize multiple times to achieve arbitrary scaling. + * In order to simplify the implementation, it is agreed that each zoom is up to 14 times, + * and at this time, the width and height only need to be aligned by 2 pixels. + * When the zoom directions are different in the two directions, for example, + * zooming in one direction (such as X) and zooming out in the other direction, + * no special processing is required. At this time, the zoom ratio in one direction or + * both directions exceeds the standard, and no special treatment is required. + */ +int MppFrmResize( + const VIDEO_FRAME_INFO_S* src, + VIDEO_FRAME_INFO_S* dst, + uint32_t dstWidth, uint32_t dstHeight); + +/* + * 销毁帧 + * Destory frame + */ +void MppFrmDestroy(VIDEO_FRAME_INFO_S* frm); + +/* + * 在框架中叠加一个或多个矩形框 + * Superimpose one or more rectangular boxes in the frame + */ +int MppFrmDrawRects(VIDEO_FRAME_INFO_S *frm, + const RectBox *boxes, int boxesNum, uint32_t color, int thick); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/modules/nnie/eb3516_nnie.c b/src/modules/nnie/eb3516_nnie.c index 0c8f442..5b44c6c 100755 --- a/src/modules/nnie/eb3516_nnie.c +++ b/src/modules/nnie/eb3516_nnie.c @@ -1,705 +1,718 @@ #include "eb3516_nnie.h" #include "hi_comm_svp.h" -#include "hi_comm_sys.h" -#include "hi_common.h" -#include "sample_comm.h" +#include "hi_type.h" #include "sample_comm_ive.h" #include "sample_comm_nnie.h" #include "sample_comm_svp.h" #include "sample_svp_nnie_software.h" +#include +#include +#include +#include + +#include "common.h" +#include "mpp/ive_img.h" +#include "mpp/vgs_img.h" #include "zlog.h" static zlog_category_t *log_nnie = NULL; -/*yolov3 para*/ -static SAMPLE_SVP_NNIE_MODEL_S g_stNnieModel = {0}; -static SAMPLE_SVP_NNIE_PARAM_S g_stNnieParam = {0}; -static SAMPLE_SVP_NNIE_YOLOV3_SOFTWARE_PARAM_S g_stYolov3Param = {0}; +#define MODEL_FILE "./coco_yolov3_detect.wk" +#define IMAGE_WIDTH 416 +#define IMAGE_HEIGHT 416 +#define USLEEP_TIME 100 +#define DETECT_OBJ_MAX 64 +#define CONF_THRESHOLD 0.40f +#define SCORE_THRESHOLD 0.25f -static HI_S32 SAMPLE_SVP_NNIE_Detection_PrintResult( - SVP_BLOB_S *pstDstScore, SVP_BLOB_S *pstDstRoi, SVP_BLOB_S *pstClassRoiNum, - HI_FLOAT f32PrintResultThresh) { - HI_U32 i = 0, j = 0; - HI_U32 u32RoiNumBias = 0; - HI_U32 u32ScoreBias = 0; - HI_U32 u32BboxBias = 0; - HI_FLOAT f32Score = 0.0f; - HI_S32 *ps32Score = - SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR(HI_S32, pstDstScore->u64VirAddr); - HI_S32 *ps32Roi = - SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR(HI_S32, pstDstRoi->u64VirAddr); - HI_S32 *ps32ClassRoiNum = - SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR(HI_S32, pstClassRoiNum->u64VirAddr); - HI_U32 u32ClassNum = pstClassRoiNum->unShape.stWhc.u32Width; - HI_S32 s32XMin = 0, s32YMin = 0, s32XMax = 0, s32YMax = 0; +#ifndef SAMPLE_SVP_NNIE_CONVERT_PTR_TO_ADDR +#define SAMPLE_SVP_NNIE_CONVERT_PTR_TO_ADDR(Type, Addr) \ + ((Type)(uintptr_t)(Addr)) +#endif - u32RoiNumBias += ps32ClassRoiNum[0]; - for (i = 1; i < u32ClassNum; i++) { - u32ScoreBias = u32RoiNumBias; - u32BboxBias = u32RoiNumBias * SAMPLE_SVP_NNIE_COORDI_NUM; - /*if the confidence score greater than result threshold, the result will - * be printed*/ - if ((HI_FLOAT)ps32Score[u32ScoreBias] / SAMPLE_SVP_NNIE_QUANT_BASE >= - f32PrintResultThresh && - ps32ClassRoiNum[i] != 0) { - SAMPLE_SVP_TRACE_INFO("==== The %dth class box info====\n", i); - } - for (j = 0; j < (HI_U32)ps32ClassRoiNum[i]; j++) { - f32Score = (HI_FLOAT)ps32Score[u32ScoreBias + j] / - SAMPLE_SVP_NNIE_QUANT_BASE; - if (f32Score < f32PrintResultThresh) { - break; - } - s32XMin = ps32Roi[u32BboxBias + j * SAMPLE_SVP_NNIE_COORDI_NUM]; - s32YMin = ps32Roi[u32BboxBias + j * SAMPLE_SVP_NNIE_COORDI_NUM + 1]; - s32XMax = ps32Roi[u32BboxBias + j * SAMPLE_SVP_NNIE_COORDI_NUM + 2]; - s32YMax = ps32Roi[u32BboxBias + j * SAMPLE_SVP_NNIE_COORDI_NUM + 3]; - SAMPLE_SVP_TRACE_INFO("%d %d %d %d %f\n", s32XMin, s32YMin, s32XMax, - s32YMax, f32Score); - } - u32RoiNumBias += ps32ClassRoiNum[i]; - } - return HI_SUCCESS; -} +static const char *LABEL_NAMES[] = { + "person", "bicycle", "car", + "motorcycle", "airplane", "bus", + "train", "truck", "boat", + "traffic light", "fire hydrant", "stop sign", + "parking meter", "bench", "bird", + "cat", "dog", "horse", + "sheep", "cow", "elephant", + "bear", "zebra", "giraffe", + "backpack", "umbrella", "handbag", + "tie", "suitcase", "frisbee", + "skis", "snowboard", "sports ball", + "kite", "baseball bat", "baseball glove", + "skateboard", "surfboard", "tennis racket", + "bottle", "wine glass", "cup", + "fork", "knife", "spoon", + "bowl", "banana", "apple", + "sandwich", "orange", "broccoli", + "carrot", "hot dog", "pizza", + "donut", "cake", "chair", + "couch", "potted plant", "bed", + "dining table", "toilet", "tv", + "laptop", "mouse", "remote", + "keyboard", "cell phone", "microwave", + "oven", "toaster", "sink", + "refrigerator", "book", "clock", + "vase", "scissors", "teddy bear", + "hair drier", "toothbrush", +}; -static HI_S32 SAMPLE_SVP_NNIE_Yolov3_SoftwareDeinit( - SAMPLE_SVP_NNIE_YOLOV3_SOFTWARE_PARAM_S *pstSoftWareParam) { - HI_S32 s32Ret = HI_SUCCESS; - SAMPLE_SVP_CHECK_EXPR_RET(NULL == pstSoftWareParam, HI_INVALID_VALUE, - SAMPLE_SVP_ERR_LEVEL_ERROR, - "Error, pstSoftWareParam can't be NULL!\n"); - if (0 != pstSoftWareParam->stGetResultTmpBuf.u64PhyAddr && - 0 != pstSoftWareParam->stGetResultTmpBuf.u64VirAddr) { - SAMPLE_SVP_MMZ_FREE(pstSoftWareParam->stGetResultTmpBuf.u64PhyAddr, - pstSoftWareParam->stGetResultTmpBuf.u64VirAddr); - pstSoftWareParam->stGetResultTmpBuf.u64PhyAddr = 0; - pstSoftWareParam->stGetResultTmpBuf.u64VirAddr = 0; - pstSoftWareParam->stDstRoi.u64PhyAddr = 0; - pstSoftWareParam->stDstRoi.u64VirAddr = 0; - pstSoftWareParam->stDstScore.u64PhyAddr = 0; - pstSoftWareParam->stDstScore.u64VirAddr = 0; - pstSoftWareParam->stClassRoiNum.u64PhyAddr = 0; - pstSoftWareParam->stClassRoiNum.u64VirAddr = 0; - } - return s32Ret; -} +static SAMPLE_SVP_NNIE_MODEL_S g_stNnieModel; +static SAMPLE_SVP_NNIE_PARAM_S g_stNnieParam; +static SAMPLE_SVP_NNIE_YOLOV3_SOFTWARE_PARAM_S g_stYolov3Param; +static int g_bIsRunning; +static pthread_t g_pidAiThread; +static int g_bEnableForward; -static HI_S32 SAMPLE_SVP_NNIE_Yolov3_Deinit( +static HI_S32 SVP_NNIE_YOLOV3_ParamInit( SAMPLE_SVP_NNIE_PARAM_S *pstNnieParam, - SAMPLE_SVP_NNIE_YOLOV3_SOFTWARE_PARAM_S *pstSoftWareParam, - SAMPLE_SVP_NNIE_MODEL_S *pstNnieModel) { - HI_S32 s32Ret = HI_SUCCESS; - /*hardware deinit*/ - if (pstNnieParam != NULL) { - s32Ret = SAMPLE_COMM_SVP_NNIE_ParamDeinit(pstNnieParam); - SAMPLE_SVP_CHECK_EXPR_TRACE( - HI_SUCCESS != s32Ret, SAMPLE_SVP_ERR_LEVEL_ERROR, - "Error,SAMPLE_COMM_SVP_NNIE_ParamDeinit failed!\n"); - } - /*software deinit*/ - if (pstSoftWareParam != NULL) { - s32Ret = SAMPLE_SVP_NNIE_Yolov3_SoftwareDeinit(pstSoftWareParam); - SAMPLE_SVP_CHECK_EXPR_TRACE( - HI_SUCCESS != s32Ret, SAMPLE_SVP_ERR_LEVEL_ERROR, - "Error,SAMPLE_SVP_NNIE_Yolov3_SoftwareDeinit failed!\n"); - } - /*model deinit*/ - if (pstNnieModel != NULL) { - s32Ret = SAMPLE_COMM_SVP_NNIE_UnloadModel(pstNnieModel); - SAMPLE_SVP_CHECK_EXPR_TRACE( - HI_SUCCESS != s32Ret, SAMPLE_SVP_ERR_LEVEL_ERROR, - "Error,SAMPLE_COMM_SVP_NNIE_UnloadModel failed!\n"); - } + SAMPLE_SVP_NNIE_YOLOV3_SOFTWARE_PARAM_S *pstYolov3Param) { + HI_S32 s32Ret = 0; + + // 初始化yolov3参数 + pstYolov3Param->u32OriImHeight = + pstNnieParam->astSegData[0].astSrc[0].unShape.stWhc.u32Height; + pstYolov3Param->u32OriImWidth = + pstNnieParam->astSegData[0].astSrc[0].unShape.stWhc.u32Width; + pstYolov3Param->u32BboxNumEachGrid = 3; + pstYolov3Param->u32ClassNum = 44; + // sample_svp_nnie_software.h 中的 + // SAMPLE_SVP_NNIE_YOLOV3_EACH_BBOX_INFER_RESULT_NUM 需要改成 u32ClassNum+5 + pstYolov3Param->au32GridNumHeight[0] = 13; + pstYolov3Param->au32GridNumHeight[1] = 26; + pstYolov3Param->au32GridNumHeight[2] = 52; + pstYolov3Param->au32GridNumWidth[0] = 13; + pstYolov3Param->au32GridNumWidth[1] = 26; + pstYolov3Param->au32GridNumWidth[2] = 52; + pstYolov3Param->u32NmsThresh = (HI_U32)(0.3f * SAMPLE_SVP_QUANT_BASE); + pstYolov3Param->u32ConfThresh = (HI_U32)(0.25f * SAMPLE_SVP_QUANT_BASE); + pstYolov3Param->u32MaxRoiNum = 10; + pstYolov3Param->af32Bias[0][0] = 116; + pstYolov3Param->af32Bias[0][1] = 90; + pstYolov3Param->af32Bias[0][2] = 156; + pstYolov3Param->af32Bias[0][3] = 198; + pstYolov3Param->af32Bias[0][4] = 373; + pstYolov3Param->af32Bias[0][5] = 326; + pstYolov3Param->af32Bias[1][0] = 30; + pstYolov3Param->af32Bias[1][1] = 61; + pstYolov3Param->af32Bias[1][2] = 62; + pstYolov3Param->af32Bias[1][3] = 45; + pstYolov3Param->af32Bias[1][4] = 59; + pstYolov3Param->af32Bias[1][5] = 119; + pstYolov3Param->af32Bias[2][0] = 10; + pstYolov3Param->af32Bias[2][1] = 13; + pstYolov3Param->af32Bias[2][2] = 16; + pstYolov3Param->af32Bias[2][3] = 30; + pstYolov3Param->af32Bias[2][4] = 33; + pstYolov3Param->af32Bias[2][5] = 23; + + // 申请辅助内存空间 + HI_U64 u64PhyAddr = 0; + HI_U8 *pu8VirAddr = NULL; + HI_U32 u32ClassNum = pstYolov3Param->u32ClassNum + 1; + HI_U32 u32TmpBufTotalSize = + SAMPLE_SVP_NNIE_Yolov3_GetResultTmpBuf(pstNnieParam, pstYolov3Param); + HI_U32 u32DstRoiSize = + SAMPLE_SVP_NNIE_ALIGN16(u32ClassNum * pstYolov3Param->u32MaxRoiNum * + sizeof(HI_U32) * SAMPLE_SVP_COORDI_NUM); + HI_U32 u32DstScoreSize = SAMPLE_SVP_NNIE_ALIGN16( + u32ClassNum * pstYolov3Param->u32MaxRoiNum * sizeof(HI_U32)); + HI_U32 u32ClassRoiNumSize = + SAMPLE_SVP_NNIE_ALIGN16(u32ClassNum * sizeof(HI_U32)); + HI_U32 u32TotalSize = + u32TmpBufTotalSize + u32DstRoiSize + u32DstScoreSize + u32ClassRoiNumSize; + s32Ret = SAMPLE_COMM_SVP_MallocCached("SAMPLE_YOLOV3_INIT", NULL, + (HI_U64 *)&u64PhyAddr, + (void **)&pu8VirAddr, u32TotalSize); + if (s32Ret != HI_SUCCESS) { + zlog_error(log_nnie, "Error: alloc memory failed!\n"); return s32Ret; + } + memset_s(pu8VirAddr, u32TotalSize, 0, u32TotalSize); + SAMPLE_COMM_SVP_FlushCache(u64PhyAddr, (void *)pu8VirAddr, u32TotalSize); + pstYolov3Param->stGetResultTmpBuf.u64PhyAddr = u64PhyAddr; + pstYolov3Param->stGetResultTmpBuf.u64VirAddr = + SAMPLE_SVP_NNIE_CONVERT_PTR_TO_ADDR(HI_U64, pu8VirAddr); + + // 设置结果blob + pstYolov3Param->stDstRoi.enType = SVP_BLOB_TYPE_S32; + pstYolov3Param->stDstRoi.u64PhyAddr = u64PhyAddr + u32TmpBufTotalSize; + pstYolov3Param->stDstRoi.u64VirAddr = SAMPLE_SVP_NNIE_CONVERT_PTR_TO_ADDR( + HI_U64, pu8VirAddr + u32TmpBufTotalSize); + pstYolov3Param->stDstRoi.u32Stride = + SAMPLE_SVP_NNIE_ALIGN16(u32ClassNum * pstYolov3Param->u32MaxRoiNum * + sizeof(HI_U32) * SAMPLE_SVP_COORDI_NUM); + pstYolov3Param->stDstRoi.u32Num = 1; + pstYolov3Param->stDstRoi.unShape.stWhc.u32Chn = 1; + pstYolov3Param->stDstRoi.unShape.stWhc.u32Height = 1; + pstYolov3Param->stDstRoi.unShape.stWhc.u32Width = + u32ClassNum * pstYolov3Param->u32MaxRoiNum * SAMPLE_SVP_COORDI_NUM; + + pstYolov3Param->stDstScore.enType = SVP_BLOB_TYPE_S32; + pstYolov3Param->stDstScore.u64PhyAddr = + u64PhyAddr + u32TmpBufTotalSize + u32DstRoiSize; + pstYolov3Param->stDstScore.u64VirAddr = SAMPLE_SVP_NNIE_CONVERT_PTR_TO_ADDR( + HI_U64, pu8VirAddr + u32TmpBufTotalSize + u32DstRoiSize); + pstYolov3Param->stDstScore.u32Stride = SAMPLE_SVP_NNIE_ALIGN16( + u32ClassNum * pstYolov3Param->u32MaxRoiNum * sizeof(HI_U32)); + pstYolov3Param->stDstScore.u32Num = 1; + pstYolov3Param->stDstScore.unShape.stWhc.u32Chn = 1; + pstYolov3Param->stDstScore.unShape.stWhc.u32Height = 1; + pstYolov3Param->stDstScore.unShape.stWhc.u32Width = + u32ClassNum * pstYolov3Param->u32MaxRoiNum; + + pstYolov3Param->stClassRoiNum.enType = SVP_BLOB_TYPE_S32; + pstYolov3Param->stClassRoiNum.u64PhyAddr = + u64PhyAddr + u32TmpBufTotalSize + u32DstRoiSize + u32DstScoreSize; + pstYolov3Param->stClassRoiNum.u64VirAddr = + SAMPLE_SVP_NNIE_CONVERT_PTR_TO_ADDR(HI_U64, + pu8VirAddr + u32TmpBufTotalSize + + u32DstRoiSize + u32DstScoreSize); + pstYolov3Param->stClassRoiNum.u32Stride = + SAMPLE_SVP_NNIE_ALIGN16(u32ClassNum * sizeof(HI_U32)); + pstYolov3Param->stClassRoiNum.u32Num = 1; + pstYolov3Param->stClassRoiNum.unShape.stWhc.u32Chn = 1; + pstYolov3Param->stClassRoiNum.unShape.stWhc.u32Height = 1; + pstYolov3Param->stClassRoiNum.unShape.stWhc.u32Width = u32ClassNum; + + return s32Ret; } -static HI_S32 SAMPLE_SVP_NNIE_Yolov3_SoftwareInit( - SAMPLE_SVP_NNIE_CFG_S *pstCfg, SAMPLE_SVP_NNIE_PARAM_S *pstNnieParam, - SAMPLE_SVP_NNIE_YOLOV3_SOFTWARE_PARAM_S *pstSoftWareParam) { - HI_S32 s32Ret = HI_SUCCESS; - HI_U32 u32ClassNum = 0; - HI_U32 u32TotalSize = 0; - HI_U32 u32DstRoiSize = 0; - HI_U32 u32DstScoreSize = 0; - HI_U32 u32ClassRoiNumSize = 0; - HI_U32 u32TmpBufTotalSize = 0; - HI_U64 u64PhyAddr = 0; - HI_U8 *pu8VirAddr = NULL; +static HI_S32 +SVP_NNIE_FillSrcData(SAMPLE_SVP_NNIE_PARAM_S *pstNnieParam, + SAMPLE_SVP_NNIE_INPUT_DATA_INDEX_S *pstInputDataIdx, + const IVE_IMAGE_S *img) { + HI_U32 segId = pstInputDataIdx->u32SegIdx; + HI_U32 nodeId = pstInputDataIdx->u32NodeIdx; - pstSoftWareParam->u32OriImHeight = - pstNnieParam->astSegData[0].astSrc[0].unShape.stWhc.u32Height; - pstSoftWareParam->u32OriImWidth = - pstNnieParam->astSegData[0].astSrc[0].unShape.stWhc.u32Width; - pstSoftWareParam->u32BboxNumEachGrid = 3; - pstSoftWareParam->u32ClassNum = 80; - pstSoftWareParam->au32GridNumHeight[0] = 13; - pstSoftWareParam->au32GridNumHeight[1] = 26; - pstSoftWareParam->au32GridNumHeight[2] = 52; - pstSoftWareParam->au32GridNumWidth[0] = 13; - pstSoftWareParam->au32GridNumWidth[1] = 26; - pstSoftWareParam->au32GridNumWidth[2] = 52; - pstSoftWareParam->u32NmsThresh = - (HI_U32)(0.3f * SAMPLE_SVP_NNIE_QUANT_BASE); - pstSoftWareParam->u32ConfThresh = - (HI_U32)(0.5f * SAMPLE_SVP_NNIE_QUANT_BASE); - pstSoftWareParam->u32MaxRoiNum = 10; - pstSoftWareParam->af32Bias[0][0] = 116; - pstSoftWareParam->af32Bias[0][1] = 90; - pstSoftWareParam->af32Bias[0][2] = 156; - pstSoftWareParam->af32Bias[0][3] = 198; - pstSoftWareParam->af32Bias[0][4] = 373; - pstSoftWareParam->af32Bias[0][5] = 326; - pstSoftWareParam->af32Bias[1][0] = 30; - pstSoftWareParam->af32Bias[1][1] = 61; - pstSoftWareParam->af32Bias[1][2] = 62; - pstSoftWareParam->af32Bias[1][3] = 45; - pstSoftWareParam->af32Bias[1][4] = 59; - pstSoftWareParam->af32Bias[1][5] = 119; - pstSoftWareParam->af32Bias[2][0] = 10; - pstSoftWareParam->af32Bias[2][1] = 13; - pstSoftWareParam->af32Bias[2][2] = 16; - pstSoftWareParam->af32Bias[2][3] = 30; - pstSoftWareParam->af32Bias[2][4] = 33; - pstSoftWareParam->af32Bias[2][5] = 23; + // 获取数据大小 + HI_U32 u32VarSize; + if (pstNnieParam->astSegData[segId].astSrc[nodeId].enType >= + SVP_BLOB_TYPE_U8 && + pstNnieParam->astSegData[segId].astSrc[nodeId].enType <= + SVP_BLOB_TYPE_YVU422SP) { + u32VarSize = sizeof(HI_U8); + } else { + u32VarSize = sizeof(HI_U32); + } - /*Malloc assist buffer memory*/ - u32ClassNum = pstSoftWareParam->u32ClassNum + 1; - - SAMPLE_SVP_CHECK_EXPR_RET( - SAMPLE_SVP_NNIE_YOLOV3_REPORT_BLOB_NUM != - pstNnieParam->pstModel->astSeg[0].u16DstNum, - HI_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR, - "Error,pstNnieParam->pstModel->astSeg[0].u16DstNum(%d) should be %d!\n", - pstNnieParam->pstModel->astSeg[0].u16DstNum, - SAMPLE_SVP_NNIE_YOLOV3_REPORT_BLOB_NUM); - u32TmpBufTotalSize = - SAMPLE_SVP_NNIE_Yolov3_GetResultTmpBuf(pstNnieParam, pstSoftWareParam); - u32DstRoiSize = - SAMPLE_SVP_NNIE_ALIGN16(u32ClassNum * pstSoftWareParam->u32MaxRoiNum * - sizeof(HI_U32) * SAMPLE_SVP_NNIE_COORDI_NUM); - u32DstScoreSize = SAMPLE_SVP_NNIE_ALIGN16( - u32ClassNum * pstSoftWareParam->u32MaxRoiNum * sizeof(HI_U32)); - u32ClassRoiNumSize = SAMPLE_SVP_NNIE_ALIGN16(u32ClassNum * sizeof(HI_U32)); - u32TotalSize = u32TotalSize + u32DstRoiSize + u32DstScoreSize + - u32ClassRoiNumSize + u32TmpBufTotalSize; - s32Ret = SAMPLE_COMM_SVP_MallocCached("SAMPLE_YOLOV3_INIT", NULL, - (HI_U64 *)&u64PhyAddr, - (void **)&pu8VirAddr, u32TotalSize); - SAMPLE_SVP_CHECK_EXPR_RET(HI_SUCCESS != s32Ret, s32Ret, - SAMPLE_SVP_ERR_LEVEL_ERROR, - "Error,Malloc memory failed!\n"); - memset(pu8VirAddr, 0, u32TotalSize); - SAMPLE_COMM_SVP_FlushCache(u64PhyAddr, (void *)pu8VirAddr, u32TotalSize); - - /*set each tmp buffer addr*/ - pstSoftWareParam->stGetResultTmpBuf.u64PhyAddr = u64PhyAddr; - pstSoftWareParam->stGetResultTmpBuf.u64VirAddr = - (HI_U64)((HI_UL)pu8VirAddr); - - /*set result blob*/ - pstSoftWareParam->stDstRoi.enType = SVP_BLOB_TYPE_S32; - pstSoftWareParam->stDstRoi.u64PhyAddr = u64PhyAddr + u32TmpBufTotalSize; - pstSoftWareParam->stDstRoi.u64VirAddr = - (HI_U64)((HI_UL)pu8VirAddr + u32TmpBufTotalSize); - pstSoftWareParam->stDstRoi.u32Stride = - SAMPLE_SVP_NNIE_ALIGN16(u32ClassNum * pstSoftWareParam->u32MaxRoiNum * - sizeof(HI_U32) * SAMPLE_SVP_NNIE_COORDI_NUM); - pstSoftWareParam->stDstRoi.u32Num = 1; - pstSoftWareParam->stDstRoi.unShape.stWhc.u32Chn = 1; - pstSoftWareParam->stDstRoi.unShape.stWhc.u32Height = 1; - pstSoftWareParam->stDstRoi.unShape.stWhc.u32Width = - u32ClassNum * pstSoftWareParam->u32MaxRoiNum * - SAMPLE_SVP_NNIE_COORDI_NUM; - - pstSoftWareParam->stDstScore.enType = SVP_BLOB_TYPE_S32; - pstSoftWareParam->stDstScore.u64PhyAddr = - u64PhyAddr + u32TmpBufTotalSize + u32DstRoiSize; - pstSoftWareParam->stDstScore.u64VirAddr = - (HI_U64)((HI_UL)pu8VirAddr + u32TmpBufTotalSize + u32DstRoiSize); - pstSoftWareParam->stDstScore.u32Stride = SAMPLE_SVP_NNIE_ALIGN16( - u32ClassNum * pstSoftWareParam->u32MaxRoiNum * sizeof(HI_U32)); - pstSoftWareParam->stDstScore.u32Num = 1; - pstSoftWareParam->stDstScore.unShape.stWhc.u32Chn = 1; - pstSoftWareParam->stDstScore.unShape.stWhc.u32Height = 1; - pstSoftWareParam->stDstScore.unShape.stWhc.u32Width = - u32ClassNum * pstSoftWareParam->u32MaxRoiNum; - - pstSoftWareParam->stClassRoiNum.enType = SVP_BLOB_TYPE_S32; - pstSoftWareParam->stClassRoiNum.u64PhyAddr = - u64PhyAddr + u32TmpBufTotalSize + u32DstRoiSize + u32DstScoreSize; - pstSoftWareParam->stClassRoiNum.u64VirAddr = - (HI_U64)((HI_UL)pu8VirAddr + u32TmpBufTotalSize + u32DstRoiSize + - u32DstScoreSize); - pstSoftWareParam->stClassRoiNum.u32Stride = - SAMPLE_SVP_NNIE_ALIGN16(u32ClassNum * sizeof(HI_U32)); - pstSoftWareParam->stClassRoiNum.u32Num = 1; - pstSoftWareParam->stClassRoiNum.unShape.stWhc.u32Chn = 1; - pstSoftWareParam->stClassRoiNum.unShape.stWhc.u32Height = 1; - pstSoftWareParam->stClassRoiNum.unShape.stWhc.u32Width = u32ClassNum; - - return s32Ret; -} - -static HI_S32 SAMPLE_SVP_NNIE_Yolov3_ParamInit( - SAMPLE_SVP_NNIE_CFG_S *pstCfg, SAMPLE_SVP_NNIE_PARAM_S *pstNnieParam, - SAMPLE_SVP_NNIE_YOLOV3_SOFTWARE_PARAM_S *pstSoftWareParam) { - HI_S32 s32Ret = HI_SUCCESS; - /*init hardware para*/ - s32Ret = SAMPLE_COMM_SVP_NNIE_ParamInit(pstCfg, pstNnieParam); - SAMPLE_SVP_CHECK_EXPR_GOTO( - HI_SUCCESS != s32Ret, INIT_FAIL_0, SAMPLE_SVP_ERR_LEVEL_ERROR, - "Error(%#x),SAMPLE_COMM_SVP_NNIE_ParamInit failed!\n", s32Ret); - - /*init software para*/ - s32Ret = SAMPLE_SVP_NNIE_Yolov3_SoftwareInit(pstCfg, pstNnieParam, - pstSoftWareParam); - SAMPLE_SVP_CHECK_EXPR_GOTO( - HI_SUCCESS != s32Ret, INIT_FAIL_0, SAMPLE_SVP_ERR_LEVEL_ERROR, - "Error(%#x),SAMPLE_SVP_NNIE_Yolov3_SoftwareInit failed!\n", s32Ret); - - return s32Ret; -INIT_FAIL_0: - s32Ret = - SAMPLE_SVP_NNIE_Yolov3_Deinit(pstNnieParam, pstSoftWareParam, NULL); - SAMPLE_SVP_CHECK_EXPR_RET( - HI_SUCCESS != s32Ret, s32Ret, SAMPLE_SVP_ERR_LEVEL_ERROR, - "Error(%#x),SAMPLE_SVP_NNIE_Yolov3_Deinit failed!\n", s32Ret); + // 填充源数据 + if (pstNnieParam->astSegData[segId].astSrc[nodeId].enType == + SVP_BLOB_TYPE_YVU422SP || + pstNnieParam->astSegData[segId].astSrc[nodeId].enType == + SVP_BLOB_TYPE_SEQ_S32) { + zlog_error(log_nnie, "Error: not support this blob type: %d!\n", + pstNnieParam->astSegData[segId].astSrc[nodeId].enType); return HI_FAILURE; -} - -static HI_S32 SAMPLE_SVP_NNIE_FillSrcData( - SAMPLE_SVP_NNIE_CFG_S *pstNnieCfg, SAMPLE_SVP_NNIE_PARAM_S *pstNnieParam, - SAMPLE_SVP_NNIE_INPUT_DATA_INDEX_S *pstInputDataIdx) { - FILE *fp = NULL; - HI_U32 i = 0, j = 0, n = 0; - HI_U32 u32Height = 0, u32Width = 0, u32Chn = 0, u32Stride = 0, u32Dim = 0; - HI_U32 u32VarSize = 0; - HI_S32 s32Ret = HI_SUCCESS; - HI_U8 *pu8PicAddr = NULL; - HI_U32 *pu32StepAddr = NULL; - HI_U32 u32SegIdx = pstInputDataIdx->u32SegIdx; - HI_U32 u32NodeIdx = pstInputDataIdx->u32NodeIdx; - HI_U32 u32TotalStepNum = 0; - - /*open file*/ - if (NULL != pstNnieCfg->pszPic) { - fp = fopen(pstNnieCfg->pszPic, "rb"); - SAMPLE_SVP_CHECK_EXPR_RET(NULL == fp, HI_INVALID_VALUE, - SAMPLE_SVP_ERR_LEVEL_ERROR, - "Error, open file failed!\n"); - } - - /*get data size*/ - if (SVP_BLOB_TYPE_U8 <= - pstNnieParam->astSegData[u32SegIdx].astSrc[u32NodeIdx].enType && - SVP_BLOB_TYPE_YVU422SP >= - pstNnieParam->astSegData[u32SegIdx].astSrc[u32NodeIdx].enType) { - u32VarSize = sizeof(HI_U8); - } else { - u32VarSize = sizeof(HI_U32); - } - - /*fill src data*/ - if (SVP_BLOB_TYPE_SEQ_S32 == - pstNnieParam->astSegData[u32SegIdx].astSrc[u32NodeIdx].enType) { - u32Dim = pstNnieParam->astSegData[u32SegIdx] - .astSrc[u32NodeIdx] - .unShape.stSeq.u32Dim; - u32Stride = - pstNnieParam->astSegData[u32SegIdx].astSrc[u32NodeIdx].u32Stride; - pu32StepAddr = SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR( - HI_U32, pstNnieParam->astSegData[u32SegIdx] - .astSrc[u32NodeIdx] - .unShape.stSeq.u64VirAddrStep); - pu8PicAddr = SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR( - HI_U8, - pstNnieParam->astSegData[u32SegIdx].astSrc[u32NodeIdx].u64VirAddr); - for (n = 0; - n < pstNnieParam->astSegData[u32SegIdx].astSrc[u32NodeIdx].u32Num; - n++) { - for (i = 0; i < *(pu32StepAddr + n); i++) { - s32Ret = fread(pu8PicAddr, u32Dim * u32VarSize, 1, fp); - SAMPLE_SVP_CHECK_EXPR_GOTO(1 != s32Ret, FAIL, - SAMPLE_SVP_ERR_LEVEL_ERROR, - "Error,Read image file failed!\n"); - pu8PicAddr += u32Stride; - } - u32TotalStepNum += *(pu32StepAddr + n); - } - SAMPLE_COMM_SVP_FlushCache( - pstNnieParam->astSegData[u32SegIdx].astSrc[u32NodeIdx].u64PhyAddr, - SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR( - HI_VOID, pstNnieParam->astSegData[u32SegIdx] - .astSrc[u32NodeIdx] - .u64VirAddr), - u32TotalStepNum * u32Stride); - } else { - u32Height = pstNnieParam->astSegData[u32SegIdx] - .astSrc[u32NodeIdx] - .unShape.stWhc.u32Height; - u32Width = pstNnieParam->astSegData[u32SegIdx] - .astSrc[u32NodeIdx] - .unShape.stWhc.u32Width; - u32Chn = pstNnieParam->astSegData[u32SegIdx] - .astSrc[u32NodeIdx] - .unShape.stWhc.u32Chn; - u32Stride = - pstNnieParam->astSegData[u32SegIdx].astSrc[u32NodeIdx].u32Stride; - pu8PicAddr = SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR( - HI_U8, - pstNnieParam->astSegData[u32SegIdx].astSrc[u32NodeIdx].u64VirAddr); - if (SVP_BLOB_TYPE_YVU420SP == - pstNnieParam->astSegData[u32SegIdx].astSrc[u32NodeIdx].enType) { - for (n = 0; - n < - pstNnieParam->astSegData[u32SegIdx].astSrc[u32NodeIdx].u32Num; - n++) { - for (i = 0; i < u32Chn * u32Height / 2; i++) { - s32Ret = fread(pu8PicAddr, u32Width * u32VarSize, 1, fp); - SAMPLE_SVP_CHECK_EXPR_GOTO( - 1 != s32Ret, FAIL, SAMPLE_SVP_ERR_LEVEL_ERROR, - "Error,Read image file failed!\n"); - pu8PicAddr += u32Stride; - } - } - } else if (SVP_BLOB_TYPE_YVU422SP == pstNnieParam->astSegData[u32SegIdx] - .astSrc[u32NodeIdx] - .enType) { - for (n = 0; - n < - pstNnieParam->astSegData[u32SegIdx].astSrc[u32NodeIdx].u32Num; - n++) { - for (i = 0; i < u32Height * 2; i++) { - s32Ret = fread(pu8PicAddr, u32Width * u32VarSize, 1, fp); - SAMPLE_SVP_CHECK_EXPR_GOTO( - 1 != s32Ret, FAIL, SAMPLE_SVP_ERR_LEVEL_ERROR, - "Error,Read image file failed!\n"); - pu8PicAddr += u32Stride; - } - } - } else { - for (n = 0; - n < - pstNnieParam->astSegData[u32SegIdx].astSrc[u32NodeIdx].u32Num; - n++) { - for (i = 0; i < u32Chn; i++) { - for (j = 0; j < u32Height; j++) { - s32Ret = - fread(pu8PicAddr, u32Width * u32VarSize, 1, fp); - SAMPLE_SVP_CHECK_EXPR_GOTO( - 1 != s32Ret, FAIL, SAMPLE_SVP_ERR_LEVEL_ERROR, - "Error,Read image file failed!\n"); - pu8PicAddr += u32Stride; - } - } - } - } - SAMPLE_COMM_SVP_FlushCache( - pstNnieParam->astSegData[u32SegIdx].astSrc[u32NodeIdx].u64PhyAddr, - SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR( - HI_VOID, pstNnieParam->astSegData[u32SegIdx] - .astSrc[u32NodeIdx] - .u64VirAddr), - pstNnieParam->astSegData[u32SegIdx].astSrc[u32NodeIdx].u32Num * - u32Chn * u32Height * u32Stride); - } - - fclose(fp); - return HI_SUCCESS; -FAIL: - - fclose(fp); + } + if (pstNnieParam->astSegData[segId].astSrc[nodeId].u32Num != 1) { + zlog_error(log_nnie, "Error: batch size must be 1!\n"); return HI_FAILURE; + } + + HI_U32 u32Height = + pstNnieParam->astSegData[segId].astSrc[nodeId].unShape.stWhc.u32Height; + HI_U32 u32Width = + pstNnieParam->astSegData[segId].astSrc[nodeId].unShape.stWhc.u32Width; + HI_U32 u32Chn = + pstNnieParam->astSegData[segId].astSrc[nodeId].unShape.stWhc.u32Chn; + HI_U32 u32Stride = pstNnieParam->astSegData[segId].astSrc[nodeId].u32Stride; + HI_U8 *pu8PicAddr = SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR( + HI_U8, pstNnieParam->astSegData[segId].astSrc[nodeId].u64VirAddr); + + if (pstNnieParam->astSegData[segId].astSrc[nodeId].enType == + SVP_BLOB_TYPE_YVU420SP) { + const HI_U8 *srcData = NULL; + // Y + srcData = + SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR(const HI_U8, img->au64VirAddr[0]); + for (HI_U32 j = 0; j < u32Height; j++) { + if (memcpy_s(pu8PicAddr, u32Width * u32VarSize, srcData, + u32Width * u32VarSize) != EOK) { + zlog_error(log_nnie, "Error: memcpy failed!\n"); + return HI_FAILURE; + } + pu8PicAddr += u32Stride; + srcData += img->au32Stride[0]; + } + // UV + srcData = + SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR(const HI_U8, img->au64VirAddr[1]); + for (HI_U32 j = 0; j < u32Height / 2; j++) { // 2: 1/2Height + if (memcpy_s(pu8PicAddr, u32Width * u32VarSize, srcData, + u32Width * u32VarSize) != EOK) { + zlog_error(log_nnie, "Error: memcpy failed!\n"); + return HI_FAILURE; + } + pu8PicAddr += u32Stride; + srcData += img->au32Stride[1]; + } + } else { + for (HI_U32 i = 0; i < u32Chn; i++) { + const HI_U8 *srcData = + SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR(const HI_U8, img->au64VirAddr[i]); + for (HI_U32 j = 0; j < u32Height; j++) { + if (memcpy_s(pu8PicAddr, u32Width * u32VarSize, srcData, + u32Width * u32VarSize) != EOK) { + zlog_error(log_nnie, "Error: memcpy failed!\n"); + return HI_FAILURE; + } + pu8PicAddr += u32Stride; + srcData += img->au32Stride[i]; + } + } + } + + // 刷新cache + HI_S32 s32Ret = SAMPLE_COMM_SVP_FlushCache( + pstNnieParam->astSegData[segId].astSrc[nodeId].u64PhyAddr, + SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR( + HI_VOID, pstNnieParam->astSegData[segId].astSrc[nodeId].u64VirAddr), + pstNnieParam->astSegData[segId].astSrc[nodeId].u32Num * u32Chn * + u32Height * u32Stride); + if (s32Ret != HI_SUCCESS) { + zlog_error(log_nnie, "SAMPLE_COMM_SVP_FlushCache failed with %#x!\n", + s32Ret); + return HI_FAILURE; + } + + return HI_SUCCESS; } -static HI_S32 SAMPLE_SVP_NNIE_Forward( - SAMPLE_SVP_NNIE_PARAM_S *pstNnieParam, - SAMPLE_SVP_NNIE_INPUT_DATA_INDEX_S *pstInputDataIdx, - SAMPLE_SVP_NNIE_PROCESS_SEG_INDEX_S *pstProcSegIdx, HI_BOOL bInstant) { - HI_S32 s32Ret = HI_SUCCESS; - HI_U32 i = 0, j = 0; - HI_BOOL bFinish = HI_FALSE; - SVP_NNIE_HANDLE hSvpNnieHandle = 0; - HI_U32 u32TotalStepNum = 0; - SAMPLE_SVP_NIE_PERF_STAT_DEF_VAR() +static HI_S32 +SVP_NNIE_Forward(SAMPLE_SVP_NNIE_PARAM_S *pstNnieParam, + SAMPLE_SVP_NNIE_INPUT_DATA_INDEX_S *pstInputDataIdx, + SAMPLE_SVP_NNIE_PROCESS_SEG_INDEX_S *pstProcSegIdx, + HI_BOOL bInstant) { + HI_S32 s32Ret = 0; + HI_BOOL bFinish = HI_FALSE; + SVP_NNIE_HANDLE hSvpNnieHandle = 0; + HI_U32 u32TotalStepNum = 0; - SAMPLE_COMM_SVP_FlushCache( - pstNnieParam->astForwardCtrl[pstProcSegIdx->u32SegIdx] - .stTskBuf.u64PhyAddr, - SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR( - HI_VOID, pstNnieParam->astForwardCtrl[pstProcSegIdx->u32SegIdx] - .stTskBuf.u64VirAddr), - pstNnieParam->astForwardCtrl[pstProcSegIdx->u32SegIdx] - .stTskBuf.u32Size); + SAMPLE_COMM_SVP_FlushCache( + pstNnieParam->astForwardCtrl[pstProcSegIdx->u32SegIdx] + .stTskBuf.u64PhyAddr, + SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR( + HI_VOID, pstNnieParam->astForwardCtrl[pstProcSegIdx->u32SegIdx] + .stTskBuf.u64VirAddr), + pstNnieParam->astForwardCtrl[pstProcSegIdx->u32SegIdx].stTskBuf.u32Size); - SAMPLE_SVP_NNIE_PERF_STAT_BEGIN() - for (i = 0; - i < pstNnieParam->astForwardCtrl[pstProcSegIdx->u32SegIdx].u32DstNum; - i++) { - if (SVP_BLOB_TYPE_SEQ_S32 == - pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx] - .astDst[i] - .enType) { - for (j = 0; j < pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx] - .astDst[i] - .u32Num; - j++) { - u32TotalStepNum += - *(SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR( - HI_U32, - pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx] + for (HI_U32 i = 0; + i < pstNnieParam->astForwardCtrl[pstProcSegIdx->u32SegIdx].u32DstNum; + i++) { + if (pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst[i].enType == + SVP_BLOB_TYPE_SEQ_S32) { + for (HI_U32 j = 0; + j < + pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst[i].u32Num; + j++) { + u32TotalStepNum += + *(SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR( + HI_U32, pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx] .astDst[i] .unShape.stSeq.u64VirAddrStep) + - j); - } - SAMPLE_COMM_SVP_FlushCache( - pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx] - .astDst[i] - .u64PhyAddr, - SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR( - HI_VOID, pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx] - .astDst[i] - .u64VirAddr), - u32TotalStepNum * - pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx] - .astDst[i] - .u32Stride); - - } else { - SAMPLE_COMM_SVP_FlushCache( - pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx] - .astDst[i] - .u64PhyAddr, - SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR( - HI_VOID, pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx] - .astDst[i] - .u64VirAddr), - pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx] - .astDst[i] - .u32Num * - pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx] - .astDst[i] - .unShape.stWhc.u32Chn * - pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx] - .astDst[i] - .unShape.stWhc.u32Height * - pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx] - .astDst[i] - .u32Stride); - } - } - - /*set input blob according to node name*/ - if (pstInputDataIdx->u32SegIdx != pstProcSegIdx->u32SegIdx) { - for (i = 0; - i < - pstNnieParam->pstModel->astSeg[pstProcSegIdx->u32SegIdx].u16SrcNum; - i++) { - for (j = 0; - j < pstNnieParam->pstModel->astSeg[pstInputDataIdx->u32SegIdx] - .u16DstNum; - j++) { - if (0 == strncmp(pstNnieParam->pstModel - ->astSeg[pstInputDataIdx->u32SegIdx] - .astDstNode[j] - .szName, - pstNnieParam->pstModel - ->astSeg[pstProcSegIdx->u32SegIdx] - .astSrcNode[i] - .szName, - SVP_NNIE_NODE_NAME_LEN)) { - pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx] - .astSrc[i] = - pstNnieParam->astSegData[pstInputDataIdx->u32SegIdx] - .astDst[j]; - break; - } - } - SAMPLE_SVP_CHECK_EXPR_RET( - (j == pstNnieParam->pstModel->astSeg[pstInputDataIdx->u32SegIdx] - .u16DstNum), - HI_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR, - "Error,can't find %d-th seg's %d-th src blob!\n", - pstProcSegIdx->u32SegIdx, i); - } - } - - /*NNIE_Forward*/ - SAMPLE_SVP_NNIE_PERF_STAT_BEGIN() - s32Ret = HI_MPI_SVP_NNIE_Forward( - &hSvpNnieHandle, - pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astSrc, - pstNnieParam->pstModel, - pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst, - &pstNnieParam->astForwardCtrl[pstProcSegIdx->u32SegIdx], bInstant); - SAMPLE_SVP_CHECK_EXPR_RET(HI_SUCCESS != s32Ret, s32Ret, - SAMPLE_SVP_ERR_LEVEL_ERROR, - "Error,HI_MPI_SVP_NNIE_Forward failed!\n"); - - if (bInstant) { - /*Wait NNIE finish*/ - while (HI_ERR_SVP_NNIE_QUERY_TIMEOUT == - (s32Ret = HI_MPI_SVP_NNIE_Query( - pstNnieParam->astForwardCtrl[pstProcSegIdx->u32SegIdx] - .enNnieId, - hSvpNnieHandle, &bFinish, HI_TRUE))) { - usleep(100); - SAMPLE_SVP_TRACE(SAMPLE_SVP_ERR_LEVEL_INFO, - "HI_MPI_SVP_NNIE_Query Query timeout!\n"); - } - } - u32TotalStepNum = 0; - - SAMPLE_SVP_NNIE_PERF_STAT_BEGIN() - for (i = 0; - i < pstNnieParam->astForwardCtrl[pstProcSegIdx->u32SegIdx].u32DstNum; - i++) { - if (SVP_BLOB_TYPE_SEQ_S32 == - pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx] - .astDst[i] - .enType) { - for (j = 0; j < pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx] + j); + } + SAMPLE_COMM_SVP_FlushCache( + pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx] + .astDst[i] + .u64PhyAddr, + SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR( + HI_VOID, pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx] + .astDst[i] + .u64VirAddr), + u32TotalStepNum * pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx] .astDst[i] - .u32Num; - j++) { - u32TotalStepNum += - *(SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR( - HI_U32, - pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx] + .u32Stride); + } else { + SAMPLE_COMM_SVP_FlushCache( + pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx] + .astDst[i] + .u64PhyAddr, + SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR( + HI_VOID, pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx] + .astDst[i] + .u64VirAddr), + pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst[i].u32Num * + pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx] + .astDst[i] + .unShape.stWhc.u32Chn * + pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx] + .astDst[i] + .unShape.stWhc.u32Height * + pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx] + .astDst[i] + .u32Stride); + } + } + + // 根据节点名称设置输入blob + if (pstInputDataIdx->u32SegIdx != pstProcSegIdx->u32SegIdx) { + for (HI_U32 i = 0; + i < pstNnieParam->pstModel->astSeg[pstProcSegIdx->u32SegIdx].u16SrcNum; + i++) { + HI_U32 j; + for (j = 0; + j < + pstNnieParam->pstModel->astSeg[pstInputDataIdx->u32SegIdx].u16DstNum; + j++) { + if (strncmp(pstNnieParam->pstModel->astSeg[pstInputDataIdx->u32SegIdx] + .astDstNode[j] + .szName, + pstNnieParam->pstModel->astSeg[pstProcSegIdx->u32SegIdx] + .astSrcNode[i] + .szName, + SVP_NNIE_NODE_NAME_LEN) == 0) { + pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astSrc[i] = + pstNnieParam->astSegData[pstInputDataIdx->u32SegIdx].astDst[j]; + break; + } + } + if (j == pstNnieParam->pstModel->astSeg[pstInputDataIdx->u32SegIdx] + .u16DstNum) { + zlog_error(log_nnie, "Error: can't find %d-th seg's %d-th src blob!\n", + pstProcSegIdx->u32SegIdx, i); + return HI_FAILURE; + } + } + } + + // 多节点输入输出的CNN类型网络预测 + s32Ret = HI_MPI_SVP_NNIE_Forward( + &hSvpNnieHandle, + pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astSrc, + pstNnieParam->pstModel, + pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst, + &pstNnieParam->astForwardCtrl[pstProcSegIdx->u32SegIdx], bInstant); + if (s32Ret != HI_SUCCESS) { + zlog_error(log_nnie, "Error: HI_MPI_SVP_NNIE_Forward failed with %#x!\n", + s32Ret); + return s32Ret; + } + + if (bInstant) { + // 查询任务是否完成 + while ((s32Ret = HI_MPI_SVP_NNIE_Query( + pstNnieParam->astForwardCtrl[pstProcSegIdx->u32SegIdx].enNnieId, + hSvpNnieHandle, &bFinish, HI_TRUE)) == + HI_ERR_SVP_NNIE_QUERY_TIMEOUT) { + usleep(USLEEP_TIME); + // zlog_erro(log_nnie, "HI_MPI_SVP_NNIE_Query Query timeout!\n"); + } + } + + u32TotalStepNum = 0; + for (HI_U32 i = 0; + i < pstNnieParam->astForwardCtrl[pstProcSegIdx->u32SegIdx].u32DstNum; + i++) { + if (pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst[i].enType == + SVP_BLOB_TYPE_SEQ_S32) { + for (HI_U32 j = 0; + j < + pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst[i].u32Num; + j++) { + u32TotalStepNum += + *(SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR( + HI_U32, pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx] .astDst[i] .unShape.stSeq.u64VirAddrStep) + - j); - } - SAMPLE_COMM_SVP_FlushCache( - pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx] - .astDst[i] - .u64PhyAddr, - SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR( - HI_VOID, pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx] - .astDst[i] - .u64VirAddr), - u32TotalStepNum * - pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx] - .astDst[i] - .u32Stride); + j); + } + SAMPLE_COMM_SVP_FlushCache( + pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx] + .astDst[i] + .u64PhyAddr, + SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR( + HI_VOID, pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx] + .astDst[i] + .u64VirAddr), + u32TotalStepNum * pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx] + .astDst[i] + .u32Stride); + } else { + SAMPLE_COMM_SVP_FlushCache( + pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx] + .astDst[i] + .u64PhyAddr, + SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR( + HI_VOID, pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx] + .astDst[i] + .u64VirAddr), + pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx].astDst[i].u32Num * + pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx] + .astDst[i] + .unShape.stWhc.u32Chn * + pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx] + .astDst[i] + .unShape.stWhc.u32Height * + pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx] + .astDst[i] + .u32Stride); + } + } - } else { - SAMPLE_COMM_SVP_FlushCache( - pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx] - .astDst[i] - .u64PhyAddr, - SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR( - HI_VOID, pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx] - .astDst[i] - .u64VirAddr), - pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx] - .astDst[i] - .u32Num * - pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx] - .astDst[i] - .unShape.stWhc.u32Chn * - pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx] - .astDst[i] - .unShape.stWhc.u32Height * - pstNnieParam->astSegData[pstProcSegIdx->u32SegIdx] - .astDst[i] - .u32Stride); + return s32Ret; +} + +static void SVP_NNIE_YOLOV3_ParseResult(SVP_BLOB_S *pstDstScore, + SVP_BLOB_S *pstDstRoi, + SVP_BLOB_S *pstClassRoiNum, + DetectObjInfo resBuf[], + HI_S32 resMaxSize, HI_S32 *resLen) { + HI_U32 u32RoiNumBias = 0; + HI_U32 u32ScoreBias = 0; + HI_U32 u32BboxBias = 0; + HI_FLOAT f32Score = 0.0f; + HI_S32 *ps32Score = + SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR(HI_S32, pstDstScore->u64VirAddr); + HI_S32 *ps32Roi = + SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR(HI_S32, pstDstRoi->u64VirAddr); + HI_S32 *ps32ClassRoiNum = + SAMPLE_SVP_NNIE_CONVERT_64BIT_ADDR(HI_S32, pstClassRoiNum->u64VirAddr); + HI_U32 u32ClassNum = pstClassRoiNum->unShape.stWhc.u32Width; + + HI_S32 resId = 0; + memset_s(resBuf, resMaxSize * sizeof(resBuf[0]), 0, + resMaxSize * sizeof(resBuf[0])); + *resLen = 0; + + u32RoiNumBias += ps32ClassRoiNum[0]; + for (HI_U32 i = 1; i < u32ClassNum; i++) { + u32ScoreBias = u32RoiNumBias; + u32BboxBias = u32RoiNumBias * SAMPLE_SVP_COORDI_NUM; + // 如果置信度分数大于结果阈值,则打印结果 + if ((HI_FLOAT)ps32Score[u32ScoreBias] / SAMPLE_SVP_QUANT_BASE >= + CONF_THRESHOLD && + ps32ClassRoiNum[i] != 0) { + for (HI_U32 j = 0; j < (HI_U32)ps32ClassRoiNum[i]; j++) { + f32Score = + (HI_FLOAT)ps32Score[u32ScoreBias + j] / SAMPLE_SVP_QUANT_BASE; + if (f32Score >= SCORE_THRESHOLD) { + if (resId >= resMaxSize) { + zlog_error(log_nnie, "Warning: resBuf is full!\n"); + break; + } + resBuf[resId].cls = i; + resBuf[resId].score = f32Score; + RectBox *box = &resBuf[resId].box; + box->xmin = ps32Roi[u32BboxBias + j * SAMPLE_SVP_COORDI_NUM]; + box->ymin = ps32Roi[u32BboxBias + j * SAMPLE_SVP_COORDI_NUM + 1]; + box->xmax = ps32Roi[u32BboxBias + j * SAMPLE_SVP_COORDI_NUM + 2]; + box->ymax = ps32Roi[u32BboxBias + j * SAMPLE_SVP_COORDI_NUM + 3]; + if (box->xmin < box->xmax && box->ymin < box->ymax) { + resId++; + } else { + zlog_error( + log_nnie, + "object %d: %f, (%d, %d), (%d, %d) discard for coord ERR\n", i, + f32Score, box->xmin, box->ymin, box->xmax, box->ymax); + } } + } + u32RoiNumBias += ps32ClassRoiNum[i]; } + } + *resLen = resId; +} + +static HI_S32 SVP_NNIE_YOLOV3_Forward(const IVE_IMAGE_S *img, + DetectObjInfo *resBuf, int resMaxSize, + int *resLen) { + HI_S32 s32Ret = 0; + SAMPLE_SVP_NNIE_INPUT_DATA_INDEX_S stInputDataIdx = {0}; + SAMPLE_SVP_NNIE_PROCESS_SEG_INDEX_S stProcSegIdx = {0}; + + // 填充源数据 + stInputDataIdx.u32SegIdx = 0; + stInputDataIdx.u32NodeIdx = 0; + s32Ret = SVP_NNIE_FillSrcData(&g_stNnieParam, &stInputDataIdx, img); + if (s32Ret != HI_SUCCESS) { + zlog_error(log_nnie, "SVP_NNIE_FillSrcData failed with %#x!\n", s32Ret); return s32Ret; + } + + // NNIE推理(process the 0-th segment) + stProcSegIdx.u32SegIdx = 0; + s32Ret = + SVP_NNIE_Forward(&g_stNnieParam, &stInputDataIdx, &stProcSegIdx, HI_TRUE); + if (s32Ret != HI_SUCCESS) { + zlog_error(log_nnie, "SVP_NNIE_Forward failed with %#x!\n", s32Ret); + return s32Ret; + } + + // CPU后处理 + s32Ret = SAMPLE_SVP_NNIE_Yolov3_GetResult(&g_stNnieParam, &g_stYolov3Param); + if (s32Ret != HI_SUCCESS) { + zlog_error(log_nnie, "SAMPLE_SVP_NNIE_Yolov3_GetResult failed with %#x!\n", + s32Ret); + return s32Ret; + } + SVP_NNIE_YOLOV3_ParseResult( + &g_stYolov3Param.stDstScore, &g_stYolov3Param.stDstRoi, + &g_stYolov3Param.stClassRoiNum, resBuf, resMaxSize, resLen); + + return HI_SUCCESS; } -bool eb3516Yolov3Init(const char *model_file, const char *pic_file) { - HI_S32 ret = HI_SUCCESS; +static void *nnie_process(void *arg) { + HI_S32 s32Ret = 0; + VIDEO_FRAME_INFO_S stFrame = {0}; + VIDEO_FRAME_INFO_S stResizedFrame = {0}; + IVE_IMAGE_S stImage = {0}; + DetectObjInfo objs[DETECT_OBJ_MAX] = {0}; + RectBox objBoxs[DETECT_OBJ_MAX] = {0}; + HI_S32 objNum = 0; - SAMPLE_SVP_NNIE_CFG_S stNnieCfg = {0}; - SAMPLE_SVP_NNIE_INPUT_DATA_INDEX_S stInputDataIdx = {0}; - SAMPLE_SVP_NNIE_PROCESS_SEG_INDEX_S stProcSegIdx = {0}; - HI_FLOAT f32PrintResultThresh = 0.0f; - - /*Set configuration parameter*/ - f32PrintResultThresh = 0.8f; - stNnieCfg.pszPic= pic_file; - stNnieCfg.u32MaxInputNum = 1; //max input image num in each batch - stNnieCfg.u32MaxRoiNum = 0; - stNnieCfg.aenNnieCoreId[0] = SVP_NNIE_ID_0;//set NNIE core - - // Get logger - log_nnie = zlog_get_category("eb3516_nnie"); - if (!log_nnie) { - return false; + while (g_bIsRunning) { + s32Ret = HI_MPI_VPSS_GetChnFrame(0, 1, &stFrame, 2000); + if (s32Ret != HI_SUCCESS) { + zlog_error(log_nnie, "HI_MPI_VPSS_GetChnFrame failed with %#x!\n", + s32Ret); + goto release; } - // Init Sys - SAMPLE_COMM_SVP_CheckSysInit(); - zlog_info(log_nnie, "Sys succeed to init"); + if (g_bEnableForward) { + s32Ret = + MppFrmResize(&stFrame, &stResizedFrame, IMAGE_WIDTH, IMAGE_HEIGHT); + if (s32Ret != HI_SUCCESS) { + zlog_error(log_nnie, "MppFrmResize failed with %#x!\n", s32Ret); + goto destroy_resized_frm; + } - // Load model - ret = SAMPLE_COMM_SVP_NNIE_LoadModel((HI_CHAR *)model_file, &g_stNnieModel); - if (HI_SUCCESS != ret) { - zlog_error(log_nnie, "NNIE failed to load model"); - goto EXIT_SYS; - } - zlog_info(log_nnie, "Model succeed to be loaded"); + s32Ret = FrmToOrigImg(&stResizedFrame, &stImage); + if (s32Ret != HI_SUCCESS) { + zlog_error(log_nnie, "FrmToOrigImg failed with %#x!\n", s32Ret); + goto destroy_resized_frm; + } - // Init parameter - g_stNnieParam.pstModel = &g_stNnieModel.stModel; - ret = SAMPLE_SVP_NNIE_Yolov3_ParamInit(&stNnieCfg, &g_stNnieParam, - &g_stYolov3Param); - if (HI_SUCCESS != ret) { - zlog_error(log_nnie, "NNIE failed to init parameter"); - goto EXIT_DEINIT; + s32Ret = SVP_NNIE_YOLOV3_Forward(&stImage, objs, DETECT_OBJ_MAX, &objNum); + if (s32Ret != HI_SUCCESS) { + zlog_error(log_nnie, "SVP_NNIE_YOLOV3_Forward failed with %#x!\n", + s32Ret); + goto destroy_resized_frm; + } + + // zlog_error(log_nnie, "YOLOv3 detection result:\n"); + for (HI_S32 i = 0; i < objNum; i++) { + RectBox *box = &objs[i].box; + RectBoxTran(box, stResizedFrame.stVFrame.u32Width, + stResizedFrame.stVFrame.u32Height, + stFrame.stVFrame.u32Width, stFrame.stVFrame.u32Height); + objBoxs[i] = *box; + // zlog_error(log_nnie, "%s: %f, (%d, %d), (%d, %d)\n", + // LABEL_NAMES[objs[i].cls], objs[i].score, + // box->xmin, box->ymin, box->xmax, box->ymax); + } + nnie_callback(objs, objNum); + + if (objNum > 0) { + MppFrmDrawRects(&stFrame, objBoxs, objNum, RGB888_RED, 4); + } + destroy_resized_frm: + MppFrmDestroy(&stResizedFrame); } - // Read src pic - stInputDataIdx.u32SegIdx = 0; - stInputDataIdx.u32NodeIdx = 0; - ret = SAMPLE_SVP_NNIE_FillSrcData(&stNnieCfg, &g_stNnieParam, - &stInputDataIdx); - if (HI_SUCCESS != ret) { - zlog_error(log_nnie, "NNIE failed to read picture"); - goto EXIT_DEINIT; + send: + s32Ret = HI_MPI_VO_SendFrame(0, 0, &stFrame, 0); + if (s32Ret != HI_SUCCESS) { + zlog_error(log_nnie, "HI_MPI_VO_SendFrame failed with %#x!\n", s32Ret); + goto release; } - - // NNIE Forward - stProcSegIdx.u32SegIdx = 0; - ret = SAMPLE_SVP_NNIE_Forward(&g_stNnieParam, &stInputDataIdx, - &stProcSegIdx, HI_TRUE); - if (HI_SUCCESS != ret) { - zlog_error(log_nnie, "NNIE failed to start forward"); - goto EXIT_DEINIT; + release: + s32Ret = HI_MPI_VPSS_ReleaseChnFrame(0, 1, &stFrame); + if (s32Ret != HI_SUCCESS) { + zlog_error(log_nnie, "HI_MPI_VPSS_ReleaseChnFrame failed with %#x!\n", + s32Ret); } + } - // Get Result - ret = SAMPLE_SVP_NNIE_Yolov3_GetResult(&g_stNnieParam, &g_stYolov3Param); - if (HI_SUCCESS != ret) { - zlog_error(log_nnie, "NNIE failed to get result"); - goto EXIT_DEINIT; - } - - // Print Result - (void)SAMPLE_SVP_NNIE_Detection_PrintResult( - &g_stYolov3Param.stDstScore, &g_stYolov3Param.stDstRoi, - &g_stYolov3Param.stClassRoiNum, f32PrintResultThresh); - -EXIT_DEINIT: - SAMPLE_SVP_NNIE_Yolov3_Deinit(&g_stNnieParam, &g_stYolov3Param, - &g_stNnieModel); -EXIT_SYS: - SAMPLE_COMM_SVP_CheckSysExit(); - return false; + return NULL; } -void eb3516Yolov3Exit(void) { - SAMPLE_SVP_NNIE_Yolov3_Deinit(&g_stNnieParam, &g_stYolov3Param, - &g_stNnieModel); - memset(&g_stNnieParam, 0, sizeof(SAMPLE_SVP_NNIE_PARAM_S)); - memset(&g_stYolov3Param, 0, - sizeof(SAMPLE_SVP_NNIE_YOLOV3_SOFTWARE_PARAM_S)); - memset(&g_stNnieModel, 0, sizeof(SAMPLE_SVP_NNIE_MODEL_S)); - SAMPLE_COMM_SVP_CheckSysExit(); +int nnie_init() { + HI_S32 s32Ret = 0; - zlog_info(log_nnie, "Yolov3 Exit Successfully"); + log_nnie = zlog_get_category("eb3516_nnie"); + if (!log_nnie) { + return HI_FALSE; + } + + SAMPLE_SVP_NNIE_CFG_S stNnieCfg = {.pszPic = NULL, + .u32MaxInputNum = 1, + .u32MaxRoiNum = 0, + .aenNnieCoreId[0] = SVP_NNIE_ID_0}; + + // s32Ret = SAMPLE_COMM_SVP_CheckSysInit(); // 不需要, SYS已经初始化过了 + // if (s32Ret != HI_SUCCESS) { + // goto init_sys_failed; + // } + s32Ret = SAMPLE_COMM_SVP_NNIE_LoadModel(MODEL_FILE, &g_stNnieModel); + if (s32Ret != HI_SUCCESS) { + zlog_error(log_nnie, "Error: SAMPLE_COMM_SVP_NNIE_LoadModel failed!\n"); + goto load_model_failed; + } + g_stNnieParam.pstModel = &g_stNnieModel.stModel; + s32Ret = SAMPLE_COMM_SVP_NNIE_ParamInit(&stNnieCfg, &g_stNnieParam); + if (s32Ret != HI_SUCCESS) { + zlog_error(log_nnie, "Error: SAMPLE_COMM_SVP_NNIE_ParamInit failed!\n"); + goto init_nnie_failed; + } + s32Ret = SVP_NNIE_YOLOV3_ParamInit(&g_stNnieParam, &g_stYolov3Param); + if (s32Ret != HI_SUCCESS) { + zlog_error(log_nnie, "Error: SVP_NNIE_YOLOV3_ParamInit failed!\n"); + goto init_yolov3_failed; + } + + g_bIsRunning = 1; + s32Ret = pthread_create(&g_pidAiThread, NULL, nnie_process, NULL); + if (s32Ret != 0) { + zlog_error(log_nnie, "Error: create nnie thread failed!\n"); + goto create_thread_failed; + } + + return s32Ret; + +create_thread_failed: + g_bIsRunning = 0; +init_yolov3_failed: + SAMPLE_SVP_MMZ_FREE(g_stYolov3Param.stGetResultTmpBuf.u64PhyAddr, + g_stYolov3Param.stGetResultTmpBuf.u64VirAddr); +init_nnie_failed: + SAMPLE_COMM_SVP_NNIE_ParamDeinit(&g_stNnieParam); +load_model_failed: + SAMPLE_COMM_SVP_NNIE_UnloadModel(&g_stNnieModel); +init_sys_failed: + return s32Ret; } + +void nnie_exit() { + g_bIsRunning = 0; + pthread_join(g_pidAiThread, NULL); + SAMPLE_SVP_MMZ_FREE(g_stYolov3Param.stGetResultTmpBuf.u64PhyAddr, + g_stYolov3Param.stGetResultTmpBuf.u64VirAddr); + SAMPLE_COMM_SVP_NNIE_ParamDeinit(&g_stNnieParam); + SAMPLE_COMM_SVP_NNIE_UnloadModel(&g_stNnieModel); +} + +int nnie_start() { + if (!g_bEnableForward) { + g_bEnableForward = 1; + return SUCCESS; + } + return FAILED; +} + +int nnie_stop() { + if (g_bEnableForward) { + g_bEnableForward = 0; + return SUCCESS; + } + return FAILED; +} + +void nnie_callback(DetectObjInfo *detections, int count) {} \ No newline at end of file diff --git a/src/modules/nnie/eb3516_nnie.h b/src/modules/nnie/eb3516_nnie.h index 536264d..a11486f 100755 --- a/src/modules/nnie/eb3516_nnie.h +++ b/src/modules/nnie/eb3516_nnie.h @@ -6,9 +6,19 @@ extern "C" { #endif #include +#include "util.h" -bool eb3516Yolov3Init(const char *model_file, const char *pic_file); -void eb3516Yolov3Exit(void); +typedef struct { + int cls; // The category of the object, an integer > 0 + float score; // Object's credibility score + RectBox box; // The rectangular area of the object (pixels) +} DetectObjInfo; + +int nnie_init(); +void nnie_exit(); +int nnie_start(); +int nnie_stop(); +void nnie_callback(DetectObjInfo *detections, int count); #ifdef __cplusplus } diff --git a/src/modules/rtsp/MJPEGDeviceSource.cpp b/src/modules/rtsp/MJPEGDeviceSource.cpp index 5e16423..a25fb89 100755 --- a/src/modules/rtsp/MJPEGDeviceSource.cpp +++ b/src/modules/rtsp/MJPEGDeviceSource.cpp @@ -42,7 +42,7 @@ MJPEGDeviceSource::~MJPEGDeviceSource() { } codec_type_t MJPEGDeviceSource::getCodecType() { - return ROV_JPEG; + return JPEG; } void MJPEGDeviceSource::signalNewFrame(const FrameData &frameData) { diff --git a/src/modules/util.c b/src/modules/util.c new file mode 100755 index 0000000..04dcfc4 --- /dev/null +++ b/src/modules/util.c @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED. + * 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. + */ + +#include "util.h" + +#include +#include +#include "hi_debug.h" + +int IntZoomTo(int n, double rate, double rateMin, double rateMax) { + HI_ASSERT(rateMin < 1 && rateMax > 1); + + if (!rateMin) { + HI_ASSERT(rateMin); + return n; + } else { + int ret; + if (rate > rateMax) { + ret = n * (int) rateMax; + } else if (rate < rateMin) { + ret = n / (int) (1 / rateMin); + } else { + ret = (int) (n * rate); + } + return ret < 1 ? 1 : ret; + } +} + +void RectBoxTran(RectBox* box, int srcWidth, int srcHeight, int dstWidth, int dstHeight) { + HI_ASSERT(box && srcWidth && srcHeight); + box->xmin = box->xmin * dstWidth / srcWidth * 2 / 2; + box->xmax = box->xmax * dstWidth / srcWidth * 2 / 2; + box->ymin = box->ymin * dstHeight / srcHeight * 2 / 2; + box->ymax = box->ymax * dstHeight / srcHeight * 2 / 2; +} + +int HiStrxfrm(char *s1, char *s2, int n) { + int i; + + for (i = 0; (i < n - 1) && s2[i]; i++) { + s1[i] = s2[i]; + } + s1[i] = 0; + return i; +} + +void RecurMutexInit(pthread_mutex_t* mutex) { + HI_ASSERT(mutex); + pthread_mutexattr_t attr; + int res; + + res = pthread_mutexattr_init(&attr); + HI_ASSERT(!res); + + res = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP); + HI_ASSERT(!res); + res = pthread_mutex_init(mutex, &attr); + HI_ASSERT(!res); + + pthread_mutexattr_destroy(&attr); +} diff --git a/src/modules/util.h b/src/modules/util.h new file mode 100755 index 0000000..53db0d3 --- /dev/null +++ b/src/modules/util.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED. + * 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. + */ + +#ifndef UTIL_H +#define UTIL_H + +#include +#include +#include + +#if __cplusplus +extern "C" { +#endif + +#define HI_PER_BASE 100 +#define HI_OVEN_BASE 2 // Even base + +/* + * RGB888常用的颜色 + * RGB888 commonly used colors + */ +#define RGB888_RED ((uint32_t)0xFF0000) +#define RGB888_GREEN ((uint32_t)0x00FF00) +#define RGB888_BLUE ((uint32_t)0x0000FF) +#define RGB888_YELLOW ((uint32_t)0xFFFF00) +#define RGB888_WHITE ((uint32_t)0xFFFFFF) +#define RGB888_BLACK ((uint32_t)0x000000) + +#ifndef SAMPLE_PRT +#define SAMPLE_PRT(fmt...) \ + do { \ + printf("[%s]-%d: ", __FUNCTION__, __LINE__); \ + printf(fmt); \ + } while (0) +#endif + +typedef struct { + int xmin; + int xmax; + int ymin; + int ymax; +} RectBox; + +/* + * 将整数放大到给定的倍数范围 + * Amplify the integer to the given multiple range + */ +int IntZoomTo(int n, double rate, double rateMin, double rateMax); + +/* + * 按比例转换坐标 + * Convert coordinates proportionally + */ +void RectBoxTran(RectBox* box, int srcWidth, int srcHeight, int dstWidth, int dstHeight); + +/* + * 字符处理接口 + * Character processing interface + */ +int HiStrxfrm(char *s1, char *s2, int n); + +/* + * 初始化recursive pmutex + * Init recursive pmutex + */ +void RecurMutexInit(pthread_mutex_t* mutex); + +#ifdef __cplusplus +} +#endif + +#endif // UTIL_H diff --git a/xmake.lua b/xmake.lua index 573eacc..7a368a1 100755 --- a/xmake.lua +++ b/xmake.lua @@ -3,13 +3,13 @@ includes("Hi3516_SDK.lua", "live555.lua", " readerwriterqueue.lua") --- Add Cross Compile Toolchain toolchain("arm-himix200-linux") -set_kind("standalone") - -set_sdkdir(path.join(os.projectdir(), "arm-himix200-linux")) + set_kind("standalone") + set_sdkdir(path.join(os.projectdir(), "arm-himix200-linux")) toolchain_end() --- Set toolchain and C/C++ standard -- set_config("sdk", "/opt/hisi-linux/x86-arm/arm-himix200-linux/") +set_config("sdk", path.join(os.projectdir(), "arm-himix200-linux")) set_toolchains("arm-himix200-linux") set_plat("cross") set_arch("arm") @@ -25,43 +25,43 @@ add_requires( ) target("ISP") -set_kind("static") -add_files("src/modules/isp/*.c") -add_includedirs("src", "src/modules") -add_deps("sample_common") -add_packages("zlog") + set_kind("static") + add_files("src/modules/isp/**.c", "src/modules/*.c") + add_includedirs("src", "src/modules", "src/modules/isp") + add_deps("sample_common") + add_packages("zlog") target_end() target("NNIE") -set_kind("static") -add_files("src/modules/nnie/*.c") -add_includedirs("src", "src/modules") -add_deps("sample_common", "sample_svp") -add_packages("zlog") + set_kind("static") + add_files("src/modules/nnie/**.c", "src/modules/*.c") + add_includedirs("src", "src/modules", "src/modules/isp") + add_deps("sample_common", "sample_svp", "ISP") + add_packages("zlog") target_end() target("RTSP") -set_kind("static") -add_files("src/modules/rtsp/*.cpp") -add_includedirs("src", "src/modules") -add_packages("live555", "zlog", "readerwriterqueue") -add_links("pthread") + set_kind("static") + add_files("src/modules/rtsp/**.cpp", "src/modules/*.c") + add_includedirs("src", "src/modules") + add_packages("live555", "zlog", "readerwriterqueue") + add_links("pthread") target_end() target("CatFeeder") -set_kind("binary") -add_includedirs("src") -add_files("src/*.cpp") -add_deps("hi_library", "ISP", "NNIE", "RTSP") -add_packages("zlog") -add_links("stdc++fs") -after_build(function(target) - os.cp("src/log.conf", "$(buildir)/cross/arm/release") -end) + set_kind("binary") + add_includedirs("src", "src/modules") + add_files("src/*.cpp") + add_deps("hi_library", "ISP", "NNIE") + add_packages("zlog") + add_links("stdc++fs") + after_build(function(target) + os.cp("src/log.conf", "$(buildir)/cross/arm/release") + end) -if is_mode("debug") then - add_defines("DEBUG") - set_symbols("debug") - set_optimize("none") -end + if is_mode("debug") then + add_defines("DEBUG") + set_symbols("debug") + set_optimize("none") + end target_end()