From 2ef4c31dec7c97f21a615ccd9e80b1c8c1e74ff2 Mon Sep 17 00:00:00 2001 From: Haejeong Kim Date: Wed, 16 Aug 2017 14:06:58 +0900 Subject: [PATCH] Re-extract face info when media item's modified time was changed. when user deletes system detected face info, modified_time changed to 0 to refresh later Change-Id: I1b32829536b1e0e2dba1885f3761635b9e704a40 --- include/dcm_svc_db.h | 15 +++++- include/dcm_svc_detect_face.h | 2 +- include/dcm_svc_internal.h | 1 + packaging/dcm-service.spec | 2 +- src/dcm_svc_db.c | 98 ++++++++++++++++++++++++++++------- src/dcm_svc_detect_face.c | 14 +++-- src/dcm_svc_internal.c | 26 +++++----- 7 files changed, 119 insertions(+), 39 deletions(-) diff --git a/include/dcm_svc_db.h b/include/dcm_svc_db.h index a63e728..ef6bf02 100755 --- a/include/dcm_svc_db.h +++ b/include/dcm_svc_db.h @@ -33,7 +33,9 @@ #define SELECT_PATH_FROM_UNEXTRACTED_DCM_MEDIA "SELECT media_uuid, path, storage_uuid, width, height, orientation, mime_type FROM media WHERE media_uuid NOT IN (SELECT DISTINCT media_uuid FROM face_scan_list) AND validity=1 AND media_type=0 AND (storage_type = 0 OR storage_type = 1);" #define SELECT_PATH_FROM_UNEXTRACTED_DCM_INTERNAL_MEDIA "SELECT media_uuid, path, storage_uuid, width, height, orientation, mime_type FROM media WHERE media_uuid NOT IN (SELECT DISTINCT media_uuid FROM face_scan_list) AND validity=1 AND media_type=0 AND storage_type=0;" -#define SELECT_MEDIA_INFO_BY_FILE_PATH_FROM_DB "SELECT media_uuid, storage_uuid, width, height, orientation, mime_type FROM media WHERE path = '%q';" +#define SELECT_MEDIA_INFO_BY_FILE_PATH_FROM_DB "SELECT media_uuid, storage_uuid, width, height, orientation, mime_type, modified_time FROM media WHERE path = '%q';" +#define SELECT_SCAN_INFO_BY_MEDIA_ID "SELECT modified_time FROM "DB_TABLE_FACE_SCAN_LIST" WHERE media_uuid = '%q';" + #define INSERT_FACE_ITEM_TO_DB "INSERT INTO " DB_TABLE_FACE" (" FACE_ITEM") VALUES ('%q', '%q', %d, %d, %d, %d, %d);" typedef struct { @@ -54,6 +56,13 @@ typedef struct { unsigned char rgb_b; } dcm_color_item_s; +typedef enum { + FACE_SCAN_NEEDED = 0, + FACE_SCAN_NO_NEEDED = 2, + FACE_SCAN_REFRESH_NEEDED = 1, + FACE_SCAN_STATUS_NONE = 3, +} dcm_face_scan_status_e; + int dcm_svc_db_connect(uid_t uid); int dcm_svc_db_disconnect(); int dcm_svc_db_get_scan_image_list_by_path(GList **image_list, gboolean mmc_mounted, const char *file_path); @@ -63,7 +72,9 @@ int dcm_svc_db_generate_uuid(dcm_face_item_s **face); int dcm_svc_db_insert_face_to_db(dcm_face_item_s *face); int dcm_svc_db_update_color_to_db(const dcm_color_item_s color); int dcm_svc_db_insert_face_to_face_scan_list(dcm_svc_item_s *scan_item); -int dcm_svc_db_check_scanned_by_media_uuid(const char *media_uuid, gboolean *media_scanned); +int dcm_svc_db_update_face_to_face_scan_list(dcm_svc_item_s *scan_item); +int dcm_svc_db_delete_face_from_db(const char *media_uuid); +int dcm_svc_db_check_scanned_by_media_uuid(const char *media_uuid, time_t modified_time, dcm_face_scan_status_e *scan_status); #endif /*_DCM_DB_UTILS_H_*/ diff --git a/include/dcm_svc_detect_face.h b/include/dcm_svc_detect_face.h index db605fc..0ca4f93 100755 --- a/include/dcm_svc_detect_face.h +++ b/include/dcm_svc_detect_face.h @@ -22,7 +22,7 @@ int dcm_face_detect_initialize(); int dcm_face_detect_finalize(); -int dcm_face_detect_process(dcm_svc_item_s *scan_item, dcm_image_info_s *image_info); +int dcm_face_detect_process(dcm_svc_item_s *scan_item, dcm_face_scan_status_e scan_status, dcm_image_info_s *image_info); #endif /*_DCM_SVC_FACE_H_*/ diff --git a/include/dcm_svc_internal.h b/include/dcm_svc_internal.h index 2a73af2..d9b99c3 100755 --- a/include/dcm_svc_internal.h +++ b/include/dcm_svc_internal.h @@ -49,6 +49,7 @@ typedef struct { char *media_uuid; char *file_path; char *storage_uuid; + time_t modified_time; int image_width; int image_height; int image_orientation; diff --git a/packaging/dcm-service.spec b/packaging/dcm-service.spec index 2cc7fc6..0b12c38 100755 --- a/packaging/dcm-service.spec +++ b/packaging/dcm-service.spec @@ -1,6 +1,6 @@ Name: dcm-service Summary: A media DCM(Digital Contents Management) Service -Version: 0.1.6 +Version: 0.1.7 Release: 0 Group: Multimedia/Service License: Apache-2.0 diff --git a/src/dcm_svc_db.c b/src/dcm_svc_db.c index a31f2a4..f203bc1 100755 --- a/src/dcm_svc_db.c +++ b/src/dcm_svc_db.c @@ -221,10 +221,7 @@ int dcm_svc_db_get_scan_image_list_by_path(GList **image_list, gboolean mmc_moun else query_string = sqlite3_mprintf(SELECT_MEDIA_INFO_BY_FILE_PATH_FROM_DB, file_path); - if (query_string == NULL) { - dcm_error("Failed to make query!"); - return MS_MEDIA_ERR_OUT_OF_MEMORY; - } + DCM_CHECK_VAL(query_string, MS_MEDIA_ERR_OUT_OF_MEMORY); ret = __dcm_svc_sql_prepare_to_step_simple((sqlite3 *)db_handle, query_string, &sql_stmt); if (ret != MS_MEDIA_ERR_NONE) { @@ -252,6 +249,7 @@ int dcm_svc_db_get_scan_image_list_by_path(GList **image_list, gboolean mmc_moun scan_item->image_height = sqlite3_column_int(sql_stmt, 3); scan_item->image_orientation = sqlite3_column_int(sql_stmt, 4); scan_item->mime_type = g_strdup((const char *)sqlite3_column_text(sql_stmt, 5)); + scan_item->modified_time = sqlite3_column_int(sql_stmt, 6); /* scan item retrieved by this function will be marked as SCAN_SINGLE */ scan_item->scan_item_type = DCM_SCAN_ITEM_TYPE_SCAN_SINGLE; @@ -401,7 +399,7 @@ int dcm_svc_db_insert_face_to_face_scan_list(dcm_svc_item_s *scan_item) return MS_MEDIA_ERR_INTERNAL; } - query_string = sqlite3_mprintf("INSERT INTO %s (media_uuid, storage_uuid) values('%q', '%q')", DB_TABLE_FACE_SCAN_LIST, scan_item->media_uuid, scan_item->storage_uuid); + query_string = sqlite3_mprintf("INSERT INTO %s (media_uuid, storage_uuid, modified_time) values('%q', '%q', '%d')", DB_TABLE_FACE_SCAN_LIST, scan_item->media_uuid, scan_item->storage_uuid, scan_item->modified_time); dcm_debug("query is %s", query_string); @@ -419,6 +417,63 @@ int dcm_svc_db_insert_face_to_face_scan_list(dcm_svc_item_s *scan_item) return ret; } +int dcm_svc_db_update_face_to_face_scan_list(dcm_svc_item_s *scan_item) +{ + int ret = MS_MEDIA_ERR_NONE; + char* query_string = NULL; + + dcm_debug_fenter(); + + DCM_CHECK_VAL(db_handle, MS_MEDIA_ERR_INVALID_PARAMETER); + DCM_CHECK_VAL(scan_item, MS_MEDIA_ERR_INVALID_PARAMETER); + DCM_CHECK_VAL(scan_item->media_uuid, MS_MEDIA_ERR_INVALID_PARAMETER); + + query_string = sqlite3_mprintf("UPDATE %s SET modified_time = %d WHERE media_uuid='%q'", DB_TABLE_FACE_SCAN_LIST, scan_item->modified_time, scan_item->media_uuid); + + dcm_debug("query is %s", query_string); + + g_mutex_trylock(&gMutexLock); + ret = media_db_request_update_db(query_string, dcm_uid); + if (ret != MS_MEDIA_ERR_NONE) + dcm_error("media_db_request_update_db is failed: %d, %s", ret, sqlite3_errmsg((sqlite3 *)db_handle)); + + g_mutex_unlock(&gMutexLock); + + DCM_SQLITE3_FREE(query_string); + + dcm_debug_fleave(); + + return ret; +} + +int dcm_svc_db_delete_face_from_db(const char *media_uuid) +{ + int ret = MS_MEDIA_ERR_NONE; + char* query_string = NULL; + + dcm_debug_fenter(); + + DCM_CHECK_VAL(db_handle, MS_MEDIA_ERR_INVALID_PARAMETER); + DCM_CHECK_VAL(media_uuid, MS_MEDIA_ERR_INVALID_PARAMETER); + + query_string = sqlite3_mprintf("DELETE FROM %s WHERE media_uuid='%q' AND user_marked = 0", DB_TABLE_FACE, media_uuid); + + dcm_sec_debug("query is %s", query_string); + + g_mutex_trylock(&gMutexLock); + ret = media_db_request_update_db(query_string, dcm_uid); + if (ret != MS_MEDIA_ERR_NONE) + dcm_error("media_db_request_update_db is failed: %d, %s", ret, sqlite3_errmsg((sqlite3 *)db_handle)); + + g_mutex_unlock(&gMutexLock); + + DCM_SQLITE3_FREE(query_string); + + dcm_debug_fleave(); + + return ret; +} + int dcm_svc_db_update_color_to_db(dcm_color_item_s color) { int ret = MS_MEDIA_ERR_NONE; @@ -447,37 +502,42 @@ int dcm_svc_db_update_color_to_db(dcm_color_item_s color) return ret; } -int dcm_svc_db_check_scanned_by_media_uuid(const char *media_uuid, gboolean *media_scanned) +int dcm_svc_db_check_scanned_by_media_uuid(const char *media_uuid, time_t modified_time, dcm_face_scan_status_e *scan_status) { int ret = MS_MEDIA_ERR_NONE; char *query_string = NULL; sqlite3_stmt *sql_stmt = NULL; - int count = 0; + time_t org_modified_time = 0; dcm_debug_fenter(); DCM_CHECK_VAL(db_handle, MS_MEDIA_ERR_INVALID_PARAMETER); DCM_CHECK_VAL(media_uuid, MS_MEDIA_ERR_INVALID_PARAMETER); - query_string = sqlite3_mprintf("SELECT count(*) FROM %s WHERE (media_uuid='%q')", DB_TABLE_FACE_SCAN_LIST, media_uuid); + query_string = sqlite3_mprintf(SELECT_SCAN_INFO_BY_MEDIA_ID, media_uuid); DCM_CHECK_VAL(query_string, MS_MEDIA_ERR_OUT_OF_MEMORY); ret = __dcm_svc_sql_prepare_to_step((sqlite3 *)db_handle, query_string, &sql_stmt); - if (ret != MS_MEDIA_ERR_NONE) { + if (ret == MS_MEDIA_ERR_DB_NO_RECORD) { + dcm_info("Scanning needed"); + *scan_status = FACE_SCAN_NEEDED; + } else if (ret == MS_MEDIA_ERR_NONE) { + org_modified_time = sqlite3_column_int(sql_stmt, 0); + if (org_modified_time == modified_time) { + dcm_info("Already scanned item"); + *scan_status = FACE_SCAN_NO_NEEDED; + } else { + dcm_info("Scanned but item updated. Scanning needed"); + *scan_status = FACE_SCAN_REFRESH_NEEDED; + } + + DCM_SQLITE3_FINALIZE(sql_stmt); + } else { dcm_error("error when __dcm_svc_sql_prepare_to_step. ret = [%d]", ret); return ret; } - count = sqlite3_column_int(sql_stmt, 0); - - DCM_SQLITE3_FINALIZE(sql_stmt); - - if (count > 0) - *media_scanned = TRUE; - else - *media_scanned = FALSE; - dcm_debug_fleave(); - return ret; + return MS_MEDIA_ERR_NONE; } diff --git a/src/dcm_svc_detect_face.c b/src/dcm_svc_detect_face.c index c579d12..0e6986c 100755 --- a/src/dcm_svc_detect_face.c +++ b/src/dcm_svc_detect_face.c @@ -104,7 +104,7 @@ int dcm_face_detect_finalize() return ret; } -int dcm_face_detect_process(dcm_svc_item_s *scan_item, dcm_image_info_s *image_info) +int dcm_face_detect_process(dcm_svc_item_s *scan_item, dcm_face_scan_status_e scan_status, dcm_image_info_s *image_info) { dcm_face_item_s *face = NULL; int face_area = 0; @@ -201,9 +201,15 @@ int dcm_face_detect_process(dcm_svc_item_s *scan_item, dcm_image_info_s *image_i DCM_SVC_FACE_RECOGNIZE_BUFFER_FAILED: - err = dcm_svc_db_insert_face_to_face_scan_list(scan_item); - if (err != MS_MEDIA_ERR_NONE) - dcm_error("Failed to insert face item into face_scan_list! err: %d", err); + if (scan_status == FACE_SCAN_REFRESH_NEEDED) { + err = dcm_svc_db_update_face_to_face_scan_list(scan_item); + if (err != MS_MEDIA_ERR_NONE) + dcm_error("Failed to update face item into face_scan_list! err: %d", err); + } else { + err = dcm_svc_db_insert_face_to_face_scan_list(scan_item); + if (err != MS_MEDIA_ERR_NONE) + dcm_error("Failed to insert face item into face_scan_list! err: %d", err); + } dcm_face_destroy_face_info(face_info); diff --git a/src/dcm_svc_internal.c b/src/dcm_svc_internal.c index ee06960..97b7752 100755 --- a/src/dcm_svc_internal.c +++ b/src/dcm_svc_internal.c @@ -190,18 +190,13 @@ static int __dcm_scan_get_item_list_by_path(const char *file_path, dcm_scan_s *d return MS_MEDIA_ERR_NONE; } -static int __dcm_scan_get_scan_status(dcm_svc_item_s *scan_item, gboolean *media_scanned) +static int __dcm_scan_get_scan_status(dcm_svc_item_s *scan_item, dcm_face_scan_status_e *scan_status) { - int ret = MS_MEDIA_ERR_NONE; - DCM_CHECK_VAL(scan_item, MS_MEDIA_ERR_INVALID_PARAMETER); DCM_CHECK_VAL(scan_item->media_uuid, MS_MEDIA_ERR_INVALID_PARAMETER); /* Check if this media is scanned or not */ - ret = dcm_svc_db_check_scanned_by_media_uuid(scan_item->media_uuid, media_scanned); - if (ret != MS_MEDIA_ERR_NONE) - dcm_error("Failed to check if this media item is scanned or not!"); - return ret; + return dcm_svc_db_check_scanned_by_media_uuid(scan_item->media_uuid, scan_item->modified_time, scan_status); } static int __dcm_scan_send_result(dcm_scan_s *data, const char *msg, const unsigned int count, dcm_ipc_port_e port) @@ -260,10 +255,11 @@ static int __dcm_scan_clear_single_item(gpointer data) static int __dcm_scan_process(dcm_svc_item_s *scan_item) { - gboolean media_scanned = false; + dcm_face_scan_status_e scan_status = FACE_SCAN_STATUS_NONE; int ret = MS_MEDIA_ERR_NONE; dcm_debug_fenter(); + DCM_CHECK_VAL(scan_item, MS_MEDIA_ERR_INVALID_PARAMETER); DCM_CHECK_VAL(scan_item->file_path, MS_MEDIA_ERR_INVALID_PARAMETER); @@ -276,7 +272,7 @@ static int __dcm_scan_process(dcm_svc_item_s *scan_item) /* Get necessary information from db again. * Media information will be inserted after face is detected. * If media uuid does not exist, retry is needed */ - ret = __dcm_scan_get_scan_status(scan_item, &media_scanned); + ret = __dcm_scan_get_scan_status(scan_item, &scan_status); if (ret != MS_MEDIA_ERR_NONE) { dcm_error("Failed to get scan item info from db! err: %d", ret); return ret; @@ -284,12 +280,12 @@ static int __dcm_scan_process(dcm_svc_item_s *scan_item) /* It is possible that when single and async scan for the same image is in the list. * If the media uuid is already scanned, skip this scan. */ - if (media_scanned == true) { + if (scan_status == FACE_SCAN_NO_NEEDED) { dcm_warn("This media is scanned already! Skip..."); DCM_SAFE_FREE(image_info.pixel); return MS_MEDIA_ERROR_ALREADY_SCANNED; } else { - dcm_debug("This media is NOT scanned yet."); + dcm_debug("Need to Scan"); } dcm_sec_debug("scan file path : [%s]", scan_item->file_path); @@ -334,8 +330,14 @@ static int __dcm_scan_process(dcm_svc_item_s *scan_item) dcm_info("Image info width: %d, height: %d, buf_width: %d, buf_height: %d", image_info.original_width, image_info.original_height, image_info.buffer_width, image_info.buffer_height); + if (scan_status == FACE_SCAN_REFRESH_NEEDED) { + ret = dcm_svc_db_delete_face_from_db(scan_item->media_uuid); + if (ret != MS_MEDIA_ERR_NONE) + dcm_error("Failed to dcm_svc_db_delete_face_from_db err: %d", ret); + } + /* Process face scan */ - ret = dcm_face_detect_process(scan_item, &image_info); + ret = dcm_face_detect_process(scan_item, scan_status, &image_info); if (ret != MS_MEDIA_ERR_NONE) dcm_error("Failed to process face detection! err: %d", ret); -- 2.34.1