From a7ae929039ae0b0b9ee729619b670e014700fc2d Mon Sep 17 00:00:00 2001
From: houxiao <houxiao@454eff88-639b-444f-9e54-f578c98de674>
Date: 星期五, 21 四月 2017 17:46:02 +0800
Subject: [PATCH] dev

---
 FaceServer/STFaceCache.cpp        |    5 
 FaceServer/make.sh                |   25 +
 FaceServer/main_face_daemon.cpp   |   55 +++
 FaceServer/face_daemon_proto.h    |    6 
 FaceServer/face-13-w52-h52.rgb565 |    0 
 FaceServer/test_client_add.cpp    |  126 ++++++++
 FaceServer/sample_face_search.cpp |  145 +++++++++
 FaceServer/face-20-w49-h49.rgb565 |    0 
 FaceServer/test_client_detect.cpp |    0 
 FaceServer/pseudo_stfacesdk.cpp   |  523 ++++++++++++++++++++++++++++++++++
 10 files changed, 871 insertions(+), 14 deletions(-)

diff --git a/FaceServer/STFaceCache.cpp b/FaceServer/STFaceCache.cpp
index 82f18e3..2c094f9 100644
--- a/FaceServer/STFaceCache.cpp
+++ b/FaceServer/STFaceCache.cpp
@@ -9,6 +9,8 @@
 #include "sample_face_search.h"
 #include <cv_face.h>
 
+#define ENABLE_AUTO_CREATE_STFACEDB
+
 struct STFaceCacheContext
 {
 	cv_handle_t handle_verify;
@@ -222,6 +224,8 @@
 	}
 	
 	stface_ctx_map_t::iterator iterCtx = dbContext.find(img.db_id);
+	
+#ifdef ENABLE_AUTO_CREATE_STFACEDB
 	if (iterCtx == dbContext.end())
 	{
 		// create db
@@ -247,6 +251,7 @@
 		dbContext.insert(std::make_pair(ctx.dbid, ctx));
 		iterCtx = dbContext.find(img.db_id);
 	}
+#endif
 	
 	if (iterCtx == dbContext.end())
 	{
diff --git a/FaceServer/face-13-w52-h52.rgb565 b/FaceServer/face-13-w52-h52.rgb565
new file mode 100644
index 0000000..7f8454e
--- /dev/null
+++ b/FaceServer/face-13-w52-h52.rgb565
Binary files differ
diff --git a/FaceServer/face-20-w49-h49.rgb565 b/FaceServer/face-20-w49-h49.rgb565
new file mode 100644
index 0000000..7fcd747
--- /dev/null
+++ b/FaceServer/face-20-w49-h49.rgb565
Binary files differ
diff --git a/FaceServer/face_daemon_proto.h b/FaceServer/face_daemon_proto.h
index 63d5741..eb475b6 100644
--- a/FaceServer/face_daemon_proto.h
+++ b/FaceServer/face_daemon_proto.h
@@ -30,6 +30,8 @@
 	int16_t width;
 	int16_t height;
 	uint8_t buff[0];
+	
+	void hton();//#todo
 };
 
 struct FDP_FaceDetectPB
@@ -39,7 +41,7 @@
 	FDP_FaceDetectPB(int32_t _db_id) : db_id(_db_id)
 	{}
 	
-	void hton();
+	void hton();//#todo
 };
 
 struct FDP_FaceDetectResult
@@ -50,7 +52,7 @@
 	FDP_FaceDetectResult(int32_t _db_id, int32_t _st_id) : db_id(_db_id), st_id(_st_id)
 	{}
 	
-	void hton();
+	void hton();//#todo
 };
 
 #pragma pack()
diff --git a/FaceServer/main_face_daemon.cpp b/FaceServer/main_face_daemon.cpp
index bcbfafb..86fee13 100644
--- a/FaceServer/main_face_daemon.cpp
+++ b/FaceServer/main_face_daemon.cpp
@@ -25,11 +25,11 @@
 	server_stop();
 }
 
