From 15d0c49e85159b9e27870aff5280c0cd95b103c4 Mon Sep 17 00:00:00 2001 From: xuxiuxi <xuxiuxi@454eff88-639b-444f-9e54-f578c98de674> Date: 星期四, 04 五月 2017 17:16:56 +0800 Subject: [PATCH] --- FaceServer/main_face_daemon.cpp | 369 +++++++++++++++++++++++++++------------------------- 1 files changed, 193 insertions(+), 176 deletions(-) diff --git a/FaceServer/main_face_daemon.cpp b/FaceServer/main_face_daemon.cpp index 9058ee4..e4783ab 100644 --- a/FaceServer/main_face_daemon.cpp +++ b/FaceServer/main_face_daemon.cpp @@ -1,183 +1,219 @@ -#include "PipeLine.h" -#include "MaterialBuffer.h" -#include "PL_RTSPClient.h" -#include "PL_RTSPServer.h" -#include "PL_H264Decoder.h" -#include "PL_H264Encoder.h" -#include "PL_AVFrameYUV420.h" -#include "PL_AVFrameBGRA.h" -#include "PL_Queue.h" -#include "PL_Scale.h" -#include "PL_Fork.h" -#include "PL_Payer.h" -#include "PL_Gainer.h" -#include "PL_SensetimeFaceTrack.h" -#include "PL_SensetimeFaceDetect.h" -#include "PL_DlibFaceTrack.h" - -#include "PipeLinePool.h" +#include <MaterialBuffer.h> +#include <logger.h> #include "ev_server.h" #include "ev_proto.h" #include "face_daemon_proto.h" +#include "sample_face_search.h" +#include "STFaceCache.h" +#include "PbFaceList.pb.h" -#include "SensetimeFaceAPIWrapper/src/FaceDBPool.h" -#include "SensetimeFaceAPIWrapper/src/faceAPI.h" +#include <signal.h> -#include "logger.h" +#include <sstream> +#include <iostream> -template<typename TPoolPtr, typename TPoolElem> -struct PoolElemLocker -{ - TPoolPtr pool; - TPoolElem elem; - PoolElemLocker(TPoolPtr _pool, TPoolElem _elem) : pool(_pool), elem(_elem) - { - - } - ~PoolElemLocker() - { - pool->release(elem); - pool->notify_free(); - } -}; +#define WRAPPER_TEXT(x) "\"" << x << "\"" -template<typename TArrayPtr> -struct ArrayDeleter -{ - TArrayPtr array; - ArrayDeleter(TArrayPtr _array) : array(_array) - { - - } - ~ArrayDeleter() - { - delete[] array; - } -}; - -PipeLinePool g_PipeLinePool; - -FaceDBPool g_faceAPIPool;//#todo config +Logger g_logger(std::cout); +STFaceCache g_STFaceCache("/opt/FaceServer/stfacedb"); evclient_proc_t evclient_proc; -bool send_SensetimeFaceDetectResult(EVClientStub& client, PipeMaterial& lastPm) +void _sigint(int sign_no) { - //if (lastPm.type != PipeMaterial::PMT_PM_LIST) + server_stop(); +} - //PipeMaterial& facePM = ((PipeMaterial*)(lastPm.buffer))[1]; - //st_ff_vect_t& faceFeatures = *((st_ff_vect_t*)facePM.buffer); - //LOG_NOTICE << "faceFeatures " << faceFeatures.size() << std::endl; - //#todo send result packet - - if (lastPm.buffer == nullptr || lastPm.type != PipeMaterial::PMT_BYTES || lastPm.buffSize != sizeof(SensetimeFaceDetectResult)) +bool send_SensetimeFaceDetectResultJson(EVClientStub& client, const fdr_vec_t& result, int ret = 0) +{ + std::stringstream ss; + ss << "{" << 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) { - LOG_WARN << "pm not available" << std::endl; - ev_send_status_packet(client, EVPStatus::EVPS_INTERNAL_ERROR); - return false; + ss << "[" << WRAPPER_TEXT(iter->db_id) << "," << WRAPPER_TEXT(iter->st_id) << "]"; + if (iter != std::prev(result.end())) + ss << ","; } - - const SensetimeFaceDetectResult* result = (const SensetimeFaceDetectResult*)lastPm.buffer; - - client.sendBuffSize = sizeof(EVPHeader)+sizeof(SensetimeFaceDetectResult); - client.sendBuff = new uint8_t[client.sendBuffSize]; + ss << "]" << LOG_ENDL; + ss << "}"; + + std::string output(ss.str());//#todo avoid copy + client.sendBuffSize = output.size(); + client.sendBuff = new uint8_t[output.size() + 1]; + strcpy((char*)client.sendBuff, output.c_str()); client.deleteSendBuff = true; - EVPHeader* evpHeader = new (client.sendBuff) EVPHeader; - evpHeader->cmd = FaceDaemonCommand::FDC_SENSETIMEFACEDETECT_RESULT; - evpHeader->size = client.sendBuffSize; - - SensetimeFaceDetectResult* evpSub = new (client.sendBuff + sizeof(EVPHeader)) SensetimeFaceDetectResult; - evpSub->school_id = result->school_id; - evpSub->st_id = result->st_id; - + LOG_DEBUG << (char*)client.sendBuff << LOG_ENDL; + return true; } -bool ev_proc_SensetimeFaceDetect(EVClientStub& client) +bool ev_proc_SensetimeFaceDetectPB(EVClientStub& client) { - //#test send 01000B0000004142434445 - //LOG_DEBUG << "cmd=" << evpHeader->cmd << ", size=" << evpHeader->size << ", \t" << (char*)(evpHeader + sizeof(EVPHeader)) << std::endl; + //#test send //00038300FE4B0000+pb + //EVPHeader* evpHeader = (EVPHeader*)client.recvBuff; + //LOG_DEBUG << "cmd=" << evpHeader->cmd << ", size=" << evpHeader->size << ", \t" << (char*)(evpHeader + sizeof(EVPHeader)) << LOG_ENDL; //return true; - FDP_Image* fdpImage = (FDP_Image*)(client.recvBuff + sizeof(EVPHeader)); - - FaceDB* _faceDB = g_faceAPIPool.get_free(fdpImage->school_id); - if (_faceDB == nullptr) - { - LOG_WARN << "can't get face db" << std::endl; - ev_send_status_packet(client, EVPStatus::EVPS_PARAMETER_ERROR); - return false; - } + EVPHeader* evpHeader = (EVPHeader*)client.recvBuff; + FDP_FaceDetectPB* fdpFaceDetectPB = (FDP_FaceDetectPB*)(client.recvBuff + sizeof(EVPHeader)); + fdpFaceDetectPB->ntoh(); - PoolElemLocker<FaceDBPool*, int> _lock_faceAPI(&g_faceAPIPool, fdpImage->school_id); + PbFaceList pbFaceList; + pbFaceList.ParseFromArray(client.recvBuff + sizeof(EVPHeader) + sizeof(FDP_FaceDetectPB), evpHeader->size - sizeof(EVPHeader) - sizeof(FDP_FaceDetectPB)); + LOGP(DEBUG, "pbFaceList: magic=%u, image_count=%u, src_width=%u, src_height=%u", + pbFaceList.magic(), pbFaceList.image_count(), pbFaceList.src_width(), pbFaceList.src_height()); - PipeLine* pipeLine = g_PipeLinePool.get_free(); - if (pipeLine == nullptr) - { - LOG_WARN << "can't get free pipeline" << std::endl; - ev_send_status_packet(client, EVPStatus::EVPS_INTERNAL_ERROR); - return false; - } + fdr_vec_t result; - PoolElemLocker<PipeLinePool*, PipeLine*> _lock_pipeLine(&g_PipeLinePool, pipeLine); - - // fill - SensetimeFaceDetectDbFrame dbFrame; - dbFrame.type = (MB_Frame::MBFType)(fdpImage->mb_type); - dbFrame.buffSize = client.recvBuffSize - sizeof(EVPHeader) - sizeof(FDP_Image); - dbFrame.buffer = new uint8_t[dbFrame.buffSize]; - ArrayDeleter<uint8_t*> _del_img((uint8_t*)dbFrame.buffer); - memcpy(dbFrame.buffer, fdpImage->buff, dbFrame.buffSize); - dbFrame.width = fdpImage->width; - dbFrame.height = fdpImage->height; - dbFrame.school_id = fdpImage->school_id; - dbFrame._faceDB = _faceDB; - - PipeMaterial pm; - pm.type = PipeMaterial::PMT_FRAME; - pm.buffer = &dbFrame; - pm.buffSize = 0; - - PipeLineElem* plElem = pipeLine->pipe(&pm); - if (! pipeLine->check_pipe_complete(plElem)) + for(int i = 0; i < pbFaceList.image_count(); i++) { - LOG_WARN << "pipeline not complete" << std::endl; - ev_send_status_packet(client, EVPStatus::EVPS_INTERNAL_ERROR); - return false; + const PbFaceList_FaceListImage& pbFaceListImage = pbFaceList.images(i); + LOGP(DEBUG, "\tpbFaceList %d: idx=%u, size=%u, type=%u, width=%u, height=%u, top_left_x=%u, top_left_y=%u", + i, pbFaceListImage.idx(), pbFaceListImage.size(), pbFaceListImage.type(), pbFaceListImage.width(), pbFaceListImage.height(), pbFaceListImage.top_left_x(), pbFaceListImage.top_left_y()); + + //#test + //char imgfn[100 * 1024]; + //sprintf(imgfn, "PB_%d_%d.yuv", 0, i); + // + //FILE * pFile = fopen(imgfn, "wb"); + const std::string* img(*pbFaceListImage.img().data()); + //fwrite(img->data(), sizeof(char), img->size(), pFile); + //fclose(pFile); + //pFile = nullptr; + + STFaceImage stimg; + stimg.db_id = fdpFaceDetectPB->db_id; + stimg.mb_type = pbFaceListImage.type(); + stimg.width = pbFaceListImage.width(); + stimg.height = pbFaceListImage.height(); + stimg.size = img->size(); + stimg.buff = (const uint8_t*)img->data(); + result.push_back(g_STFaceCache.detect(stimg)); } - - if (!plElem->gain(pm)) - { - LOG_WARN << "pipeline gain error" << std::endl; - ev_send_status_packet(client, EVPStatus::EVPS_INTERNAL_ERROR); - return false; - } - - // can not release pipleline unless pm not used - send_SensetimeFaceDetectResult(client, pm); - return false; + //#test + //result.push_back(FDP_FaceDetectResult(-1,123)); + //result.push_back(FDP_FaceDetectResult(2,456)); + //result.push_back(FDP_FaceDetectResult(0,0)); + + return send_SensetimeFaceDetectResultJson(client, result); } -bool ev_proc(EVClientStub& client) +bool ev_proc_SensetimeFaceDetectSave(EVClientStub& client) { + EVPHeader* evpHeader = (EVPHeader*)client.recvBuff; + FDP_Image* fdpImage = (FDP_Image*)(client.recvBuff + sizeof(EVPHeader)); + fdpImage->ntoh(); + + 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; + + LOGP(DEBUG, "stfaceImg db_id=%d, mb_type=%d, width=%d, height=%d, size=%d", + (int)stfaceImg.db_id, (int)stfaceImg.mb_type, (int)stfaceImg.width, (int)stfaceImg.height, (int)stfaceImg.size); + + //char imgfn[100 * 1024]; + //static int i = 0; + //sprintf(imgfn, "IMG_%d_%d_w%d_h%d.rgb565", stfaceImg.db_id, ++i, stfaceImg.width, stfaceImg.height); + //FILE * pFile = fopen(imgfn, "wb"); + //fwrite(stfaceImg.buff, sizeof(char), stfaceImg.size, pFile); + //fclose(pFile); + //pFile = nullptr; + + 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; + EVPHeader* evpHeader = (EVPHeader*)client.recvBuff; if (evpHeader->size != client.recvBuffSize) { - LOG_WARN << "Truncated buffer " << (evpHeader->size - client.recvBuffSize) << " bytes" << std::endl; + LOG_WARN << "Truncated buffer " << (evpHeader->size - client.recvBuffSize) << " bytes" << LOG_ENDL; return false; } switch(evpHeader->cmd) { - case EVPCommand::EVPC_USER_DEFINE + 1: - return ev_proc_SensetimeFaceDetect(client); + case FaceDaemonCommand::FDC_SENSETIMEFACEDETECT_PB: + //000383000800000001 + return ev_proc_SensetimeFaceDetectPB(client); break; default: - LOG_WARN << "Unknown command" << std::endl; - ev_send_status_packet(client, EVPStatus::EVPS_PARAMETER_ERROR); + 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_rawbin(EVClientStub& client) +{ + LOG_DEBUG << "ev_dispatcher_proto_rawbin" << 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; + + 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->proto) + { + 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); return false; break; } @@ -188,46 +224,27 @@ int main(int argc, char** argv) { - initLogger(LV_DEBUG); + g_logger.set_level(VERBOSE); - PipeLine::register_global_elem_creator("PL_SensetimeFaceTrack", create_PL_SensetimeFaceTrack); - PipeLine::register_global_elem_creator("PL_Gainer", create_PL_Gainer); - - g_PipeLinePool = new PipeLinePool(true); - - for (int i = 0; i < 5; i++) - { - PipeLine* pipeLine = new PipeLine; + signal(SIGINT, _sigint); - { - PL_Payer_Config config; - config.copyData = true;//#todo false - PL_Gainer* ple = (PL_Gainer*)pipeLine->push_elem("PL_Gainer"); - bool ret = ple->init(&config); - if (!ret) - { - LOG_ERROR << "ple init error" << std::endl; - exit(EXIT_FAILURE); - } - } - - { - SensetimeFaceTrackConfig config; - config.draw_face_rect = false; - config.draw_face_feature_point = false; - config.generate_face_feature = true; - PL_SensetimeFaceTrack* ple = (PL_SensetimeFaceTrack*)pipeLine->push_elem("PL_SensetimeFaceTrack"); - bool ret = ple->init(&config); - if (!ret) - { - LOG_ERROR << "ple init error" << std::endl; - exit(EXIT_FAILURE); - } - } - - g_PipeLinePool.manage(pipeLine); + if (!g_STFaceCache.init()) + { + LOG_WARN << "g_STFaceCache.init return false" << LOG_ENDL; + return EXIT_FAILURE; } - evclient_proc = ev_proc; - return server_main(argc, argv); + if (!g_STFaceCache.load_dbs()) + { + LOG_WARN << "g_STFaceCache.load_dbs return false" << LOG_ENDL; + return EXIT_FAILURE; + } + + evclient_proc = ev_dispatcher_proto; + int ec = server_main(argc, argv); + + g_STFaceCache.close_dbs(); + g_STFaceCache.finit(); + + return ec; } -- Gitblit v1.8.0