From e5cff5a3ef373a5090f45cd1dfb0b85d9c851d5d Mon Sep 17 00:00:00 2001
From: FuJuntang <strongtiger_001@163.com>
Date: 星期三, 06 七月 2022 10:04:09 +0800
Subject: [PATCH] Add video recorder and playback support.
---
service/ptz/ptz.c | 164 ++---
service/capabilities/capa.c | 43 +
test/av_test/av_test.c | 66 ++
service/av_demux/video_conv.sh | 58 ++
service/ptz/ptz.h | 24
Makefile | 11
test/probe_test/Makefile | 5
service/av_demux/av_demux.h | 100 +++
comm/proto_comm.c | 146 +++-
service/av_demux/av_demux.c | 810 +++++++++++++++++++++++++++++++
test/ptz_test/ptz_test.c | 2
comm/proto_dbg.h | 3
test/av_test/Makefile | 52 ++
test/Makefile.inc | 5
comm/proto_comm.h | 46 +
test/ptz_test/Makefile | 5
16 files changed, 1,373 insertions(+), 167 deletions(-)
diff --git a/Makefile b/Makefile
index 593f2b1..a9a81be 100644
--- a/Makefile
+++ b/Makefile
@@ -8,6 +8,8 @@
RM := rm
CFLAGS += -c -Wall -DWITH_DOM -DWITH_NONAMESPACES -DWITH_OPENSSL
+CFLAGS += -DPROTOBUF_USS_DLLS
+CFLAGS += -fPIC -Wunused-function
SOURCES_CORE += \
core/soapC.c \
@@ -25,7 +27,8 @@
service/probe/probe.c \
service/deviceinfo/dev_info.c \
service/capabilities/capa.c \
- service/ptz/ptz.c
+ service/ptz/ptz.c \
+ service/av_demux/av_demux.c
SOURCES_COMM += \
comm/proto_dbg.c \
@@ -35,6 +38,7 @@
OBJECTS_ONVIF_SRVS := $(patsubst %.c,$(TEMPDIR)%.o,$(filter %.c, $(SOURCES_SRVS)))
OBJECTS_ONVIF_COMM := $(patsubst %.c,$(TEMPDIR)%.o,$(filter %.c, $(SOURCES_COMM)))
+FFMPEG_DIR = thirdparty/ffmpeg
OPENSSL_DIR = thirdparty/openssl
TARGET_LIB = libonvif_std.so
@@ -42,18 +46,21 @@
INCLUDE += -Icore/ \
-Icomm/ \
-Iservice \
+ -I$(FFMPEG_DIR)/include \
-I$(OPENSSL_DIR)/include
CFLAGS += $(INCLUDE)
CFLAGS += -Wno-unused
+LDFLAGS += -L$(FFMPEG_DIR)/lib
LDFLAGS += -L$(OPENSSL_DIR)/lib
+LDFLAGS += -Lthirdparty
LDLIBS += -lavcodec -lavdevice -lavfilter -lavformat \
-lavutil -lswresample -lswscale
LDLIBS += -lcrypto -lssl -lpthread -ldl -lrt -lm
CFLAGS += -fPIC
-DIRS_TEST = test/probe_test test/ptz_test
+DIRS_TEST = test/probe_test test/ptz_test test/av_test
%.o: $(SOURCES_CORE)/%.cpp $(SOURCES_SRVS)/%.cpp $(SOURCES_COMM)/%.cpp
@echo " CPP " $@;
diff --git a/comm/proto_comm.c b/comm/proto_comm.c
index df226ca..21c3c26 100644
--- a/comm/proto_comm.c
+++ b/comm/proto_comm.c
@@ -1,73 +1,131 @@
-
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
+#include <time.h>
+#include <signal.h>
+
#include "proto_comm.h"
#include "proto_dbg.h"
+int timer_init(timer_t *timer_index, void (*timer_handler)(union sigval para)) {
+ struct sigevent event;
+ timer_t timer;
+ int ret;
+
+ memset(&event, 0x00, sizeof(event));
+ event.sigev_value.sival_int = ENABLE;
+ event.sigev_value.sival_ptr = NULL;
+ event.sigev_notify = SIGEV_THREAD;
+ event.sigev_notify_function = timer_handler;
+
+ ret = timer_create(CLOCK_REALTIME, &event, &timer);
+ if (ret) {
+ return -1;
+ }
+
+ if (timer_index != NULL) {
+ *timer_index = timer;
+ }
+
+ return 0;
+}
+
+int timer_start(timer_t timer_index, int sec) {
+ int ret;
+ struct itimerspec ts;
+
+ ts.it_interval.tv_sec = 0;
+ ts.it_interval.tv_nsec = 0;
+ ts.it_value.tv_sec = sec;
+ ts.it_value.tv_nsec = 0;
+ ret = timer_settime(timer_index, 0, &ts, NULL);
+ if (ret) {
+ return -1;
+ }
+
+ return ret;
+}
+
+int timer_stop(timer_t timer_index) {
+
+ int ret = timer_start(timer_index, 0);
+
+ return ret;
+}
+
+int timer_destroy(timer_t timer_index) {
+ int ret;
+
+ ret = timer_delete(timer_index);
+
+ return ret;
+}
+
void soap_perror(struct soap *soap, const char *str)
{
- if (NULL == str) {
- SOAP_DBGERR("[soap] error: %d, %s, %s\n", soap->error, *soap_faultcode(soap), *soap_faultstring(soap));
- } else {
- SOAP_DBGERR("[soap] %s error: %d, %s, %s\n", str, soap->error, *soap_faultcode(soap), *soap_faultstring(soap));
- }
- return;
+ if (NULL == str) {
+ SOAP_DBGERR("[soap] error: %d, %s, %s\n", soap->error, *soap_faultcode(soap), *soap_faultstring(soap));
+ } else {
+ SOAP_DBGERR("[soap] %s error: %d, %s, %s\n", str, soap->error, *soap_faultcode(soap), *soap_faultstring(soap));
+ }
+
+ return;
}
void* proto_soap_malloc(struct soap *soap, unsigned int n)
{
- void *p = NULL;
+ void *p = NULL;
- if (n > 0) {
- p = soap_malloc(soap, n);
- SOAP_ASSERT(NULL != p);
- memset(p, 0x00 ,n);
- }
- return p;
+ if (n > 0) {
+ p = soap_malloc(soap, n);
+ SOAP_ASSERT(NULL != p);
+ memset(p, 0x00 ,n);
+ }
+
+ return p;
}
struct soap *proto_soap_new(int timeout)
{
- struct soap *soap = NULL; // soap环境变量
+ struct soap *soap = NULL;
- SOAP_ASSERT(NULL != (soap = soap_new()));
+ SOAP_ASSERT(NULL != (soap = soap_new()));
- soap_set_namespaces(soap, namespaces); // 设置soap的namespaces
- soap->recv_timeout = timeout;
- soap->send_timeout = timeout;
- soap->connect_timeout = timeout;
+ soap_set_namespaces(soap, namespaces);
+ soap->recv_timeout = timeout;
+ soap->send_timeout = timeout;
+ soap->connect_timeout = timeout;
#if defined(__linux__) || defined(__linux)
- soap->socket_flags = MSG_NOSIGNAL;
+ soap->socket_flags = MSG_NOSIGNAL;
#endif
- soap_set_mode(soap, SOAP_C_UTFSTRING);
+ soap_set_mode(soap, SOAP_C_UTFSTRING);
- return soap;
+ return soap;
}
void proto_soap_delete(struct soap *soap)
{
- soap_destroy(soap); // remove deserialized class instances (C++ only)
- soap_end(soap); // Clean up deserialized data (except class instances) and temporary data
- soap_done(soap); // Reset, close communications, and remove callbacks
- soap_free(soap); // Reset and deallocate the context created with soap_new or soap_copy
+ soap_destroy(soap); // remove deserialized class instances (C++ only)
+ soap_end(soap); // Clean up deserialized data (except class instances) and temporary data
+ soap_done(soap); // Reset, close communications, and remove callbacks
+ soap_free(soap); // Reset and deallocate the context created with soap_new or soap_copy
}
int proto_SetAuthInfo(struct soap *soap, const char *username, const char *password)
{
- int result = 0;
+ int result = 0;
- SOAP_ASSERT(NULL != username);
- SOAP_ASSERT(NULL != password);
+ SOAP_ASSERT(NULL != username);
+ SOAP_ASSERT(NULL != password);
- result = soap_wsse_add_UsernameTokenDigest(soap, NULL, username, password);
- SOAP_CHECK_ERROR(result, soap, "add_UsernameTokenDigest");
+ result = soap_wsse_add_UsernameTokenDigest(soap, NULL, username, password);
+ SOAP_CHECK_ERROR(result, soap, "add_UsernameTokenDigest");
EXIT:
- return result;
+ return result;
}
float para_check(float data)
@@ -85,11 +143,6 @@
return ret;
}
-/************************************************************************
- *初始化soap描述消息头
-
- *在本函数内部通过proto_soap_malloc分配的内存,将在proto_soap_delete中被释放
-************************************************************************/
void proto_init_header(struct soap *soap)
{
struct SOAP_ENV__Header *header = NULL;
@@ -109,27 +162,22 @@
return;
}
-/************************************************************************
- *初始化探测设备的范围和类型
-
- *在本函数内部通过proto_soap_malloc分配的内存,将在proto_soap_delete中被释放
-************************************************************************/
void proto_init_ProbeType(struct soap *soap, struct wsdd__ProbeType *probe)
{
- struct wsdd__ScopesType *scope = NULL; // 用于描述查找哪类的Web服务
+ struct wsdd__ScopesType *scope = NULL;
SOAP_ASSERT(NULL != soap);
SOAP_ASSERT(NULL != probe);
scope = (struct wsdd__ScopesType *)proto_soap_malloc(soap, sizeof(struct wsdd__ScopesType));
- soap_default_wsdd__ScopesType(soap, scope); // 设置寻找设备的范围
+ soap_default_wsdd__ScopesType(soap, scope);
scope->__item = (char*)proto_soap_malloc(soap, strlen(SOAP_ITEM) + 1);
strcpy(scope->__item, SOAP_ITEM);
memset(probe, 0x00, sizeof(struct wsdd__ProbeType));
soap_default_wsdd__ProbeType(soap, probe);
probe->Scopes = scope;
- probe->Types = (char*)proto_soap_malloc(soap, strlen(SOAP_TYPES) + 1); // 设置寻找设备的类型
+ probe->Types = (char*)proto_soap_malloc(soap, strlen(SOAP_TYPES) + 1);
strcpy(probe->Types, SOAP_TYPES);
return;
@@ -139,7 +187,7 @@
*rtsp://100.100.100.140:554/av0_0
*rtsp://username:password@100.100.100.140:554/av0_0
************************************************************************/
-int make_uri_withauth(char *src_uri, char *username, char *password, char *dest_uri, unsigned int size_dest_uri)
+int bridge_uri(char *src_uri, const char *username, const char *password, char *dest_uri, unsigned int size_dest_uri)
{
int result = 0;
unsigned int needBufSize = 0;
@@ -150,14 +198,14 @@
SOAP_ASSERT(NULL != dest_uri);
memset(dest_uri, 0x00, size_dest_uri);
- needBufSize = strlen(src_uri) + strlen(username) + strlen(password) + 3; // 检查缓存是否足够,包括‘:’和‘@’和字符串结束符
+ needBufSize = strlen(src_uri) + strlen(username) + strlen(password) + 3; //check buf size with character ‘:’ and ‘@'
if (size_dest_uri < needBufSize) {
SOAP_DBGERR("dest uri buf size is not enough.\n");
result = -1;
goto EXIT;
}
- if (0 == strlen(username) && 0 == strlen(password)) { // 生成新的uri地址
+ if (0 == strlen(username) && 0 == strlen(password)) {
strcpy(dest_uri, src_uri);
} else {
char *p = strstr(src_uri, "//");
diff --git a/comm/proto_comm.h b/comm/proto_comm.h
index 9ca7239..97f3a0b 100644
--- a/comm/proto_comm.h
+++ b/comm/proto_comm.h
@@ -8,6 +8,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
+#include <time.h>
+#include <signal.h>
+
#include "soapH.h"
#include "soapStub.h"
#include "wsaapi.h"
@@ -24,6 +27,10 @@
#define min(a,b) (((a) < (b)) ? (a) : (b))
#endif
+#define WT_TIME 5
+#define STOP_WT_TIME 3
+#define WT_MAX_TIME (60 * 20)
+
#define SOAP_ASSERT assert
#define SOAP_DBGERR printf
@@ -33,27 +40,46 @@
#define SOAP_DBGLOG
#endif
+#define USERNAME "On_admin"
+#define PASSWORD "a12345678"
+
#define SOAP_TO "urn:schemas-xmlsoap-org:ws:2005:04:discovery"
#define SOAP_ACTION "http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe"
#define SOAP_MCAST_ADDR "soap.udp://239.255.255.250:3702"
-#define SOAP_ITEM "" // 寻找的设备范围
-#define SOAP_TYPES "dn:NetworkVideoTransmitter" // 寻找的设备类型
+#define SOAP_ITEM ""
+#define SOAP_TYPES "dn:NetworkVideoTransmitter" //device type
+
+#define ADDR_PREFIX "http://"
+#define ADDR_LAST "/"
+
+#define NAME_BRIDGE "_"
+#define NAME_DOT "."
+#define NAME_MID "-"
#define SOAP_SOCK_TIMEOUT (10) //sec
+
+#define TRUE 1
+#define FALSE 0
+
+#define ENABLE 0
+#define DISABLE 1
#define PARA_MIN (-1)
#define PARA_MAX (1)
-#define PROTO_ADDRESS_SIZE (128) // URI地址长度
-#define PROTO_TOKEN_SIZE (65) // token长度
+#define PROTO_ADDRESS_SIZE (128)
+#define PROTO_TOKEN_SIZE (65) //token size
+#define PTOTO_ADDRESS_ADD (65)
-/* 视频编码器配置信息 */
+#define MAX_BUF_SIZE 600
+
+/*video encoder configurations */
struct tagVideoEncoderConfiguration
{
- char token[PROTO_TOKEN_SIZE]; // 唯一标识该视频编码器的令牌字符串
- int Width; // 分辨率
+ char token[PROTO_TOKEN_SIZE]; //video token
+ int Width; //resolution
int Height;
};
@@ -78,6 +104,10 @@
} \
} while (0)
+int timer_init(timer_t *timer_index, void (*timer_handler)(union sigval para));
+int timer_start(timer_t timer_index, int sec);
+int timer_stop(timer_t timer_index);
+int timer_destroy(timer_t timer_index);
void soap_perror(struct soap *soap, const char *str);
void * proto_soap_malloc(struct soap *soap, unsigned int n);
@@ -89,7 +119,7 @@
void proto_init_ProbeType(struct soap *soap, struct wsdd__ProbeType *probe);
float para_check(float data);
-int make_uri_withauth(char *src_uri, char *username, char *password, char *dest_uri, unsigned int size_dest_uri);
+int bridge_uri(char *src_uri, const char *username, const char *password, char *dest_uri, unsigned int size_dest_uri);
int soap_wsse_add_UsernameTokenDigest(struct soap *soap, const char *id, const char *username, const char *password);
int proto_GetDeviceInformation(const char *DeviceXAddr, const char *username, const char *passwd);
diff --git a/comm/proto_dbg.h b/comm/proto_dbg.h
index 5858a5f..f001b86 100644
--- a/comm/proto_dbg.h
+++ b/comm/proto_dbg.h
@@ -22,7 +22,6 @@
};
#ifdef PROTO_DEBUG
-
void dump__wsdd__ProbeMatches(struct __wsdd__ProbeMatches *rep);
void dump__GetPresetsResponse(struct _tptz__GetPresetsResponse *rep);
void dump_tds__GetCapabilitiesResponse(struct _tds__GetCapabilitiesResponse *rep);
@@ -44,7 +43,6 @@
void dump_trt__GetVideoEncoderConfigurationOptionsResponse(struct _trt__GetVideoEncoderConfigurationOptionsResponse *rep);
void log_level_val(unsigned int level, const char *prestr, enum LOG_TYPE type, const void *val);
#else
-
#define dump__wsdd__ProbeMatches
#define dump_tds__GetCapabilitiesResponse
#define dump_tds__GetDeviceInformationResponse
@@ -63,6 +61,7 @@
#define dump_trt__GetVideoEncoderConfigurationsResponse
#define dump_trt__GetCompatibleVideoEncoderConfigurationsResponse
#define dump_trt__GetVideoEncoderConfigurationOptionsResponse
+#define log_level_val
#endif
diff --git a/service/av_demux/av_demux.c b/service/av_demux/av_demux.c
new file mode 100644
index 0000000..99dbf2c
--- /dev/null
+++ b/service/av_demux/av_demux.c
@@ -0,0 +1,810 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <signal.h>
+#include <sys/wait.h>
+#include <time.h>
+#include <sys/vfs.h>
+#include <stdint.h>
+#include <sys/stat.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <dirent.h>
+
+#include "libavcodec/avcodec.h"
+#include "libavdevice/avdevice.h"
+#include "libavformat/avformat.h"
+#include "libavfilter/avfilter.h"
+#include "libavutil/avutil.h"
+#include "libswscale/swscale.h"
+#include "libavutil/pixdesc.h"
+
+#include "probe/probe.h"
+#include "av_demux/av_demux.h"
+#include "proto_comm.h"
+#include "proto_dbg.h"
+
+static AVDevs *gAVDevs = NULL;
+
+static int data_cmp(char *s1, char *s2, char *dlim);
+
+/*signal process interrupt handler*/
+static void handler(int sig)
+{
+ sync();
+}
+
+void av_timer_handler(union sigval para)
+{
+ gAVDevs->slice_stat = FALSE;
+}
+
+/*parse the location to get the right direction*/
+static int get_dir_with_key(char *dir_path, char *name, char *key, char *buf, int length) {
+ DIR *pDir;
+ char *ptr;
+ char temp = 0;
+ char found = FALSE;
+ struct dirent * entry;
+ char parse_buf[MAX_BUF_SIZE] = { 0x00 };
+
+ pDir = opendir(dir_path);
+ if (
+ pDir == NULL) {
+ SOAP_DBGERR("the path(%s) can not be opened!\n", dir_path);
+
+ return -1;
+ }
+
+ while((entry = readdir(pDir)) != NULL) {
+
+ if (entry->d_type & DT_DIR) {
+
+ if ((strcmp(entry->d_name, ".") != 0) && (strcmp(entry->d_name, "..") != 0)) {
+
+ ptr = strstr(entry->d_name, NAME_BRIDGE);
+
+ if ((ptr != NULL) && (strcmp(ptr + 1, name) == 0)) {
+
+ if (data_cmp(entry->d_name, key, NAME_MID) <= 0) {
+
+ found = TRUE;
+ if (temp == 0) {
+ memcpy(parse_buf, entry->d_name, sizeof(parse_buf));
+
+ temp = 1;
+
+ } else {
+
+ if (data_cmp(parse_buf, entry->d_name, NAME_MID) < 0) {
+ memset(parse_buf, 0x00, sizeof(parse_buf));
+ memcpy(parse_buf, entry->d_name, sizeof(parse_buf));
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ closedir(pDir);
+
+ if (found == TRUE) {
+ memcpy(buf, dir_path, length - 1);
+ memcpy(buf + strlen(buf), "/", length - strlen(buf) - 1);
+ memcpy(buf + strlen(buf), parse_buf, length - strlen(buf) - 1);
+ } else {
+ buf[0] = 0;
+ }
+
+ return found;
+}
+
+int playback_get_key(playback_key set, char *buf, int length) {
+ int ret;
+ char parse_buf[MAX_BUF_SIZE] = { 0x00 };
+ char buf_temp[MAX_BUF_SIZE] = { 0x00 };
+
+ if ((set.name == NULL) || (set.date == NULL) || (set.time == NULL)) {
+ SOAP_DBGERR("invalid playbeck key set parameters!\n");
+
+ return 0;
+ }
+
+ ret = get_dir_with_key(VIDEO_PUT_DIR, set.name, set.date, parse_buf, sizeof(parse_buf));
+ if (ret > 0) {
+ ret = get_file_with_key(parse_buf, set.time, buf_temp, sizeof(buf_temp), 0);
+ if (ret > 0) {
+ memcpy(buf, buf_temp, length);
+ }
+ }
+
+ return ret;
+}
+
+static int get_dir_oldest(char *dir_path, char *buf, int length) {
+ DIR *pDir;
+ char temp = 0;
+ int found = FALSE;
+ struct dirent * entry;
+ char parse_buf[MAX_BUF_SIZE] = { 0x00 };
+
+ pDir = opendir(dir_path);
+ if (
+ pDir == NULL) {
+ SOAP_DBGERR("the path(%s) can not be opened!\n", dir_path);
+
+ return -1;
+ }
+
+ while((entry = readdir(pDir)) != NULL) {
+
+ if (entry->d_type & DT_DIR) {
+
+ if ((strcmp(entry->d_name, ".") != 0) && (strcmp(entry->d_name, "..") != 0)) {
+
+ found = TRUE;
+ if (temp == 0) {
+ memcpy(parse_buf, entry->d_name, sizeof(parse_buf));
+
+ temp = 1;
+
+ } else {
+
+ if (data_cmp(parse_buf, entry->d_name, NAME_MID) > 0) {
+ memset(parse_buf, 0x00, sizeof(parse_buf));
+ memcpy(parse_buf, entry->d_name, sizeof(parse_buf));
+ }
+ }
+ }
+ }
+ }
+
+ closedir(pDir);
+
+ if (found == TRUE) {
+ memcpy(buf, dir_path, length);
+ memcpy(buf + strlen(buf), "/", length - strlen(buf) - 1);
+ memcpy(buf + strlen(buf), parse_buf, length - strlen(buf) - 1);
+
+ return 0;
+ }
+
+ buf[0] = 0x00;
+
+ return -1;
+}
+
+/*parse the location to get the right file.
+* flag - include the key itself or not
+*/
+static int get_file_with_key(char *dir_path, char *key, char *buf, int length, int flag) {
+ DIR *pDir;
+ char temp = 0;
+ char found = FALSE;
+ char found_flag = FALSE;
+ struct dirent * entry;
+ char parse_buf[MAX_BUF_SIZE] = { 0x00 };
+
+ pDir = opendir(dir_path);
+ if (pDir == NULL) {
+ SOAP_DBGERR("the path(%s) can not be opened!\n", dir_path);
+
+ return -1;
+ }
+
+ while((entry = readdir(pDir)) != NULL) {
+
+ if (entry->d_type & DT_REG) {
+
+ if ((key != NULL) && (data_cmp(key, entry->d_name, NAME_MID) >= 0)) {
+
+ if ((flag == 1) && (data_cmp(key, entry->d_name, NAME_MID) > 0)) {
+ found = TRUE;
+ } else if (flag == 0) {
+ found = TRUE;
+ }
+ } else if (key == NULL) {
+ found = TRUE;
+ }
+
+ if (found == TRUE) {
+
+ found_flag = TRUE;
+
+ if (temp == 0) {
+ memcpy(parse_buf, entry->d_name, sizeof(parse_buf));
+
+ temp = 1;
+
+ } else {
+
+ if (data_cmp(parse_buf, entry->d_name, NAME_MID) < 0) {
+ memset(parse_buf, 0x00, sizeof(parse_buf));
+ memcpy(parse_buf, entry->d_name, sizeof(parse_buf));
+ }
+ }
+
+ found = FALSE;
+ }
+ }
+ }
+
+ closedir(pDir);
+
+ if (found_flag == TRUE) {
+ memcpy(buf, dir_path, length - 1);
+ memcpy(buf + strlen(buf), "/", length - strlen(buf) - 1);
+ memcpy(buf + strlen(buf), parse_buf, length - strlen(buf) - 1);
+ } else {
+ buf[0] = 0;
+ }
+
+ return found_flag;
+}
+
+/*compare the string between s1 and s2*/
+static int data_cmp(char *s1, char *s2, char *dlim)
+{
+ int data1;
+ int data2;
+ char *ptr1;
+ char *ptr2;
+
+ data1 = atoi(s1);
+ data2 = atoi(s2);
+ if (data1 > data2)
+ return 1;
+
+ if (data1 < data2)
+ return -1;
+
+ ptr1 = strstr(s1, dlim);
+ ptr2 = strstr(s2, dlim);
+ data1 = atoi(ptr1 + 1);
+ data2 = atoi(ptr2 + 1);
+ if (data1 > data2)
+ return 1;
+
+ if (data1 < data2)
+ return -1;
+
+ ptr1 = strstr(ptr1 + 1, dlim);
+ ptr2 = strstr(ptr2 + 1, dlim);
+ data1 = atoi(ptr1 + 1);
+ data2 = atoi(ptr2 + 1);
+ if (data1 > data2)
+ return 1;
+
+ if (data1 < data2)
+ return -1;
+
+ return 0;
+}
+
+/*av stream capture task*/
+static void *task_av_capture(void *arg)
+{
+ struct timespec time_exp;
+
+ time_exp.tv_sec = WT_TIME;
+ time_exp.tv_nsec = 0;
+ //int data = *(int *)arg;
+
+ pthread_detach(pthread_self());
+
+ while(1) {
+ sem_timedwait(&(gAVDevs->sem_cap), &time_exp);
+
+ while(gAVDevs->run_stat == TRUE) {
+
+ av_start_cap(gAVDevs);
+
+ gAVDevs->slice_stat = TRUE;
+
+ }
+
+ if (gAVDevs->dev_stat == DISABLE) {
+
+ gAVDevs->proc_stat = DISABLE;
+
+ }
+ }
+
+ return 0;
+}
+
+/*monitor the disk usage*/
+static void *task_disk_mon(void *arg)
+{
+ int ret;
+ uint64_t blocksize;
+ uint64_t totalsize;
+ uint64_t availableDisk;
+ struct statfs diskInfo;
+ char buf[MAX_BUF_SIZE] = { 0x00 };
+ char buf_cmd[MAX_BUF_SIZE] = { 0x00 };
+
+ pthread_detach(pthread_self());
+
+ while(1) {
+ statfs(VIDEO_PUT_DIR, &diskInfo);
+
+ blocksize = diskInfo.f_bsize;
+ totalsize = blocksize * diskInfo.f_blocks;
+ availableDisk = diskInfo.f_bavail * blocksize;
+
+ while ((availableDisk * 1.0 / totalsize) < DISK_FREE_THRES) {
+ ret = get_dir_oldest(VIDEO_PUT_DIR, buf, sizeof(buf));
+ if (ret == 0) {
+ memcpy(buf_cmd, "rm -rf ", sizeof(buf_cmd));
+ snprintf(buf_cmd + strlen(buf_cmd), sizeof(buf_cmd) - strlen(buf_cmd) - 1, "rm -rf %s", buf);
+ system(buf_cmd);
+ sleep(WT_TIME);
+
+ statfs(VIDEO_PUT_DIR, &diskInfo);
+
+ blocksize = diskInfo.f_bsize;
+ totalsize = blocksize * diskInfo.f_blocks;
+ availableDisk = diskInfo.f_bavail * blocksize;
+
+ memset(buf, 0x00, sizeof(buf));
+ memset(buf_cmd, 0x00, sizeof(buf_cmd));
+ } else {
+
+ break;
+ }
+ }
+
+ sleep(WT_MAX_TIME);
+ }
+
+ return NULL;
+}
+
+/*initialize the stream data channel*/
+int proto_AVInit(void) {
+
+ int ret;
+ int flag;
+ pthread_t tid;
+ struct stat stat_buf;
+
+ if (stat(VIDEO_CONF_DATA, &stat_buf) != 0) {
+ SOAP_DBGERR("The video configuration(%s) is not existed! Please put it firstly!\n", VIDEO_CONF_DATA);
+
+ return -1;
+ }
+
+ ret = chmod(VIDEO_CONF_DATA, 0777);
+ if (ret < 0) {
+ SOAP_DBGERR("parse the configuration error: %s\n", strerror(errno));
+
+ return -1;
+ }
+
+ ret = DiscoverDevice(cb_av_probe);
+ if (ret <= 0) {
+ return -1;
+ }
+
+ ret = pthread_create(&tid, NULL, task_av_capture, &flag);
+ if (ret) {
+ return -1;
+ }
+
+ ret = pthread_create(&tid, NULL, task_disk_mon, &flag);
+ if (ret) {
+ return -1;
+ }
+
+ return 0;
+}
+
+void proto_AVStart(AVDevs *DevData) {
+
+ DevData->slice_stat = TRUE;
+
+ DevData->run_stat = TRUE;
+
+ sem_post(&(DevData->sem_cap));
+
+}
+
+static int av_start_cap(AVDevs *DevData) {
+ int ret;
+ pid_t pid;
+ char data_buf[MAX_BUF_SIZE] = { 0x00 };
+ char temp_buf[MAX_BUF_SIZE] = { 0x00 };
+ char data_buf_temp[MAX_BUF_SIZE] = { 0x00 };
+ char buf[MAX_BUF_SIZE] = { 0x00 };
+
+ signal(SIGINT, handler);
+
+ pid = fork();
+ if (pid < 0) {
+ SOAP_DBGERR("AV start failure: fork failed!\n");
+
+ return -1;
+
+ }
+
+ if (pid > 0) {
+
+ timer_start(gAVDevs->timer_id, gAVDevs->timer_sec);
+
+ while((gAVDevs->run_stat == TRUE) && (gAVDevs->slice_stat == TRUE)) {
+ sleep(1);
+ }
+ timer_stop(gAVDevs->timer_id);
+
+ kill(pid, SIGINT);
+
+ wait(NULL);
+
+ sync();
+
+ if ((gAVDevs->work_mode == PAUSE) && (gAVDevs->pause_enable == FALSE)) {
+
+ gAVDevs->pause_enable = TRUE;
+
+ } else if ((gAVDevs->work_mode == PAUSE) && (gAVDevs->pause_enable == TRUE)) {
+
+ system_date_get(data_buf_temp, sizeof(data_buf_temp));
+
+ ret = get_dir_with_key(VIDEO_PUT_DIR, gAVDevs->ip, data_buf_temp, data_buf, sizeof(data_buf));
+ if (ret > 0) {
+
+ memcpy(temp_buf, data_buf, sizeof(temp_buf) - 1);
+ memset(data_buf, 0x00, sizeof(data_buf));
+ get_file_with_key(temp_buf, NULL, data_buf, sizeof(data_buf), 0);
+
+ memset(data_buf_temp, 0x00, sizeof(data_buf_temp));
+ get_file_with_key(temp_buf, data_buf, data_buf_temp, sizeof(data_buf_temp), 1);
+
+ snprintf(buf, sizeof(buf) - 1, "%s", VIDEO_CONF_DATA);
+ snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf) - 1, "%s %s", data_buf_temp, data_buf);
+ system(buf);
+ }
+
+ gAVDevs->work_mode = NORMAL;
+
+ gAVDevs->pause_enable = FALSE;
+ }
+
+ } else {
+
+ ret = video_file_create(data_buf, sizeof(data_buf));
+ if (ret < 0) {
+ return 0;
+ }
+
+ ret = execl(FFMPEG_BIN_DIR, "ffmpeg", "-f", "rtsp", "-rtsp_transport", "tcp", "-i", gAVDevs->uri_data, "-vcodec", "copy", "-y", data_buf, (char *)NULL);
+ if (ret < 0) {
+ SOAP_DBGERR("ffmpeg stuffs are not available: %s\n", strerror(errno));
+ SOAP_DBGERR("please check and confirm it had already been installed correctly!\n");
+ }
+
+ }
+
+ return 0;
+}
+
+void proto_AVStop(AVDevs *DevData, enum wr_mode mode) {
+
+ DevData->run_stat = FALSE;
+
+ DevData->work_mode = mode;
+}
+
+static int video_file_create(char *data_buf, int length) {
+
+ int ret;
+ int len;
+ struct stat stat_buf;
+ char buf[MAX_BUF_SIZE] = { 0x00 };
+
+ struct tm tloc;
+ time_t now;
+ time(&now);
+ localtime_r(&now, &tloc);
+
+ if (stat(VIDEO_PUT_DIR, &stat_buf) != 0) {
+ memcpy(buf, "mkdir -p ", sizeof(buf));
+ snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf) - 1, "%s", VIDEO_PUT_DIR);
+ system(buf);
+ }
+
+ memset(buf, 0x00, sizeof(buf));
+ len = MAX_BUF_SIZE - 1;
+ snprintf(buf, len, "%s", VIDEO_PUT_DIR);
+ len = (MAX_BUF_SIZE - 1) >= strlen(buf) ? MAX_BUF_SIZE - 1 - strlen(buf) : 0;
+ snprintf(buf + strlen(buf), len, "/%d-", tloc.tm_year + 1900);
+ len = (MAX_BUF_SIZE - 1) >= strlen(buf) ? MAX_BUF_SIZE - 1 - strlen(buf) : 0;
+ snprintf(buf + strlen(buf), len, "%d-", tloc.tm_mon + 1);
+ len = (MAX_BUF_SIZE - 1) >= strlen(buf) ? MAX_BUF_SIZE - 1 - strlen(buf) : 0;
+ snprintf(buf + strlen(buf), len, "%d", tloc.tm_mday);
+ len = (MAX_BUF_SIZE - 1) >= strlen(buf) ? MAX_BUF_SIZE - 1 - strlen(buf) : 0;
+ snprintf(buf + strlen(buf), len, "_%s", gAVDevs->ip);
+
+ if (stat(buf, &stat_buf) != 0) {
+
+ ret = mkdir(buf, 0777);
+ if (ret < 0) {
+ SOAP_DBGERR("the video put dir create failure: %s\n", strerror(errno));
+
+ return -1;
+ }
+ }
+
+ time(&now);
+ localtime_r(&now, &tloc);
+ len = (MAX_BUF_SIZE - 1) >= strlen(buf) ? MAX_BUF_SIZE - 1 - strlen(buf) : 0;
+ snprintf(buf + strlen(buf), len, "/%d-", tloc.tm_hour);
+ len = (MAX_BUF_SIZE - 1) >= strlen(buf) ? MAX_BUF_SIZE - 1 - strlen(buf) : 0;
+ snprintf(buf + strlen(buf), len, "%d-", tloc.tm_min);
+ len = (MAX_BUF_SIZE - 1) >= strlen(buf) ? MAX_BUF_SIZE - 1 - strlen(buf) : 0;
+ snprintf(buf + strlen(buf), len, "%d.mp4", tloc.tm_sec);
+
+ memcpy(data_buf, buf, length);
+
+ return 0;
+}
+
+static void system_date_get(char *buf, int len)
+{
+ struct tm tloc;
+ time_t now;
+ time(&now);
+ localtime_r(&now, &tloc);
+
+ sprintf(buf, "%d", tloc.tm_year + 1900);
+ sprintf(buf + strlen(buf), "-%d", tloc.tm_mon + 1);
+ sprintf(buf + strlen(buf), "-%d", tloc.tm_mday);
+
+ return;
+}
+
+static void cb_av_probe(char *DeviceXAddr)
+{
+ int ret;
+ int len;
+ char *pos_s, *pos_e;
+
+ if (gAVDevs == NULL) {
+
+ gAVDevs = malloc(sizeof(AVDevs));
+
+ SOAP_ASSERT(gAVDevs != NULL);
+
+ memset(gAVDevs, 0x00, sizeof(AVDevs));
+
+ pos_s = strstr(DeviceXAddr, ADDR_PREFIX);
+ pos_e = strstr(DeviceXAddr + strlen(ADDR_PREFIX), ADDR_LAST);
+ len = pos_e - DeviceXAddr - strlen(ADDR_PREFIX);
+ memcpy(gAVDevs->ip, DeviceXAddr + strlen(ADDR_PREFIX), len);
+
+ gAVDevs->timer_sec = VIDEO_DURATION;
+
+ gAVDevs->dev_stat = ENABLE;
+ gAVDevs->run_stat = FALSE;
+
+ ret = sem_init(&(gAVDevs->sem_cap), 0, 0);
+ SOAP_ASSERT(ret == 0);
+
+ timer_init(&(gAVDevs->timer_id), av_timer_handler);
+ }
+
+ /*Get the device capabilities*/
+ proto_GetCapabilities(DeviceXAddr, &(gAVDevs->capa), USERNAME, PASSWORD);
+
+ /*Parse the stream configurations*/
+ proto_GetProfiles(gAVDevs->capa.MediaXAddr, &(gAVDevs->profiles), USERNAME, PASSWORD);
+
+ proto_GetStreamUri(gAVDevs->capa.MediaXAddr, gAVDevs->profiles->token, gAVDevs->uri, sizeof(gAVDevs->uri), USERNAME, PASSWORD);
+
+ bridge_uri(gAVDevs->uri, USERNAME, PASSWORD, gAVDevs->uri_data, sizeof(gAVDevs->uri_data));
+
+}
+
+AVDevs *proto_AVGethandle(void)
+{
+ return gAVDevs;
+}
+
+void proto_AVClose(void)
+{
+ if (gAVDevs != NULL) {
+
+ if (gAVDevs->dev_stat == ENABLE) {
+ proto_AVStop(gAVDevs, NORMAL);
+ }
+
+ gAVDevs->dev_stat = DISABLE;
+
+ while(gAVDevs->proc_stat != DISABLE) {
+ sleep(2);
+ }
+
+ sem_destroy(&(gAVDevs->sem_cap));
+
+ timer_destroy(gAVDevs->timer_id);
+
+ free(gAVDevs->profiles);
+
+ free(gAVDevs);
+
+ gAVDevs = NULL;
+ }
+}
+
+/*get the video and audio packet*/
+void get_stream(AVDevs *DevData)
+{
+ unsigned int i;
+ int ret;
+ int video_st_index = -1;
+ int audio_st_index = -1;
+ AVFormatContext *ifmt_ctx = NULL;
+ AVPacket pkt;
+ AVStream *st = NULL;
+ char errbuf[64];
+
+ /*Open the input file for reading*/
+ if ((ret = avformat_open_input(&ifmt_ctx, DevData->uri_data, 0, NULL)) < 0) {
+ SOAP_DBGERR("Could not open input file '%s' (error '%s')\n", DevData->uri_data, av_make_error_string(errbuf, sizeof(errbuf), ret));
+
+ goto EXIT;
+ }
+
+ /*Get information on the input file (number of streams etc.))*/
+ if ((ret = avformat_find_stream_info(ifmt_ctx, NULL)) < 0) {
+ SOAP_DBGERR("Could not open find stream info (error '%s')\n", av_make_error_string(errbuf, sizeof(errbuf), ret));
+
+ goto EXIT;
+ }
+
+ for (i = 0; i < ifmt_ctx->nb_streams; i++) {
+ av_dump_format(ifmt_ctx, i, DevData->uri_data, 0);
+ }
+
+ /*find video stream index*/
+ for (i = 0; i < ifmt_ctx->nb_streams; i++) {
+
+ st = ifmt_ctx->streams[i];
+
+ switch(st->codec->codec_type) {
+
+ case AVMEDIA_TYPE_AUDIO:
+ audio_st_index = i;
+
+ break;
+
+ case AVMEDIA_TYPE_VIDEO:
+ video_st_index = i;
+
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if (-1 == video_st_index) {
+ SOAP_DBGERR("No H.264 video stream in the input file\n");
+
+ goto EXIT;
+ }
+
+ /*initialize packet*/
+ av_init_packet(&pkt);
+ pkt.data = NULL;
+ pkt.size = 0;
+
+ while (1) {
+ do {
+
+ ret = av_read_frame(ifmt_ctx, &pkt);
+
+ } while (ret == AVERROR(EAGAIN));
+
+ if (ret < 0) {
+ SOAP_DBGERR("Could not read frame (error '%s')\n", av_make_error_string(errbuf, sizeof(errbuf), ret));
+
+ break;
+ }
+
+ /*video frame*/
+ if (pkt.stream_index == video_st_index) {
+
+ SOAP_DBGERR("Video Packet size = %d\n", pkt.size);
+
+ } else if(pkt.stream_index == audio_st_index) {
+ /*audio frame*/
+ SOAP_DBGERR("Audio Packet size = %d\n", pkt.size);
+
+ } else {
+
+ SOAP_DBGERR("Unknow Packet size = %d\n", pkt.size);
+
+ }
+
+ av_packet_unref(&pkt);
+ }
+
+EXIT:
+
+ if (NULL != ifmt_ctx) {
+
+ avformat_close_input(&ifmt_ctx);
+
+ ifmt_ctx = NULL;
+ }
+
+ return ;
+}
+
+/*Get the device service stream address*/
+int proto_GetStreamUri(const char *MediaXAddr, char *ProfileToken, char *uri, unsigned int sizeuri, const char *username, const char *passwd)
+{
+
+ int result = 0;
+ struct soap *soap = NULL;
+ struct tt__StreamSetup ttStreamSetup;
+ struct tt__Transport ttTransport;
+ struct _trt__GetStreamUri req;
+ struct _trt__GetStreamUriResponse rep;
+
+ SOAP_ASSERT(NULL != MediaXAddr);
+ SOAP_ASSERT(NULL != uri);
+
+ memset(uri, 0x00, sizeuri);
+
+ SOAP_ASSERT(NULL != (soap = proto_soap_new(SOAP_SOCK_TIMEOUT)));
+
+ memset(&req, 0x00, sizeof(req));
+ memset(&rep, 0x00, sizeof(rep));
+ memset(&ttStreamSetup, 0x00, sizeof(ttStreamSetup));
+ memset(&ttTransport, 0x00, sizeof(ttTransport));
+
+ ttStreamSetup.Stream = tt__StreamType__RTP_Unicast;
+ ttStreamSetup.Transport = &ttTransport;
+ ttStreamSetup.Transport->Protocol = tt__TransportProtocol__RTSP;
+ ttStreamSetup.Transport->Tunnel = NULL;
+ req.StreamSetup = &ttStreamSetup;
+ req.ProfileToken = ProfileToken;
+
+ proto_SetAuthInfo(soap, username, passwd);
+ result = soap_call___trt__GetStreamUri(soap, MediaXAddr, NULL, &req, &rep);
+ SOAP_CHECK_ERROR(result, soap, "GetServices");
+
+ dump_trt__GetStreamUriResponse(&rep);
+
+ result = -1;
+ if (NULL != rep.MediaUri) {
+ if (NULL != rep.MediaUri->Uri) {
+ if (sizeuri > strlen(rep.MediaUri->Uri)) {
+
+ strcpy(uri, rep.MediaUri->Uri);
+
+ result = 0;
+ } else {
+ SOAP_DBGERR("Not enough cache!\n");
+ }
+ }
+ }
+
+EXIT:
+
+ if (NULL != soap) {
+ proto_soap_delete(soap);
+ }
+
+ return result;
+
+}
+
+
diff --git a/service/av_demux/av_demux.h b/service/av_demux/av_demux.h
new file mode 100644
index 0000000..e8de362
--- /dev/null
+++ b/service/av_demux/av_demux.h
@@ -0,0 +1,100 @@
+#ifndef __SRV_AV_DEMUX_H__
+#define __SRV_AV_DEMUX_H__
+
+#include <semaphore.h>
+#include <pthread.h>
+
+#include "capabilities/capa.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define VIDEO_PUT_DIR "/home/Work/Log_repo/video_log"
+#define VIDEO_CONF_DATA "/usr/bin/video_conv.sh"
+#define FFMPEG_BIN_DIR "/home/Work/Sources_temp/ffmpeg_sources/host/bin/ffmpeg"
+
+#define VIDEO_DURATION (5 * 60) //sec
+
+#define KB (1024.0)
+#define MB (KB * 1024.0)
+#define GB (MB * 1024.0)
+#define DISK_FREE_THRES (0.05)
+
+/*the player work mode status*/
+enum wr_mode {
+ NORMAL,
+ PAUSE,
+};
+
+/*playback mode set key*/
+typedef struct _playback_key {
+
+ /*format: 192.168.1.101*/
+ char name[PTOTO_ADDRESS_ADD];
+
+ /*format: 2022-6-28*/
+ char date[PTOTO_ADDRESS_ADD];
+
+ /*format: 21-32-19*/
+ char time[PTOTO_ADDRESS_ADD];
+
+} playback_key;
+
+/*the operational handle*/
+typedef struct _AVDevs {
+
+ /*the devices capabilities*/
+ struct tagCapabilities capa;
+
+ /*the profies for each servies*/
+ struct tagProfile *profiles;
+
+ timer_t timer_id;
+ int timer_sec;
+
+ sem_t sem_cap;
+
+ volatile char run_stat;
+ volatile char slice_stat;
+
+ char ip[PROTO_ADDRESS_SIZE];
+
+ char uri[PROTO_ADDRESS_SIZE + PTOTO_ADDRESS_ADD];
+ char uri_data[PROTO_ADDRESS_SIZE + PTOTO_ADDRESS_ADD];
+
+ /*the device work stat*/
+ char dev_stat;
+
+ /*the process work stat*/
+ char proc_stat;
+
+ /*the stat record for pause work mode*/
+ char pause_enable;
+ char pause_prev_loc[MAX_BUF_SIZE];
+ char pause_cur_loc[MAX_BUF_SIZE];
+
+ enum wr_mode work_mode;
+
+} AVDevs;
+
+int proto_AVInit(void);
+void proto_AVStart(AVDevs *DevData);
+void proto_AVStop(AVDevs *DevData, enum wr_mode mode);
+void proto_AVClose(void);
+AVDevs *proto_AVGethandle(void);
+void get_stream(AVDevs *DevData);
+int playback_get_key(playback_key set, char *buf, int length);
+
+static int get_dir_with_key(char *dir_path, char *name, char *key, char *buf, int length);
+static int get_file_with_key(char *dir_path, char *key, char *buf, int length, int flag);
+static int get_dir_oldest(char *dir_path, char *buf, int length);
+
+static void cb_av_probe(char *DeviceXAddr);
+static int video_file_create(char *buf, int len);
+static int av_start_cap(AVDevs *DevData);
+
+static void system_date_get(char *buf, int len);
+
+#endif
+
diff --git a/service/av_demux/video_conv.sh b/service/av_demux/video_conv.sh
new file mode 100644
index 0000000..f822601
--- /dev/null
+++ b/service/av_demux/video_conv.sh
@@ -0,0 +1,58 @@
+#!/bin/sh
+
+exist_file()
+{
+ if [ -e "$1" ]
+ then
+ return 1
+ else
+ return 2
+ fi
+}
+
+if [ $# != 2 ] ; then
+echo "USAGE: $0 media_src1 media_src2"
+exit 1;
+fi
+
+arg1=`basename $1`
+
+arg2=`basename $2`
+
+mainN1=${arg1%%.*}
+mainE=${arg1#*.}
+mainN2=${arg2%%.*}
+
+dirname=`dirname $1`
+
+exist_file $1
+value=$?
+
+if [ $value -eq 2 ]
+then
+ echo "No source media ${arg1} found in the directory! Put it here firstly!\n"
+ exit
+fi
+
+exist_file $2
+value=$?
+
+if [ $value -eq 2 ]
+then
+ echo "No source media ${arg2} found in the directory! Put it here firstly!\n"
+ exit
+fi
+
+output1=${mainN1}.ts
+output2=${mainN2}.ts
+
+ffmpeg -i $1 -vcodec copy -acodec copy -vbsf h264_mp4toannexb ${output1}
+ffmpeg -i $2 -vcodec copy -acodec copy -vbsf h264_mp4toannexb ${output2}
+ffmpeg -i "concat:${output1}|${output2}" -acodec copy -vcodec copy -absf aac_adtstoasc ${mainN1}.${mainE}
+
+rm -rf ${output1}
+rm -rf ${output2}
+rm -rf $1
+mv ${mainN1}.${mainE} ${dirname}
+
+
diff --git a/service/capabilities/capa.c b/service/capabilities/capa.c
index fd2033f..6fc0847 100644
--- a/service/capabilities/capa.c
+++ b/service/capabilities/capa.c
@@ -87,6 +87,49 @@
return rep.__sizeProfiles;
}
+int proto_GetVideoSource(const char *DeviceXAddr, char *buf, int len, const char *username, const char *passwd) {
+ int result = 0;
+ struct soap *soap = NULL;
+ struct _trt__GetVideoSources *getVideoSources;
+ struct _trt__GetVideoSourcesResponse *getVideoSourcesRes;
+
+ SOAP_ASSERT(NULL != DeviceXAddr);
+ SOAP_ASSERT(NULL != buf);
+ SOAP_ASSERT(NULL != (soap = proto_soap_new(SOAP_SOCK_TIMEOUT)));
+
+ getVideoSources = soap_new__trt__GetVideoSources(soap, 1);
+ getVideoSourcesRes = soap_new__trt__GetVideoSourcesResponse(soap, 1);
+
+ proto_SetAuthInfo(soap, username, passwd);
+
+ result = soap_call___trt__GetVideoSources(soap, DeviceXAddr, NULL, getVideoSources, getVideoSourcesRes);
+ SOAP_CHECK_ERROR(result, soap, "GetVideoSourc");
+
+ if (getVideoSourcesRes->__sizeVideoSources <= 0) {
+
+ result = SOAP_NO_DATA;
+ SOAP_CHECK_ERROR(result, soap, "GetVideoSourc");
+
+ } else {
+
+ for (int i = 0; i < getVideoSourcesRes->__sizeVideoSources; i++) {
+
+ log_level_val(0, "get video source token: ", log_str, getVideoSourcesRes->VideoSources[i].token);
+
+ if (i == 0) {
+ strncpy(buf, getVideoSourcesRes->VideoSources[i].token, len);
+ }
+ }
+ }
+
+EXIT:
+ if (NULL != soap) {
+ proto_soap_delete(soap);
+ }
+
+ return result;
+}
+
int proto_GetCapabilities(const char *DeviceXAddr, struct tagCapabilities *capa, const char *username, const char *passwd)
{
int result = 0;
diff --git a/service/ptz/ptz.c b/service/ptz/ptz.c
index c7991f0..5921a42 100644
--- a/service/ptz/ptz.c
+++ b/service/ptz/ptz.c
@@ -2,6 +2,7 @@
#include <stdlib.h>
#include <unistd.h>
#include <semaphore.h>
+#include <string.h>
#include <pthread.h>
#include <signal.h>
#include <errno.h>
@@ -22,9 +23,9 @@
int ret;
SOAP_ASSERT(DevData != NULL);
- SOAP_ASSERT(DevData->profilesToken != NULL);
+ SOAP_ASSERT(DevData->profiles != NULL);
- ret = DevData->profilesToken->venc.Width;
+ ret = DevData->profiles->venc.Width;
return ret;
}
@@ -35,14 +36,17 @@
int ret;
SOAP_ASSERT(DevData != NULL);
- SOAP_ASSERT(DevData->profilesToken != NULL);
+ SOAP_ASSERT(DevData->profiles != NULL);
- ret = DevData->profilesToken->venc.Height;
+ ret = DevData->profiles->venc.Height;
return ret;
}
static void cb_probe(char *DeviceXAddr) {
+
+ int len;
+ char *pos_s, *pos_e;
if (gPtzDevs == NULL) {
@@ -51,10 +55,15 @@
SOAP_ASSERT(gPtzDevs != NULL);
memset(gPtzDevs, 0x00, sizeof(PtzDevs));
+
+ pos_s = strstr(DeviceXAddr, ADDR_PREFIX);
+ pos_e = strstr(DeviceXAddr + strlen(ADDR_PREFIX), ADDR_LAST);
+ len = pos_e - DeviceXAddr - strlen(ADDR_PREFIX);
+ memcpy(gPtzDevs->ip, DeviceXAddr + strlen(ADDR_PREFIX), len);
}
proto_GetCapabilities(DeviceXAddr, &(gPtzDevs->capa), USERNAME, PASSWORD);
- proto_GetProfiles(gPtzDevs->capa.MediaXAddr, &(gPtzDevs->profilesToken), USERNAME, PASSWORD);
+ proto_GetProfiles(gPtzDevs->capa.MediaXAddr, &(gPtzDevs->profiles), USERNAME, PASSWORD);
}
@@ -76,7 +85,7 @@
ret = sem_init(&(gPtzDevs->sem_tour), 0, 0);
SOAP_ASSERT(ret == 0);
- timer_init(&(gPtzDevs->timer_id));
+ timer_init(&(gPtzDevs->timer_id), ptz_timer_handler);
gPtzDevs->dev_stat = DISABLE;
pthread_mutex_init(&(gPtzDevs->node_mutex), NULL);
@@ -93,7 +102,7 @@
timer_destroy(gPtzDevs->timer_id);
- free(gPtzDevs->profilesToken);
+ free(gPtzDevs->profiles);
free(gPtzDevs);
@@ -194,70 +203,20 @@
}
/*the timer process heandler*/
-static void timer_handler(union sigval para) {
+void ptz_timer_handler(union sigval para) {
if (gPtzDevs != NULL) {
+
+ pthread_mutex_lock(&(gPtzDevs->node_mutex));
gPtzDevs->wt_stat = DISABLE;
pthread_cond_signal(&(gPtzDevs->cond));
+
+ pthread_mutex_unlock(&(gPtzDevs->node_mutex));
}
return;
-}
-
-static int timer_init(timer_t *timer_index) {
- struct sigevent event;
- timer_t timer;
- int ret;
-
- memset(&event, 0x00, sizeof(event));
- event.sigev_value.sival_int = ENABLE;
- event.sigev_value.sival_ptr = NULL;
- event.sigev_notify = SIGEV_THREAD;
- event.sigev_notify_function = timer_handler;
-
- ret = timer_create(CLOCK_REALTIME, &event, &timer);
- if (ret) {
- return -1;
- }
-
- if (timer_index != NULL) {
- *timer_index = timer;
- }
-
- return 0;
-}
-
-static int timer_start(timer_t timer_index, int sec) {
- int ret;
- struct itimerspec ts;
-
- ts.it_interval.tv_sec = 0;
- ts.it_interval.tv_nsec = 0;
- ts.it_value.tv_sec = sec;
- ts.it_value.tv_nsec = 0;
- ret = timer_settime(timer_index, 0, &ts, NULL);
- if (ret) {
- return -1;
- }
-
- return ret;
-}
-
-static int timer_stop(timer_t timer_index) {
-
- int ret = timer_start(timer_index, 0);
-
- return ret;
-}
-
-static int timer_destroy(timer_t timer_index) {
- int ret;
-
- ret = timer_delete(timer_index);
-
- return ret;
}
/*initialize the PTZ*/
@@ -355,7 +314,7 @@
struct _tptz__GetStatusResponse *getStatusResponse = NULL;
SOAP_ASSERT(DevData != NULL);
- SOAP_ASSERT(NULL != DevData->profilesToken);
+ SOAP_ASSERT(NULL != DevData->profiles);
SOAP_ASSERT(NULL != (soap = proto_soap_new(SOAP_SOCK_TIMEOUT)));
getStatus = soap_new__tptz__GetStatus(soap, 1);
@@ -364,7 +323,7 @@
strncpy(PTZXAddr, DevData->capa.PTZXAddr, PROTO_ADDRESS_SIZE);
proto_SetAuthInfo(soap, username, passwd);
- getStatus->ProfileToken = DevData->profilesToken->token;
+ getStatus->ProfileToken = DevData->profiles->token;
result = soap_call___tptz__GetStatus(soap, PTZXAddr, NULL, getStatus, getStatusResponse);
SOAP_CHECK_ERROR(result, soap, "proto_PTZ_GetStatus");
@@ -614,7 +573,7 @@
char PTZXAddr[PROTO_ADDRESS_SIZE] = { 0x00 };
SOAP_ASSERT(DevData != NULL);
- SOAP_ASSERT(NULL != DevData->profilesToken);
+ SOAP_ASSERT(NULL != DevData->profiles);
SOAP_ASSERT(NULL != (soap = proto_soap_new(SOAP_SOCK_TIMEOUT)));
proto_PTZ_GetStatus(DevData, &pos_get, username, passwd);
@@ -628,7 +587,7 @@
strncpy(PTZXAddr, DevData->capa.PTZXAddr, PROTO_ADDRESS_SIZE);
proto_SetAuthInfo(soap, username, passwd);
- absMove->ProfileToken = DevData->profilesToken->token;
+ absMove->ProfileToken = DevData->profiles->token;
absMove->Position = soap_new_tt__PTZVector(soap, 1);
absMove->Position->PanTilt = soap_new_tt__Vector2D(soap, 1);
@@ -660,7 +619,7 @@
enum xsd__boolean xsd_false = xsd__boolean__false_;
SOAP_ASSERT(DevData != NULL);
- SOAP_ASSERT(NULL != DevData->profilesToken);
+ SOAP_ASSERT(NULL != DevData->profiles);
SOAP_ASSERT(NULL != (soap = proto_soap_new(SOAP_SOCK_TIMEOUT)));
struct _tptz__Stop *tptzStop = soap_new__tptz__Stop(soap, 1);
@@ -668,7 +627,7 @@
strncpy(PTZXAddr, DevData->capa.PTZXAddr, PROTO_ADDRESS_SIZE);
proto_SetAuthInfo(soap, username, passwd);
- tptzStop->ProfileToken = DevData->profilesToken->token;
+ tptzStop->ProfileToken = DevData->profiles->token;
tptzStop->PanTilt = &xsd_true;
tptzStop->Zoom = &xsd_false;
@@ -693,7 +652,7 @@
char PTZXAddr[PROTO_ADDRESS_SIZE] = { 0x00 };
SOAP_ASSERT(DevData != NULL);
- SOAP_ASSERT(NULL != DevData->profilesToken);
+ SOAP_ASSERT(NULL != DevData->profiles);
SOAP_ASSERT(NULL != (soap = proto_soap_new(SOAP_SOCK_TIMEOUT)));
struct _tptz__ContinuousMove* contMove = soap_new__tptz__ContinuousMove(soap, 1);
@@ -705,7 +664,7 @@
strncpy(PTZXAddr, DevData->capa.PTZXAddr, PROTO_ADDRESS_SIZE);
proto_SetAuthInfo(soap, username, passwd);
- contMove->ProfileToken = DevData->profilesToken->token;
+ contMove->ProfileToken = DevData->profiles->token;
contMove->Velocity = soap_new_tt__PTZSpeed(soap, 1);
memset(contMove->Velocity, 0x00, sizeof(struct tt__PTZSpeed));
contMove->Velocity->PanTilt = soap_new_tt__Vector2D(soap, 1);
@@ -863,7 +822,7 @@
char PTZXAddr[PROTO_ADDRESS_SIZE] = { 0x00 };
SOAP_ASSERT(DevData != NULL);
- SOAP_ASSERT(NULL != DevData->profilesToken);
+ SOAP_ASSERT(NULL != DevData->profiles);
SOAP_ASSERT(NULL != (soap = proto_soap_new(SOAP_SOCK_TIMEOUT)));
pos_p = para_check(pos_p);
@@ -875,7 +834,7 @@
strncpy(PTZXAddr, DevData->capa.PTZXAddr, PROTO_ADDRESS_SIZE);
proto_SetAuthInfo(soap, username, passwd);
- relMove->ProfileToken = DevData->profilesToken->token;
+ relMove->ProfileToken = DevData->profiles->token;
relMove->Translation = (struct tt__PTZVector *)soap_malloc(soap, sizeof(struct tt__PTZVector));
memset(relMove->Translation, 0x00, sizeof(struct tt__PTZVector));
relMove->Translation->PanTilt = soap_new_tt__Vector2D(soap, 1);
@@ -953,7 +912,7 @@
}
/*set the focus-on functionality*/
-int proto_PTZ_ImagingSet(PtzDevs *DevData, float speed, const char *username, const char *passwd) {
+int proto_PTZ_ImagingSet(PtzDevs *DevData, enum PTZCMD cmd, float speed, const char *username, const char *passwd) {
int result = 0;
float speed_val;
struct soap *soap = NULL;
@@ -961,34 +920,61 @@
struct tt__ContinuousFocus *stContFocus = NULL;
struct _timg__Move *stMoveReq = NULL;
struct _timg__MoveResponse *stMoveRes = NULL;
+ struct _timg__Stop *stStopReq = NULL;
+ struct _timg__StopResponse *stStopRes = NULL;
SOAP_ASSERT(NULL != DevData);
- SOAP_ASSERT(NULL != DevData->profilesToken);
+ SOAP_ASSERT(NULL != DevData->profiles);
SOAP_ASSERT(NULL != (soap = proto_soap_new(SOAP_SOCK_TIMEOUT)));
stFocusMove = soap_new_tt__FocusMove(soap, 1);
stContFocus = soap_new_tt__ContinuousFocus(soap, 1);
-
- proto_SetAuthInfo(soap, username, passwd);
-
+
stMoveReq = soap_new__timg__Move(soap, 1);
stMoveRes = soap_new__timg__MoveResponse(soap, 1);
+
+ stStopReq = soap_new__timg__Stop(soap, 1);
+ stStopRes = soap_new__timg__StopResponse(soap, 1);
memset(stMoveReq, 0x00, sizeof(struct _timg__Move));
memset(stMoveRes, 0x00, sizeof(struct _timg__MoveResponse));
- speed_val = pos_res_z(speed);
+ memset(stStopReq, 0x00, sizeof(struct _timg__Stop));
+ memset(stStopRes, 0x00, sizeof(struct _timg__StopResponse));
- stContFocus->Speed = speed_val;
+ stMoveReq->Focus = stFocusMove;
+ stMoveReq->Focus->Continuous = stContFocus;
+
+ stMoveReq->VideoSourceToken = DevData->profiles->videoCfg.sourceToken;
+ stStopReq->VideoSourceToken = DevData->profiles->videoCfg.sourceToken;
+
+ proto_SetAuthInfo(soap, username, passwd);
+
+ speed_val = pos_res_z(speed);
+ switch(cmd) {
+ case PTZ_CMD_FOCUS_IN:
+ stContFocus->Speed = speed_val;
+
+ break;
+
+ case PTZ_CMD_FOCUS_OUT:
+ stContFocus->Speed = speed_val * (-1);
+
+ break;
+
+ default:
+ result = soap_call___timg__Stop(soap, DevData->capa.MediaXAddr, NULL, stStopReq, stStopRes);
+ SOAP_CHECK_ERROR(result, soap, "proto_PTZ_ImagingSet");
+
+ break;
+ }
+
stFocusMove->Continuous = stContFocus;
stFocusMove->Absolute = NULL;
stFocusMove->Relative = NULL;
- stMoveReq->Focus = stFocusMove;
- stMoveReq->VideoSourceToken = DevData->profilesToken->videoCfg.token;
-
- result = soap_call___timg__Move(soap, DevData->profilesToken->token, NULL, stMoveReq, stMoveRes);
- SOAP_CHECK_ERROR(result, soap, "proto_PTZ_FocusSet");
+ result = soap_call___timg__Move(soap, DevData->capa.MediaXAddr, NULL, stMoveReq, stMoveRes);
+ SOAP_CHECK_ERROR(result, soap, "proto_PTZ_ImagingSet");
EXIT:
if (NULL != soap) {
@@ -1007,7 +993,7 @@
char PTZXAddr[PROTO_ADDRESS_SIZE] = { 0x00 };
SOAP_ASSERT(DevData != NULL);
- SOAP_ASSERT(NULL != DevData->profilesToken);
+ SOAP_ASSERT(NULL != DevData->profiles);
SOAP_ASSERT(NULL != (soap = proto_soap_new(SOAP_SOCK_TIMEOUT)));
strncpy(PTZXAddr, DevData->capa.PTZXAddr, PROTO_ADDRESS_SIZE);
@@ -1020,7 +1006,7 @@
memset(setPreset, 0x00, sizeof(struct _tptz__SetPreset));
memset(setPresetRes, 0x00, sizeof(struct _tptz__SetPresetResponse));
- setPreset->ProfileToken = DevData->profilesToken->token;
+ setPreset->ProfileToken = DevData->profiles->token;
if (posName != NULL) {
setPreset->PresetName = (char *)posName;
}
@@ -1039,7 +1025,7 @@
memset(getPresets, 0x00, sizeof(struct _tptz__GetPresets));
memset(getPresetsRes, 0x00, sizeof(struct _tptz__GetPresetsResponse));
- getPresets->ProfileToken = DevData->profilesToken->token;
+ getPresets->ProfileToken = DevData->profiles->token;
result = soap_call___tptz__GetPresets(soap, PTZXAddr, NULL, getPresets, getPresetsRes);
SOAP_CHECK_ERROR(result, soap, "proto_PTZPreset");
@@ -1055,7 +1041,7 @@
memset(gotoPreset, 0x00, sizeof(struct _tptz__GotoPreset));
memset(gotoPresetRes, 0x00, sizeof(struct _tptz__GotoPresetResponse));
- gotoPreset->ProfileToken = DevData->profilesToken->token;
+ gotoPreset->ProfileToken = DevData->profiles->token;
if (posToken != NULL) {
sprintf(buf, "%d", *posToken);
@@ -1072,7 +1058,7 @@
memset(rmPreset, 0x00, sizeof(struct _tptz__RemovePreset));
memset(rmPresetRes, 0x00, sizeof(struct _tptz__RemovePresetResponse));
- rmPreset->ProfileToken = DevData->profilesToken->token;
+ rmPreset->ProfileToken = DevData->profiles->token;
if (posToken != NULL) {
sprintf(buf, "%d", *posToken);
rmPreset->PresetToken = buf;
diff --git a/service/ptz/ptz.h b/service/ptz/ptz.h
index 37e0894..6071030 100644
--- a/service/ptz/ptz.h
+++ b/service/ptz/ptz.h
@@ -10,9 +10,6 @@
#include "capabilities/capa.h"
-#define USERNAME "On_admin"
-#define PASSWORD "a12345678"
-
#define HK_IDS_2DE 1
#if defined(HK_IDS_2DE)
@@ -44,9 +41,6 @@
#define MIN_TOUR_TIME 15
#define MIN_TOUR_POS 2
-#define WT_TIME 5
-#define STOP_WT_TIME 3
-
#define MAX_IMG_SCALE 0.5
#define PI 3.14159
@@ -60,9 +54,6 @@
#define COEF_FV_A 0.953
#define COEF_FV_B 0.598
#define COEF_FV_C 0.166
-
-#define ENABLE 0
-#define DISABLE 1
/*PTZ working stat*/
enum PTZStat {
@@ -95,6 +86,9 @@
PTZ_CMD_RIGHTDOWN,
PTZ_CMD_ZOOM_IN,
PTZ_CMD_ZOOM_OUT,
+ PTZ_CMD_FOCUS_IN,
+ PTZ_CMD_FOCUS_OUT,
+ PTZ_CMD_FOCUS_STOP,
};
/*the tradditional preset control command*/
@@ -143,7 +137,7 @@
struct tagCapabilities capa;
- struct tagProfile *profilesToken;
+ struct tagProfile *profiles;
PresetToure_node *posNode;
int posNode_count;
@@ -166,6 +160,8 @@
/*the touring process work stat*/
char proc_stat;
+
+ char ip[PROTO_ADDRESS_SIZE];
enum tourType tour_type;
@@ -199,7 +195,7 @@
int proto_PTZPreset(PtzDevs *DevData, const char *posName, enum PreSetCMD cmd, \
int *posToken, const char *username, const char *passwd);
-int proto_PTZ_ImagingSet(PtzDevs *DevData, float speed, const char *username, const char *passwd);
+int proto_PTZ_ImagingSet(PtzDevs *DevData, enum PTZCMD cmd, float speed, const char *username, const char *passwd);
static void *task_preset_touring(void *arg);
float proto_PTZZoom_get(PtzDevs *DevData, int x0, int y0, int x1, int y1);
@@ -209,11 +205,7 @@
void proto_PTZWaitStopped(PtzDevs *DevData, const char *username, const char *passwd);
void proto_PTZPreset_tour_stop(PtzDevs *DevData);
-static void timer_handler(union sigval para);
-static int timer_init(timer_t *timer_index);
-static int timer_start(timer_t timer_index, int sec);
-static int timer_stop(timer_t timer_index);
-static int timer_destroy(timer_t timer_index);
+static void ptz_timer_handler(union sigval para);
#ifdef __cplusplus
}
diff --git a/test/Makefile.inc b/test/Makefile.inc
index e9c20a2..75bb0e3 100644
--- a/test/Makefile.inc
+++ b/test/Makefile.inc
@@ -27,15 +27,20 @@
OBJECTS_ONVIF := $(patsubst %.c,$(TEMPDIR)%.o,$(filter %.c, $(SOURCES_CORE)))
OBJECTS_COMM := $(patsubst %.c,$(TEMPDIR)%.o,$(filter %.c, $(SOURCES_COMM)))
+FFMPEG_DIR = ../../thirdparty/ffmpeg
OPENSSL_DIR = ../../thirdparty/openssl
#
INCLUDE += -I../../core/ \
-I../../comm/ \
+ -I$(FFMPEG_DIR)/include \
-I$(OPENSSL_DIR)/include
CFLAGS += $(INCLUDE)
+LDFLAGS += -L$(FFMPEG_DIR)/lib
LDFLAGS += -L$(OPENSSL_DIR)/lib
+LDLIBS += -lavcodec -lavdevice -lavfilter -lavformat \
+ -lavutil -lswresample -lswscale
LDLIBS += -lcrypto -lssl -lpthread -ldl
%.o: %.cpp
diff --git a/test/av_test/Makefile b/test/av_test/Makefile
new file mode 100644
index 0000000..33ba199
--- /dev/null
+++ b/test/av_test/Makefile
@@ -0,0 +1,52 @@
+CC := gcc
+CPP := g++
+LD := ld
+AR := ar
+STRIP := strip
+RM := rm
+
+PROGRAM = av_stream_test
+
+SOURCES += av_test.c
+
+CFLAGS += -Wall -DWITH_DOM -DWITH_NONAMESPACES -DWITH_OPENSSL -Wno-unused
+
+OBJECTS := $(patsubst %.c,$(TEMPDIR)%.o,$(filter %.c, $(SOURCES)))
+
+%.o: %.cpp
+ @echo " CPP " $@;
+ @$(CPP) $(CFLAGS) -c -o $@ $<
+
+%.o: %.c
+ @echo " CC " $@;
+ @$(CC) $(CFLAGS) -c -o $@ $<
+
+FFMPEG_DIR = ../../thirdparty/ffmpeg
+OPENSSL_DIR = ../../thirdparty/openss
+
+LDFLAGS += -L$(FFMPEG_DIR)/lib
+LDFLAGS += -L$(OPENSSL_DIR)/lib
+LDFLAGS += -L../../
+LDLIBS += -lonvif_std
+LDLIBS += -lavcodec -lavdevice -lavfilter -lavformat \
+ -lavutil -lswresample -lswscale
+LDLIBS += -lcrypto -lssl -lpthread -ldl -lrt
+LDLIBS += -lprotobuf -lprotobuf-lite
+
+INCLUDE += -I../../core/ \
+ -I../../comm/ \
+ -I../../service \
+ -I$(FFMPEG_DIR)/include \
+ -I$(OPENSSL_DIR)/include
+CFLAGS += $(INCLUDE)
+
+all: $(OBJECTS)
+ $(CC) -o $(PROGRAM) $(OBJECTS) $(LDFLAGS) $(LDLIBS) $(CFLAGS)
+
+clean:
+ $(RM) -f $(OBJECTS)
+ $(RM) -f $(PROGRAM)
+
+allclean: clean
+ $(RM) -f $(OBJECTS_ONVIF)
+
diff --git a/test/av_test/av_test.c b/test/av_test/av_test.c
new file mode 100644
index 0000000..7f4e660
--- /dev/null
+++ b/test/av_test/av_test.c
@@ -0,0 +1,66 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include "PTZBinding.nsmap"
+#include "av_demux/av_demux.h"
+
+int main(int argc, char **argv)
+{
+ int ret;
+ char parse_buf[MAX_BUF_SIZE] = { 0x00 };
+ playback_key data_set = {"192.168.1.101", "2022-7-3", "21-52-16"};
+ AVDevs *handle = NULL;
+
+ ret = proto_AVInit();
+ if (ret < 0) {
+ printf("AV stream initialization failure!\n");
+
+ return 0;
+ }
+
+ printf("start the av stream:\n");
+ handle = proto_AVGethandle();
+ proto_AVStart(handle);
+
+ sleep(5 * 60 * 2);
+
+ printf("stop the av stream now:\n");
+ proto_AVStop(handle, NORMAL);
+
+ sleep(3);
+
+ printf("re-start the AV now:\n");
+ proto_AVStart(handle);
+
+ sleep(120);
+
+ printf("pause the av stream now:\n");
+ proto_AVStop(handle, PAUSE);
+
+ sleep(20);
+
+ printf("resume the av:\n");
+ proto_AVStart(handle);
+
+ sleep(200);
+
+ printf("stop the av");
+ proto_AVStop(handle, NORMAL);
+
+ sleep(3);
+
+ ret = playback_get_key(data_set, parse_buf, sizeof(parse_buf));
+ if (ret > 0) {
+ printf("found the playback file: %s\n", parse_buf);
+ } else {
+ printf("the playback file is not existed!\n");
+ }
+
+ sleep(3000);
+ printf("now exit the process:\n");
+ proto_AVClose();
+
+ return 0;
+}
+
diff --git a/test/probe_test/Makefile b/test/probe_test/Makefile
index a9ba811..4b8a57b 100644
--- a/test/probe_test/Makefile
+++ b/test/probe_test/Makefile
@@ -19,16 +19,21 @@
@echo " CC " $@;
@$(CC) $(CFLAGS) -c -o $@ $<
+FFMPEG_DIR = ../../thirdparty/ffmpeg
OPENSSL_DIR = ../../thirdparty/openss
+LDFLAGS += -L$(FFMPEG_DIR)/lib
LDFLAGS += -L$(OPENSSL_DIR)/lib
LDFLAGS += -L../../
LDLIBS += -lonvif_std
+LDLIBS += -lavcodec -lavdevice -lavfilter -lavformat \
+ -lavutil -lswresample -lswscale
LDLIBS += -lcrypto -lssl -lpthread -ldl -lm -lrt
INCLUDE += -I../../core/ \
-I../../comm/ \
-I../../service \
+ -I$(FFMPEG_DIR)/include \
-I$(OPENSSL_DIR)/include
CFLAGS += $(INCLUDE)
diff --git a/test/ptz_test/Makefile b/test/ptz_test/Makefile
index 0eb8ec3..8328d26 100644
--- a/test/ptz_test/Makefile
+++ b/test/ptz_test/Makefile
@@ -21,16 +21,21 @@
@echo " CC " $@;
@$(CC) $(CFLAGS) -c -o $@ $<
+FFMPEG_DIR = ../../thirdparty/ffmpeg
OPENSSL_DIR = ../../thirdparty/openss
+LDFLAGS += -L$(FFMPEG_DIR)/lib
LDFLAGS += -L$(OPENSSL_DIR)/lib
LDFLAGS += -L../../
LDLIBS += -lonvif_std
+LDLIBS += -lavcodec -lavdevice -lavfilter -lavformat \
+ -lavutil -lswresample -lswscale
LDLIBS += -lcrypto -lssl -lpthread -ldl -lm -lrt
INCLUDE += -I../../core/ \
-I../../comm/ \
-I../../service \
+ -I$(FFMPEG_DIR)/include \
-I$(OPENSSL_DIR)/include
CFLAGS += $(INCLUDE)
diff --git a/test/ptz_test/ptz_test.c b/test/ptz_test/ptz_test.c
index 02d924d..bcc04f5 100644
--- a/test/ptz_test/ptz_test.c
+++ b/test/ptz_test/ptz_test.c
@@ -13,7 +13,6 @@
{
int ret;
PosCur pos_get;
- float data;
int preset0, preset1, preset2;
float pval, tval, zval;
float speed_p, speed_t, speed_z;
@@ -131,6 +130,7 @@
* secondly, zoom in the object that is describled with left-up and right-down pixel;
* finally, restore the image as original size;
*/
+ float data;
proto_PTZ_GetStatus(handle, &pos_get, USERNAME, PASSWORD);
proto_PTZGetPT(handle, 0, 0, &pval, &tval, USERNAME, PASSWORD);
proto_PTZSet(handle, pval, tval, pos_get.z, USERNAME, PASSWORD);
--
Gitblit v1.8.0