-bool send_SensetimeFaceDetectResultJson(EVClientStub& client, const fdr_vec_t& result)
+bool send_SensetimeFaceDetectResultJson(EVClientStub& client, const fdr_vec_t& result, int ret = 0)
 {
 	std::stringstream ss;
 	ss << "{" << LOG_ENDL;
-	ss << "\"ret\":" << WRAPPER_TEXT(0) << "," << LOG_ENDL;
+	ss << "\"ret\":" << WRAPPER_TEXT(ret) << "," << LOG_ENDL;
 	ss << "\"count\":" << WRAPPER_TEXT(result.size()) << "," << LOG_ENDL;
 	ss << "\"result\":[";
 	for(fdr_vec_t::const_iterator iter = result.begin(); iter != result.end(); ++iter)
@@ -103,6 +103,27 @@
 	return send_SensetimeFaceDetectResultJson(client, result);
 }
 
+bool ev_proc_SensetimeFaceDetectSave(EVClientStub& client)
+{
+	EVPHeader* evpHeader = (EVPHeader*)client.recvBuff;
+	FDP_Image* fdpImage = (FDP_Image*)(client.recvBuff + sizeof(EVPHeader));
+	
+	STFaceImage stfaceImg;
+	stfaceImg.db_id = fdpImage->db_id;
+	stfaceImg.mb_type = fdpImage->mb_type;
+	stfaceImg.width = fdpImage->width;
+	stfaceImg.height = fdpImage->height;
+	stfaceImg.size = evpHeader->size - sizeof(EVPHeader) - sizeof(FDP_Image);
+	stfaceImg.buff = fdpImage->buff;
+	
+	fdr_vec_t result;
+	FDP_FaceDetectResult fdrResult = g_STFaceCache.add(stfaceImg);
+	result.push_back(fdrResult);
+	
+	int ret = (fdrResult.db_id == 0 ? -1 : 0);
+	return send_SensetimeFaceDetectResultJson(client, result, ret);
+}
+
 bool ev_dispatcher_proto_pb(EVClientStub& client)
 {
 	LOG_DEBUG << "ev_dispatcher_proto_pb" << LOG_ENDL;
@@ -131,6 +152,33 @@
 	return false;
 }
 
