You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1142 lines
38 KiB
1142 lines
38 KiB
|
7 months ago
|
/**
|
||
|
|
********************************************************************************
|
||
|
|
* Copyright (C) 2021 NEXTCHIP Inc. All rights reserved.
|
||
|
|
* This software is the confidential and proprietary information of
|
||
|
|
* NEXTCHIP, Inc. ("Confidential Information"). You shall not disclose such
|
||
|
|
* Confidential Information and shall use it only in accordance with
|
||
|
|
* the terms of the license agreement you entered into with NEXTCHIP.
|
||
|
|
********************************************************************************
|
||
|
|
|
||
|
|
********************************************************************************
|
||
|
|
* @file : wayland_npu_app.c
|
||
|
|
*
|
||
|
|
* @brief : wayland_npu application
|
||
|
|
*
|
||
|
|
* @author : Software Development Team. NextChip Inc.
|
||
|
|
*
|
||
|
|
* @date : 2024.04.26.
|
||
|
|
*
|
||
|
|
* @version : 1.0.0
|
||
|
|
********************************************************************************
|
||
|
|
* @note
|
||
|
|
*
|
||
|
|
********************************************************************************
|
||
|
|
*/
|
||
|
|
|
||
|
|
/*
|
||
|
|
********************************************************************************
|
||
|
|
* INCLUDES
|
||
|
|
********************************************************************************
|
||
|
|
*/
|
||
|
|
|
||
|
|
#include <stdio.h>
|
||
|
|
#include <stdlib.h>
|
||
|
|
#include <string.h>
|
||
|
|
#include <stdbool.h>
|
||
|
|
#include <math.h>
|
||
|
|
#include <assert.h>
|
||
|
|
#include <signal.h>
|
||
|
|
#include <linux/input.h>
|
||
|
|
#include <fcntl.h>
|
||
|
|
#include <errno.h>
|
||
|
|
#include <pthread.h>
|
||
|
|
#include <unistd.h>
|
||
|
|
#include <sys/ioctl.h>
|
||
|
|
#include <linux/videodev2.h>
|
||
|
|
#include <sys/mman.h>
|
||
|
|
#include <GLES2/gl2.h>
|
||
|
|
#include <EGL/egl.h>
|
||
|
|
#include <time.h>
|
||
|
|
#include <errno.h>
|
||
|
|
#include <SOIL.h>
|
||
|
|
#include <sys/eventfd.h>
|
||
|
|
#include <arm_neon.h>
|
||
|
|
#include <omp.h>
|
||
|
|
|
||
|
|
#include "wayland_egl.h"
|
||
|
|
#include "nc_opengl_init.h"
|
||
|
|
#include "v4l2_interface.h"
|
||
|
|
#include "nc_opengl_shader.h"
|
||
|
|
#include "nc_opengl_interface.h"
|
||
|
|
#include "nc_ts_fsync_flipflop_buffers.h"
|
||
|
|
#include "nc_app_config_parser.h"
|
||
|
|
#include "nc_cnn_aiware_runtime.h"
|
||
|
|
#include "nc_cnn_communicator.h"
|
||
|
|
#include "nc_cnn_worker_for_postprocess.h"
|
||
|
|
#include "nc_neon.h"
|
||
|
|
#ifdef AIWARE_DEVICE_SUPPORTED
|
||
|
|
#include "aiware/runtime/c/aiwaredevice.h"
|
||
|
|
#endif
|
||
|
|
#include "nc_opengl_ttf_font.h"
|
||
|
|
#ifdef USE_BYTETRACK
|
||
|
|
#include "nc_cnn_tracker.h"
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#ifdef USE_8MP_VI
|
||
|
|
#include "nc_dsr_helper.h"
|
||
|
|
#include "nc_dsr_set.h"
|
||
|
|
#include "nc_dmabuf_ctrl_helper.h"
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#ifdef USE_ADAS_LD
|
||
|
|
#include"ADAS_LD_Lib.h"
|
||
|
|
#endif
|
||
|
|
|
||
|
|
/*
|
||
|
|
********************************************************************************
|
||
|
|
* DEFINES
|
||
|
|
********************************************************************************
|
||
|
|
*/
|
||
|
|
|
||
|
|
#define VIS0_MAX_CH (0)
|
||
|
|
#define VIS1_MAX_CH (1)
|
||
|
|
#define VIDEO_MAX_CH (VIS0_MAX_CH + VIS1_MAX_CH)
|
||
|
|
|
||
|
|
#define VIDEO_BUFFER_NUM (3)
|
||
|
|
|
||
|
|
#ifdef USE_8MP_VI
|
||
|
|
#define VIDEO_WIDTH MAX_WIDTH_FOR_VDMA_CNN_DS
|
||
|
|
#define VIDEO_HEIGHT MAX_HEIGHT_FOR_VDMA_CNN_DS
|
||
|
|
#else
|
||
|
|
#define VIDEO_WIDTH NPU_INPUT_WIDTH
|
||
|
|
#define VIDEO_HEIGHT NPU_INPUT_HEIGHT
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#define CAP_FPS (30)
|
||
|
|
|
||
|
|
#define MQ_NAME_CNN_BUF "/cnn_data"
|
||
|
|
#define DEV_FILE_DSR "/dev/dsr"
|
||
|
|
|
||
|
|
#ifdef SHOW_PELEE_SEG
|
||
|
|
#define NETWORK_FILE_PELEE_SEG "misc/networks/peleeseg/peleeseg_640x384_apache6sr250_aiw4939.aiwbin"
|
||
|
|
#endif
|
||
|
|
#ifdef SHOW_PELEE_DETECT
|
||
|
|
#define NETWORK_FILE_PELEE_DET "misc/networks/peleeDet/peleedet_10class_640x384_apache6sr250_aiw4939.aiwbin"
|
||
|
|
#endif
|
||
|
|
#ifdef SHOW_YOLOV5_DETECT
|
||
|
|
#define NETWORK_FILE_YOLOV5_DET "misc/networks/Yolov5s/yolov5s_coco_640x384_apache6sr250_aiw4939.aiwbin"
|
||
|
|
#endif
|
||
|
|
#ifdef SHOW_YOLOV8_DETECT
|
||
|
|
#define NETWORK_FILE_YOLOV8_DET "misc/networks/Yolov8/yolov8s_coco_640x384_apache6sr250_aiw4939.aiwbin"
|
||
|
|
#endif
|
||
|
|
#ifdef SHOW_UFLD_LANE
|
||
|
|
#define NETWORK_FILE_UFLD_LANE "misc/networks/ufld/ufld_a6sr250_aiw4939.aiwbin"
|
||
|
|
#endif
|
||
|
|
#ifdef SHOW_TRI_CHIMERA
|
||
|
|
#define NETWORK_FILE_TRI_CHIMERA "misc/networks/trichimera/trichimera_640x384_a6sr_aiw4939.aiwbin"
|
||
|
|
#endif
|
||
|
|
#define COLOR_PALETTE_CNT (10)
|
||
|
|
typedef enum {
|
||
|
|
RGBA_R = 0,
|
||
|
|
RGBA_G,
|
||
|
|
RGBA_B,
|
||
|
|
RGBA_A,
|
||
|
|
RGBA_CNT,
|
||
|
|
} E_RGBA_IDX;
|
||
|
|
|
||
|
|
/* don't modify */
|
||
|
|
#define MAX_WIDTH_FOR_VDMA_CNN_DS (1920)
|
||
|
|
#define MAX_HEIGHT_FOR_VDMA_CNN_DS (1080)
|
||
|
|
/********************/
|
||
|
|
|
||
|
|
/*
|
||
|
|
********************************************************************************
|
||
|
|
* VARIABLE DECLARATIONS
|
||
|
|
********************************************************************************
|
||
|
|
*/
|
||
|
|
|
||
|
|
st_npu_input_info npu_input_info;
|
||
|
|
struct gl_npu_program g_npu_prog;
|
||
|
|
GLuint g_seg_texture;
|
||
|
|
struct gl_font_program g_font_prog;
|
||
|
|
Font font_38;
|
||
|
|
Font font_24;
|
||
|
|
|
||
|
|
unsigned char* image_data;
|
||
|
|
static int running = 1;
|
||
|
|
|
||
|
|
st_nc_v4l2_config v4l2_config[VIDEO_MAX_CH];
|
||
|
|
|
||
|
|
struct viewport g_viewport[VIDEO_MAX_CH];
|
||
|
|
|
||
|
|
#ifdef USE_8MP_VI
|
||
|
|
size_t BUFF_SIZE;
|
||
|
|
int dsr_fd;
|
||
|
|
DSR_Data_t dsr_info;
|
||
|
|
dma_alloc_info dma_info;
|
||
|
|
st_nc_dsr_config dsr_config;
|
||
|
|
img_input_config dsr_input_config;
|
||
|
|
img_output_config dsr_output_config;
|
||
|
|
#endif
|
||
|
|
/*
|
||
|
|
********************************************************************************
|
||
|
|
* FUNCTION DEFINITIONS
|
||
|
|
********************************************************************************
|
||
|
|
*/
|
||
|
|
#ifdef USE_8MP_VI
|
||
|
|
static int dsr_init(void)
|
||
|
|
{
|
||
|
|
int input_fd = 0, output_fd = 0;
|
||
|
|
long page_size = sysconf(_SC_PAGESIZE);
|
||
|
|
|
||
|
|
dsr_input_config.format = IMG_FORMAT_RGB888;
|
||
|
|
dsr_input_config.width = MAX_WIDTH_FOR_VDMA_CNN_DS;
|
||
|
|
dsr_input_config.height = MAX_HEIGHT_FOR_VDMA_CNN_DS;
|
||
|
|
dsr_output_config.format = IMG_FORMAT_RGB888;
|
||
|
|
|
||
|
|
BUFF_SIZE = dsr_input_config.width * dsr_input_config.height * 3;
|
||
|
|
BUFF_SIZE = ((BUFF_SIZE + page_size - 1) / page_size) * page_size;
|
||
|
|
|
||
|
|
|
||
|
|
if(dsr_config_downscale(&dsr_config, 1, NPU_INPUT_WIDTH, NPU_INPUT_HEIGHT) < 0){
|
||
|
|
perror("Error: DSR config fail");
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
if(open_device_and_dma_buffers(DEV_FILE_DSR, &dsr_fd, &input_fd, &output_fd, BUFF_SIZE) < 0){
|
||
|
|
perror("Error: DSR open fail");
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
if(dsr_setup_buffer(&dsr_info, dsr_fd, &dma_info, input_fd, output_fd, BUFF_SIZE) < 0){
|
||
|
|
perror("Error: DSR setup fail");
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
static int dsr_deinit(void)
|
||
|
|
{
|
||
|
|
nc_dmabuf_ctrl_end_cpu_access(dma_info.dmabuf_fd_in);
|
||
|
|
nc_dmabuf_ctrl_end_cpu_access(dma_info.dmabuf_fd_out);
|
||
|
|
|
||
|
|
nc_dmabuf_ctrl_free_dma_fd(dma_info.dmabuf_fd_in);
|
||
|
|
nc_dmabuf_ctrl_free_dma_fd(dma_info.dmabuf_fd_out);
|
||
|
|
|
||
|
|
nc_dmabuf_ctrl_close();
|
||
|
|
|
||
|
|
for (int i = 0; i < BUFF_NUM; i++) {
|
||
|
|
if (dsr_info.dsr_in_buf[i] != MAP_FAILED) {
|
||
|
|
munmap(dsr_info.dsr_in_buf[i], BUFF_SIZE);
|
||
|
|
}
|
||
|
|
if (dsr_info.dsr_out_buf[i] != MAP_FAILED) {
|
||
|
|
munmap(dsr_info.dsr_out_buf[i], BUFF_SIZE);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
dsr_device_deinit(&dsr_fd);
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
|
void set_viewport_config(void)
|
||
|
|
{
|
||
|
|
#if(VIDEO_MAX_CH == 1)
|
||
|
|
// full screen view
|
||
|
|
g_viewport[0].x = 0;
|
||
|
|
g_viewport[0].y = 0;
|
||
|
|
g_viewport[0].width = WINDOW_WIDTH;
|
||
|
|
g_viewport[0].height = WINDOW_HEIGHT;
|
||
|
|
#elif(VIDEO_MAX_CH > 1)
|
||
|
|
// quad view
|
||
|
|
for(int i = 0; i < VIDEO_MAX_CH; i++)
|
||
|
|
{
|
||
|
|
g_viewport[i].width = WINDOW_WIDTH/2;
|
||
|
|
g_viewport[i].height = WINDOW_HEIGHT/2;
|
||
|
|
|
||
|
|
// Set the view position for each channel
|
||
|
|
switch(i)
|
||
|
|
{
|
||
|
|
case 0:
|
||
|
|
g_viewport[i].x = 0;
|
||
|
|
g_viewport[i].y = WINDOW_HEIGHT/2;
|
||
|
|
break;
|
||
|
|
case 1:
|
||
|
|
g_viewport[i].x = WINDOW_WIDTH/2;
|
||
|
|
g_viewport[i].y = WINDOW_HEIGHT/2;
|
||
|
|
break;
|
||
|
|
case 2:
|
||
|
|
g_viewport[i].x = 0;
|
||
|
|
g_viewport[i].y = 0;
|
||
|
|
break;
|
||
|
|
case 3:
|
||
|
|
g_viewport[i].x = WINDOW_WIDTH/2;
|
||
|
|
g_viewport[i].y = 0;
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
|
||
|
|
void set_v4l2_config(void)
|
||
|
|
{
|
||
|
|
int i = 0, j = 0;
|
||
|
|
|
||
|
|
for(i = 0; i < VIS0_MAX_CH; i++) {
|
||
|
|
v4l2_config[i].video_buf.video_device_num = CNN_DEVICE_NUM(VISION0) + i;
|
||
|
|
v4l2_config[i].video_buf.video_fd = -1;
|
||
|
|
#ifdef USE_8MP_VI
|
||
|
|
v4l2_config[i].dma_mode = INTERLEAVE;
|
||
|
|
#else
|
||
|
|
v4l2_config[i].dma_mode = PLANAR;
|
||
|
|
#endif
|
||
|
|
v4l2_config[i].img_process = MODE_DS;
|
||
|
|
v4l2_config[i].pixformat = V4L2_PIX_FMT_RGB24;
|
||
|
|
v4l2_config[i].crop_x_start = 0;
|
||
|
|
v4l2_config[i].crop_y_start = 0;
|
||
|
|
v4l2_config[i].crop_width = 0;
|
||
|
|
v4l2_config[i].crop_height = 0;
|
||
|
|
#ifdef USE_8MP_VI
|
||
|
|
v4l2_config[i].ds_width = MAX_WIDTH_FOR_VDMA_CNN_DS;
|
||
|
|
v4l2_config[i].ds_height = MAX_HEIGHT_FOR_VDMA_CNN_DS;
|
||
|
|
#else
|
||
|
|
v4l2_config[i].ds_width = VIDEO_WIDTH;
|
||
|
|
v4l2_config[i].ds_height = VIDEO_HEIGHT;
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
|
||
|
|
for(j = VIS0_MAX_CH; j < VIDEO_MAX_CH; j++) {
|
||
|
|
v4l2_config[j].video_buf.video_device_num = CNN_DEVICE_NUM(VISION1) + j;
|
||
|
|
v4l2_config[j].video_buf.video_fd = -1;
|
||
|
|
#ifdef USE_8MP_VI
|
||
|
|
v4l2_config[j].dma_mode = INTERLEAVE;
|
||
|
|
#else
|
||
|
|
v4l2_config[j].dma_mode = PLANAR;
|
||
|
|
#endif
|
||
|
|
v4l2_config[j].img_process = MODE_DS;
|
||
|
|
v4l2_config[j].pixformat = V4L2_PIX_FMT_RGB24;
|
||
|
|
v4l2_config[j].crop_x_start = 0;
|
||
|
|
v4l2_config[j].crop_y_start = 0;
|
||
|
|
v4l2_config[j].crop_width = 0;
|
||
|
|
v4l2_config[j].crop_height = 0;
|
||
|
|
#ifdef USE_8MP_VI
|
||
|
|
v4l2_config[j].ds_width = MAX_WIDTH_FOR_VDMA_CNN_DS;
|
||
|
|
v4l2_config[j].ds_height = MAX_HEIGHT_FOR_VDMA_CNN_DS;
|
||
|
|
#else
|
||
|
|
v4l2_config[j].ds_width = VIDEO_WIDTH;
|
||
|
|
v4l2_config[j].ds_height = VIDEO_HEIGHT;
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
int send_cnn_buf (uint8_t *ptr_cnn_buf, uint64_t time_stamp_us, uint32_t cam_ch, E_NETWORK_UID net_id)
|
||
|
|
{
|
||
|
|
int ret = 0;
|
||
|
|
stCnnData *cnn_data;
|
||
|
|
struct mq_attr attr;
|
||
|
|
attr.mq_maxmsg = MAX_MQ_MSG_CNT;
|
||
|
|
attr.mq_msgsize = sizeof(stCnnData*);
|
||
|
|
int oflag = O_WRONLY | O_CREAT;
|
||
|
|
mqd_t mfd = mq_open(MQ_NAME_CNN_BUF, oflag, 0666, &attr);
|
||
|
|
if (mfd == -1) {
|
||
|
|
perror("mq open error");
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
cnn_data = (stCnnData*)malloc(sizeof(stCnnData));
|
||
|
|
cnn_data->cam_ch = cam_ch;
|
||
|
|
cnn_data->ptr_cnn_buf = ptr_cnn_buf;
|
||
|
|
cnn_data->time_stamp_us = time_stamp_us;
|
||
|
|
cnn_data->net_id = net_id;
|
||
|
|
|
||
|
|
if ((ret = mq_send(mfd, (const char *)&cnn_data, attr.mq_msgsize, 1)) == -1) {
|
||
|
|
printf("errno of mq_send = %d\n", errno);
|
||
|
|
}
|
||
|
|
mq_close(mfd);
|
||
|
|
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
int receive_cnn_buf (stCnnData **out_cnn_buf)
|
||
|
|
{
|
||
|
|
int ret = 0;
|
||
|
|
struct mq_attr attr;
|
||
|
|
attr.mq_maxmsg = MAX_MQ_MSG_CNT;
|
||
|
|
attr.mq_msgsize = sizeof(stCnnData *);
|
||
|
|
int oflag = O_RDONLY | O_CREAT;
|
||
|
|
mqd_t mfd = mq_open(MQ_NAME_CNN_BUF, oflag, 0666, &attr);
|
||
|
|
if (mfd == -1) {
|
||
|
|
perror("mq open error");
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
if ((ret = (int32_t)mq_receive(mfd, (char*)out_cnn_buf, attr.mq_msgsize, NULL)) == -1) {
|
||
|
|
printf("errno of mq_receive = %d\n", errno);
|
||
|
|
}
|
||
|
|
mq_close(mfd);
|
||
|
|
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
int v4l2_initialize(void)
|
||
|
|
{
|
||
|
|
for(int i = 0; i < VIDEO_MAX_CH; i++)
|
||
|
|
{
|
||
|
|
v4l2_config[i].video_buf.video_fd = nc_v4l2_open(v4l2_config[i].video_buf.video_device_num, true);
|
||
|
|
if(v4l2_config[i].video_buf.video_fd == errno) {
|
||
|
|
printf("[error] nc_v4l2_open() failure!\n");
|
||
|
|
} else {
|
||
|
|
if(nc_v4l2_init_device_and_stream_on(&v4l2_config[i], VIDEO_BUFFER_NUM) < 0) {
|
||
|
|
printf("[error] nc_v4l2_init_device_and_stream_on() failure!\n");
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
nc_v4l2_show_user_config(&v4l2_config[0], VIDEO_MAX_CH);
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
void nc_draw_gl_npu(struct viewport viewport, int network_task, pp_result_buf *net_result, struct gl_npu_program g_npu_prog)
|
||
|
|
{
|
||
|
|
stCnnPostprocessingResults *det_result = &net_result->cnn_result;
|
||
|
|
stObjDrawInfo *draw_cnn = &net_result->draw_info;
|
||
|
|
stSegDrawInfo *draw_seg = &net_result->seg_info;
|
||
|
|
stLaneDrawInfo *draw_lane = &net_result->lane_draw_info;
|
||
|
|
|
||
|
|
int max_class_cnt = draw_cnn->max_class_cnt;
|
||
|
|
int max_seg_class_cnt = draw_seg->max_class_cnt;
|
||
|
|
float target_view_ratio = 1.f;
|
||
|
|
char buftext[128];
|
||
|
|
|
||
|
|
target_view_ratio = (float)WINDOW_HEIGHT / (float)viewport.height;
|
||
|
|
|
||
|
|
glViewport(viewport.x, viewport.y, viewport.width, viewport.height);
|
||
|
|
|
||
|
|
if(network_task == DETECTION)
|
||
|
|
{
|
||
|
|
float** color = (float**)malloc(max_class_cnt * sizeof(float*));
|
||
|
|
for (int i = 0; i < max_class_cnt; ++i) {
|
||
|
|
color[i] = (float*)malloc(RGBA_CNT * sizeof(float));
|
||
|
|
}
|
||
|
|
|
||
|
|
for (int j = 0; j < max_class_cnt; ++j) {
|
||
|
|
color[j][RGBA_R] = (float)(draw_cnn->class_colors[j].r) / 255.0f;
|
||
|
|
color[j][RGBA_G] = (float)(draw_cnn->class_colors[j].g) / 255.0f;
|
||
|
|
color[j][RGBA_B] = (float)(draw_cnn->class_colors[j].b) / 255.0f;
|
||
|
|
color[j][RGBA_A] = 1.0f;
|
||
|
|
}
|
||
|
|
|
||
|
|
for(int i=0; i<draw_cnn->max_class_cnt; i++){
|
||
|
|
for(int bidx = 0; bidx < det_result->class_objs[i].obj_cnt; bidx++) {
|
||
|
|
stObjInfo obj_info = det_result->class_objs[i].objs[bidx];
|
||
|
|
nc_opengl_draw_rectangle(obj_info.bbox.x, obj_info.bbox.y, obj_info.bbox.w, obj_info.bbox.h, color[i], g_npu_prog);
|
||
|
|
|
||
|
|
// draw bbox label
|
||
|
|
#ifdef USE_BYTETRACK
|
||
|
|
// show track id (not cnn probability)
|
||
|
|
if (obj_info.track_id < 0) sprintf(buftext, "%s:%0.2f", draw_cnn->class_names[i], obj_info.prob);
|
||
|
|
else sprintf(buftext, "[%d]%s:%0.2f", obj_info.track_id, draw_cnn->class_names[i], obj_info.prob);
|
||
|
|
#else
|
||
|
|
sprintf(buftext, "%s:%0.2f", draw_cnn->class_names[i], obj_info.prob);
|
||
|
|
#endif
|
||
|
|
float textcolor[3] = {color[i][RGBA_R], color[i][RGBA_G], color[i][RGBA_B]};
|
||
|
|
nc_opengl_draw_text(&font_24, buftext, obj_info.bbox.x, (float)WINDOW_HEIGHT - (obj_info.bbox.y-12), target_view_ratio, textcolor, WINDOW_WIDTH, WINDOW_HEIGHT, g_font_prog);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
for (int i = 0; i < max_class_cnt; ++i) {
|
||
|
|
free(color[i]);
|
||
|
|
}
|
||
|
|
free(color);
|
||
|
|
}
|
||
|
|
else if(network_task == SEGMENTATION)
|
||
|
|
{
|
||
|
|
glBindTexture(GL_TEXTURE_2D, g_seg_texture);
|
||
|
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, draw_seg->width, draw_seg->height, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, det_result->seg);
|
||
|
|
|
||
|
|
float color[COLOR_PALETTE_CNT][RGBA_CNT];
|
||
|
|
|
||
|
|
for (int j = 0; j < max_seg_class_cnt; ++j) {
|
||
|
|
color[j][RGBA_R] = (float)(draw_seg->class_colors[j].r) / 255.0f;
|
||
|
|
color[j][RGBA_G] = (float)(draw_seg->class_colors[j].g) / 255.0f;
|
||
|
|
color[j][RGBA_B] = (float)(draw_seg->class_colors[j].b) / 255.0f;
|
||
|
|
color[j][RGBA_A] = (float)(draw_seg->class_colors[j].a) / 255.0f;
|
||
|
|
}
|
||
|
|
nc_opengl_draw_segmentation(g_seg_texture, (float**)color, draw_seg->max_class_cnt, g_npu_prog);
|
||
|
|
}
|
||
|
|
else if(network_task == LANE)
|
||
|
|
{
|
||
|
|
float color[COLOR_PALETTE_CNT][RGBA_CNT];
|
||
|
|
|
||
|
|
for (int j = 0; j < draw_lane->max_lane_num; ++j) {
|
||
|
|
color[j][RGBA_R] = (float)(draw_lane->index_colors[j].r) / 255.0f;
|
||
|
|
color[j][RGBA_G] = (float)(draw_lane->index_colors[j].g) / 255.0f;
|
||
|
|
color[j][RGBA_B] = (float)(draw_lane->index_colors[j].b) / 255.0f;
|
||
|
|
color[j][RGBA_A] = 1.0f;
|
||
|
|
}
|
||
|
|
|
||
|
|
for(int i = 0; i < draw_lane->max_lane_num; i++)
|
||
|
|
{
|
||
|
|
int point_num = det_result->lane_det[i].point_cnt;
|
||
|
|
int lane_class = det_result->lane_det[i].lane_class;
|
||
|
|
|
||
|
|
if(point_num == 0) continue;
|
||
|
|
|
||
|
|
for(int j=0; j<point_num-1; j++)
|
||
|
|
{
|
||
|
|
float st_x = det_result->lane_det[i].point[j].x;
|
||
|
|
float st_y = det_result->lane_det[i].point[j].y;
|
||
|
|
float end_x = det_result->lane_det[i].point[j+1].x;
|
||
|
|
float end_y = det_result->lane_det[i].point[j+1].y;
|
||
|
|
|
||
|
|
nc_opengl_draw_line(st_x, st_y, end_x, end_y, lane_class, color[i], g_npu_prog);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
#ifdef USE_UFLD_NETWORK_DEBUGGING
|
||
|
|
float color_table[6][RGBA_CNT] = {{1.0f,1.0f,1.0f,0.15f}, // white (grid)
|
||
|
|
{1.0f,0.0f,0.0f,1.0f}, // red (index 0)
|
||
|
|
{0.0f,0.0f,1.0f,1.0f}, // blue (index 1)
|
||
|
|
{1.0f,1.0f,0.0f,1.0f}, // yellow (index 2)
|
||
|
|
{0.0f,1.0f,0.0f,1.0f}, // green (index 3)
|
||
|
|
{0.0f,0.0f,0.0f,1.0f}}; // black (final point)
|
||
|
|
stUFLD_dbg_info* debug_info = NULL;
|
||
|
|
int info_cnt = 0;
|
||
|
|
|
||
|
|
#if defined(DBG_ROW_ANCHOR)
|
||
|
|
|
||
|
|
float row_cell_num = (float)(draw_lane->row_cell_num);
|
||
|
|
float row_cell_width = WINDOW_WIDTH/(float)(row_cell_num-1);
|
||
|
|
float row_cell_height = (draw_lane->row_anchor_max - draw_lane->row_anchor_min) * WINDOW_HEIGHT * (1/ (float)(draw_lane->row_anchor_num - 1));
|
||
|
|
|
||
|
|
//draw row anchor grid
|
||
|
|
for(int i=0 ; i<(draw_lane->row_anchor_num); i++)
|
||
|
|
{
|
||
|
|
nc_opengl_draw_debugging_grid_line(0, draw_lane->row_anchor[i] * WINDOW_HEIGHT, WINDOW_WIDTH-1, draw_lane->row_anchor[i] * WINDOW_HEIGHT, 1, color_table[0], g_npu_prog);
|
||
|
|
}
|
||
|
|
|
||
|
|
for(float j=0; j<row_cell_num; j++)
|
||
|
|
{
|
||
|
|
nc_opengl_draw_debugging_grid_line(j/(row_cell_num-1)*WINDOW_WIDTH, 0, j/(row_cell_num-1)*WINDOW_WIDTH, WINDOW_HEIGHT-1, 1, color_table[0], g_npu_prog);
|
||
|
|
}
|
||
|
|
|
||
|
|
for(int i = 0; i < draw_lane->max_lane_num; i++)
|
||
|
|
{
|
||
|
|
if(draw_lane->lane_anchor_info[i] != 0) continue;
|
||
|
|
|
||
|
|
info_cnt = det_result->lane_det[i].dbg_info_cnt;
|
||
|
|
if(info_cnt == 0) continue;
|
||
|
|
|
||
|
|
for(int j=0; j<info_cnt; j++)
|
||
|
|
{
|
||
|
|
debug_info = &(det_result->lane_det[i].ufld_dbg_info[j]);
|
||
|
|
|
||
|
|
//draw max_indices
|
||
|
|
nc_opengl_draw_rectangle(debug_info->x, debug_info->y, row_cell_width, row_cell_height , color_table[i+1], g_npu_prog);
|
||
|
|
|
||
|
|
//draw stddev
|
||
|
|
nc_opengl_draw_line(debug_info->index_min, debug_info->y + row_cell_height/2, debug_info->index_max, debug_info->y + row_cell_height/2, 1, color_table[i+1], g_npu_prog);
|
||
|
|
|
||
|
|
//draw final result (point)
|
||
|
|
nc_opengl_draw_rectangle(debug_info->final_point.x-3, debug_info->final_point.y-3, 6, 6, color_table[5], g_npu_prog);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
#elif defined(DBG_COL_ANCHOR)
|
||
|
|
|
||
|
|
float col_cell_num = (float)(draw_lane->col_cell_num);
|
||
|
|
float col_cell_width = (draw_lane->col_anchor_max - draw_lane->col_anchor_min) * WINDOW_WIDTH * (1/ (float)(draw_lane->col_anchor_num - 1));
|
||
|
|
float col_cell_height = WINDOW_HEIGHT/(float)(col_cell_num-1);
|
||
|
|
|
||
|
|
//draw column anchor grid
|
||
|
|
for(int i=0 ; i<(draw_lane->col_anchor_num); i++)
|
||
|
|
{
|
||
|
|
nc_opengl_draw_debugging_grid_line(draw_lane->col_anchor[i] * WINDOW_WIDTH, 0, draw_lane->col_anchor[i] * WINDOW_WIDTH, WINDOW_HEIGHT-1, 1, color_table[0], g_npu_prog);
|
||
|
|
}
|
||
|
|
|
||
|
|
for(float j=0; j<col_cell_num; j++)
|
||
|
|
{
|
||
|
|
nc_opengl_draw_debugging_grid_line(0, j/(col_cell_num-1)*WINDOW_HEIGHT, WINDOW_WIDTH-1, j/(col_cell_num-1)*WINDOW_HEIGHT, 1, color_table[0], g_npu_prog);
|
||
|
|
}
|
||
|
|
|
||
|
|
for(int i = 0; i < draw_lane->max_lane_num; i++)
|
||
|
|
{
|
||
|
|
if(draw_lane->lane_anchor_info[i] != 1) continue;
|
||
|
|
|
||
|
|
info_cnt = det_result->lane_det[i].dbg_info_cnt;
|
||
|
|
if(info_cnt == 0) continue;
|
||
|
|
|
||
|
|
for(int j=0; j<info_cnt; j++)
|
||
|
|
{
|
||
|
|
debug_info = &(det_result->lane_det[i].ufld_dbg_info[j]);
|
||
|
|
|
||
|
|
//draw max_indices
|
||
|
|
nc_opengl_draw_rectangle(debug_info->x, debug_info->y, col_cell_width, col_cell_height , color_table[i+1], g_npu_prog);
|
||
|
|
|
||
|
|
//draw stddev
|
||
|
|
nc_opengl_draw_line(debug_info->x + col_cell_width/2, debug_info->index_min, debug_info->x + col_cell_width/2, debug_info->index_max, 1, color_table[i+1], g_npu_prog);
|
||
|
|
|
||
|
|
//draw final result (point)
|
||
|
|
nc_opengl_draw_rectangle(debug_info->final_point.x-3, debug_info->final_point.y-3, 6, 6, color_table[5], g_npu_prog);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
// printf("Invalid network %d\n", sel_network);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void gl_initialize(struct window *window)
|
||
|
|
{
|
||
|
|
int width, height, channels;
|
||
|
|
char buf[128];
|
||
|
|
|
||
|
|
sprintf(buf, "misc/image/nextchip_s.png");
|
||
|
|
image_data = SOIL_load_image(buf, &width, &height, &channels, SOIL_LOAD_RGBA);
|
||
|
|
|
||
|
|
// init video shader
|
||
|
|
nc_opengl_init_video_shader(window, 0);
|
||
|
|
|
||
|
|
// init texture for video draw
|
||
|
|
for(int i=0;i<VIDEO_MAX_CH;i++)
|
||
|
|
{
|
||
|
|
glGenTextures(1, &window->gl.texture[i]);
|
||
|
|
glBindTexture(GL_TEXTURE_2D, window->gl.texture[i]);
|
||
|
|
|
||
|
|
//stbi_set_flip_vertically_on_load(true);
|
||
|
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image_data);
|
||
|
|
//glGenerateMipmap(GL_TEXTURE_2D);
|
||
|
|
|
||
|
|
// set texture filtering parameters
|
||
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Load the font using the freetype library.
|
||
|
|
nc_opengl_load_font("misc/font/NotoSans-Regular.ttf", 38, &font_38);
|
||
|
|
nc_opengl_load_font("misc/font/NotoSans-Regular.ttf", 24, &font_24);
|
||
|
|
// init font shader
|
||
|
|
nc_opengl_init_font_shader(&g_font_prog);
|
||
|
|
|
||
|
|
// init npu shader
|
||
|
|
nc_opengl_init_npu_shader(&g_npu_prog);
|
||
|
|
|
||
|
|
// init texture for segmentation draw
|
||
|
|
glGenTextures(1, &g_seg_texture);
|
||
|
|
glBindTexture(GL_TEXTURE_2D, g_seg_texture);
|
||
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||
|
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||
|
|
|
||
|
|
// set viewport
|
||
|
|
glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
|
||
|
|
}
|
||
|
|
|
||
|
|
// #define SHOW_FPS
|
||
|
|
#ifdef SHOW_FPS
|
||
|
|
float calc_fps_at_loop_ent1(int update_period_fcnt)
|
||
|
|
{
|
||
|
|
static uint64_t s_time = 0;
|
||
|
|
static float fps = 0.f;
|
||
|
|
static uint64_t fcnt = 0;
|
||
|
|
uint64_t elapsed_ms = 0;
|
||
|
|
fcnt++;
|
||
|
|
if (fcnt % update_period_fcnt == 1) {
|
||
|
|
if (s_time == 0) {
|
||
|
|
s_time = nc_get_mono_time();
|
||
|
|
} else {
|
||
|
|
elapsed_ms = nc_elapsed_time(s_time);
|
||
|
|
// printf("fcnt(%d) elapsed_ms(%d)\n", fcnt, elapsed_ms);
|
||
|
|
if (elapsed_ms > 0) fps = (float)((fcnt-1) / (elapsed_ms/1000.f));
|
||
|
|
|
||
|
|
// re-init
|
||
|
|
fcnt = 1;
|
||
|
|
s_time = nc_get_mono_time();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return fps;
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
|
void render(void *data, struct wl_callback *callback, uint32_t time)
|
||
|
|
{
|
||
|
|
static struct timespec begin, end, set_time;
|
||
|
|
static uint64_t fpstime = 0;
|
||
|
|
static uint64_t fpscount = 0;
|
||
|
|
static uint64_t fpscount_00 = 0;
|
||
|
|
static uint64_t frametime = 0;
|
||
|
|
static uint64_t opengl_time = 0;
|
||
|
|
static uint64_t framecnt = 0;
|
||
|
|
int networkOrder[VIDEO_MAX_CH];
|
||
|
|
|
||
|
|
(void)time;
|
||
|
|
|
||
|
|
clock_gettime(CLOCK_MONOTONIC, &begin);
|
||
|
|
struct window *window = (struct window *)data;
|
||
|
|
// uint64_t start_time = 0;
|
||
|
|
|
||
|
|
assert(window->callback == callback);
|
||
|
|
window->callback = NULL;
|
||
|
|
|
||
|
|
if (callback)
|
||
|
|
wl_callback_destroy(callback);
|
||
|
|
|
||
|
|
if (!window->configured)
|
||
|
|
return;
|
||
|
|
|
||
|
|
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
|
||
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||
|
|
|
||
|
|
for(int i = 0;i<VIDEO_MAX_CH;i++)
|
||
|
|
{
|
||
|
|
if (v4l2_config[i].video_buf.video_fd == -1)
|
||
|
|
{
|
||
|
|
// Upload texture from logo image data
|
||
|
|
glBindTexture(GL_TEXTURE_2D, window->gl.texture[i]);
|
||
|
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, VIDEO_WIDTH, VIDEO_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, image_data);
|
||
|
|
|
||
|
|
}else
|
||
|
|
{
|
||
|
|
struct v4l2_buffer video_buf;
|
||
|
|
CLEAR(video_buf);
|
||
|
|
|
||
|
|
// Queue the buffer for capturing a new frame
|
||
|
|
if (nc_v4l2_dequeue_buffer(v4l2_config[i].video_buf.video_fd, &video_buf) == -1) {
|
||
|
|
//printf("Error VIDIOC_DQBUF buffer %d\n", video_buf.index);
|
||
|
|
}else
|
||
|
|
{
|
||
|
|
#if (VIDEO_MAX_CH == 4)
|
||
|
|
if (((framecnt % 2 == 0) && (i == 0 || i == 2)) ||
|
||
|
|
((framecnt % 2 == 1) && (i == 1 || i == 3)))
|
||
|
|
#endif
|
||
|
|
{
|
||
|
|
uint64_t time_stamp_us = 0;
|
||
|
|
networkOrder[i] = nc_get_cnn_networks_id();
|
||
|
|
unsigned char* rgbdata_for_cnn = (unsigned char *)malloc(npu_input_info.rgb_size);
|
||
|
|
#ifdef USE_8MP_VI
|
||
|
|
memcpy(dsr_info.dsr_in_buf[0], (uint8_t *)v4l2_config[i].video_buf.buffers[video_buf.index].start, MAX_WIDTH_FOR_VDMA_CNN_DS*MAX_HEIGHT_FOR_VDMA_CNN_DS*RGB_CNT);
|
||
|
|
dsr_downscale(dsr_fd, &dsr_info, dsr_input_config, dsr_output_config, dsr_config, 0);
|
||
|
|
nc_rgb_interleaved_to_planar_neon((unsigned char *)dsr_info.dsr_out_buf[0] \
|
||
|
|
,(unsigned char *)rgbdata_for_cnn \
|
||
|
|
,(unsigned char *)rgbdata_for_cnn + NPU_INPUT_WIDTH*NPU_INPUT_HEIGHT \
|
||
|
|
,(unsigned char *)rgbdata_for_cnn + NPU_INPUT_WIDTH*NPU_INPUT_HEIGHT*2 \
|
||
|
|
, NPU_INPUT_WIDTH, NPU_INPUT_HEIGHT);
|
||
|
|
#else
|
||
|
|
memcpy(rgbdata_for_cnn, (unsigned char *)v4l2_config[i].video_buf.buffers[video_buf.index].start, npu_input_info.rgb_size); // 600us
|
||
|
|
#endif
|
||
|
|
send_cnn_buf (rgbdata_for_cnn, time_stamp_us, (uint32_t)i, (E_NETWORK_UID)networkOrder[i]);// 50us
|
||
|
|
// printf("send cnn msg : %llu us\n", nc_elapsed_us_time(start_time));
|
||
|
|
}
|
||
|
|
#ifndef USE_8MP_VI
|
||
|
|
unsigned char *interleaved_rgb = (unsigned char *)malloc(NPU_INPUT_WIDTH*NPU_INPUT_HEIGHT*3);
|
||
|
|
// start_time = nc_get_mono_us_time();
|
||
|
|
nc_rgb_planar_to_interleaved_neon((uint8_t*)v4l2_config[i].video_buf.buffers[video_buf.index].start \
|
||
|
|
,(uint8_t*)v4l2_config[i].video_buf.buffers[video_buf.index].start + NPU_INPUT_DATA_SIZE \
|
||
|
|
,(uint8_t*)v4l2_config[i].video_buf.buffers[video_buf.index].start + (NPU_INPUT_DATA_SIZE*2) \
|
||
|
|
,interleaved_rgb, NPU_INPUT_WIDTH, NPU_INPUT_HEIGHT);// NPU ON:3ms, NPU OFF:600us
|
||
|
|
// printf("conv interleaved: %llu us\n", nc_elapsed_us_time(start_time));
|
||
|
|
#endif
|
||
|
|
if(nc_v4l2_queue_buffer(v4l2_config[i].video_buf.video_fd, video_buf.index) == -1) {
|
||
|
|
printf("Error VIDIOC_QBUF buffer %d\n", video_buf.index);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Upload texture from video buffer
|
||
|
|
glBindTexture(GL_TEXTURE_2D, window->gl.texture[i]);
|
||
|
|
#ifdef USE_8MP_VI
|
||
|
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, VIDEO_WIDTH, VIDEO_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, v4l2_config[i].video_buf.buffers[video_buf.index].start);
|
||
|
|
#else
|
||
|
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, VIDEO_WIDTH, VIDEO_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, interleaved_rgb);
|
||
|
|
if(interleaved_rgb){
|
||
|
|
// printf("free inter\n");
|
||
|
|
free(interleaved_rgb);
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
#ifdef SHOW_FPS
|
||
|
|
printf(" -- fps(%0.1f)\n", calc_fps_at_loop_ent1(20));
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// draw video texture
|
||
|
|
glViewport(g_viewport[i].x, g_viewport[i].y, g_viewport[i].width, g_viewport[i].height);
|
||
|
|
nc_opengl_draw_texture(window->gl.texture[i], window);
|
||
|
|
}
|
||
|
|
|
||
|
|
#ifdef USE_ADAS_LD
|
||
|
|
draw_ld_output_opengl();
|
||
|
|
#endif
|
||
|
|
|
||
|
|
// draw cnn network result
|
||
|
|
for(uint32_t ch = 0; ch < VIDEO_MAX_CH; ch++)
|
||
|
|
{
|
||
|
|
if (v4l2_config[ch].video_buf.video_fd == -1){
|
||
|
|
|
||
|
|
}
|
||
|
|
else{
|
||
|
|
uint64_t time_stamp = 0;
|
||
|
|
|
||
|
|
#ifdef DETECT_NETWORK
|
||
|
|
pp_result_buf *det_buf = NULL;
|
||
|
|
det_buf = (pp_result_buf *)nc_tsfs_ff_get_readable_buffer_and_timestamp(ch+DETECT_NETWORK, &time_stamp);
|
||
|
|
if (det_buf) {
|
||
|
|
nc_draw_gl_npu(g_viewport[ch], det_buf->net_task, det_buf, g_npu_prog);
|
||
|
|
}
|
||
|
|
nc_tsfs_ff_finish_read_buf(ch+DETECT_NETWORK);
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#ifdef SEGMENT_NETWORK
|
||
|
|
pp_result_buf *seg_buf = NULL;
|
||
|
|
seg_buf = (pp_result_buf *)nc_tsfs_ff_get_readable_buffer_and_timestamp(ch+SEGMENT_NETWORK, &time_stamp);
|
||
|
|
if (seg_buf) {
|
||
|
|
nc_draw_gl_npu(g_viewport[ch], seg_buf->net_task, seg_buf, g_npu_prog);
|
||
|
|
}
|
||
|
|
nc_tsfs_ff_finish_read_buf(ch+SEGMENT_NETWORK);
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#ifdef LANE_NETWORK
|
||
|
|
pp_result_buf *lane_buf = NULL;
|
||
|
|
lane_buf = (pp_result_buf *)nc_tsfs_ff_get_readable_buffer_and_timestamp(ch+LANE_NETWORK, &time_stamp);
|
||
|
|
if (lane_buf) {
|
||
|
|
nc_draw_gl_npu(g_viewport[ch], lane_buf->net_task, lane_buf, g_npu_prog);
|
||
|
|
}
|
||
|
|
nc_tsfs_ff_finish_read_buf(ch+LANE_NETWORK);
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
framecnt++;
|
||
|
|
fpscount+=1;
|
||
|
|
char buftext[256];
|
||
|
|
|
||
|
|
sprintf(buftext,"GL: %lums, Frame: %lums/%lufps", opengl_time, frametime, fpscount_00);
|
||
|
|
|
||
|
|
glViewport(0,0, WINDOW_WIDTH, WINDOW_HEIGHT);
|
||
|
|
float textcolor[3] = {1.0, 0.0, 0.0}; // R, G, B
|
||
|
|
nc_opengl_draw_text(&font_38, buftext, 10, 1020, 1.0f, textcolor, WINDOW_WIDTH, WINDOW_HEIGHT, g_font_prog);
|
||
|
|
|
||
|
|
clock_gettime(CLOCK_MONOTONIC, &end);
|
||
|
|
|
||
|
|
opengl_time = ((end.tv_sec - begin.tv_sec)*1000 + (end.tv_nsec - begin.tv_nsec)/1000000);
|
||
|
|
|
||
|
|
frametime = ((end.tv_sec - set_time.tv_sec)*1000 + (end.tv_nsec - set_time.tv_nsec)/1000000);
|
||
|
|
|
||
|
|
set_time = end;
|
||
|
|
|
||
|
|
fpstime = fpstime + frametime;
|
||
|
|
|
||
|
|
if(fpstime>=1000)
|
||
|
|
{
|
||
|
|
if(fpscount_00>0)
|
||
|
|
{
|
||
|
|
fpscount_00 = (fpscount_00 + fpscount)/2;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
fpscount_00=fpscount;
|
||
|
|
}
|
||
|
|
|
||
|
|
fpscount=0;
|
||
|
|
fpstime=0;
|
||
|
|
}
|
||
|
|
|
||
|
|
nc_wayland_display_draw(window,(void *)render);
|
||
|
|
}
|
||
|
|
|
||
|
|
int npu_init(st_npu_input_info *npu_input_info)
|
||
|
|
{
|
||
|
|
/* Initialize CNN */
|
||
|
|
if (nc_aiw_init_cnn() < 0 ) {
|
||
|
|
fprintf(stderr, "nc_aiw_init_cnn() failure!!\n");
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
#ifdef SHOW_YOLOV8_DETECT
|
||
|
|
if (nc_aiw_add_network_to_builder(nc_localize_path((const char *)NETWORK_FILE_YOLOV8_DET), NETWORK_YOLOV8_DET, nc_postprocess_yolov8_inference_result) < 0) {
|
||
|
|
fprintf(stderr, "nc_aiw_add_network_to_builder() failure!!\n");
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
#ifdef SHOW_YOLOV5_DETECT
|
||
|
|
if (nc_aiw_add_network_to_builder(nc_localize_path((const char *)NETWORK_FILE_YOLOV5_DET), NETWORK_YOLOV5_DET, nc_postprocess_yolov5_inference_result) < 0) {
|
||
|
|
fprintf(stderr, "nc_aiw_add_network_to_builder() failure!!\n");
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
#ifdef SHOW_PELEE_SEG
|
||
|
|
if (nc_aiw_add_network_to_builder(nc_localize_path((const char *)NETWORK_FILE_PELEE_SEG), NETWORK_PELEE_SEG, nc_postprocess_segmentation_inference_result) < 0) {
|
||
|
|
fprintf(stderr, "nc_aiw_add_network_to_builder() failure!!\n");
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
#ifdef SHOW_PELEE_DETECT
|
||
|
|
if (nc_aiw_add_network_to_builder(nc_localize_path((const char *)NETWORK_FILE_PELEE_DET), NETWORK_PELEE_DET, nc_postprocess_pelee_inference_result) < 0) {
|
||
|
|
fprintf(stderr, "nc_aiw_add_network_to_builder() failure!!\n");
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
#ifdef SHOW_UFLD_LANE
|
||
|
|
if (nc_aiw_add_network_to_builder(nc_localize_path((const char *)NETWORK_FILE_UFLD_LANE), NETWORK_UFLD_LANE, nc_postprocess_ufld_inference_result) < 0) {
|
||
|
|
fprintf(stderr, "nc_aiw_add_network_to_builder() failure!!\n");
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
#ifdef SHOW_TRI_CHIMERA
|
||
|
|
if (nc_aiw_add_network_to_builder(nc_localize_path((const char *)NETWORK_FILE_TRI_CHIMERA), NETWORK_TRI_CHIMERA, nc_postprocess_trichimera_inference_result) < 0) {
|
||
|
|
fprintf(stderr, "nc_aiw_add_network_to_builder() failure!!\n");
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
if(nc_aiw_finish_network_builder() < 0 ) {
|
||
|
|
fprintf(stderr, "nc_aiw_finish_network_builder() failure!!\n");
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
// obtain the input resoltution for the CNN network
|
||
|
|
// get information of the input tensor
|
||
|
|
aiwTensorInfo in_tinfo;
|
||
|
|
#ifdef SHOW_YOLOV8_DETECT
|
||
|
|
if(nc_get_cnn_network_input_resol(NETWORK_YOLOV8_DET, &in_tinfo) < 0)
|
||
|
|
{
|
||
|
|
printf("failed to get the input resolution for the CNN network\n");
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
#ifdef SHOW_YOLOV5_DETECT
|
||
|
|
if(nc_get_cnn_network_input_resol(NETWORK_YOLOV5_DET, &in_tinfo) < 0)
|
||
|
|
{
|
||
|
|
printf("failed to get the input resolution for the CNN network\n");
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
#ifdef SHOW_PELEE_SEG
|
||
|
|
if(nc_get_cnn_network_input_resol(NETWORK_PELEE_SEG, &in_tinfo) < 0)
|
||
|
|
{
|
||
|
|
printf("failed to get the input resolution for the CNN network\n");
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
#ifdef SHOW_PELEE_DETECT
|
||
|
|
if(nc_get_cnn_network_input_resol(NETWORK_PELEE_DET, &in_tinfo) < 0)
|
||
|
|
{
|
||
|
|
printf("failed to get the input resolution for the CNN network\n");
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
#ifdef SHOW_UFLD_LANE
|
||
|
|
if(nc_get_cnn_network_input_resol(NETWORK_UFLD_LANE, &in_tinfo) < 0)
|
||
|
|
{
|
||
|
|
printf("failed to get the input resolution for the CNN network\n");
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
#ifdef SHOW_TRI_CHIMERA
|
||
|
|
if(nc_get_cnn_network_input_resol(NETWORK_TRI_CHIMERA, &in_tinfo) < 0)
|
||
|
|
{
|
||
|
|
printf("failed to get the input resolution for the CNN network\n");
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
|
npu_input_info->w = in_tinfo.dim.w;// network input width
|
||
|
|
npu_input_info->h = in_tinfo.dim.h;// network input height
|
||
|
|
npu_input_info->rgb_size = in_tinfo.dim.w * in_tinfo.dim.h * RGB_CNT;
|
||
|
|
|
||
|
|
#ifdef USE_BYTETRACK
|
||
|
|
for (int i = 0; i < VIDEO_MAX_CH; i++) {
|
||
|
|
E_NETWORK_UID net_id;
|
||
|
|
#ifdef SHOW_PELEE_DETECT
|
||
|
|
net_id = NETWORK_PELEE_DET;
|
||
|
|
#endif
|
||
|
|
#ifdef SHOW_YOLOV5_DETECT
|
||
|
|
net_id = NETWORK_YOLOV5_DET;
|
||
|
|
#endif
|
||
|
|
#ifdef SHOW_YOLOV8_DETECT
|
||
|
|
net_id = NETWORK_YOLOV8_DET;
|
||
|
|
#endif
|
||
|
|
#ifndef SHOW_PELEE_SEG
|
||
|
|
if (nc_init_bytetrackers(CAP_FPS, i, net_id) != 0) {
|
||
|
|
perror("nc_init_bytetrackers() error");
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
|
printf("aiw finish\n");
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
static void signal_int()
|
||
|
|
{
|
||
|
|
running = 0;
|
||
|
|
nc_cnn_postprocess_stop();
|
||
|
|
}
|
||
|
|
|
||
|
|
static void usage(int error_code)
|
||
|
|
{
|
||
|
|
fprintf(stderr, "Usage: simple-egl [OPTIONS]\n\n"
|
||
|
|
" -f\tRun in fullscreen mode\n"
|
||
|
|
" -o\tCreate an opaque surface\n"
|
||
|
|
" -h\tThis help text\n\n");
|
||
|
|
|
||
|
|
exit(error_code);
|
||
|
|
}
|
||
|
|
|
||
|
|
void *cnn_task(void *arg)
|
||
|
|
{
|
||
|
|
(void) arg;
|
||
|
|
printf("CNN TASK RUN!!\n");
|
||
|
|
|
||
|
|
while (running) {
|
||
|
|
stCnnData *cnn_data = NULL;
|
||
|
|
if(receive_cnn_buf(&cnn_data) != -1){
|
||
|
|
nc_aiw_run_cnn(cnn_data->ptr_cnn_buf, cnn_data->time_stamp_us, cnn_data->cam_ch, cnn_data->net_id);
|
||
|
|
if(cnn_data) {
|
||
|
|
free(cnn_data->ptr_cnn_buf);
|
||
|
|
free(cnn_data);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
printf("EXIT CNN_TASK!!\n");
|
||
|
|
return NULL;
|
||
|
|
}
|
||
|
|
|
||
|
|
int main(int argc, char **argv)
|
||
|
|
{
|
||
|
|
struct sigaction sigint;
|
||
|
|
struct display display;
|
||
|
|
struct window window;
|
||
|
|
int i, ret = 0;
|
||
|
|
pthread_t p_thread[MAX_TASK_CNT];
|
||
|
|
int task_cnt = 0;
|
||
|
|
int thr_id;
|
||
|
|
int status;
|
||
|
|
|
||
|
|
for (i = 1; i < argc; i++) {
|
||
|
|
if (strcmp("-f", argv[i]) == 0)
|
||
|
|
window.fullscreen = 1;
|
||
|
|
else if (strcmp("-o", argv[i]) == 0)
|
||
|
|
window.opaque = 1;
|
||
|
|
else if (strcmp("-h", argv[i]) == 0)
|
||
|
|
usage(EXIT_SUCCESS);
|
||
|
|
else
|
||
|
|
usage(EXIT_FAILURE);
|
||
|
|
}
|
||
|
|
|
||
|
|
sigint.sa_handler = (sighandler_t)signal_int;
|
||
|
|
sigemptyset(&sigint.sa_mask);
|
||
|
|
sigint.sa_flags = SA_RESETHAND;
|
||
|
|
sigaction(SIGINT, &sigint, NULL);
|
||
|
|
|
||
|
|
memset(&display, 0, sizeof(display));
|
||
|
|
memset(&window, 0, sizeof(window));
|
||
|
|
memset(&v4l2_config, 0, sizeof(v4l2_config));
|
||
|
|
|
||
|
|
set_v4l2_config();
|
||
|
|
|
||
|
|
nc_init_path_localizer();
|
||
|
|
|
||
|
|
window.display = &display;
|
||
|
|
display.window = &window;
|
||
|
|
window.window_size.width = WINDOW_WIDTH;
|
||
|
|
window.window_size.height = WINDOW_HEIGHT;
|
||
|
|
|
||
|
|
set_viewport_config();
|
||
|
|
|
||
|
|
nc_wayland_display_init(&display,(void *)render);
|
||
|
|
|
||
|
|
ret = v4l2_initialize();
|
||
|
|
if(ret < 0) {
|
||
|
|
printf("Error v4l2_initialize\n");
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
gl_initialize(&window);
|
||
|
|
#ifdef USE_8MP_VI
|
||
|
|
dsr_init();
|
||
|
|
#endif
|
||
|
|
#ifdef USE_ADAS_LD
|
||
|
|
ld_opengl_program_set(&g_npu_prog);
|
||
|
|
NC_ADAS_OPEN();
|
||
|
|
#endif
|
||
|
|
|
||
|
|
// create thread-safe flip-flop buffer
|
||
|
|
for (int i = 0; i < VIDEO_MAX_CH; i++) {
|
||
|
|
if (v4l2_config[i].video_buf.video_fd == -1){
|
||
|
|
|
||
|
|
}
|
||
|
|
else{
|
||
|
|
#ifdef DETECT_NETWORK
|
||
|
|
int det_buf_size = sizeof(pp_result_buf);
|
||
|
|
if(nc_tsfs_ff_create_buffers(i+DETECT_NETWORK, det_buf_size) < 0) {
|
||
|
|
exit(1);
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
#ifdef SEGMENT_NETWORK
|
||
|
|
int seg_buf_size = sizeof(pp_result_buf);
|
||
|
|
if(nc_tsfs_ff_create_buffers(i+SEGMENT_NETWORK, seg_buf_size) < 0) {
|
||
|
|
exit(1);
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
#ifdef LANE_NETWORK
|
||
|
|
int lane_buf_size = sizeof(pp_result_buf);
|
||
|
|
if(nc_tsfs_ff_create_buffers(i+LANE_NETWORK, lane_buf_size) < 0) {
|
||
|
|
exit(1);
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
}
|
||
|
|
mq_unlink(MQ_NAME_CNN_BUF);
|
||
|
|
|
||
|
|
if(npu_init(&npu_input_info) < 0) {
|
||
|
|
printf("failed to init NPU\n");
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
printf("create tasks\n");
|
||
|
|
thr_id = pthread_create(&p_thread[task_cnt++], NULL, cnn_task, (void *)NULL);
|
||
|
|
if (thr_id < 0) {
|
||
|
|
perror("thread create error : cnn_task");
|
||
|
|
exit(1);
|
||
|
|
}
|
||
|
|
|
||
|
|
cnn_postprocess_arg cnn_post_param;
|
||
|
|
cnn_post_param.target_width = WINDOW_WIDTH;
|
||
|
|
cnn_post_param.target_height = WINDOW_HEIGHT;
|
||
|
|
thr_id = pthread_create(&p_thread[task_cnt++], NULL, nc_cnn_postprocess_task, (void *)&cnn_post_param);
|
||
|
|
if (thr_id < 0) {
|
||
|
|
perror("thread create error : nc_cnn_postprocess_task");
|
||
|
|
exit(1);
|
||
|
|
}
|
||
|
|
|
||
|
|
#ifdef USE_ADAS_LD
|
||
|
|
thr_id = pthread_create(&p_thread[task_cnt++], NULL, ld_task, NULL);
|
||
|
|
if (thr_id < 0) {
|
||
|
|
perror("thread create error : ld_task");
|
||
|
|
exit(1);
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
|
while (running && ret != -1)
|
||
|
|
{
|
||
|
|
ret = wl_display_dispatch(display.display);
|
||
|
|
}
|
||
|
|
|
||
|
|
for(int i =0; i< task_cnt; i++) {
|
||
|
|
pthread_join(p_thread[i], (void **)&status);
|
||
|
|
}
|
||
|
|
|
||
|
|
#ifdef USE_ADAS_LD
|
||
|
|
NC_ADAS_CLOSE();
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#ifdef USE_BYTETRACK
|
||
|
|
for (int i = 0; i < VIDEO_MAX_CH; i++) {
|
||
|
|
nc_deInit_bytetrackers(i);
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#ifdef USE_8MP_VI
|
||
|
|
dsr_deinit();
|
||
|
|
#endif
|
||
|
|
nc_wayland_display_destroy(&display);
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|