Files

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;
}