+bool ev_dispatcher_proto_rawbin(EVClientStub& client)
+{
+	LOG_DEBUG << "ev_dispatcher_proto_pb" << LOG_ENDL;
+	
+	EVPHeader* evpHeader = (EVPHeader*)client.recvBuff;
+	if (evpHeader->size != client.recvBuffSize)
+	{
+		LOG_WARN << "Truncated buffer " << (evpHeader->size - client.recvBuffSize) << " bytes" << LOG_ENDL;
+		return false;
+	}
+
+	switch(evpHeader->cmd)
+	{
+	case FaceDaemonCommand::FDC_SENSETIMEFACEDETECT_SAVE:
+		return ev_proc_SensetimeFaceDetectSave(client);
+	break;
+	default:
+		LOG_WARN << "Unknown command" << LOG_ENDL;
+		ev_send_status_packet(client, EVPStatus::EVPS_COMMAND_ERROR);
+		return false;
+	break;
+	}
+	
+	// return false to disconnect
+	return false;
+}
+
 bool ev_dispatcher_proto(EVClientStub& client)
 {
 	LOG_DEBUG << "ev_dispatcher_proto" << LOG_ENDL;
@@ -147,6 +195,9 @@
 	case EVPProto::EVPP_PROTOBUF:
 		return ev_dispatcher_proto_pb(client);
 	break;
+	case EVPProto::EVPP_RAW_BIN:
+		return ev_dispatcher_proto_rawbin(client);
+	break;
 	default:
 		LOG_WARN << "Unknown proto" << LOG_ENDL;
 		ev_send_status_packet(client, EVPStatus::EVPS_PROTO_ERROR);
diff --git a/FaceServer/make.sh b/FaceServer/make.sh
index dd03a91..dae06e5 100644
--- a/FaceServer/make.sh
+++ b/FaceServer/make.sh
@@ -12,23 +12,28 @@
 STFACESDK_INC="-I$STFACESDK_BASE/include"
 STFACESDK_LIB="-L$STFACESDK_BASE/libs/linux-x86_64"
 
+LIBYUV_BASE=/opt/libyuv/inst
+LIBYUV_INC="-I$LIBYUV_BASE/include"
+LIBYUV_LIB="-L$LIBYUV_BASE/lib -lyuv"
+
 OPENCV_LIB=`pkg-config --libs-only-l opencv`
 
-CPPFLAGS+="-g -c -std=c++11 -pthread -DSERVER_PORT=5432 -DSTFACESDK_BASE=\"$STFACESDK_BASE\" -I$PIPELINE_BASE -I$VISITFACE_BASE $PROTOBUF_INC $STFACESDK_INC "
-LDFLAGS+="-pthread -levent $PROTOBUF_LIB $STFACESDK_LIB $OPENCV_LIB " # -lcvface_api 
+CPPFLAGS+="-g -c -std=c++11 -pthread -DSERVER_PORT=5432 -DSTFACESDK_BASE=\"$STFACESDK_BASE\" -I$PIPELINE_BASE -I$VISITFACE_BASE $PROTOBUF_INC $STFACESDK_INC $LIBYUV_INC "
+LDFLAGS+="-pthread -levent $PROTOBUF_LIB $STFACESDK_LIB $OPENCV_LIB $LIBYUV_LIB " # -lcvface_api 
 
 rm *.o
-rm face_server
-rm test_client
+rm face_server test_client_detect test_client_add
 
 g++ $PIPELINE_BASE/Logger/src/logger.cc $CFLAGS $CPPFLAGS
 g++ ev_server.cpp -DUSER_DEFINE_EVCLIENT_PROC $CFLAGS $CPPFLAGS
 g++ $VISITFACE_BASE/PbFaceList.pb.cc $CFLAGS $CPPFLAGS
 g++ main_face_daemon.cpp $CFLAGS $CPPFLAGS
 g++ sample_face_search.cpp $CFLAGS $CPPFLAGS
+g++ pseudo_stfacesdk.cpp $CFLAGS $CPPFLAGS
 g++ STFaceCache.cpp $CFLAGS $CPPFLAGS
 
-g++ test_client.cpp $CFLAGS $CPPFLAGS
+g++ test_client_detect.cpp $CFLAGS $CPPFLAGS
+g++ test_client_add.cpp $CFLAGS $CPPFLAGS
 
 g++ -g -std=c++11 \
   logger.o \
@@ -36,13 +41,19 @@
   PbFaceList.pb.o \
   main_face_daemon.o \
   sample_face_search.o \
+  pseudo_stfacesdk.o \
   STFaceCache.o \
   $LDFLAGS -o face_server
 #
 
 g++ -g -std=c++11 \
-  test_client.o \
-  $LDFLAGS -o test_client
+  test_client_detect.o \
+  $LDFLAGS -o test_client_detect
+#
+
+g++ -g -std=c++11 \
+  test_client_add.o \
+  $LDFLAGS -o test_client_add
 #
 
 #export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/protobuf/inst/lib:/opt/st_face-6.3.1-verify_p1-linux-524d0c3/libs/linux-x86_64
diff --git a/FaceServer/pseudo_stfacesdk.cpp b/FaceServer/pseudo_stfacesdk.cpp
index e69de29..9ee95bd 100644
--- a/FaceServer/pseudo_stfacesdk.cpp
+++ b/FaceServer/pseudo_stfacesdk.cpp
@@ -0,0 +1,523 @@
+#include <cv_common.h>
+#include <cv_face.h>
+#include <cv_utils.h>
+
+CV_SDK_API cv_result_t cv_image_allocate(
+	int width,
+	int height,
+	cv_pixel_format pixel_format,
+	cv_image ** image
+)
+{
+	return 0;
+}
+
+CV_SDK_API void
+cv_image_release(cv_image* image)
+{
+}
+
+CV_SDK_API cv_result_t
+cv_common_color_convert(
+	const cv_image* image_src,
+	cv_image* image_dst
+)
+{
+	return 0;
+}
+
+CV_SDK_API
+cv_result_t
+cv_common_image_affine_transfer(
+	const cv_image *image_src,
+	const cv_pointf_t *src_points_array,
+	const int src_points_count,
+	const cv_pointf_t *dst_points_array,
+	const int dst_points_count,
+	cv_image *image_dst
+)
+{
+	return 0;
+}
+
+CV_SDK_API
+cv_result_t
+cv_common_image_resize(
+       const cv_image *image_src,
+       cv_image *image_dst,
+       cv_image_resize_method method
+)
+{
+	return 0;
+}
+
+CV_SDK_API
+cv_result_t
+cv_common_image_crop(
+       const cv_image *image_src,
+       const cv_rect_t *crop_area,
+       cv_image *image_dst
+)
+{
+	return 0;
+}
+
+CV_SDK_API
+cv_result_t
+cv_common_image_rotate(
+       const cv_image *image_src,
+       cv_image *image_dst,
+       unsigned int rotate_degree
+)
+{
+	return 0;
+}
+
+CV_SDK_API cv_result_t
+cv_common_load_model(
+	const char *file,
+	cv_model_t *model
+)
+{
+	return 0;
+}
+
+CV_SDK_API
+void cv_common_unload_model(
+	cv_model_t model
+)
+{
+}
+
+CV_SDK_API cv_result_t
+cv_common_load_resource(
+	const unsigned char *model_start,
+	const unsigned char *model_end,
+	cv_model_t *model
+)
+{
+	return 0;
+}
+
+CV_SDK_API cv_result_t
+cv_common_load_composite_model(
+	const char *file,
+	cv_composite_model_t *model
+)
+{
+	return 0;
+}
+
+CV_SDK_API cv_result_t
+cv_common_unload_composite_model(
+       cv_composite_model_t model
+)
+{
+	return 0;
+}
+
+CV_SDK_API cv_result_t
+cv_common_composite_model_get_submodel(
+       cv_composite_model_t model,
+       const char *name,
+       cv_model_t *submodel
+)
+{
+	return 0;
+}
+
+CV_SDK_API
+void
+cv_face_algorithm_info()
+{
+}
+
+CV_SDK_API
+cv_result_t
+cv_face_init_license_config(const char* szLicense)
+{
+	return 0;
+}
+
+CV_SDK_API
+cv_result_t
+cv_face_create_detector(
+	cv_handle_t *handle,
+	const char *model_path,
+	unsigned int config
+)
+{
+	return 0;
+}
+
+CV_SDK_API
+cv_result_t cv_face_detect_get_threshold(
+	cv_handle_t detector_handle,
+	float *threshold
+	)
+{
+	return 0;
+}
+
+CV_SDK_API
+cv_result_t cv_face_detect_set_threshold(
+	cv_handle_t detector_handle,
+	float threshold
+	)
+{
+	return 0;
+}
+
+CV_SDK_API
+void cv_face_destroy_detector(
+	cv_handle_t detector_handle
+)
+{
+}
+
+CV_SDK_API
+cv_result_t
+cv_face_detect(
+	cv_handle_t detector_handle,
+	const unsigned char *image,
+	cv_pixel_format pixel_format,
+	int image_width,
+	int image_height,
+	int image_stride,
+	cv_face_orientation orientation,
+	cv_face_t **p_faces_array,
+	int *p_faces_count
+)
+{
+	return 0;
+}
+
+CV_SDK_API
+void
+cv_face_release_detector_result(
+	cv_face_t *faces_array,
+	int faces_count
+)
+{
+	return;
+}
+
+CV_SDK_API
+cv_result_t
+cv_face_create_tracker(
+	cv_handle_t *handle,
+	const char *model_path,
+	unsigned int config
+)
+{
+	return 0;
+}
+
+CV_SDK_API
+void
+cv_face_destroy_tracker(
+	cv_handle_t tracker_handle
+)
+{
+	return;
+}
+
+CV_SDK_API
+cv_result_t
+cv_face_track(
+	cv_handle_t tracker_handle,
+	const unsigned char *image,
+	cv_pixel_format pixel_format,
+	int image_width,
+	int image_height,
+	int image_stride,
+	cv_face_orientation orientation,
+	cv_face_t **p_faces_array,
+	int *p_faces_count
+)
+{
+	return 0;
+}
+
+CV_SDK_API
+void
+cv_face_reset_tracker(
+	cv_handle_t tracker_handle
+)
+{
+	return;
+}
+
+CV_SDK_API
+void
+cv_face_release_tracker_result(
+	cv_face_t *faces_array,
+	int faces_count
+)
+{
+}
+
+CV_SDK_API
+cv_result_t
+cv_face_track_set_detect_face_cnt_limit(
+	cv_handle_t tracker_handle,
+	int detect_face_cnt_limit,
+	int* val
+)
+{
+	return 0;
+}
+
+CV_SDK_API
+cv_result_t
+cv_verify_create_handle(
+	cv_handle_t* handle,
+	const char *model_path
+)
+{
+	return 0;
+}
+
+CV_SDK_API
+cv_result_t
+cv_verify_duplicate_handle(
+	cv_handle_t old_handle,
+	cv_handle_t* new_handle
+)
+{
+	return 0;
+}
+
+CV_SDK_API
+void
+cv_verify_destroy_handle(
+	cv_handle_t verify_handle
+)
+{
+	return;
+}
+
+CV_SDK_API
+int
+cv_verify_get_version(
+	cv_handle_t verify_handle
+)
+{
+	return 0;
+}
+
+CV_SDK_API
+int
+cv_verify_get_feature_length(
+	cv_handle_t verify_handle
+)
+{
+	return 0;
+}
+
+CV_SDK_API
+cv_result_t
+cv_verify_get_feature(
+	cv_handle_t verify_handle,
+	const unsigned char *image,
+	cv_pixel_format pixel_format,
+	int image_width,
+	int image_height,
+	int image_stride,
+	const cv_face_t *face,
+	cv_feature_t **p_feature,
+	unsigned int *feature_blob_size
+)
+{
+	return 0;
+}
+
+CV_SDK_API
+cv_result_t
+cv_verify_serialize_feature(
+	const cv_feature_t *feature,
+	char *feature_str
+)
+{
+	return 0;
+}
+
+CV_SDK_API
+cv_feature_t *
+cv_verify_deserialize_feature(
+	const char *feature_str
+)
+{
+	return 0;
+}
+
+CV_SDK_API
+cv_result_t
+cv_verify_compare_feature(
+	cv_handle_t verify_handle,
+	const cv_feature_t *feature1,
+	const cv_feature_t *feature2,
+	float *score
+)
+{
+	return 0;
+}
+
+CV_SDK_API
+void
+cv_verify_release_feature(
+	cv_feature_t *feature
+)
+{
+	return;
+}
+
+CV_SDK_API
+cv_result_t
+cv_verify_create_db(cv_handle_t *handle)
+{
+	return 0;
+}
+
+CV_SDK_API
+void
+cv_verify_destroy_db(
+	cv_handle_t db_handle
+)
+{
+}
+
+CV_SDK_API
+cv_result_t
+cv_verify_build_db(
+	cv_handle_t db_handle,
+	cv_feature_t* const *items,
+	unsigned int item_count
+)
+{
+	return 0;
+}
+
+CV_SDK_API
+cv_result_t
+cv_verify_add_face(
+	cv_handle_t db_handle,
+	const cv_feature_t *item,
+	int *idx
+)
+{
+	return 0;
+}
+
+CV_SDK_API
+cv_result_t
+cv_verify_delete_face(
+	cv_handle_t db_handle,
+	int idx
+)
+{
+	return 0;
+}
+
+CV_SDK_API
+cv_result_t
+cv_verify_save_db(
+	cv_handle_t db_handle,
+	const char *db_path
+)
+{
+	return 0;
+}
+
+CV_SDK_API
+cv_result_t
+cv_verify_load_db(
+	cv_handle_t db_handle,
+	const char *db_path
+)
+{
+	return 0;
+}
+
+CV_SDK_API
+cv_result_t
+cv_verify_search_face(
+	cv_handle_t verify_handle,
+	cv_handle_t db_handle,
+	const cv_feature_t *query,
+	unsigned int top_k,
+	int *top_idxs,
+	float *top_scores,
+	unsigned int *result_length
+)
+{
+	return 0;
+}
+
+CV_SDK_API
+cv_result_t
+cv_verify_search_face_from_list(
+	cv_handle_t verify_handle,
+	cv_feature_t* const *list_feature,
+	int list_count,
+	const cv_feature_t *query,
+	unsigned int top_k,
+	int *top_idxs,
+	float *top_scores,
+	unsigned int *result_length
+)
+{
+	return 0;
+}
+
+CV_SDK_API
+cv_result_t
+cv_verify_grouping(
+	cv_handle_t verify_handle,
+	const cv_feature_t * const *features,
+	unsigned int feature_count,
+	unsigned int *p_groups_array,
+	unsigned int *groups_count
+)
+{
+	return 0;
+}
+
+CV_SDK_API
+void
+cv_verify_initialize_labels(
+	unsigned int *p_groups_array,
+	unsigned int feature_count
+)
+{
+}
+
+CV_SDK_API
+cv_result_t
+cv_face_create_clustering(
+cv_handle_t *clustering_handle,
+const char* model_path
+)
+{
+	return 0;
+}
+
+CV_SDK_API
+cv_result_t
+cv_face_clustering(
+cv_handle_t clustering_handle,
+const cv_feature_t * const *features,
+unsigned int *labels,
+int size
+)
+{
+	return 0;
+}
+
+CV_SDK_API
+void
+cv_face_clustering_destroy(
+cv_handle_t clustering_handle
+)
+{
+}
diff --git a/FaceServer/sample_face_search.cpp b/FaceServer/sample_face_search.cpp
index 6876364..8889cac 100644
--- a/FaceServer/sample_face_search.cpp
+++ b/FaceServer/sample_face_search.cpp
@@ -1,4 +1,5 @@
 #include "sample_face_search.h"
+#include <MaterialBuffer.h>
 #include "STFaceCache.h"
 #include <logger.h>
 
@@ -7,6 +8,11 @@
 #include <cv_face.h>
 
 #include <opencv2/opencv.hpp>
+#include <libyuv/convert.h>
+#define SUBSAMPLE(v, a) ((((v) + (a) - 1)) / (a))
+
+#define MAX_FACE_IMAGE_WIDTH 640
+#define MAX_FACE_IMAGE_HEIGHT 480
 
 using namespace std;
 using namespace cv;
@@ -46,7 +52,66 @@
 	return p_feature;
 }
 
