提交 2c0181b7 authored 作者: blu's avatar blu

recording

上级 298fb4fe
......@@ -46,7 +46,7 @@ payload: JSON
```
topic: evcamera/v1.0/res_rep
qos:2
retian: true
retian: false
payload: JSON
```
......@@ -90,7 +90,12 @@ payload:
"features": {
"motion": {
"enable": 1,
"region": {"min": [0.5,0.5], "max": [0.75, 0.75]},
"region": {
"minX": 0.1,
"minY": 0.1,
"maxX": 0.9,
"maxY": 0.9
},
"level": 3
},
"record":{
......@@ -119,11 +124,13 @@ payload:
"rid": "<random_str>",
"sn": "A000000Z",
"data": {
{
"op": "replace",
"path": "/features/ai/face_thresh",
"value": 0.5
}
[
{
"op": "replace",
"path": "/features/ai/face_thresh",
"value": 0.5
}
]
}
```
......@@ -147,8 +154,13 @@ payload:
"features": {
"motion": {
"enable": 1,
"region": {"min": [0.5,0.5], "max": [0.75, 0.75]},
"level": 3 // 1 - 6
"level": 3, // 1 - 6
"region":{
"minX": 0.1,
"minY": 0.1,
"maxX": 0.9,
"maxY": 0.9
}
},
"record":{
"enable": 1,
......@@ -158,7 +170,13 @@ payload:
"ai":{
"enable": 1,
"face_thresh": 0.75, // 0 - 1
"human_thresh": 0.63 // 0 - 1
"human_thresh": 0.63, // 0 - 1
"region":{
"minX": 0.1,
"minY": 0.1,
"maxX": 0.9,
"maxY": 0.9
}
}
}
}
......
......@@ -8,12 +8,12 @@ if("${VENDOR}" STREQUAL "")
set(SHAREDINCS "${CMAKE_SOURCE_DIR}/../include")
endif()
#set_source_files_properties(main.cc PROPERTIES COMPILE_FLAGS -g)
set(COMM_INC_DIR ${VENDOR}/shared/include ${VENDOR}/hi3518/include ${SHAREDINCS})
set(COMMON_LIB_DIR ${VENDOR}/shared/lib ${VENDOR}/hi3518/lib)
list(APPEND COMMON_LIBS fmt m dl pthread XmMaQue securec XmSns_50H20AI uv)
list(APPEND COMMON_LIBS fmt m dl pthread)
list(APPEND XM_LIBS XmMaQue securec XmSns_50H20AI)
include_directories(${CMAKE_SOURCE_DIR} ${PROJECT_SOURCE_DIR} ${COMM_INC_DIR})
link_directories(${COMMON_LIB_DIR} /root/xiongmai/arm-himix100-linux/target/lib/)
......@@ -27,10 +27,8 @@ add_library(motion STATIC motion.cc)
add_executable(test_mqtt test_mqtt.cc)
target_link_libraries(test_mqtt PUBLIC paho-mqtt3a fmt m dl pthread)
add_executable(test_jsoncons test_jsoncons.cc)
add_executable(evcamera main.cc)
target_link_libraries(evcamera PUBLIC ntp paho-mqtt3a tcp_client smart motion ${COMMON_LIBS})
target_link_libraries(evcamera PUBLIC ntp paho-mqtt3a tcp_client smart motion zmq ${COMMON_LIBS} ${XM_LIBS})
add_executable(ntp_client ntp_main.cc)
target_link_libraries(ntp_client PUBLIC ntp)
差异被折叠。
差异被折叠。
......@@ -22,7 +22,7 @@ int getNtpTime(time_t * txTm)
{
int socket_ = 0, n = 0, rv = 0; // Socket file descriptor and the n return result from writing/reading from the socket.
int portno = 123; // NTP UDP port number.
const char* host_name = "cn.pool.ntp.org"; // NTP server host-name.
const char* host_name = "time.nist.gov"; // NTP server host-name.
// Structure that defines the 48 byte NTP packet protocol.
typedef struct {
......
......@@ -33,6 +33,23 @@ int raw_connect(std::string host, std::string port, int *socket_, int recv_timeo
last_errno = errno;
continue;
}
struct timeval timeout;
timeout.tv_sec = recv_timeout;
timeout.tv_usec = 0;
if (setsockopt (*socket_, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)) < 0) {
spdlog::error("setsockopt SO_RCVTIMEO failed");
return -1;
}
timeout.tv_sec = send_timeout;
if (setsockopt (*socket_, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout)) < 0) {
spdlog::error("setsockopt SO_SNDTIMEO failed");
return -1;
}
rv = ::connect(*socket_, rp->ai_addr, rp->ai_addrlen);
if (rv == 0) {
auto addr = (struct sockaddr_in *)rp->ai_addr;
......@@ -50,21 +67,6 @@ int raw_connect(std::string host, std::string port, int *socket_, int recv_timeo
rv = -1;
}
}
struct timeval timeout;
timeout.tv_sec = recv_timeout;
timeout.tv_usec = 0;
if (setsockopt (*socket_, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)) < 0) {
spdlog::error("setsockopt SO_RCVTIMEO failed");
return -1;
}
timeout.tv_sec = send_timeout;
if (setsockopt (*socket_, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout)) < 0) {
spdlog::error("setsockopt SO_SNDTIMEO failed");
return -1;
}
::freeaddrinfo(addrinfo_result);
return rv;
......
......@@ -42,15 +42,15 @@ XM_S32 MaQue_Demo_Mem_setLength(XM_HANDLE handle, XM_U32 len)
XM_S32 MaQue_Demo_Mem_alloc(XM_HANDLE *pHandle, MaQueMemAllocParam_s *pstAllocParam)
{
pthread_mutex_lock(&g_mutexMem);
DemoMemory_s *pstMem = NULL;
pstMem = (DemoMemory_s *)malloc(sizeof(DemoMemory_s));
memset(pstMem, 0, sizeof(*pstMem));
if (!pstMem) {
spdlog::error("malloc failed!");
pthread_mutex_unlock(&g_mutexMem);
return -1;
}
memset(pstMem, 0, sizeof(*pstMem));
pthread_mutex_lock(&g_mutexMem);
switch(pstAllocParam->eMemType) {
case MAQUE_MEM_TYPE_VIDEO_ENC:
......@@ -61,7 +61,6 @@ XM_S32 MaQue_Demo_Mem_alloc(XM_HANDLE *pHandle, MaQueMemAllocParam_s *pstAllocPa
XM_U8 * raw = (XM_U8 *)malloc(pstAllocParam->nBufSize + sizeof(evpacket_t));
pstMem->pBuffer = raw + sizeof(evpacket_t);
//printf("malloc. raw: %08X, shifted: %08X\n", (uint32_t)raw, (uint32_t)pstMem->pBuffer);
if (raw) {
pstMem->index = 0xff;
pstMem->nBufSize = pstAllocParam->nBufSize;
......
......@@ -12,31 +12,31 @@ extern "C"
static int smartCnt = 0;
XM_S32 MaQue_JpegEnc_getFrame_callback (XM_VOID *pUserArg, MaQueSmartJpegFrame_s *pstJpegFrame)
{
if(smartCnt > 0) {
smartCnt--;
return 0;
}
smartCnt = 1000;
XM_CHAR acFile[256] = {0};
FILE *pFile;
static XM_S32 jpeg_cnt = 0;
// if(smartCnt > 0) {
// smartCnt--;
// return 0;
// }
// smartCnt = 1000;
// XM_CHAR acFile[256] = {0};
// FILE *pFile;
// static XM_S32 jpeg_cnt = 0;
printf("aClassName[%s] idx = %d, toltal = %d\n", pstJpegFrame->aClassName, pstJpegFrame->nIndex, pstJpegFrame->nToltalJpeg);
if (jpeg_cnt < 30000) {
sprintf(acFile, "ai/snap_%d.jpg", jpeg_cnt);
pFile = fopen(acFile, "wb");
if (pFile == NULL) {
spdlog::error("open file err");
return XM_FAILURE;
}
// if (jpeg_cnt < 30000) {
// sprintf(acFile, "ai/snap_%d.jpg", jpeg_cnt);
// pFile = fopen(acFile, "wb");
// if (pFile == NULL) {
// spdlog::error("open file err");
// return XM_FAILURE;
// }
fwrite(pstJpegFrame->pBuffer, pstJpegFrame->nDataLen, 1, pFile);
fflush(pFile);
// fwrite(pstJpegFrame->pBuffer, pstJpegFrame->nDataLen, 1, pFile);
// fflush(pFile);
fclose(pFile);
jpeg_cnt++;
}
// fclose(pFile);
// jpeg_cnt++;
// }
return XM_SUCCESS;
}
......
......@@ -6,6 +6,12 @@
#include <fstream>
#include <algorithm>
#include <sys/statvfs.h>
#include <mutex>
#include <set>
#include <zmq.h>
#include <string>
#include <spdlog/spdlog.h>
#include <fmt/format.h>
using namespace std;
using namespace jsoncons;
......@@ -52,8 +58,8 @@ const string kMsgSn = "sn";
char hostArr[] = "192.168.55.104";
char portArr[] = "7123";
char *host = hostArr, *port = portArr;
char recFilePathArr[] = "/mnt/sd/record/rec.264";
char *recFilePath = recFilePathArr;
string recFilePath = "/mnt/sd/records/";
const long long TS_2020 = 1577836800000L;
/// topics
string sub_topic = "evcamera/v1.0/request/";
......@@ -79,25 +85,32 @@ bool is_sdcard_avail(char *path = nullptr)
json make_default_config(){
return R"(
{
"sn": "A000000Z",
"vgw": "192.168.55.104:7123",
"mqtt": "admin:vJ3zHqWrHbrqxVMT@evcloudsvc.ilabservice.cloud:11883",
"upload": "evcloudsvc.ilabservice.cloud:10008",
"features": {
"motion": {
"enable": 1,
"region": {"min": [0.35,0.35], "max": [0.65, 0.65]},
"level": 3
},
"record":{
"enable": 1,
"interval": 300,
"duration": 24
"vgw":"evcloudsvc.ilabservice.cloud:7123",
"mqtt":"admin:vJ3zHqWrHbrqxVMT@evcloudsvc.ilabservice.cloud:11883",
"upload":"evcloudsvc.ilabservice.cloud:10010",
"features":{
"push":0,
"motion":{
"enabled":1,
"region":{
"maxX":1,
"maxY":1,
"minX":0,
"minY":0
},
"level":3
},
"recordLen":120,
"ai":{
"enable": 1,
"faceThresh": 0.6,
"humanThresh": 0.6
"enabled":1,
"faceThresh":0.75,
"humanThresh":0.63,
"region":{
"maxX":1,
"maxY":1,
"minX":0,
"minY":0
}
}
}
}
......@@ -119,6 +132,7 @@ void get_mac_addr(char *buf, char *intf = nullptr){
*(buf+ i++) = ::toupper(k);
}
}
*(buf+i) = 0;
}
bool get_sdcard_megabytes(uint64_t &total, uint64_t &free, char* path = nullptr)
......@@ -141,6 +155,228 @@ bool get_sdcard_megabytes(uint64_t &total, uint64_t &free, char* path = nullptr)
return true;
}
template <typename T>
using cb_remove_elem = void(*)(T elem);
template <typename TN>
class OrderedList {
private:
set<TN> list_;
size_t maxSize;
mutex mut;
TN oldestTs;
cb_remove_elem<TN> fn_remove;
unsigned long cntInsert = 0;
public:
OrderedList() = delete;
OrderedList(ssize_t maxSize, cb_remove_elem<TN> fn_remove):maxSize(maxSize), fn_remove(fn_remove){}
void insert(TN elem, cb_remove_elem<TN> fn=nullptr)
{
// list_.insert(lower_bound(list_.begin(), list_.end(), elem), elem);
if(cntInsert % 10 == 0) {
oldestTs = chrono::duration_cast<chrono::milliseconds>(chrono::system_clock::now().time_since_epoch()).count() - 60*2*1000*maxSize;
spdlog::info("record: maxSlices {}, oldestTs {}", maxSize, oldestTs);
}
++cntInsert;
if(elem < oldestTs){
if(fn != nullptr){
(*fn)(elem);
}else if(fn_remove != nullptr){
(*fn_remove)(elem);
}
return;
}
if(list_.size() == 0) {
list_.insert(list_.begin(),elem);
return;
}
auto itr = list_.rbegin();
for(; itr != list_.rend(); itr++) {
if(*itr < elem) {
break;
}
}
if(itr == list_.rbegin() ) {
list_.insert(list_.end(), elem);
}
else {
list_.insert(itr.base(), elem);
}
if(list_.size() > maxSize) {
lock_guard<mutex> lg(mut);
auto ts = *(list_.begin());
list_.erase(list_.begin());
if(fn != nullptr){
(*fn)(ts);
}else if(fn_remove != nullptr){
(*fn_remove)(ts);
}else{
// no callback available
}
// auto baseName = videoFileTs2Name(ts);
// fs::path fname(this->urlOut + "/" + baseName + ".mp4");
// fs::remove(fname);
}
}
set<TN> findByRange(TN tss, TN tse, TN & offsetS, TN &offsetE){
set<TN> ret;
lock_guard<mutex> lg(mut);
if(list_.size() == 0) {
return ret;
}
TN first = *(list_.begin());
auto _it = list_.end();
TN end = *(--_it);
if(tse < first||tss > end) {
spdlog::info("range requested ({}, {}) is not in range existed ({}, {}).", tss, tse, first, end);
return ret;
}
first = end = 0;
int found = 0;
TN last = 0;
auto itr = list_.rbegin();
for(; itr != list_.rend(); itr++) {
if(*itr > tse) {
continue;
}
if(*itr <= tse) {
if(found != 1) {
spdlog::info("\t matched : {}, s:{}, e:{}", *itr, tss, tse);
found = 1;
// check the end offset, not guaranteed
if( itr != list_.rbegin()){
auto t = itr;
last = *(--t);
}
}
ret.insert(*itr);
if(tss >= *itr) {
break;
}
}
}
if(found == 1) {
auto itr = ret.begin();
offsetS = tss - *itr;
if(last != 0) {
offsetE = last - tse;
}
}
return ret;
}
};
/// returns negtive for failure, otherwise success
int setupDealer(void **ctx, void **s, string ident, string addr, int sndQS=0, int timeoutMs = -1) {
int ret = 0;
*ctx = zmq_ctx_new();
*s = zmq_socket(*ctx, ZMQ_DEALER);
ret = 1;
zmq_setsockopt(*s, ZMQ_TCP_KEEPALIVE, &ret, sizeof (ret));
ret = 20;
zmq_setsockopt(*s, ZMQ_TCP_KEEPALIVE_IDLE, &ret, sizeof (ret));
zmq_setsockopt(*s, ZMQ_TCP_KEEPALIVE_INTVL, &ret, sizeof (ret));
ret = 2;
zmq_setsockopt(*s, ZMQ_TCP_KEEPALIVE_CNT, &ret, sizeof (ret));
if(sndQS!=0){
zmq_setsockopt(*s, ZMQ_SNDHWM, &sndQS, sizeof (sndQS));
}
if(timeoutMs != 0) {
if(timeoutMs == -1) {
timeoutMs = 5 *1000;
}
zmq_setsockopt(*s, ZMQ_RCVTIMEO, &timeoutMs, sizeof(timeoutMs));
}
ret = zmq_setsockopt(*s, ZMQ_IDENTITY, ident.c_str(), ident.size());
if(ret < 0) {
zmq_close(*s);
zmq_ctx_destroy(*ctx);
spdlog::debug("{} failed setsockopts ZMQ_ROUTING_ID to {}: {}", ident, addr, zmq_strerror(zmq_errno()));
}else{
ret = zmq_connect(*s, addr.c_str());
if(ret != 0) {
zmq_close(*s);
zmq_ctx_destroy(*ctx);
spdlog::error("{} failed connect dealer: {}", ident, addr);
}
}
return ret;
}
int setupRouter(void **ctx, void **s, string addr, int rcvQS=0){
int ret = 0;
*ctx = zmq_ctx_new();
*s = zmq_socket(*ctx, ZMQ_ROUTER);
ret = 1;
zmq_setsockopt(*s, ZMQ_TCP_KEEPALIVE, &ret, sizeof (ret));
ret = 5;
zmq_setsockopt(*s, ZMQ_TCP_KEEPALIVE_IDLE, &ret, sizeof (ret));
zmq_setsockopt(*s, ZMQ_TCP_KEEPALIVE_INTVL, &ret, sizeof (ret));
ret = 2;
zmq_setsockopt(*s, ZMQ_TCP_KEEPALIVE_CNT, &ret, sizeof (ret));
if(rcvQS !=0) {
zmq_setsockopt(*s, ZMQ_RCVHWM, &rcvQS, sizeof(rcvQS));
}
ret = zmq_bind(*s, addr.c_str());
if(ret < 0) {
spdlog::debug("failed to bind zmq at {} for reason: {}, retrying load configuration...", addr, zmq_strerror(zmq_errno()));
}
return ret;
}
int z_recv_multiple(void *s, vector<uint8_t> &buf, int &frames) {
int64_t more = 1;
size_t more_size = sizeof(more);
int ret = 0;
int cnt = 0;
while(more > 0) {
cnt++;
zmq_msg_t msg;
ret = zmq_msg_init(&msg);
if(ret < 0) {
spdlog::debug("failed to receive multiple msg on zmq_msg_init: {}", zmq_strerror(zmq_errno()));
break;
}
ret = zmq_msg_recv(&msg, s, 0);
if(ret < 0) {
spdlog::debug("z_recv_multiple: {}", zmq_strerror(zmq_errno()));
break;
}
buf.insert(buf.end(), (uint8_t*)zmq_msg_data(&msg), (uint8_t*)zmq_msg_data(&msg)+ret);
zmq_msg_close(&msg);
ret = zmq_getsockopt(s, ZMQ_RCVMORE, &more, &more_size);
if(ret < 0) {
spdlog::debug("z_recv_multiple: {}", zmq_strerror(zmq_errno()));
break;
}
}
if(ret < 0 || (frames != 0 && cnt != frames)) {
spdlog::error("failed to recv msg: {}", ret < 0? zmq_strerror(ret): "invalid frames");
return -1;
}else{
frames = cnt;
}
return 0;
}
}
......
......@@ -11,16 +11,16 @@ endif()
set(COMM_INC_DIR ${VENDOR}/shared/include ${VENDOR}/x64/include ${SHAREDINC})
set(COMMON_LIB_DIR ${VENDOR}/shared/lib ${VENDOR}/x64/lib)
# list(APPEND COMMON_LIBS avformat avdevice avcodec swscale avfilter avutil swresample lzma x264 fmt uv pthread dl m z)
list(APPEND COMM_LIBS fmt uv pthread dl m z)
list(APPEND COMM_LIBS fmt zmq pthread dl m z)
list(APPEND VGW_LIBS avformat avcodec swscale avutil swresample lzma x264)
include_directories(${CMAKE_SOURCE_DIR} ${PROJECT_SOURCE_DIR} ${COMM_INC_DIR})
link_directories(${COMMON_LIB_DIR})
#add_library(mime STATIC mime.c)
#add_library(util STATIC utils.cpp)
add_executable(vgw videogateway.cc)
target_link_libraries(vgw PUBLIC ${VGW_LIBS} ${COMM_LIBS})
add_executable(agent agent.cc)
target_link_libraries(agent PUBLIC paho-mqtt3a ${COMM_LIBS})
# add_executable(test_mqtt test_mqtt_rd.cc)
# target_link_libraries(test_mqtt PUBLIC ${COMM_LIBS})
# add_executable(agent agent.cc)
# target_link_libraries(agent PUBLIC paho-mqtt3a ${COMM_LIBS})
差异被折叠。
libzmq @ a84ffa12
Subproject commit 2aa87c94cc8be57a878e2e3c6a0551e8fdf6c886
Subproject commit a84ffa12b2eb3569ced199660bac5ad128bff1f0
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论