Files

1044 lines
29 KiB
C

#include "data_base.h"
static db_attr g_svp_db[MAX_DB_NUM] = { 0 };
/*
data:
argc: row_num
argv: col value
azColName: col name
*/
static xmedia_s32 name_callback(xmedia_void* data, xmedia_s32 argc, xmedia_char** argv, xmedia_char** azColName)
{
if (data == NULL) {
printf("callback func storage data is null\n");
return XMEDIA_NULL;
}
xmedia_char *result = (xmedia_char *)data;
if (argc > 0) {
if (argv[0]) {
memcpy((xmedia_char*)result, argv[0], NAME_LEN);
}
} else {
printf("can not match name from index\n");
}
return XMEDIA_SUCCESS;
}
static xmedia_s32 index_callback(xmedia_void* data, xmedia_s32 argc, xmedia_char** argv, xmedia_char** azColName)
{
if (data == NULL) {
printf("callback func storage data is null\n");
return XMEDIA_NULL;
}
printf("come in to index_callback\n");
xmedia_s32 *result = (xmedia_s32 *)data;
if (argc > 0) {
if (argv[0]) {
*result = atoi(argv[0]);
printf("match index: %d\n", *result);
}
} else {
printf("can not match index from name\n");
}
return XMEDIA_SUCCESS;
}
xmedia_void printf_matrix(matrix_data *matrix) {
printf("o_matrix row: %d, col: %d\n", matrix->row_num, matrix->col_num);
for (xmedia_s32 i = 0; i < matrix->row_num; i++) {
for (xmedia_s32 j = 0; j < matrix->col_num; j++) {
printf("%lf ", matrix->data[i][j]);
}
printf("\n");
}
}
xmedia_void printf_t_matrix(t_matrix_data *matrix) {
printf("t_matrix row: %d, col: %d\n", matrix->row_num, matrix->col_num);
for (xmedia_s32 i = 0; i < matrix->row_num; i++) {
for (xmedia_s32 j = 0; j < matrix->col_num; j++) {
printf("%lf ", matrix->data[i][j]);
}
printf("\n");
}
}
xmedia_void printf_r_matrix(r_matrix_data *matrix) {
printf("r_matrix row: %d, col: %d\n", matrix->row_num, matrix->col_num);
for (int i = 0; i < matrix->row_num; i++) {
for (int j = 0; j < matrix->col_num; j++) {
printf("%lf ", matrix->data[i][j]);
}
printf("\n");
}
}
static xmedia_s32 create_table(sqlite3* sql3_db, xmedia_s32 col_num, xmedia_char *table_name)
{
xmedia_s32 ret;
xmedia_char create_table_cmd[1000];
sprintf(create_table_cmd, "CREATE TABLE IF NOT EXISTS %s (id TEXT, ", table_name);
for (xmedia_s32 i = 1; i <= col_num - 1; i++) {
xmedia_char columnName[20];
sprintf(columnName, "val%d REAL", i);
strcat(create_table_cmd, columnName);
if (i != (col_num - 1)) {
strcat(create_table_cmd, ", ");
}
}
strcat(create_table_cmd, ");");
printf("%s\n", create_table_cmd);
ret = sqlite3_exec(sql3_db, create_table_cmd, 0, 0, 0);
if (ret != SQLITE_OK) {
printf("can not exce SQL: %s\n", sqlite3_errmsg(sql3_db));
sqlite3_close(sql3_db);
return XMEDIA_FAILURE;
}
return XMEDIA_SUCCESS;
}
static xmedia_s32 table_insert_one_row(sqlite3* sql3_db, xmedia_char *name, xmedia_s32 index,
xmedia_s32 col_num, xmedia_char *table_name)
{
xmedia_s32 ret;
xmedia_char id[MAX_NAME_LEN];
xmedia_char table_insert_cmd[1000]; //保证能装完513个数据 512 * (8 + 4) + 30
sprintf(table_insert_cmd, "INSERT INTO %s (id, ", table_name);
for (xmedia_s32 j = 1; j <= col_num - 1; j++) {
xmedia_char col[10];
sprintf(col, "val%d", j);
strcat(table_insert_cmd, col);
if (j != col_num - 1) {
strcat(table_insert_cmd, ", ");
}
}
strcat(table_insert_cmd, ") VALUES ('");
sprintf(id, "%s", name);
strcat(table_insert_cmd, id);
strcat(table_insert_cmd, "', ");
for (xmedia_s32 j = 1; j <= col_num - 1; j++) { //这里还可以增加其他信息
xmedia_s32 value = index;
xmedia_char value_str[20];
sprintf(value_str, "%d", value);
strcat(table_insert_cmd, value_str);
if (j != col_num - 1) {
strcat(table_insert_cmd, ", ");
}
}
strcat(table_insert_cmd, ");");
printf("insert %d info :\n %s\n", index, table_insert_cmd);
ret = sqlite3_exec(sql3_db, table_insert_cmd, 0, 0, 0);
if (ret != SQLITE_OK) {
printf("can not insert SQL: %s\n", sqlite3_errmsg(sql3_db));
sqlite3_close(sql3_db);
return XMEDIA_FAILURE;
}
return XMEDIA_SUCCESS;
}
static xmedia_s32 search_id(sqlite3* sql3_db, xmedia_char *str, xmedia_s32 index)
{
xmedia_s32 ret;
if (str == NULL) {
printf("storage name space is null\n");
return XMEDIA_NULL;
}
// 外部数据
double extra_val[SQL_COL_NUM - 1];
for (xmedia_s32 i = 1; i <= SQL_COL_NUM - 1; i++) {
extra_val[i - 1] = index;
}
// 查询匹配的行
xmedia_char select_cmd[100];
sprintf(select_cmd, "SELECT id FROM my_table WHERE ");
for (xmedia_s32 i = 1; i <= SQL_COL_NUM - 1; i++) {
xmedia_char colName[10];
sprintf(colName, "val%d", i);
strcat(select_cmd, colName);
xmedia_char val_str[20];
sprintf(val_str, " = %f", extra_val[i - 1]);
strcat(select_cmd, val_str);
if (i != SQL_COL_NUM - 1) {
strcat(select_cmd, " AND ");
}
}
strcat(select_cmd, ";");
ret = sqlite3_exec(sql3_db, select_cmd, name_callback, str, 0);
if (ret != SQLITE_OK) {
printf("can not query SQL: %s\n", sqlite3_errmsg(sql3_db));
sqlite3_close(sql3_db);
return SQL_ERROR;
}
return XMEDIA_SUCCESS;
}
static xmedia_s32 search_index(sqlite3* sql3_db, xmedia_char *name_str, xmedia_s32 *index)
{
xmedia_s32 ret;
if (name_str == NULL) {
printf("name is invalid\n");
return XMEDIA_NULL;
}
if (index == NULL) {
printf("storage index space is null\n");
return XMEDIA_NULL;
}
// 查询匹配的行
xmedia_char select_cmd[100];
sprintf(select_cmd, "SELECT val1 FROM my_table WHERE id = '");
xmedia_char col_name[50];
sprintf(col_name, name_str);
strcat(select_cmd, col_name);
strcat(select_cmd, "';");
printf("find str is :\n %s \n", select_cmd);
ret = sqlite3_exec(sql3_db, select_cmd, index_callback, index, 0);
if (ret != SQLITE_OK) {
printf("can not query SQL: %s\n", sqlite3_errmsg(sql3_db));
//sqlite3_close(sql3_db);
return SQL_ERROR;
}
return XMEDIA_SUCCESS;
}
static xmedia_s32 insert_row(double row[], xmedia_s32 size, matrix_data *matri)
{
if (matri == NULL) {
printf("the matri is not exist\n");
return XMEDIA_NULL;
}
if (matri->row_num >= MAX_ROWS) {
printf("Database is full, can not insert more rows.\n");
return PUSH_FAILED;
}
if (size > MAX_COLS) {
printf("Row size exceeds maximum number of colums. can not insert rows.\n");
return PUSH_FAILED;
}
for (xmedia_s32 i = 0; i < size; i++) {
matri->data[matri->row_num][i] = row[i];
}
matri->row_num++;
matri->col_num = size;
return XMEDIA_SUCCESS;
}
static xmedia_s32 delete_row(xmedia_s32 row_index, matrix_data *matri) {
if (row_index < 0 || row_index > matri->row_num) {
printf("Invalid row index. can not delete row.\n");
return XMEDIA_FAILURE;
}
for (xmedia_s32 i = row_index; i < matri->row_num - 1; i++) {
for (xmedia_s32 j = 0; j < matri->col_num; j++) {
matri->data[i][j] = matri->data[i + 1][j];
}
}
matri->row_num -= 1;
return XMEDIA_SUCCESS;
}
static xmedia_s32 normalize_matrix(matrix_data *matrix)
{
if (matrix == NULL) {
return XMEDIA_NULL;
}
// find the max value from matrix
for (xmedia_s32 i = 0; i < matrix->row_num; i++) {
double sum_of_square = 0.0;
for (xmedia_s32 j = 0; j < matrix->col_num; j++) {
sum_of_square += matrix->data[i][j] * matrix->data[i][j];
}
double model_len = sqrt(sum_of_square);
for (xmedia_s32 j = 0; j < matrix->col_num; j++) {
matrix->data[i][j] /= model_len;
}
}
return XMEDIA_SUCCESS;
}
static xmedia_s32 matrix_transpose(matrix_data *matrix, t_matrix_data *t_matrix)
{
if (matrix == NULL || t_matrix == NULL) {
printf("can not transpose, matrix or t_matrix is null\n");
return XMEDIA_NULL;
}
for (xmedia_s32 i = 0; i < matrix->row_num; i++) {
for (xmedia_s32 j = 0; j < matrix->col_num; j++) {
t_matrix->data[j][i] = matrix->data[i][j];
}
}
t_matrix->row_num = matrix->col_num;
t_matrix->col_num = matrix->row_num;
return XMEDIA_SUCCESS;
}
static xmedia_s32 check_dot_result(r_matrix_data *matrix, double similarity_thres, db_match_result *result)
{
double min = 1.0;
xmedia_s32 i, j;
if (matrix == NULL) {
printf("check dot result failed!\n");
return XMEDIA_FAILURE;
}
// multi target, clear result firstly
result->face_num = 0;
result->match_num = 0;
memset(result->match_col, -1, sizeof(xmedia_s32) * MAX_MATCH_NUM);
for (i = 0; i < matrix->row_num; i++) {
for (j = 0; j < matrix->col_num; j++) {
if (matrix->data[i][j] <= similarity_thres) { // pick data from similarity_thres, data_value in [0, 1]
if (min > matrix->data[i][j]) { // get the samllest value in row
min = matrix->data[i][j];
result->match_col[i] = j;
}
}
}
min = 1.0;
}
result->face_num = matrix->row_num;
return XMEDIA_SUCCESS;
}
static xmedia_s32 svp_matrix_dot(t_matrix_data *t_matrix, r_matrix_data *result_matrix,
xmedia_svp_fr_output *face_matrix)
{
if (face_matrix == NULL || t_matrix == NULL || result_matrix == NULL) {
printf("matrix handle is null\n");
return XMEDIA_NULL;
}
for (xmedia_s32 i = 0; i < face_matrix->face_num; i++) {
for (xmedia_s32 j = 0; j < t_matrix->col_num; j++) {
for (xmedia_s32 k = 0; k < MAX_COLS; k++) {
result_matrix->data[i][j] += face_matrix->fr_result[i].vector[k] * t_matrix->data[k][j];
}
// [-1, 1] --> [0, 1]
result_matrix->data[i][j] = 0.5 - 0.5 * result_matrix->data[i][j]; // 0.5 - 0.5*cosine
}
}
result_matrix->row_num = face_matrix->face_num;
result_matrix->col_num = t_matrix->col_num;
return XMEDIA_SUCCESS;
}
static xmedia_s32 check_db_cfg_info(config_info *cfg)
{
if (cfg->file_name == NULL) {
printf("cfg file_name is NULL\n");
return XMEDIA_FAILURE;
}
if (cfg->match_thres > 1.0 || cfg->match_thres < 0.0) {
printf("cfg match_thres %f is invaild, recommend 0.0 ~ 1.0\n", cfg->match_thres);
return XMEDIA_FAILURE;
}
return XMEDIA_SUCCESS;
}
static xmedia_s32 check_add_person_info(add_person_info *person_info)
{
xmedia_double sum = 0.0;
xmedia_s32 i = 0;
if (person_info->add_person_name == NULL) {
printf("add person name is null\n");
return XMEDIA_FAILURE;
}
for (; i < MAX_COLS; i++) {
sum += person_info->add_person_feature[i];
}
if (sum == 0.0 || i != MAX_COLS) {
printf("add person info is invalid\n");
return XMEDIA_FAILURE;
}
return XMEDIA_SUCCESS;
}
static xmedia_s32 append_person_info_to_file(xmedia_char *file, add_person_info *person_info)
{
FILE *fp;
if (file == NULL) {
printf("file is null\n");
return XMEDIA_FAILURE;
}
fp = fopen(file, "a");
if (fp == NULL) {
printf("can not open file\n");
}
fprintf(fp, "\"%s\" #", person_info->add_person_name);
for (xmedia_s32 i = 0; i < MAX_COLS; i++) {
fprintf(fp, "%lf", person_info->add_person_feature[i]);
if (i != MAX_COLS - 1) {
fprintf(fp, ",");
}
}
fprintf(fp, "#\n");
printf("finish write data to file\n");
fclose(fp);
return XMEDIA_SUCCESS;
}
static xmedia_s32 delete_person_info_from_file(xmedia_char *file, xmedia_char *name)
{
FILE *read_fp;
FILE *clear_fp;
FILE *write_fp;
xmedia_char *tmp_buffer;
xmedia_char *delete_start;
xmedia_char *delete_end;
xmedia_s32 file_size;
if (file == NULL) {
printf("file is null\n");
return XMEDIA_FAILURE;
}
// read origin data to buffer
read_fp = fopen(file, "r");
if (read_fp == NULL) {
printf("can not open file\n");
}
fseek(read_fp, 0, SEEK_END);
file_size = ftell(read_fp);
fseek(read_fp, 0, SEEK_SET);
tmp_buffer = (xmedia_char*)malloc(file_size);
if (tmp_buffer == NULL) {
printf("malloc tmp_buffer for data file failed\n");
return XMEDIA_FAILURE;
}
fread(tmp_buffer, sizeof(xmedia_char), file_size, read_fp);
fclose(read_fp);
// clear file
clear_fp = fopen(file, "w");
if (clear_fp == NULL) {
printf("can not open clear_fp_file\n");
goto OPEN_CLEAR_FAILED;
}
fclose(clear_fp);
// determine location
delete_start = strstr(tmp_buffer, name) - 1;
delete_end = strchr(delete_start + MAX_NAME_LEN + 3, '#');// " 空格 # 三个字符
write_fp = fopen(file, "w");
if (write_fp == NULL) {
printf("can not open write_fp_file, txt file is empty!!!\n");
free(tmp_buffer);
return XMEDIA_FAILURE;
}
fwrite(tmp_buffer, sizeof(xmedia_char), delete_start - tmp_buffer, write_fp);
fwrite(delete_end + 1, sizeof(xmedia_char), (tmp_buffer + file_size) - (delete_end + 1), write_fp);
fclose(write_fp);
free(tmp_buffer);
return XMEDIA_SUCCESS;
OPEN_CLEAR_FAILED:
free(tmp_buffer);
return XMEDIA_FAILURE;
}
xmedia_s32 svp_init_database(db_attr **fr_db_attr, config_info *cfg)
{
FILE *fp;
xmedia_s32 ret;
xmedia_s32 index;
xmedia_slong file_size;
xmedia_char *tmp_buffer;
xmedia_char* start;
xmedia_char *end;
xmedia_char *sql;
xmedia_char data[MAX_FEATURE_LEN];
xmedia_char* token;
xmedia_char* delimiter = ",";
xmedia_char *err_msg;
xmedia_s32 last_index = -1;
xmedia_s32 match_name_index;
xmedia_char name[MAX_NAME_LEN];
xmedia_char *info_table = "my_table";
if (fr_db_attr == NULL) {
printf("fr_db_attr is null\n");
return XMEDIA_FAILURE;
}
if (cfg == NULL) {
printf("database cfg is NULL\n");
return XMEDIA_FAILURE;
}
// check cfg info
ret = check_db_cfg_info(cfg);
if (ret != XMEDIA_SUCCESS) {
printf("database cfg param is invalid\n");
return XMEDIA_FAILURE;
}
// find idle
for (index = 0; index < MAX_DB_NUM; index++) {
if (!g_svp_db[index].use_flag) {
break;
}
}
if (index >= MAX_DB_NUM) {
printf("db num is out of range 2\n");
return XMEDIA_FAILURE;
}
g_svp_db[index].feature_db = malloc(sizeof(face_feature_db));
g_svp_db[index].feature_db->o_matrix = malloc(sizeof(matrix_data));
g_svp_db[index].feature_db->t_matrix = malloc(sizeof(t_matrix_data));
g_svp_db[index].feature_db->r_matrix = malloc(sizeof(r_matrix_data));
if (!g_svp_db[index].feature_db) {
printf("g_svp_db[index].feature_db malloc failed\n");
return MALLOC_FAILED;
}
if (!g_svp_db[index].feature_db->o_matrix) {
printf("o_matrix malloc failed\n");
free(g_svp_db[index].feature_db);
return MALLOC_FAILED;
}
if (!g_svp_db[index].feature_db->t_matrix) {
printf("t_matrix malloc failed\n");
free(g_svp_db[index].feature_db);
free(g_svp_db[index].feature_db->o_matrix);
return MALLOC_FAILED;
}
if (!g_svp_db[index].feature_db->r_matrix) {
printf("r_matrix malloc failed\n");
free(g_svp_db[index].feature_db);
free(g_svp_db[index].feature_db->o_matrix);
free(g_svp_db[index].feature_db->t_matrix);
return MALLOC_FAILED;
}
memset(g_svp_db[index].feature_db->o_matrix, 0x00, sizeof(matrix_data));
memset(g_svp_db[index].feature_db->t_matrix, 0x00, sizeof(t_matrix_data));
memset(g_svp_db[index].feature_db->r_matrix, 0x00, sizeof(r_matrix_data));
g_svp_db[index].match_thres = cfg->match_thres;
g_svp_db[index].filepath = cfg->file_name;
ret = sqlite3_open("./res/person_name_id", &g_svp_db[index].sql3_db);
if (ret != SQLITE_OK) {
printf("can not open SQL database: %s\n", sqlite3_errmsg(g_svp_db[index].sql3_db));
return 1;
}
ret = create_table(g_svp_db[index].sql3_db, SQL_COL_NUM, info_table);
if (ret != 0) {
printf("can not create table\n");
return XMEDIA_FAILURE;
}
fp = fopen(cfg->file_name, "r");
if (!fp) {
printf("open data file failed\n");
return XMEDIA_FAILURE;
}
fseek(fp, 0, SEEK_END);
file_size = ftell(fp);
fseek(fp, 0, SEEK_SET);
tmp_buffer = (xmedia_char*)malloc(file_size);
if (tmp_buffer == NULL) {
printf("malloc tmp_buffer for data file failed\n");
goto MALLOC_TMP_BUFF;
}
fread(tmp_buffer, sizeof(xmedia_char), file_size, fp);
start = strchr(tmp_buffer, '"');
while (start != NULL) {
end = strchr(start + 1, '"');
strncpy(name, start + 1, end - start - 1);
name[end - start - 1] = '\0';
printf("name: %s\n", name);
// 查找当前数据库中最大的index
sql = "SELECT MAX(val1) FROM my_table;";
ret = sqlite3_exec(g_svp_db[index].sql3_db, sql, index_callback, &last_index, &err_msg);
if (ret != SQLITE_OK) {
sqlite3_free(err_msg);
sqlite3_close(g_svp_db[index].sql3_db);
return 1;
}
printf("sql table max index %d\n", last_index);
// 判断数据库中是否有这个人
match_name_index = -1;
ret = search_index(g_svp_db[index].sql3_db, name, &match_name_index);
if (ret != XMEDIA_SUCCESS) {
printf("can not search sql\n");
goto FAIL_INSERT;
}
if (match_name_index == -1) { // add new one
printf("sql db cann't find %s, add!!!\n", name);
ret = table_insert_one_row(g_svp_db[index].sql3_db, name, last_index + 1, SQL_COL_NUM, info_table);
if (ret != 0) {
printf("insert info data failed\n");
goto FAIL_INSERT;
}
}
// 提取##之间的数据
start = strchr(end + 1, '#');
end = strchr(start + 1, '#');
strncpy(data, start + 1, end - start - 1);
data[end - start - 1] = '\0';
token = strtok(data, delimiter);
xmedia_double row[MAX_COLS] = {0};
xmedia_s32 data_index = 0;
while (token != NULL) {
if (data_index > MAX_COLS) {
goto FAIL_INSERT;
}
row[data_index] = atof(token);
token = strtok(NULL, delimiter);
data_index++;
}
ret = insert_row(row, MAX_COLS, g_svp_db[index].feature_db->o_matrix);
if (ret != 0) {
printf("insert feature data failed\n");
goto FAIL_INSERT;
}
printf("finish one people\n");
start = strchr(end + 1, '"');
}
fclose(fp);
free(tmp_buffer);
// txt is empty
if (g_svp_db[index].feature_db->o_matrix->row_num == 0) {
printf("txt file is empty\n");
g_svp_db[index].db_empty_flag = XMEDIA_TRUE;
}
// normlize
ret = normalize_matrix(g_svp_db[index].feature_db->o_matrix);
if (ret != XMEDIA_SUCCESS) {
printf("normlize failed\n");
goto FAIL_INSERT;
}
ret = matrix_transpose(g_svp_db[index].feature_db->o_matrix, g_svp_db[index].feature_db->t_matrix);
if (ret != XMEDIA_SUCCESS) {
printf("matrix_transpose failed\n");
goto FAIL_INSERT;
}
g_svp_db[index].use_flag = XMEDIA_TRUE;
*fr_db_attr = &g_svp_db[index];
printf("database init successfully\n");
return XMEDIA_SUCCESS;
FAIL_INSERT:
free(tmp_buffer);
MALLOC_TMP_BUFF:
free(g_svp_db[index].feature_db->o_matrix);
free(g_svp_db[index].feature_db->t_matrix);
free(g_svp_db[index].feature_db->r_matrix);
free(g_svp_db[index].feature_db);
sqlite3_close(g_svp_db[index].sql3_db);
fclose(fp);
return XMEDIA_FAILURE;
}
xmedia_s32 svp_deinit_database(db_attr *fr_db_attr)
{
xmedia_s32 ret;
xmedia_s32 db_handle = 0;
if (fr_db_attr == NULL) {
printf("fr_db_attr is null\n");
return XMEDIA_FAILURE;
}
for (; db_handle < MAX_DB_NUM; db_handle++) {
if (fr_db_attr == &g_svp_db[db_handle]) {
break;
}
}
if (db_handle >= MAX_DB_NUM) {
return XMEDIA_FAILURE;
}
if (!g_svp_db[db_handle].use_flag) {
return XMEDIA_FAILURE;
}
if (g_svp_db[db_handle].feature_db->o_matrix) {
free(g_svp_db[db_handle].feature_db->o_matrix);
}
if (g_svp_db[db_handle].feature_db->t_matrix) {
free(g_svp_db[db_handle].feature_db->t_matrix);
}
if (g_svp_db[db_handle].feature_db->r_matrix) {
free(g_svp_db[db_handle].feature_db->r_matrix);
}
if (g_svp_db[db_handle].feature_db) {
free(g_svp_db[db_handle].feature_db);
}
if (g_svp_db[db_handle].sql3_db) {
ret = sqlite3_close(g_svp_db[db_handle].sql3_db);
if (ret != SQLITE_OK) {
printf("sql close failed\n");
}
}
g_svp_db[db_handle].use_flag = XMEDIA_FALSE;
printf("database deinit successfully\n");
return 0;
}
xmedia_s32 svp_get_match_result(db_attr *fr_db_attr, xmedia_svp_fr_output *face_matrix, db_match_result *result)
{
xmedia_s32 ret;
xmedia_s32 db_handle = 0;
if (result == NULL) {
printf("db_result is null\n");
return XMEDIA_FAILURE;
}
if (face_matrix == NULL) {
printf("face matrix is null\n");
return XMEDIA_FAILURE;
}
if (face_matrix->face_num == 0) {
return XMEDIA_SUCCESS;
}
if (fr_db_attr == NULL) {
printf("db handle is null\n");
return XMEDIA_FAILURE;
}
for (; db_handle < MAX_DB_NUM; db_handle++) {
if (fr_db_attr == &g_svp_db[db_handle]) {
break;
}
}
if (db_handle >= MAX_DB_NUM) {
printf("db_handle is invalid\n");
return XMEDIA_FAILURE;
}
if (fr_db_attr->db_empty_flag) {
printf("data_base is empty, please input data\n");
return XMEDIA_SUCCESS;
}
t_matrix_data *t_matrix = g_svp_db[db_handle].feature_db->t_matrix;
r_matrix_data *result_matrix = g_svp_db[db_handle].feature_db->r_matrix;
memset(result_matrix, 0x00, sizeof(r_matrix_data));
ret = svp_matrix_dot(t_matrix, result_matrix, face_matrix);
if (ret != XMEDIA_SUCCESS) {
printf("matrix dot failed\n");
return XMEDIA_FAILURE;
}
// check result
memset(result->match_name, 0, sizeof(result->match_name));
check_dot_result(result_matrix, fr_db_attr->match_thres, result);
for (xmedia_s32 i = 0; i < result->face_num; i++) {
if (result->match_col[i] != -1) {
ret = search_id(fr_db_attr->sql3_db,result->match_name[i], result->match_col[i]);
if (ret != 0) { // got name
printf("DB can not search \n");
}
if (strcmp(result->match_name[i], "") != 0) { // got name
result->match_num++;
// printf("DB match %s\n", result->match_name[i]);
}
}
}
return XMEDIA_SUCCESS;
}
xmedia_s32 svp_add_someone_to_database(db_attr *fr_db_attr, add_person_info *person_info)
{
xmedia_s32 ret = 0;
xmedia_char *sql;
xmedia_char *err_msg;
xmedia_s32 last_index = -1;
xmedia_s32 match_name_index;
xmedia_char *info_table = "my_table";
xmedia_s32 db_handle = 0;
if (fr_db_attr == NULL) {
printf("fr_db_attr is null\n");
return XMEDIA_FAILURE;
}
if (person_info == NULL) {
printf("person info is null\n");
return XMEDIA_FAILURE;
}
for (; db_handle < MAX_DB_NUM; db_handle++) {
if (fr_db_attr == &g_svp_db[db_handle]) {
break;
}
}
if (db_handle >= MAX_DB_NUM) {
return XMEDIA_FAILURE;
}
// check person info
ret = check_add_person_info(person_info);
if (ret != XMEDIA_SUCCESS) {
printf("person info invalid\n");
return XMEDIA_FAILURE;
}
// find max index in sql
sql = "SELECT MAX(val1) FROM my_table;";
ret = sqlite3_exec(fr_db_attr->sql3_db, sql, index_callback, &last_index, &err_msg);
if (ret != SQLITE_OK) {
sqlite3_free(err_msg);
sqlite3_close(fr_db_attr->sql3_db);
return XMEDIA_FAILURE;
}
printf("sql table max index %d\n", last_index);
// check if has add person
match_name_index = -1;
ret = search_index(fr_db_attr->sql3_db, person_info->add_person_name, &match_name_index);
if (ret != XMEDIA_SUCCESS) {
printf("can not search sql\n");
return XMEDIA_FAILURE;
}
// add to sql
if (match_name_index == -1) {
ret = table_insert_one_row(fr_db_attr->sql3_db, person_info->add_person_name,
last_index + 1, SQL_COL_NUM, info_table);
if (ret != 0) {
printf("insert info data failed\n");
return XMEDIA_FAILURE;
}
// add to feature o_matrix
ret = insert_row(person_info->add_person_feature, MAX_COLS, fr_db_attr->feature_db->o_matrix);
if (ret != 0) {
sqlite3_free(err_msg);
sqlite3_close(fr_db_attr->sql3_db);
return XMEDIA_FAILURE;
}
fr_db_attr->db_empty_flag = XMEDIA_FALSE;
ret = normalize_matrix(fr_db_attr->feature_db->o_matrix);
if (ret != XMEDIA_SUCCESS) {
sqlite3_free(err_msg);
sqlite3_close(fr_db_attr->sql3_db);
return XMEDIA_FAILURE;
}
ret = matrix_transpose(fr_db_attr->feature_db->o_matrix, fr_db_attr->feature_db->t_matrix);
if (ret != XMEDIA_SUCCESS) {
sqlite3_free(err_msg);
sqlite3_close(fr_db_attr->sql3_db);
return XMEDIA_FAILURE;
}
// update info to txt file
ret = append_person_info_to_file(fr_db_attr->filepath, person_info);
if (ret != XMEDIA_SUCCESS) {
printf("append_person_info_to_file\n");
return XMEDIA_FAILURE;
}
printf("add %s to database successfully, index is %d\n", person_info->add_person_name, last_index + 1);
return XMEDIA_SUCCESS;
}
printf("person already in database\n");
return XMEDIA_FAILURE;
}
xmedia_s32 svp_delete_someone_from_database(db_attr *fr_db_attr, xmedia_char *name)
{
xmedia_s32 ret;
xmedia_s32 match_name_index;
xmedia_char *err_msg;
xmedia_s32 db_handle = 0;
if (fr_db_attr == NULL) {
printf("db handle is null\n");
return XMEDIA_FAILURE;
}
for (; db_handle < MAX_DB_NUM; db_handle++) {
if (fr_db_attr == &g_svp_db[db_handle]) {
break;
}
}
if (db_handle >= MAX_DB_NUM) {
return XMEDIA_FAILURE;
}
if (name == NULL) {
printf("delete name is invalid\n");
return XMEDIA_FAILURE;
}
// find index by name
match_name_index = -1;
ret = search_index(fr_db_attr->sql3_db, name, &match_name_index);
if (ret != XMEDIA_SUCCESS) {
printf("can not search sql\n");
return XMEDIA_FAILURE;
}
// if index valid, go on
if (match_name_index != -1) {
// updata sql index
xmedia_char delete_table_cmd[100];
sprintf(delete_table_cmd, "DELETE FROM my_table WHERE val1 = %d;", match_name_index);
ret = sqlite3_exec(fr_db_attr->sql3_db, delete_table_cmd, NULL, 0, &err_msg);
if (ret != SQLITE_OK) {
sqlite3_free(err_msg);
sqlite3_close(fr_db_attr->sql3_db);
return XMEDIA_FAILURE;
}
xmedia_char update_table_cmd[100];
sprintf(update_table_cmd, "UPDATE my_table SET val1 = val1 - 1 WHERE val1 > %d;", match_name_index);
ret = sqlite3_exec(fr_db_attr->sql3_db, update_table_cmd, NULL, 0, &err_msg);
if (ret != SQLITE_OK) {
sqlite3_free(err_msg);
sqlite3_close(fr_db_attr->sql3_db);
return XMEDIA_FAILURE;
}
// delete feature o_matrix row by index
ret = delete_row(match_name_index, fr_db_attr->feature_db->o_matrix);
if (ret != XMEDIA_SUCCESS) {
printf("use name search index failed\n");
return XMEDIA_FAILURE;
}
ret = normalize_matrix(fr_db_attr->feature_db->o_matrix);
if (ret != XMEDIA_SUCCESS) {
sqlite3_free(err_msg);
sqlite3_close(fr_db_attr->sql3_db);
return XMEDIA_FAILURE;
}
ret = matrix_transpose(fr_db_attr->feature_db->o_matrix, fr_db_attr->feature_db->t_matrix);
if (ret != XMEDIA_SUCCESS) {
sqlite3_free(err_msg);
sqlite3_close(fr_db_attr->sql3_db);
return XMEDIA_FAILURE;
}
// delete person from txt file
ret = delete_person_info_from_file(fr_db_attr->filepath, name);
if (ret != XMEDIA_SUCCESS) {
printf("delete_person_info_from_file failed\n");
return XMEDIA_FAILURE;
}
printf("delete %s from database successfully,origin index is %d\n", name, match_name_index);
return XMEDIA_SUCCESS;
}
printf("%s not in database\n", name);
return XMEDIA_FAILURE;
}