-cv_feature_t *stface_extract_feature(stface_handles& handles, const STFaceImage& image);//#todo
+cv_feature_t *stface_extract_feature(stface_handles& handles, const STFaceImage& image)
+{
+	cv_pixel_format stimgfmt = CV_PIX_FMT_GRAY8;
+	
+	if (image.width > MAX_FACE_IMAGE_WIDTH || image.height > MAX_FACE_IMAGE_HEIGHT)
+	{
+		LOG_WARN << "image too big" << LOG_ENDL;
+		return nullptr;
+	}
+	
+	uint8_t imgbuf[MAX_FACE_IMAGE_WIDTH * MAX_FACE_IMAGE_HEIGHT * 4];
+	size_t imgbufSize = 0;
+	if (image.mb_type == MB_Frame::MBFT_RGB565)
+	{
+		uint8* dst_y = (uint8*)(imgbuf);
+        uint8* dst_u = (uint8*)(dst_y + (image.height * image.width));
+        uint8* dst_v = (uint8*)(dst_u + (image.height * image.width / 4));
+		
+		int ret = libyuv::RGB565ToI420(
+			image.buff, image.width, 
+			dst_y, image.width, 
+			dst_u, SUBSAMPLE(image.width, 2), 
+			dst_v, SUBSAMPLE(image.width, 2), 
+			image.width, image.height
+		);
+		imgbufSize = image.height * image.width * 1.5;
+	}
+	else
+	{
+		LOG_WARN << "mb frame type not support" << LOG_ENDL;
+		return nullptr;
+	}
+	
+	Mat matImg(cv::Size(image.width, image.height), CV_8UC1, imgbuf);
+	if (!matImg.data)
+	{
+		return nullptr;
+	}
+	
+	cv_feature_t *p_feature = nullptr;
+	cv_face_t *p_face = nullptr;
+	int face_count = 0;
+	cv_result_t st_result = CV_OK;
+	st_result = cv_face_detect(handles.handle_detect, matImg.data, stimgfmt, matImg.cols, matImg.rows, matImg.step, CV_FACE_UP, &p_face, &face_count);
+	if (face_count >= 1)
+	{
+		st_result = cv_verify_get_feature(handles.handle_verify, (unsigned char *)matImg.data, stimgfmt, matImg.cols, matImg.rows, matImg.step, p_face, &p_feature, nullptr);
+		if (st_result != CV_OK)
+		{
+			LOGP(DEBUG, "cv_verify_get_feature failed, error code %d\n", st_result);
+		}
+	}
+	else
+	{
+		LOGP(DEBUG, "can't find face in");
+	}
+	// release the memory of face
+	cv_face_release_detector_result(p_face, face_count);
+	return p_feature;
+}
 
 int stface_db_add(stface_handles& handles, const char *image_path) {
 	cv_feature_t *p_feature = stface_extract_feature(handles, image_path);
@@ -62,7 +127,22 @@
 	return idx;
 }
 
