/* Copyright (c), 2001-2022, Shenshu Tech. Co., Ltd. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "sample_comm.h" #define SAMPLE_VDA_MD_CHN 0 #define SAMPLE_VDA_OD_CHN 1 typedef struct { td_bool thread_start; ot_vda_chn vda_chn; } sample_vda_param; static pthread_t g_vda_pid[2]; /* 2 : number of pid */ static sample_vda_param g_md_param; static sample_vda_param g_od_param; td_void sample_common_vda_handle_sig(void) { /* join thread */ if (g_od_param.thread_start == TD_TRUE) { g_od_param.thread_start = TD_FALSE; pthread_join(g_vda_pid[SAMPLE_VDA_OD_CHN], 0); } /* join thread */ if (g_md_param.thread_start == TD_TRUE) { g_md_param.thread_start = TD_FALSE; pthread_join(g_vda_pid[SAMPLE_VDA_MD_CHN], 0); } } /* vda MD mode print -- Md OBJ */ td_s32 sample_common_vda_md_prt_obj(FILE *fp, ot_vda_data *vda_data) { ot_vda_rgn *vda_obj = TD_NULL; td_u32 i; fprintf(fp, "===== %s =====\n", __FUNCTION__); if (vda_data->data.md_data.obj_valid != TD_TRUE) { fprintf(fp, "obj_valid = FALSE.\n"); return TD_SUCCESS; } fprintf(fp, "obj_num=%d, idx_of_max_obj=%d, size_of_max_obj=%d, size_of_total_obj=%d\n", vda_data->data.md_data.obj_data.obj_num, vda_data->data.md_data.obj_data.idx_of_max_obj, vda_data->data.md_data.obj_data.size_of_max_obj, vda_data->data.md_data.obj_data.size_of_total_obj); for (i = 0; i < vda_data->data.md_data.obj_data.obj_num; i++) { vda_obj = vda_data->data.md_data.obj_data.addr + i; fprintf(fp, "[%u]\t upper_left_x=%d, upper_left_y=%d, lower_right_x=%d, lower_right_y=%d\n", i, vda_obj->upper_left_x, vda_obj->upper_left_y, vda_obj->lower_right_x, vda_obj->lower_right_y); } fflush(fp); return TD_SUCCESS; } /* vda MD mode print -- Alarm Pixel Count */ td_s32 sample_common_vda_md_prt_ap(FILE *fp, ot_vda_data *vda_data) { fprintf(fp, "===== %s =====\n", __FUNCTION__); if (vda_data->data.md_data.pixel_num_valid != TD_TRUE) { fprintf(fp, "pixel_num_valid = FALSE.\n"); return TD_SUCCESS; } fprintf(fp, "alarm_pixel_cnt=%d\n", vda_data->data.md_data.alarm_pixel_cnt); fflush(fp); return TD_SUCCESS; } /* vda MD mode print -- SAD */ td_s32 sample_common_vda_md_prt_sad(FILE *fp, ot_vda_data *vda_data) { td_u32 i, j; td_void *addr = TD_NULL; fprintf(fp, "===== %s =====\n", __FUNCTION__); if (vda_data->data.md_data.mb_sad_valid != TD_TRUE) { fprintf(fp, "mb_sad_valid = FALSE.\n"); return TD_SUCCESS; } for (i = 0; i < vda_data->mb_height; i++) { addr = (td_void *)((td_uintptr_t)vda_data->data.md_data.mb_sad_data.addr + i * vda_data->data.md_data.mb_sad_data.stride); for (j = 0; j < vda_data->mb_width; j++) { td_u8 *addr_temp0 = TD_NULL; td_u16 *addr_temp1 = TD_NULL; if (OT_VDA_MB_SAD_8BIT == vda_data->data.md_data.mb_sad_data.mb_sad_bits) { addr_temp0 = (td_u8 *)addr + j; fprintf(fp, "%-4d ", *addr_temp0); } else { addr_temp1 = (td_u16 *)addr + j; fprintf(fp, "%-6d ", *addr_temp1); } } printf("\n"); } fflush(fp); return TD_SUCCESS; } td_s32 sample_comm_vda_md_prt_result(ot_vda_chn vda_chn, FILE *fp) { td_s32 ret; ot_vda_data vda_data; /* step 2.3 : call mpi to get one-frame stream */ ret = ss_mpi_vda_get_data(vda_chn, &vda_data, -1); if (ret != TD_SUCCESS) { sample_print("ss_mpi_vda_get_data failed with %#x!\n", ret); return TD_FAILURE; } /* step 2.4 : save frame to file */ printf("\033[0;0H"); /* move cursor */ ret = sample_common_vda_md_prt_sad(fp, &vda_data); if (ret != TD_SUCCESS) { sample_print("prt sda fail\n"); return TD_FAILURE; } ret = sample_common_vda_md_prt_obj(fp, &vda_data); if (ret != TD_SUCCESS) { sample_print("prt obj fail\n"); return TD_FAILURE; } ret = sample_common_vda_md_prt_ap(fp, &vda_data); if (ret != TD_SUCCESS) { sample_print("prt ap fail\n"); return TD_FAILURE; } /* step 2.5 : release stream */ ret = ss_mpi_vda_release_data(vda_chn, &vda_data); if (ret != TD_SUCCESS) { sample_print("ss_mpi_vda_release_data failed with %#x!\n", ret); return TD_FAILURE; } return TD_SUCCESS; } /* vda MD mode thread process */ td_void *sample_common_vda_md_get_result(td_void *data) { td_s32 ret; ot_vda_chn vda_chn; sample_vda_param *md_param = TD_NULL; td_s32 maxfd = 0; FILE *fp = stdout; td_s32 vda_fd; fd_set read_fds; struct timeval timeout_val; prctl(PR_SET_NAME, "ot_MdGetResult", 0, 0, 0); md_param = (sample_vda_param *)data; vda_chn = md_param->vda_chn; /* * decide the stream file name, and open file to save stream * Set Venc Fd. */ vda_fd = ss_mpi_vda_get_fd(vda_chn); if (vda_fd < 0) { sample_print("ss_mpi_vda_get_fd failed with %#x!\n", vda_fd); return TD_NULL; } if (maxfd <= vda_fd) { maxfd = vda_fd; } while (md_param->thread_start == TD_TRUE) { FD_ZERO(&read_fds); FD_SET(vda_fd, &read_fds); timeout_val.tv_sec = 2; /* 2 : second */ timeout_val.tv_usec = 0; ret = select(maxfd + 1, &read_fds, TD_NULL, TD_NULL, &timeout_val); if (ret < 0) { sample_print("select failed!\n"); break; } else if (ret == 0) { sample_print("get vda result time out, exit thread\n"); break; } if (FD_ISSET(vda_fd, &read_fds)) { ret = sample_comm_vda_md_prt_result(vda_chn, fp); } } return TD_NULL; } td_s32 sample_common_vda_set_vpss_bind(ot_vda_chn vda_chn, td_u32 chn) { td_s32 ret; ot_mpp_chn src_chn, dest_chn; src_chn.mod_id = OT_ID_VPSS; src_chn.chn_id = chn; src_chn.dev_id = 0; dest_chn.mod_id = OT_ID_VDA; dest_chn.chn_id = vda_chn; dest_chn.dev_id = 0; ret = ss_mpi_sys_bind(&src_chn, &dest_chn); if (ret != TD_SUCCESS) { sample_print("bind err(0x%x)!\n", ret); return ret; } return TD_SUCCESS; } /* start vda MD mode */ td_s32 sample_common_vda_md_start(ot_vda_chn vda_chn, td_u32 chn, ot_size *size) { td_s32 ret; ot_vda_chn_attr vda_chn_attr; if (size->width > OT_VDA_MAX_WIDTH || size->height > OT_VDA_MAX_HEIGHT) { sample_print("Picture size invalid!\n"); return TD_FAILURE; } /* step 1 create vda channel */ vda_chn_attr.work_mode = OT_VDA_WORK_MODE_MD; vda_chn_attr.width = size->width; vda_chn_attr.height = size->height; vda_chn_attr.attr.md_attr.vda_alg = OT_VDA_ALG_REF; vda_chn_attr.attr.md_attr.mb_size = OT_VDA_MB_16PIXEL; vda_chn_attr.attr.md_attr.mb_sad_bits = OT_VDA_MB_SAD_8BIT; vda_chn_attr.attr.md_attr.ref_mode = OT_VDA_REF_MODE_DYNAMIC; vda_chn_attr.attr.md_attr.md_buf_num = 8; /* 8 : buf number */ vda_chn_attr.attr.md_attr.vda_interval = 4; /* 4 : frame interval */ vda_chn_attr.attr.md_attr.bg_up_src_wgt = 128; /* 128 : weight of source pictures */ vda_chn_attr.attr.md_attr.sad_threshold = 100; /* 100 : alarm threshold */ vda_chn_attr.attr.md_attr.obj_num_max = 128; /* 128 : number of output OBJ regions */ ret = ss_mpi_vda_create_chn(vda_chn, &vda_chn_attr); if (ret != TD_SUCCESS) { sample_print("ss_mpi_vda_create_chn err!\n"); return ret; } /* step 2: vda chn bind vpss chn */ ret = sample_common_vda_set_vpss_bind(vda_chn, chn); if (ret != TD_SUCCESS) { sample_print("err!\n"); return ret; } /* step 3: vda chn start recv picture */ ret = ss_mpi_vda_start_recv_pic(vda_chn); if (ret != TD_SUCCESS) { sample_print("ss_mpi_vda_start_recv_pic err!\n"); return ret; } /* step 4: create thread to get result */ g_md_param.thread_start = TD_TRUE; g_md_param.vda_chn = vda_chn; pthread_create(&g_vda_pid[SAMPLE_VDA_MD_CHN], 0, sample_common_vda_md_get_result, (td_void *)&g_md_param); return TD_SUCCESS; } /* stop vda, and stop vda thread -- MD */ td_void sample_common_vda_md_stop(ot_vda_chn vda_chn, td_u32 chn) { td_s32 ret; ot_mpp_chn src_chn, dest_chn; /* join thread */ if (g_md_param.thread_start == TD_TRUE) { g_md_param.thread_start = TD_FALSE; pthread_join(g_vda_pid[SAMPLE_VDA_MD_CHN], 0); } /* vda stop recv picture */ ret = ss_mpi_vda_stop_recv_pic(vda_chn); if (ret != TD_SUCCESS) { sample_print("ss_mpi_vda_stop_recv_pic err(0x%x)!!!!\n", ret); } /* unbind vda chn & vpss chn */ src_chn.mod_id = OT_ID_VPSS; src_chn.chn_id = chn; src_chn.dev_id = 0; dest_chn.mod_id = OT_ID_VDA; dest_chn.chn_id = vda_chn; dest_chn.dev_id = 0; ret = ss_mpi_sys_unbind(&src_chn, &dest_chn); if (ret != TD_SUCCESS) { sample_print("err(0x%x)!!!!\n", ret); } /* destroy vda chn */ ret = ss_mpi_vda_destroy_chn(vda_chn); if (ret != TD_SUCCESS) { sample_print("err(0x%x)!!!!\n", ret); } return; } /* vda OD mode thread process */ td_s32 sample_common_vda_od_prt(FILE *fp, ot_vda_data *vda_data) { td_u32 i; fprintf(fp, "===== %s =====\n", __FUNCTION__); fprintf(fp, "OD region total count =%d\n", vda_data->data.od_data.rgn_num); for (i = 0; i < vda_data->data.od_data.rgn_num; i++) { fprintf(fp, "OD region[%u]: %d\n", i, vda_data->data.od_data.rgn_alarm_en[i]); } fflush(fp); return TD_SUCCESS; } /* vda OD mode thread process */ td_void *sample_common_vda_od_get_result(td_void *data) { td_s32 i; td_s32 ret; ot_vda_chn vda_chn; ot_vda_data vda_data; td_s32 rgn_num; sample_vda_param *od_param = TD_NULL; FILE *fp = stdout; prctl(PR_SET_NAME, "ot_OdGetResult", 0, 0, 0); od_param = (sample_vda_param *)data; vda_chn = od_param->vda_chn; while (od_param->thread_start == TD_TRUE) { ret = ss_mpi_vda_get_data(vda_chn, &vda_data, -1); if (ret != TD_SUCCESS) { sample_print("ss_mpi_vda_get_data failed with %#x!\n", ret); return TD_NULL; } ret = sample_common_vda_od_prt(fp, &vda_data); if (ret != TD_SUCCESS) { ss_mpi_vda_release_data(vda_chn, &vda_data); sample_print("od prt fail!\n"); return TD_NULL; } rgn_num = (td_s32)vda_data.data.od_data.rgn_num; for (i = 0; i < rgn_num; i++) { if (vda_data.data.od_data.rgn_alarm_en[i] == TD_FALSE) { continue; } printf("################vda_chn--%d,Rgn--%d,Occ!\n", vda_chn, i); ret = ss_mpi_vda_reset_od_rgn(vda_chn, i); if (ret != TD_SUCCESS) { ss_mpi_vda_release_data(vda_chn, &vda_data); sample_print("ss_mpi_vda_reset_od_rgn failed with %#x!\n", ret); return TD_NULL; } } ret = ss_mpi_vda_release_data(vda_chn, &vda_data); if (ret != TD_SUCCESS) { sample_print("ss_mpi_vda_release_data failed with %#x!\n", ret); return TD_NULL; } usleep(200 * 1000); /* 200 * 1000 : waiting for 200ms */ } return TD_NULL; } /* start vda OD mode */ td_s32 sample_common_vda_od_start(ot_vda_chn vda_chn, td_u32 chn, ot_size *size) { ot_vda_chn_attr vda_chn_attr; td_s32 ret; if (size->width > OT_VDA_MAX_WIDTH || size->height > OT_VDA_MAX_HEIGHT) { sample_print("Picture size invalid!\n"); return TD_FAILURE; } /* step 1 : create vda channel */ vda_chn_attr.work_mode = OT_VDA_WORK_MODE_OD; vda_chn_attr.width = size->width; vda_chn_attr.height = size->height; vda_chn_attr.attr.od_attr.vda_alg = OT_VDA_ALG_REF; vda_chn_attr.attr.od_attr.mb_size = OT_VDA_MB_8PIXEL; vda_chn_attr.attr.od_attr.mb_sad_bits = OT_VDA_MB_SAD_8BIT; vda_chn_attr.attr.od_attr.ref_mode = OT_VDA_REF_MODE_DYNAMIC; vda_chn_attr.attr.od_attr.vda_interval = 4; /* 4 : frame interval */ vda_chn_attr.attr.od_attr.bg_up_src_wgt = 128; /* 128 : weight of source pictures */ vda_chn_attr.attr.od_attr.rgn_num = 1; vda_chn_attr.attr.od_attr.od_rgn_attr[0].rect.x = 0; vda_chn_attr.attr.od_attr.od_rgn_attr[0].rect.y = 0; vda_chn_attr.attr.od_attr.od_rgn_attr[0].rect.width = size->width; vda_chn_attr.attr.od_attr.od_rgn_attr[0].rect.height = size->height; vda_chn_attr.attr.od_attr.od_rgn_attr[0].sad_threshold = 100; /* 100 : alarm threshold */ vda_chn_attr.attr.od_attr.od_rgn_attr[0].area_threshold = 60; /* 60 : region area alarm threshold */ vda_chn_attr.attr.od_attr.od_rgn_attr[0].occlusion_cnt_threshold = 6; /* 6: occlusion count alarm threshold */ vda_chn_attr.attr.od_attr.od_rgn_attr[0].uncover_cnt_threshold = 2; /* 2 : Maximum uncover count */ ret = ss_mpi_vda_create_chn(vda_chn, &vda_chn_attr); if (ret != TD_SUCCESS) { sample_print("ss_mpi_vda_create_chn err(0x%x)!\n", ret); return ret; } /* step 2 : bind vda channel to vpss channel */ ret = sample_common_vda_set_vpss_bind(vda_chn, chn); if (ret != TD_SUCCESS) { sample_print("err!\n"); return ret; } /* vda start rcv picture */ ret = ss_mpi_vda_start_recv_pic(vda_chn); if (ret != TD_SUCCESS) { sample_print("ss_mpi_vda_start_recv_pic err(0x%x)!\n", ret); return ret; } g_od_param.thread_start = TD_TRUE; g_od_param.vda_chn = vda_chn; pthread_create(&g_vda_pid[SAMPLE_VDA_OD_CHN], 0, sample_common_vda_od_get_result, (td_void *)&g_od_param); return TD_SUCCESS; } /* stop vda, and stop vda thread -- OD */ td_void sample_common_vda_od_stop(ot_vda_chn vda_chn, td_u32 chn) { td_s32 ret; ot_mpp_chn src_chn, dest_chn; /* join thread */ if (g_od_param.thread_start == TD_TRUE) { g_od_param.thread_start = TD_FALSE; pthread_join(g_vda_pid[SAMPLE_VDA_OD_CHN], 0); } /* vda stop recv picture */ ret = ss_mpi_vda_stop_recv_pic(vda_chn); if (ret != TD_SUCCESS) { sample_print("ss_mpi_vda_stop_recv_pic err(0x%x)!!!!\n", ret); } /* unbind vda chn & vi chn */ src_chn.mod_id = OT_ID_VPSS; src_chn.chn_id = chn; src_chn.dev_id = 0; dest_chn.mod_id = OT_ID_VDA; dest_chn.chn_id = vda_chn; dest_chn.dev_id = 0; ret = ss_mpi_sys_unbind(&src_chn, &dest_chn); if (ret != TD_SUCCESS) { sample_print("ss_mpi_sys_unbind err(0x%x)!!!!\n", ret); } /* destroy vda chn */ ret = ss_mpi_vda_destroy_chn(vda_chn); if (ret != TD_SUCCESS) { sample_print("ss_mpi_vda_destroy_chn err(0x%x)!!!!\n", ret); } return; }