697 lines
20 KiB
C
697 lines
20 KiB
C
#include "app_config.h"
|
|
#ifdef CONFIG_ENABLE_VLIST
|
|
#include "sock_api/sock_api.h"
|
|
#include "os/os_api.h"
|
|
#include "server/net_server.h"
|
|
#include "server/server_core.h"
|
|
#include "server/ctp_server.h"
|
|
#include "server/rt_stream_pkg.h"
|
|
#include "server/simple_mov_unpkg.h"
|
|
#include "packet.h"
|
|
#include "generic/list.h"
|
|
|
|
#define VIDEO_PREVIEW_TASK_NAME "video_preview"
|
|
#define VIDEO_PREVIEW_TASK_STK 0x1000
|
|
#define VIDEO_PREVIEW_TASK_PRIO 22
|
|
|
|
struct __preview {
|
|
struct list_head cli_head;
|
|
u32 id;
|
|
u8 state;
|
|
void *video_preview_sock_hdl;
|
|
int (*cb)(void *priv, u8 *data, size_t len);
|
|
u8 kill_flag;
|
|
|
|
OS_MUTEX mutex;
|
|
|
|
};
|
|
|
|
|
|
static struct __preview preview_info;
|
|
#define preview_info_hander (&preview_info)
|
|
|
|
struct __preview_cli_info {
|
|
struct list_head entry;
|
|
char (*filename)[64];
|
|
u32 num;
|
|
int offset;
|
|
u16 timeinv;
|
|
u8 direct;
|
|
u8 state;
|
|
struct sockaddr_in remote_addr;
|
|
struct __packet_info pinfo;
|
|
u8 kill_flag;
|
|
int pid;
|
|
u32 tmp_is_30fps;
|
|
struct net_req *req;
|
|
};
|
|
|
|
|
|
static void video_preview_cli_thread(void *arg)
|
|
{
|
|
int ret;
|
|
FILE *fd;
|
|
char name[32];
|
|
char buf[256];
|
|
int i = 0;
|
|
int count = 0;
|
|
u32 msec = 0;
|
|
struct __preview_cli_info *cli = (struct __preview_cli_info *)arg;
|
|
|
|
puts("\nstart video_preview_cli_thread\n");
|
|
os_mutex_pend(&preview_info_hander->mutex, 0);
|
|
cli->pinfo.data = (u8 *)zalloc(IMAGE_SIZE);
|
|
cli->pinfo.len = IMAGE_SIZE;
|
|
if (cli->pinfo.data == NULL) {
|
|
printf("%s err , no mem !!!\n\n", __func__);
|
|
CTP_CMD_COMBINED(NULL, CTP_NET_ERR, "MULTI_COVER_FIGURE", "NOTIFY", CTP_NET_ERR_MSG);
|
|
goto err2;
|
|
}
|
|
cli->pinfo.type = PREVIEW_TYPE;
|
|
cli->pinfo.fd = NULL;
|
|
cli->pinfo.fast_play_mask = 0;
|
|
cli->pinfo.state = 0;//预览模式
|
|
while (1) {
|
|
if (!strstr(cli->filename[i], "storage")) {
|
|
send_end_packet(&cli->pinfo);
|
|
sprintf(buf, "status:%d", 1);
|
|
CTP_CMD_COMBINED(NULL, CTP_NO_ERR, "MULTI_COVER_FIGURE", "NOTIFY", buf);
|
|
break;
|
|
}
|
|
|
|
if (cli->kill_flag) {
|
|
printf("wanning : cli->kill_flag : %d \n", cli->kill_flag);
|
|
goto err2;
|
|
}
|
|
printf("filename[%d]:%s \n", i, cli->filename[i]);
|
|
fd = fopen(cli->filename[i], "r");
|
|
if (fd == NULL) {
|
|
printf("%s fopen fail\n", __func__);
|
|
CTP_CMD_COMBINED(NULL, CTP_OPEN_FILE, "MULTI_COVER_FIGURE", "NOTIFY", CTP_OPEN_FILE_MSG);
|
|
i++;
|
|
continue;
|
|
}
|
|
#if (defined CONFIG_NET_PKG_H264)
|
|
if (!is_vaild_mov_file(fd)) {
|
|
/* sprintf(buf, "path_%d:%s", i, cli->filename[i]); */
|
|
printf("%s is Invalid MOV\n", __func__);
|
|
CTP_CMD_COMBINED(NULL, CTP_OPEN_FILE, "MULTI_COVER_FIGURE", "NOTIFY", CTP_OPEN_FILE_MSG);
|
|
i++;
|
|
fclose(fd);
|
|
continue;
|
|
}
|
|
#elif (defined CONFIG_NET_PKG_JPEG)
|
|
avi_net_preview_unpkg_init(fd, cli->pinfo.state);
|
|
if (!is_vaild_avi_file(fd, cli->pinfo.state)) {
|
|
printf("err %s is Invalid AVI!!!\n", __func__);
|
|
CTP_CMD_COMBINED(NULL, CTP_OPEN_FILE, "MULTI_COVER_FIGURE", "NOTIFY", CTP_OPEN_FILE_MSG);
|
|
i++;
|
|
fclose(fd);
|
|
continue;
|
|
}
|
|
#endif
|
|
cli->pinfo.fd = fd;
|
|
strcpy(cli->pinfo.file_name, cli->filename[i]);
|
|
if (update_data(&cli->pinfo)) {
|
|
printf("err get media info fail\n");
|
|
goto err2;
|
|
}
|
|
ret = send_media_packet(&cli->pinfo);
|
|
if (ret <= 0) {
|
|
printf("err send_media_packet\n");
|
|
CTP_CMD_COMBINED(NULL, CTP_NET_ERR, "MULTI_COVER_FIGURE", "NOTIFY", CTP_NET_ERR_MSG);
|
|
goto err2;
|
|
}
|
|
|
|
ret = send_date_packet(&cli->pinfo, 0);
|
|
if (ret <= 0) {
|
|
printf("err send_data_packet\n");
|
|
CTP_CMD_COMBINED(NULL, CTP_NET_ERR, "MULTI_COVER_FIGURE", "NOTIFY", CTP_NET_ERR_MSG);
|
|
goto err2;
|
|
}
|
|
ret = send_video_packet(&cli->pinfo, 0);
|
|
if (ret <= 0) {
|
|
printf("send video preview err !!!!!\n\n");
|
|
CTP_CMD_COMBINED(NULL, CTP_NET_ERR, "MULTI_COVER_FIGURE", "NOTIFY", CTP_NET_ERR_MSG);
|
|
goto err2;
|
|
}
|
|
#if (defined CONFIG_NET_PKG_H264)
|
|
msec = i * cli->pinfo.info.sample_duration * 1000 / cli->pinfo.info.scale;
|
|
if (msec) {
|
|
incr_date_time(&cli->pinfo.time, msec / 1000);
|
|
|
|
}
|
|
#elif (defined CONFIG_NET_PKG_JPEG)
|
|
printf("avi_net_unpkg_exit...\n");
|
|
avi_net_unpkg_exit(fd, cli->pinfo.state);
|
|
#endif
|
|
printf("--%s get preview ok--\n", cli->pinfo.file_name);
|
|
fclose(cli->pinfo.fd);
|
|
cli->pinfo.fd = NULL;
|
|
i++;
|
|
}
|
|
|
|
err2:
|
|
|
|
#if (defined CONFIG_NET_PKG_JPEG)
|
|
avi_net_unpkg_exit(fd, cli->pinfo.state);
|
|
#endif
|
|
|
|
if (cli->filename != NULL) {
|
|
free(cli->filename);
|
|
}
|
|
if (cli->pinfo.info.stco_tab != NULL) {
|
|
free(cli->pinfo.info.stco_tab);
|
|
cli->pinfo.info.stco_tab = NULL;
|
|
}
|
|
if (cli->pinfo.info.stsz_tab != NULL) {
|
|
free(cli->pinfo.info.stsz_tab);
|
|
cli->pinfo.info.stsz_tab = NULL;
|
|
}
|
|
if (cli->pinfo.info.audio_stco_tab != NULL) {
|
|
free(cli->pinfo.info.audio_stco_tab);
|
|
cli->pinfo.info.audio_stco_tab = NULL;
|
|
}
|
|
if (cli->pinfo.fd != NULL) {
|
|
fclose(cli->pinfo.fd);
|
|
cli->pinfo.fd = NULL;
|
|
}
|
|
if (cli->pinfo.data) {
|
|
free(cli->pinfo.data);
|
|
}
|
|
if (cli->req) {
|
|
free(cli->req);
|
|
}
|
|
|
|
list_del(&cli->entry);
|
|
sock_unreg(cli->pinfo.sock);
|
|
cli->pinfo.data = NULL;
|
|
cli->kill_flag = 0;
|
|
free(cli);
|
|
os_mutex_post(&preview_info_hander->mutex);
|
|
|
|
}
|
|
|
|
//后期需要换找I帧的方法
|
|
static int find_idr_frame(struct __packet_info *pinfo, u32 offset)
|
|
{
|
|
int i = 0;
|
|
char buf[5];
|
|
size_t sample_offset;
|
|
size_t sample_size;
|
|
int ret;
|
|
|
|
float frame_per_ts = 0 ;
|
|
|
|
#if (defined CONFIG_NET_H264)
|
|
i = offset * pinfo->info.scale / (pinfo->info.sample_duration * 1000);
|
|
while (1) {
|
|
|
|
if (i >= pinfo->info.video_sample_count) {
|
|
return pinfo->info.video_sample_count - 1;//必须要减1
|
|
}
|
|
|
|
sample_size = get_sample_size(pinfo->info.stsz_tab, i);
|
|
sample_offset = get_chunk_offset(pinfo->info.stco_tab, i);
|
|
fseek(pinfo->fd, sample_offset, SEEK_SET);
|
|
ret = fread(pinfo->fd, buf, 5);
|
|
|
|
if (buf[4] != 0x67) {
|
|
i++;
|
|
} else {
|
|
return i;
|
|
}
|
|
|
|
}
|
|
|
|
#elif (defined CONFIG_NET_JPEG)
|
|
return avi_get_video_num(pinfo->fd, offset, pinfo->state); //返回seq
|
|
#endif
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
static int send_date_per_fps(struct __preview_cli_info *cli, u32 i)
|
|
{
|
|
int ret = 0;
|
|
|
|
int is_30fps = 0;
|
|
u32 sec = (i - cli->tmp_is_30fps) / (cli->pinfo.info.scale / cli->pinfo.info.sample_duration);
|
|
if (sec) {
|
|
|
|
ret = send_date_packet(&cli->pinfo, sec);
|
|
|
|
cli->tmp_is_30fps = i;
|
|
}
|
|
return ret;
|
|
}
|
|
//成功:返回起始帧或结束帧 失败;-1
|
|
static int switch_direct_and_file(struct __preview_cli_info *cli)
|
|
{
|
|
int i = 0;
|
|
|
|
if (cli->direct) {
|
|
//behind
|
|
if (cli->offset <= 0) {
|
|
send_end_packet(&cli->pinfo);
|
|
cli->pinfo.fd = play_prev(&cli->pinfo);
|
|
|
|
if (cli->pinfo.fd == NULL) {
|
|
return -1;
|
|
}
|
|
|
|
update_data(&cli->pinfo);
|
|
cli->offset = ((cli->pinfo.info.durition / cli->pinfo.info.scale) * 1000);
|
|
i = cli->pinfo.info.video_sample_count - 1;
|
|
}
|
|
|
|
} else {
|
|
//forward
|
|
if (cli->offset >= ((cli->pinfo.info.durition / cli->pinfo.info.scale) * 1000)) {
|
|
send_end_packet(&cli->pinfo);
|
|
cli->pinfo.fd = play_next(&cli->pinfo);
|
|
if (cli->pinfo.fd == NULL) {
|
|
return -1;
|
|
}
|
|
update_data(&cli->pinfo);
|
|
i = 0;
|
|
cli->offset = 0;
|
|
}
|
|
|
|
}
|
|
|
|
if (cli->direct) {
|
|
cli->offset -= cli->timeinv;
|
|
} else {
|
|
cli->offset += cli->timeinv;
|
|
}
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
static void video_thus_cli_thread(void *arg)
|
|
{
|
|
int ret;
|
|
FILE *fd;
|
|
char name[32];
|
|
char buf[64];
|
|
int i = 0;
|
|
int count = 0;
|
|
u32 msec = 0;
|
|
struct __preview_cli_info *cli = (struct __preview_cli_info *)arg;
|
|
|
|
printf("\n %s \n", __func__);
|
|
os_mutex_pend(&preview_info_hander->mutex, 0);
|
|
cli->pinfo.data = (u8 *)zalloc(IMAGE_SIZE);
|
|
cli->pinfo.len = IMAGE_SIZE;
|
|
if (cli->pinfo.data == NULL) {
|
|
printf("%s err , no mem !!!\n\n", __func__);
|
|
CTP_CMD_COMBINED(NULL, CTP_NET_ERR, "MULTI_COVER_FIGURE", "NOTIFY", CTP_NET_ERR_MSG);
|
|
goto err2;
|
|
}
|
|
cli->pinfo.type = PREVIEW_TYPE;
|
|
cli->pinfo.fd = NULL;
|
|
cli->pinfo.fast_play_mask = 1;
|
|
cli->pinfo.state = 0;//预览模式
|
|
fd = fopen(cli->filename[i], "r");
|
|
if (fd == NULL) {
|
|
CTP_CMD_COMBINED(NULL, CTP_OPEN_FILE, "THUMBNAILS", "NOTIFY", CTP_OPEN_FILE_MSG);
|
|
goto err2;
|
|
}
|
|
|
|
#if (defined CONFIG_NET_PKG_H264)
|
|
if (!is_vaild_mov_file(fd)) {
|
|
CTP_CMD_COMBINED(NULL, CTP_OPEN_FILE, "THUMBNAILS", "NOTIFY", CTP_OPEN_FILE_MSG);
|
|
fclose(fd);
|
|
goto err2;
|
|
}
|
|
|
|
#elif (defined CONFIG_NET_PKG_JPEG)
|
|
avi_net_playback_unpkg_init(fd, cli->pinfo.state);
|
|
if (!is_vaild_avi_file(fd, cli->pinfo.state)) {
|
|
CTP_CMD_COMBINED(NULL, CTP_OPEN_FILE, "THUMBNAILS", "NOTIFY", CTP_OPEN_FILE_MSG);
|
|
fclose(fd);
|
|
goto err2;
|
|
}
|
|
#endif
|
|
cli->pinfo.fd = fd;
|
|
strcpy(cli->pinfo.file_name, cli->filename[0]);
|
|
if (update_data(&cli->pinfo)) {
|
|
printf("get media info fail\n");
|
|
goto err2;
|
|
}
|
|
ret = send_media_packet(&cli->pinfo);
|
|
if (ret <= 0) {
|
|
CTP_CMD_COMBINED(NULL, CTP_NET_ERR, "THUMBNAILS", "NOTIFY", CTP_NET_ERR_MSG);
|
|
goto err2;
|
|
}
|
|
incr_date_time(&cli->pinfo.time, cli->offset / 1000);
|
|
while (1) {
|
|
if (cli->kill_flag) {
|
|
printf("kill by other thread \n");
|
|
goto err2;
|
|
}
|
|
i = find_idr_frame(&cli->pinfo, cli->offset);
|
|
#if 0 //暂时不用,当时间偏移量大于当前,切换到下视频,AVI不能打开!!!!
|
|
i = switch_direct_and_file(cli);
|
|
|
|
if (i < 0) {
|
|
goto err2;
|
|
}
|
|
#endif
|
|
if ((count + 1) == cli->num) {
|
|
send_end_packet(&cli->pinfo);
|
|
}
|
|
ret = send_date_packet(&cli->pinfo, cli->timeinv / 1000);
|
|
if (ret <= 0) {
|
|
printf("send_data_packet errr !!\n");
|
|
CTP_CMD_COMBINED(NULL, CTP_NET_ERR, "THUMBNAILS", "NOTIFY", CTP_NET_ERR_MSG);
|
|
goto err2;
|
|
}
|
|
|
|
ret = send_video_packet(&cli->pinfo, i);
|
|
if (ret < 0) {
|
|
printf("send_video_packet errr !!\n");
|
|
/* sprintf(buf, "path:%s", cli->filename[i]); */
|
|
CTP_CMD_COMBINED(NULL, CTP_NET_ERR, "THUMBNAILS", "NOTIFY", CTP_NET_ERR_MSG);
|
|
goto err2;
|
|
}
|
|
|
|
count++;
|
|
cli->offset += cli->timeinv;
|
|
if (cli->num != 0 && count == cli->num) {
|
|
sprintf(buf, "status:%d", 1);
|
|
CTP_CMD_COMBINED(NULL, CTP_NO_ERR, "THUMBNAILS", "NOTIFY", buf);
|
|
break;
|
|
}
|
|
}
|
|
puts("------------get thus preview ok----------------\n");
|
|
err2:
|
|
#ifdef CONFIG_NET_PKG_JPEG
|
|
avi_net_unpkg_exit(fd, cli->pinfo.state);
|
|
#endif
|
|
if (cli->pinfo.info.stco_tab != NULL) {
|
|
free(cli->pinfo.info.stco_tab);
|
|
cli->pinfo.info.stco_tab = NULL;
|
|
}
|
|
|
|
if (cli->pinfo.info.stsz_tab != NULL) {
|
|
free(cli->pinfo.info.stsz_tab);
|
|
cli->pinfo.info.stsz_tab = NULL;
|
|
}
|
|
|
|
if (cli->pinfo.info.audio_stco_tab != NULL) {
|
|
free(cli->pinfo.info.audio_stco_tab);
|
|
cli->pinfo.info.audio_stco_tab = NULL;
|
|
}
|
|
|
|
if (cli->pinfo.fd != NULL) {
|
|
fclose(cli->pinfo.fd);
|
|
cli->pinfo.fd = NULL;
|
|
}
|
|
if (cli->pinfo.data) {
|
|
free(cli->pinfo.data);
|
|
}
|
|
if (cli->req) {
|
|
free(cli->req);
|
|
}
|
|
|
|
list_del(&cli->entry);
|
|
sock_unreg(cli->pinfo.sock);
|
|
cli->pinfo.data = NULL;
|
|
cli->kill_flag = 0;
|
|
free(cli);
|
|
os_mutex_post(&preview_info_hander->mutex);
|
|
}
|
|
|
|
|
|
static int create_app_thread(struct net_req *req, void *sock, struct sockaddr_in *remote_addr)
|
|
{
|
|
char name[32];
|
|
static u32 count = 0;
|
|
int ret;
|
|
|
|
struct __preview_cli_info *cli = zalloc(sizeof(struct __preview_cli_info));
|
|
|
|
if (cli == NULL) {
|
|
goto __err1;
|
|
}
|
|
cli->filename = req->pre.filename;
|
|
cli->pinfo.sock = sock;
|
|
cli->pinfo.data = NULL;
|
|
cli->pinfo.len = 0;
|
|
cli->req = req;
|
|
|
|
printf("create cli thread\n");
|
|
memcpy(&cli->remote_addr, remote_addr, sizeof(struct sockaddr_in));
|
|
os_mutex_pend(&preview_info_hander->mutex, 0);
|
|
list_add_tail(&cli->entry, &preview_info_hander->cli_head);
|
|
os_mutex_post(&preview_info_hander->mutex);
|
|
switch (req->pre.type) {
|
|
case PREVIEW:
|
|
sprintf(name, "preview_cli_%d", count++);
|
|
ret = thread_fork(name, 25, 2048, 0, &cli->pid, video_preview_cli_thread, (void *)cli);
|
|
if (ret != OS_NO_ERR) {
|
|
free(cli->req);
|
|
free(cli);
|
|
}
|
|
break;
|
|
|
|
case THUS:
|
|
cli->num = req->pre.num;
|
|
cli->offset = req->pre.offset;
|
|
cli->timeinv = req->pre.timeinv;
|
|
sprintf(name, "thus_cli_%d", count++);
|
|
ret = thread_fork(name, 25, 2048, 0, &cli->pid, video_thus_cli_thread, (void *)cli);
|
|
if (ret != OS_NO_ERR) {
|
|
free(cli->req);
|
|
free(cli);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
free(cli->req);
|
|
free(cli);
|
|
break;
|
|
}
|
|
msleep(100);
|
|
return 0;
|
|
|
|
__err1:
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
int video_preview_req_handler2(void *msg)
|
|
{
|
|
struct sockaddr_in remote_addr;
|
|
fd_set rdset;
|
|
struct timeval tv = {5, 0};//1s不来连接返回错误
|
|
void *sock_hdl = NULL;
|
|
int ret;
|
|
char buf[64];
|
|
socklen_t addrlen = sizeof(remote_addr);
|
|
if (msg == NULL) {
|
|
goto __err1;
|
|
}
|
|
struct net_req *req = (struct net_req *)msg;
|
|
strcpy(buf, "status:0");
|
|
if (req->pre.type == PREVIEW) {
|
|
CTP_CMD_COMBINED(NULL, CTP_NO_ERR, "MULTI_COVER_FIGURE", "NOTIFY", buf);
|
|
} else if (req->pre.type == THUS) {
|
|
CTP_CMD_COMBINED(NULL, CTP_NO_ERR, "THUMBNAILS", "NOTIFY", buf);
|
|
}
|
|
while (1) {
|
|
FD_ZERO(&rdset);
|
|
FD_SET(sock_get_socket(preview_info_hander->video_preview_sock_hdl), &rdset);
|
|
ret = sock_select(preview_info_hander->video_preview_sock_hdl, &rdset, NULL, NULL, &tv);
|
|
if (ret < 0) {
|
|
goto __err1;
|
|
} else if (ret == 0) {
|
|
puts("accept time out\n");
|
|
if (req->pre.type == PREVIEW) {
|
|
CTP_CMD_COMBINED(NULL, CTP_REQUEST, "MULTI_COVER_FIGURE", "NOTIFY", CTP_REQUEST_MSG);
|
|
} else if (req->pre.type == THUS) {
|
|
CTP_CMD_COMBINED(NULL, CTP_REQUEST, "THUMBNAILS", "NOTIFY", CTP_REQUEST_MSG);
|
|
}
|
|
|
|
free(req);
|
|
return -1;
|
|
|
|
} else {
|
|
sock_hdl = sock_accept(preview_info_hander->video_preview_sock_hdl, (struct sockaddr *)&remote_addr, &addrlen, NULL, NULL);
|
|
|
|
if (sock_hdl == NULL) {
|
|
goto __err1;
|
|
}
|
|
|
|
if (create_app_thread(req, sock_hdl, &remote_addr)) {
|
|
goto __err1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
}
|
|
__err1:
|
|
sock_unreg(preview_info_hander->video_preview_sock_hdl);
|
|
free(req);
|
|
return -1;
|
|
|
|
}
|
|
static void pre_thread(void *arg)
|
|
{
|
|
video_preview_req_handler2(arg);
|
|
}
|
|
|
|
int video_preview_post_msg(struct net_req *_req)
|
|
{
|
|
int ret = 0;
|
|
static u32 count = 0;
|
|
char buf[32];
|
|
struct net_req *req = zalloc(sizeof(struct net_req));
|
|
|
|
if (req == NULL) {
|
|
return -1;
|
|
}
|
|
memcpy(req, _req, sizeof(struct net_req));
|
|
sprintf(buf, "pre_thread%d", count++);
|
|
ret = thread_fork(buf, 25, 0x512, 0, 0, pre_thread, (void *)req);
|
|
if (ret != OS_NO_ERR) {
|
|
free(req);
|
|
return -1;
|
|
}
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
int preview_init(u16 port, int callback(void *priv, u8 *data, size_t len))
|
|
{
|
|
puts("preview_init\n");
|
|
int ret;
|
|
struct sockaddr_in dest_addr;
|
|
preview_info_hander->video_preview_sock_hdl = sock_reg(AF_INET, SOCK_STREAM, 0, NULL, NULL);
|
|
|
|
if (preview_info_hander->video_preview_sock_hdl == NULL) {
|
|
printf("%s %d->Error in socket()\n", __func__, __LINE__);
|
|
goto EXIT;
|
|
}
|
|
|
|
if (sock_set_reuseaddr(preview_info_hander->video_preview_sock_hdl)) {
|
|
printf("%s %d->Error in sock_set_reuseaddr(),errno=%d\n", __func__, __LINE__, errno);
|
|
goto EXIT;
|
|
}
|
|
|
|
dest_addr.sin_family = AF_INET;
|
|
dest_addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
dest_addr.sin_port = htons(port);
|
|
ret = sock_bind(preview_info_hander->video_preview_sock_hdl, (struct sockaddr *)&dest_addr, sizeof(struct sockaddr));
|
|
|
|
if (ret) {
|
|
printf("%s %d->Error in bind(),errno=%d\n", __func__, __LINE__, errno);
|
|
goto EXIT;
|
|
}
|
|
|
|
ret = sock_listen(preview_info_hander->video_preview_sock_hdl, 0xff);
|
|
|
|
if (ret) {
|
|
printf("%s %d->Error in listen()\n", __func__, __LINE__);
|
|
goto EXIT;
|
|
}
|
|
|
|
os_mutex_create(&preview_info_hander->mutex);
|
|
INIT_LIST_HEAD(&preview_info_hander->cli_head);
|
|
|
|
return 0;
|
|
EXIT:
|
|
sock_unreg(preview_info_hander->video_preview_sock_hdl);
|
|
preview_info_hander->video_preview_sock_hdl = NULL;
|
|
return -1;
|
|
}
|
|
int video_preview_and_thus_all_disconnect(void)
|
|
{
|
|
puts("---------------video_cli_disconnect\n\n");
|
|
struct __preview_cli_info *cli = NULL;
|
|
struct list_head *pos = NULL, *node = NULL;
|
|
os_mutex_pend(&preview_info_hander->mutex, 0);
|
|
if (list_empty(&preview_info_hander->cli_head)) {
|
|
puts("video_preview cli is emtry\n");
|
|
os_mutex_post(&preview_info_hander->mutex);
|
|
return -1;
|
|
}
|
|
|
|
list_for_each_safe(pos, node, &preview_info_hander->cli_head) {
|
|
cli = list_entry(pos, struct __preview_cli_info, entry);
|
|
cli->kill_flag = 1;
|
|
sock_set_quit(cli->pinfo.sock);
|
|
}
|
|
os_mutex_post(&preview_info_hander->mutex);
|
|
return 0;
|
|
|
|
}
|
|
void preview_uninit(void)
|
|
{
|
|
video_preview_and_thus_all_disconnect();
|
|
sock_unreg(preview_info_hander->video_preview_sock_hdl);
|
|
os_mutex_del(&preview_info_hander->mutex, OS_DEL_ALWAYS);
|
|
}
|
|
|
|
int video_cli_slide(struct sockaddr_in *dst_addr, u8 direct)
|
|
{
|
|
struct __preview_cli_info *cli = NULL;
|
|
struct list_head *pos = NULL, *node = NULL;
|
|
os_mutex_pend(&preview_info_hander->mutex, 0);
|
|
if (list_empty(&preview_info_hander->cli_head)) {
|
|
puts("video_preview cli is emtry\n");
|
|
os_mutex_post(&preview_info_hander->mutex);
|
|
return -1;
|
|
}
|
|
|
|
list_for_each_safe(pos, node, &preview_info_hander->cli_head) {
|
|
cli = list_entry(pos, struct __preview_cli_info, entry);
|
|
|
|
if (cli->remote_addr.sin_addr.s_addr == dst_addr->sin_addr.s_addr
|
|
&& cli->remote_addr.sin_port == dst_addr->sin_port) {
|
|
cli->direct = direct;
|
|
os_mutex_post(&preview_info_hander->mutex);
|
|
return 0;
|
|
}
|
|
}
|
|
os_mutex_post(&preview_info_hander->mutex);
|
|
return -1;
|
|
|
|
}
|
|
int video_preview_and_thus_disconnect(struct sockaddr_in *dst_addr)
|
|
{
|
|
struct __preview_cli_info *cli = NULL;
|
|
struct list_head *pos = NULL, *node = NULL;
|
|
|
|
os_mutex_pend(&preview_info_hander->mutex, 0);
|
|
if (list_empty(&preview_info_hander->cli_head)) {
|
|
puts("video_preview cli is emtry\n");
|
|
os_mutex_post(&preview_info_hander->mutex);
|
|
return -1;
|
|
}
|
|
|
|
|
|
list_for_each_safe(pos, node, &preview_info_hander->cli_head) {
|
|
cli = list_entry(pos, struct __preview_cli_info, entry);
|
|
|
|
if (dst_addr != NULL
|
|
&& cli->remote_addr.sin_addr.s_addr == dst_addr->sin_addr.s_addr) {
|
|
cli->kill_flag = 1;
|
|
sock_set_quit(cli->pinfo.sock);
|
|
os_mutex_post(&preview_info_hander->mutex);
|
|
return 0;
|
|
}
|
|
}
|
|
os_mutex_post(&preview_info_hander->mutex);
|
|
printf("%s not find it\n", __func__);
|
|
return -1;
|
|
|
|
}
|
|
#endif
|