-int stface_db_add(stface_handles& handles, const STFaceImage& image);//#todo
+int stface_db_add(stface_handles& handles, const STFaceImage& image)
+{
+	cv_feature_t *p_feature = stface_extract_feature(handles, image);
+	if (!p_feature)
+	{
+		return -1;
+	}
+	int idx;
+	cv_result_t cv_result = cv_verify_add_face(handles.handle_db, p_feature, &idx);
+	if (cv_result != CV_OK)
+	{
+		LOGP(DEBUG, "cv_verify_add_face failed, error code %d\n", cv_result);
+	}
+	cv_verify_release_feature(p_feature);
+	return idx;
+}
 
 bool stface_db_del(stface_handles& handles, int idx) {
 	if (idx < 0) {
@@ -104,6 +184,25 @@
 		LOGP(DEBUG, "load done!\n");
 	}
 
+	return true;
+}
+
+bool stface_db_create(stface_handles& handles, const char *db_path)
+{
+	cv_result_t cv_result = cv_verify_create_db(&handles.handle_db);
+	if (cv_result != CV_OK)
+	{
+		LOG_WARN << "cv_verify_create_db return false" << LOG_ENDL;
+		return false;
+	}
+		
+	cv_result = cv_verify_save_db(handles.handle_db, db_path);
+	if (cv_result != CV_OK)
+	{
+		LOG_WARN << "cv_verify_save_db return false" << LOG_ENDL;
+		return false;
+	}
+	
 	return true;
 }
 
