508 lines
15 KiB
C
508 lines
15 KiB
C
/*
|
|
Copyright (c), 2001-2022, Shenshu Tech. Co., Ltd.
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/ioctl.h>
|
|
#include <sys/poll.h>
|
|
#include <sys/time.h>
|
|
#include <fcntl.h>
|
|
#include <errno.h>
|
|
#include <pthread.h>
|
|
#include <math.h>
|
|
#include <unistd.h>
|
|
#include <signal.h>
|
|
#include <sys/prctl.h>
|
|
|
|
#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;
|
|
}
|