#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;
|
|
}
|
|
|