@@ -193,7 +292,47 @@
 	return true;
 }
 
-bool stface_search_db(stface_handles& handles, const STFaceImage& image, top_idx_score_vect_t& result);//#todo
+bool stface_search_db(stface_handles& handles, const STFaceImage& image, top_idx_score_vect_t& result)
+{
+	cv_feature_t *p_feature = stface_extract_feature(handles, image);
+	if (p_feature == nullptr)
+	{
+		LOGP(DEBUG, "extract failed !\n");
+		return false;
+	}
+
+	int top_k = 10;
+	int *top_idxs = new int[top_k];
+	float *top_scores = new float[top_k];
+	unsigned int result_length = 0;
+	cv_result_t cv_result = cv_verify_search_face(handles.handle_verify, handles.handle_db, p_feature, top_k, top_idxs, top_scores, &result_length);
+	if (cv_result == CV_OK)
+	{
+		for (unsigned int t = 0; t < result_length; t++)
+		{
+			// const cv_feature_t item = result[t].item;
+			LOGP(DEBUG, "%d\t", top_idxs[t]);
+			LOGP(DEBUG, "%0.2f\n", top_scores[t]);
+			
+			result.push_back(TopIdxScore(top_idxs[t],  top_scores[t]));
+		}
+	}
+	else
+	{
+		LOGP(DEBUG, "cv_verify_search_face failed, error code %d\n", cv_result);
+	}
+	if (top_idxs)
+	{
+		delete[] top_idxs;
+	}
+	if (top_scores)
+	{
+		delete[] top_scores;
+	}
+	cv_verify_release_feature(p_feature);
+
+	return true;
+}
 
 bool stface_search_list(stface_handles& handles, char *image_path, char *list_path) {
 	cv_feature_t *p_feature = stface_extract_feature(handles, image_path);
diff --git a/FaceServer/test_client_add.cpp b/FaceServer/test_client_add.cpp
new file mode 100644
index 0000000..6a07947
--- /dev/null
+++ b/FaceServer/test_client_add.cpp
@@ -0,0 +1,126 @@
+/************************************
+ * For msmr 
+ * server.c
+ * tesing the speed of bufferevent_write
+ * 2015-02-03
+ * author@tom
+************************************/
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <event2/event.h>
+#include <event2/bufferevent.h>
+#include <event2/buffer.h>
+#include <netinet/tcp.h>
+#include <arpa/inet.h>
+
+#include <unistd.h>
+
+#include "ev_proto.h"
+#include "face_daemon_proto.h"
+
+#include <MaterialBuffer.h>
+
+/*
+void make_msg(char* mesg, int& length)
+{
+	EVPHeader* evpHeader = new (mesg) EVPHeader;
+	evpHeader->proto = EVPProto::EVPP_PROTOBUF;
+	evpHeader->cmd = FaceDaemonCommand::FDC_SENSETIMEFACEDETECT_PB;
+	evpHeader->size = length;
+	
+	FILE* pFile = fopen("facelist-3.pb", "rb");
+	size_t fsize = fread(mesg + sizeof(EVPHeader), 1, length - sizeof(EVPHeader), pFile);
+	fclose(pFile);
+}
+*/
+
+void make_msg(char* mesg, int& length)
+{
+	EVPHeader* evpHeader = new (mesg) EVPHeader;
+	FDP_Image* fdpImage = new (mesg + sizeof(EVPHeader)) FDP_Image;
+
+	evpHeader->proto = EVPProto::EVPP_RAW_BIN;
+	evpHeader->cmd = FaceDaemonCommand::FDC_SENSETIMEFACEDETECT_SAVE;
+	evpHeader->size = sizeof(EVPHeader) + sizeof(FDP_Image);
+	
+	fdpImage->db_id = 123;
+	fdpImage->mb_type = MB_Frame::MBFT_RGB565;
+	fdpImage->width = 52;
+	fdpImage->height = 52;
+	
+	FILE* pFile = fopen("face-13-w52-h52.rgb565", "rb");
+	length = fread(fdpImage->buff, 1, length, pFile);
+	fclose(pFile);
+	
+	evpHeader->size += length;
+	length = evpHeader->size;
+}
+
+int main()
+{
+    // build the message to be sent
+    int length = 1024 * 1024; // the size of message
+    char* mesg = (char*)malloc((length+1)*sizeof(char)); // Look out the end mark '/0' of a C string
+    if (mesg == NULL)
+        exit(1);
+    int i;
+    //for (i=0; i<length; i++) 
+    //    strcat(mesg, "a");
+
+	make_msg(mesg, length);
+
+    printf("%s\n", mesg);
+    printf("%d\n", (int)strlen(mesg));
+
+    // build socket
+    int port = 5432;
+
+    struct sockaddr_in server_addr;
+    memset(&server_addr, 0, sizeof(server_addr));
+    server_addr.sin_family = AF_INET;
+    server_addr.sin_addr.s_addr = inet_addr("192.168.1.146");
+    server_addr.sin_port = htons(port);
+
+    // build event base
+    struct event_base* base = event_base_new();
+
+    // set TCP_NODELAY to let data arrive at the server side quickly
+    evutil_socket_t fd;
+    fd = socket(AF_INET, SOCK_STREAM, 0);
+    struct bufferevent* conn = bufferevent_socket_new(base,fd,BEV_OPT_CLOSE_ON_FREE);
+    int enable = 1;
+    if(setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (void*)&enable, sizeof(enable)) < 0)
+       printf("ERROR: TCP_NODELAY SETTING ERROR!\n");
+    //bufferevent_setcb(conn, NULL, NULL, NULL, NULL); // For client, we don't need callback function
+    bufferevent_enable(conn, EV_WRITE);
+    if(bufferevent_socket_connect(conn,(struct sockaddr*)&server_addr,sizeof(server_addr)) == 0)
+            printf("connect success\n");
+
+    // start to send data
+    bufferevent_write(conn,mesg,length);
+    // check the output evbuffer
+    struct evbuffer* output = bufferevent_get_output(conn);
+
+    event_base_dispatch(base);
+ 
+	char readbuf[10];
+	int readbufsize = read(fd, readbuf, sizeof(readbuf));
+	while(readbufsize>0)
+	{
+		readbuf[readbufsize] = '\0';
+		printf("%s", readbuf);
+		readbufsize = read(fd, readbuf, sizeof(readbuf));
+	}
+	printf("\n");
+
+    free(mesg);
+    mesg = NULL;
+
+    bufferevent_free(conn);
+    event_base_free(base);
+
+    printf("Client program is over\n");
+
+    return 0;
+}
\ No newline at end of file
diff --git a/FaceServer/test_client.cpp b/FaceServer/test_client_detect.cpp
similarity index 100%
rename from FaceServer/test_client.cpp
rename to FaceServer/test_client_detect.cpp

--
Gitblit v1.8.0