完整无线视频传输程序(已封装)
2012-09-19 22:55
351 查看
/*
* tcp.cpp
*
* Created on: 2012-5-20
* Author: root
*/
#include "tcp.h"
#include "opencv2/opencv.hpp"
/*defines*/
#define BUFFER_SIZE 1024
#define success 1
#define error 0
#define SERVER_PORT1 9000 //发送图片的端口
#define SERVER_PORT2 8000 //接收Rect的端口
#define SERVER_PORT3 7000 //接收控制指令的端口
#define SERVER_PORT4 10000 //发送UWB坐标回地面站
#define LISTEN_QUEUE 20
/*TCP varies*/
//int sock_fd; //定义端口文件描述符
/*以下全是外部变量*/
int new_server_socket1;
int new_server_socket2;
int new_server_socket3;
int new_server_socket4;
int server_socket1,server_socket2,server_socket3,server_socket4;
int pthread_ret1,pthread_ret2,pthread_ret3,pthread_ret4;
pthread_t id1,id2,id3,id4;
/*外部函数声明*/
extern void *ImgProc_Thread(void *id);
extern void *RecvRect_Thread(void *);
extern void *RecvCmd_Thread(void *id);
extern void *SendCoordinate2UGS(void *id);
FILE* stream; //文件指针
//char Image_Buffer[1024*100]; //将缓冲区设置为100k
//char buffer[BUFFER_SIZE]; //BUFFER_SIZE 1024b
int sock_buf_size=1024*100; //这是用来设置TCP缓冲区的
/*vector*/
vector<unsigned char>buf; //乘放的容器
vector<int> compression_params;
/*存放强制从vector转换来的图片数据*/
unsigned char* buffer;
/*function*/
void Server_Init(void)
{
/*设计思路,端口是对应应用的,所以每个连接使用的应该是不一样的端口(未经过验证)*/
struct sockaddr_in server_addr1; //定义地址结构,创建此服务器端口用来发送图像数据(端口是面向应用的)
struct sockaddr_in server_addr2; //连接此服务器端口用来接收地面站发过来的Rect
struct sockaddr_in server_addr3; //连接此服务器端口用来接收地面站发送来的控制指令
struct sockaddr_in server_addr4; //连接此服务器端口用来发送UWB坐标给UGS
struct sockaddr_in client_addr1;
struct sockaddr_in client_addr2;
struct sockaddr_in client_addr3;
struct sockaddr_in client_addr4;
socklen_t length1=sizeof(client_addr1);
socklen_t length2=sizeof(client_addr2);
socklen_t length3=sizeof(client_addr3);
socklen_t length4=sizeof(client_addr4);
bzero(&server_addr1,sizeof(server_addr1)); //全部置零
bzero(&server_addr2,sizeof(server_addr2));
bzero(&server_addr3,sizeof(server_addr3));
bzero(&server_addr4,sizeof(server_addr4));
//设置地址相关的属性
server_addr1.sin_family=AF_INET;
server_addr1.sin_addr.s_addr=htons(INADDR_ANY);
server_addr1.sin_port=htons(SERVER_PORT1);
server_addr2.sin_family=AF_INET;
server_addr2.sin_addr.s_addr=htons(INADDR_ANY);
server_addr2.sin_port=htons(SERVER_PORT2);
server_addr3.sin_family=AF_INET;
server_addr3.sin_addr.s_addr=htons(INADDR_ANY);
server_addr3.sin_port=htons(SERVER_PORT3);
server_addr4.sin_family=AF_INET;
server_addr4.sin_addr.s_addr=htons(INADDR_ANY);
server_addr4.sin_port=htons(SERVER_PORT4);
server_socket1=socket(AF_INET,SOCK_STREAM,0); //第一步,创建socket
if(server_socket1<0)
{
printf("socket1 create error\n");
exit(1);
}
server_socket2=socket(AF_INET,SOCK_STREAM,0); //第一步,创建socket
if(server_socket2<0)
{
printf("socket2 create error\n");
exit(1);
}
server_socket3=socket(AF_INET,SOCK_STREAM,0); //第一步,创建socket
if(server_socket3<0)
{
printf("socket3 create error\n");
exit(1);
}
server_socket4=socket(AF_INET,SOCK_STREAM,0); //第一步,创建socket
if(server_socket4<0)
{
printf("socket4 create error\n");
exit(1);
}
/*以下的函数还没确认是不是有用*/
// setsockopt( server_socket, SOL_SOCKET, SO_RCVBUF,
// (char *)&sock_buf_size, sizeof(sock_buf_size) );//设置接收缓冲区大小
/*第二步,端口和IP地址绑定:只有TCP的服务器端才需要这个步骤*/
if(bind(server_socket1,(struct sockaddr*)&server_addr1,sizeof(server_addr1)))
{
printf("IP address 1 bind error\n");
exit(1);
}
if(bind(server_socket2,(struct sockaddr*)&server_addr2,sizeof(server_addr2)))
{
printf("IP address 2 bind error\n");
exit(1);
}
if(bind(server_socket3,(struct sockaddr*)&server_addr3,sizeof(server_addr3)))
{
printf("IP address 3 bind error\n");
exit(1);
}
if(bind(server_socket4,(struct sockaddr*)&server_addr4,sizeof(server_addr4)))
{
printf("IP address 4 bind error\n");
exit(1);
}
/*服务器端监听server_socket端口,最多响应20个客户端请求*/
if(listen(server_socket1,LISTEN_QUEUE))
{
printf("Ground station 1 listen error\n");
exit(1);
}
printf("Video Transmission socket waiting for connection...\n");
if(listen(server_socket2,LISTEN_QUEUE))
{
printf("Ground station 2 listen error\n");
exit(1);
}
printf("TLD Rect receiving socket waiting connection...\n");
if(listen(server_socket3,LISTEN_QUEUE))
{
printf("Ground station 3 listen error\n");
exit(1);
}
printf("UAV Control CMD transmission socket waiting connection...\n");
if(listen(server_socket4,LISTEN_QUEUE))
{
printf("Ground station 3 listen error\n");
exit(1);
}
printf("UWB Coordinate Sending back socket waiting for connection...\n");
/*accept函数阻塞等待UAV的connect请求*/
/**************************************************************************************************/
/*考虑到accept()函数是阻塞模式,而连接请求又是确定的,故设计两次接收*/
new_server_socket1=accept(server_socket1,(struct sockaddr*)&client_addr1,&length1);
if(new_server_socket1==-1)
{
printf("accept1 error!\n");
exit(0);
}
printf("Connect with Ground Station sock1 successfully--GS IP:%s\n",inet_ntoa(client_addr1.sin_addr));
pthread_ret1=pthread_create(&id1,NULL,ImgProc_Thread,&new_server_socket1);//创建一个线程
/*************************************************************************************************/
/*已经将new_server_socket作为入口参数传入*/
new_server_socket2=accept(server_socket2,(struct sockaddr*)&client_addr2,&length2);
if(new_server_socket2==-1)
{
printf("accept2 error!\n");
exit(0);
}
printf("Connect with Ground Station sock2 successfully--GS IP:%s\n",inet_ntoa(client_addr2.sin_addr));
pthread_ret2=pthread_create(&id2,NULL,RecvRect_Thread,&new_server_socket2);//创建接收线程
/**********************************************************************************************/
new_server_socket3=accept(server_socket3,(struct sockaddr*)&client_addr3,&length3);
if(new_server_socket3==-1)
{
printf("accept3 error!\n");
}
printf("Connect with Ground Station sock3 successfully--GS IP:%s\n",inet_ntoa(client_addr3.sin_addr));
/*创建命令接收线程*/
pthread_ret3=pthread_create(&id3,NULL,RecvCmd_Thread,&new_server_socket3);
/*********************************************************************************************/
new_server_socket4=accept(server_socket4,(struct sockaddr*)&client_addr4,&length4);
if(new_server_socket4==-1)
{
printf("accept4 error!\n");
}
printf("Connect with Ground Station sock4 successfully--GS IP:%s\n",inet_ntoa(client_addr4.sin_addr));
/*创建命令接收线程*/
pthread_ret4=pthread_create(&id4,NULL,SendCoordinate2UGS,&new_server_socket4);
}
/*图像压缩编码并发送
* 入口参数:Mat image
* 出口参数:无
* 设计思路:不写成文件,直接存到内存,防止频繁硬盘读写耗费时间
* 最后修改:2012-5-24
* */
void Encode_Send(Mat img,int sock_fd)
{
int packet_cnt=0;
int send_len=0;
/*初始化全局参数*/
compression_params.push_back(CV_IMWRITE_JPEG_QUALITY);
compression_params.push_back(60); //这是数值的大小反映的是图像的质量,取值范围:0-100
bool res = imencode(".jpg",img,buf,compression_params);
if(res==1)
{
// cout<<"Ecode one image done!"<<endl;
}
/*压缩处理的jpg图片尺寸不会超过int 65535*/
int left_length = buf.size(); //这个buf的大小是不是取出的图像数据的大小
//printf("total_length:%d\n",left_length);
/*先发送图片的大小*/
send(sock_fd,&left_length,sizeof(int),0);
//printf("Send jpg_len done!\n");
unsigned char* buffer; //存放从vector强制转换来的图像数据
/*添加动态内存管理2012-5-30*/
buffer = (unsigned char*)malloc(left_length*sizeof(unsigned char));
unsigned char dest[1024];
buffer=(unsigned char *)&buf[0];
while(left_length>1024)
{
send_len=send(sock_fd,memcpy(dest,buffer+packet_cnt*1024,1024),1024,0);
if(send_len<0)
printf("send error!\n");
left_length-=1024;
packet_cnt++;
}
/*剩余数据小于1024*/
send_len=send(sock_fd,memcpy(dest,buffer+packet_cnt*1024,left_length),left_length,0);
if(send_len!=left_length)
{
printf("last packets send error!\n");
}
else
{
//printf("Last packets len:%d\n",send_len);
}
}
/*接收bounding box的坐标值
* 入口参数:无
* 出口参数:Rect 即为接收到的矩形框*/
Rect Recv_BoundingBox(int sock_fd)
{
Rect box;
box.x=0;
box.y=0;
box.width=0;
box.height=0;
printf("wait Ground station to send back the Rect\n");
int len=recv(sock_fd,&box,sizeof(Rect),0);
if(len!=sizeof(Rect))
{
printf("Rect receive error!\n");
}
//printf("box.x: box.y: box.w: box.h: %d %d %d %d %d\n",box.x,box.y,box.width,box.height);
return box;
}
* tcp.cpp
*
* Created on: 2012-5-20
* Author: root
*/
#include "tcp.h"
#include "opencv2/opencv.hpp"
/*defines*/
#define BUFFER_SIZE 1024
#define success 1
#define error 0
#define SERVER_PORT1 9000 //发送图片的端口
#define SERVER_PORT2 8000 //接收Rect的端口
#define SERVER_PORT3 7000 //接收控制指令的端口
#define SERVER_PORT4 10000 //发送UWB坐标回地面站
#define LISTEN_QUEUE 20
/*TCP varies*/
//int sock_fd; //定义端口文件描述符
/*以下全是外部变量*/
int new_server_socket1;
int new_server_socket2;
int new_server_socket3;
int new_server_socket4;
int server_socket1,server_socket2,server_socket3,server_socket4;
int pthread_ret1,pthread_ret2,pthread_ret3,pthread_ret4;
pthread_t id1,id2,id3,id4;
/*外部函数声明*/
extern void *ImgProc_Thread(void *id);
extern void *RecvRect_Thread(void *);
extern void *RecvCmd_Thread(void *id);
extern void *SendCoordinate2UGS(void *id);
FILE* stream; //文件指针
//char Image_Buffer[1024*100]; //将缓冲区设置为100k
//char buffer[BUFFER_SIZE]; //BUFFER_SIZE 1024b
int sock_buf_size=1024*100; //这是用来设置TCP缓冲区的
/*vector*/
vector<unsigned char>buf; //乘放的容器
vector<int> compression_params;
/*存放强制从vector转换来的图片数据*/
unsigned char* buffer;
/*function*/
void Server_Init(void)
{
/*设计思路,端口是对应应用的,所以每个连接使用的应该是不一样的端口(未经过验证)*/
struct sockaddr_in server_addr1; //定义地址结构,创建此服务器端口用来发送图像数据(端口是面向应用的)
struct sockaddr_in server_addr2; //连接此服务器端口用来接收地面站发过来的Rect
struct sockaddr_in server_addr3; //连接此服务器端口用来接收地面站发送来的控制指令
struct sockaddr_in server_addr4; //连接此服务器端口用来发送UWB坐标给UGS
struct sockaddr_in client_addr1;
struct sockaddr_in client_addr2;
struct sockaddr_in client_addr3;
struct sockaddr_in client_addr4;
socklen_t length1=sizeof(client_addr1);
socklen_t length2=sizeof(client_addr2);
socklen_t length3=sizeof(client_addr3);
socklen_t length4=sizeof(client_addr4);
bzero(&server_addr1,sizeof(server_addr1)); //全部置零
bzero(&server_addr2,sizeof(server_addr2));
bzero(&server_addr3,sizeof(server_addr3));
bzero(&server_addr4,sizeof(server_addr4));
//设置地址相关的属性
server_addr1.sin_family=AF_INET;
server_addr1.sin_addr.s_addr=htons(INADDR_ANY);
server_addr1.sin_port=htons(SERVER_PORT1);
server_addr2.sin_family=AF_INET;
server_addr2.sin_addr.s_addr=htons(INADDR_ANY);
server_addr2.sin_port=htons(SERVER_PORT2);
server_addr3.sin_family=AF_INET;
server_addr3.sin_addr.s_addr=htons(INADDR_ANY);
server_addr3.sin_port=htons(SERVER_PORT3);
server_addr4.sin_family=AF_INET;
server_addr4.sin_addr.s_addr=htons(INADDR_ANY);
server_addr4.sin_port=htons(SERVER_PORT4);
server_socket1=socket(AF_INET,SOCK_STREAM,0); //第一步,创建socket
if(server_socket1<0)
{
printf("socket1 create error\n");
exit(1);
}
server_socket2=socket(AF_INET,SOCK_STREAM,0); //第一步,创建socket
if(server_socket2<0)
{
printf("socket2 create error\n");
exit(1);
}
server_socket3=socket(AF_INET,SOCK_STREAM,0); //第一步,创建socket
if(server_socket3<0)
{
printf("socket3 create error\n");
exit(1);
}
server_socket4=socket(AF_INET,SOCK_STREAM,0); //第一步,创建socket
if(server_socket4<0)
{
printf("socket4 create error\n");
exit(1);
}
/*以下的函数还没确认是不是有用*/
// setsockopt( server_socket, SOL_SOCKET, SO_RCVBUF,
// (char *)&sock_buf_size, sizeof(sock_buf_size) );//设置接收缓冲区大小
/*第二步,端口和IP地址绑定:只有TCP的服务器端才需要这个步骤*/
if(bind(server_socket1,(struct sockaddr*)&server_addr1,sizeof(server_addr1)))
{
printf("IP address 1 bind error\n");
exit(1);
}
if(bind(server_socket2,(struct sockaddr*)&server_addr2,sizeof(server_addr2)))
{
printf("IP address 2 bind error\n");
exit(1);
}
if(bind(server_socket3,(struct sockaddr*)&server_addr3,sizeof(server_addr3)))
{
printf("IP address 3 bind error\n");
exit(1);
}
if(bind(server_socket4,(struct sockaddr*)&server_addr4,sizeof(server_addr4)))
{
printf("IP address 4 bind error\n");
exit(1);
}
/*服务器端监听server_socket端口,最多响应20个客户端请求*/
if(listen(server_socket1,LISTEN_QUEUE))
{
printf("Ground station 1 listen error\n");
exit(1);
}
printf("Video Transmission socket waiting for connection...\n");
if(listen(server_socket2,LISTEN_QUEUE))
{
printf("Ground station 2 listen error\n");
exit(1);
}
printf("TLD Rect receiving socket waiting connection...\n");
if(listen(server_socket3,LISTEN_QUEUE))
{
printf("Ground station 3 listen error\n");
exit(1);
}
printf("UAV Control CMD transmission socket waiting connection...\n");
if(listen(server_socket4,LISTEN_QUEUE))
{
printf("Ground station 3 listen error\n");
exit(1);
}
printf("UWB Coordinate Sending back socket waiting for connection...\n");
/*accept函数阻塞等待UAV的connect请求*/
/**************************************************************************************************/
/*考虑到accept()函数是阻塞模式,而连接请求又是确定的,故设计两次接收*/
new_server_socket1=accept(server_socket1,(struct sockaddr*)&client_addr1,&length1);
if(new_server_socket1==-1)
{
printf("accept1 error!\n");
exit(0);
}
printf("Connect with Ground Station sock1 successfully--GS IP:%s\n",inet_ntoa(client_addr1.sin_addr));
pthread_ret1=pthread_create(&id1,NULL,ImgProc_Thread,&new_server_socket1);//创建一个线程
/*************************************************************************************************/
/*已经将new_server_socket作为入口参数传入*/
new_server_socket2=accept(server_socket2,(struct sockaddr*)&client_addr2,&length2);
if(new_server_socket2==-1)
{
printf("accept2 error!\n");
exit(0);
}
printf("Connect with Ground Station sock2 successfully--GS IP:%s\n",inet_ntoa(client_addr2.sin_addr));
pthread_ret2=pthread_create(&id2,NULL,RecvRect_Thread,&new_server_socket2);//创建接收线程
/**********************************************************************************************/
new_server_socket3=accept(server_socket3,(struct sockaddr*)&client_addr3,&length3);
if(new_server_socket3==-1)
{
printf("accept3 error!\n");
}
printf("Connect with Ground Station sock3 successfully--GS IP:%s\n",inet_ntoa(client_addr3.sin_addr));
/*创建命令接收线程*/
pthread_ret3=pthread_create(&id3,NULL,RecvCmd_Thread,&new_server_socket3);
/*********************************************************************************************/
new_server_socket4=accept(server_socket4,(struct sockaddr*)&client_addr4,&length4);
if(new_server_socket4==-1)
{
printf("accept4 error!\n");
}
printf("Connect with Ground Station sock4 successfully--GS IP:%s\n",inet_ntoa(client_addr4.sin_addr));
/*创建命令接收线程*/
pthread_ret4=pthread_create(&id4,NULL,SendCoordinate2UGS,&new_server_socket4);
}
/*图像压缩编码并发送
* 入口参数:Mat image
* 出口参数:无
* 设计思路:不写成文件,直接存到内存,防止频繁硬盘读写耗费时间
* 最后修改:2012-5-24
* */
void Encode_Send(Mat img,int sock_fd)
{
int packet_cnt=0;
int send_len=0;
/*初始化全局参数*/
compression_params.push_back(CV_IMWRITE_JPEG_QUALITY);
compression_params.push_back(60); //这是数值的大小反映的是图像的质量,取值范围:0-100
bool res = imencode(".jpg",img,buf,compression_params);
if(res==1)
{
// cout<<"Ecode one image done!"<<endl;
}
/*压缩处理的jpg图片尺寸不会超过int 65535*/
int left_length = buf.size(); //这个buf的大小是不是取出的图像数据的大小
//printf("total_length:%d\n",left_length);
/*先发送图片的大小*/
send(sock_fd,&left_length,sizeof(int),0);
//printf("Send jpg_len done!\n");
unsigned char* buffer; //存放从vector强制转换来的图像数据
/*添加动态内存管理2012-5-30*/
buffer = (unsigned char*)malloc(left_length*sizeof(unsigned char));
unsigned char dest[1024];
buffer=(unsigned char *)&buf[0];
while(left_length>1024)
{
send_len=send(sock_fd,memcpy(dest,buffer+packet_cnt*1024,1024),1024,0);
if(send_len<0)
printf("send error!\n");
left_length-=1024;
packet_cnt++;
}
/*剩余数据小于1024*/
send_len=send(sock_fd,memcpy(dest,buffer+packet_cnt*1024,left_length),left_length,0);
if(send_len!=left_length)
{
printf("last packets send error!\n");
}
else
{
//printf("Last packets len:%d\n",send_len);
}
}
/*接收bounding box的坐标值
* 入口参数:无
* 出口参数:Rect 即为接收到的矩形框*/
Rect Recv_BoundingBox(int sock_fd)
{
Rect box;
box.x=0;
box.y=0;
box.width=0;
box.height=0;
printf("wait Ground station to send back the Rect\n");
int len=recv(sock_fd,&box,sizeof(Rect),0);
if(len!=sizeof(Rect))
{
printf("Rect receive error!\n");
}
//printf("box.x: box.y: box.w: box.h: %d %d %d %d %d\n",box.x,box.y,box.width,box.height);
return box;
}
相关文章推荐
- 无线图像(视频)传输系统ARM9+Atmega16+OV7620+nrf24l01
- H264 视频文件 帧格式 传输封装等 杂碎
- videocapture库制作python视频高速传输程序
- 视频无线传输设备
- 微信小程序教学第二章(含视频):小程序中级实战教程之预备篇 - 封装网络请求及 mock 数据
- 微信小程序教学第二章(含视频):小程序中级实战教程之预备篇 - 封装网络请求及 mock 数据
- H264 视频文件 帧格式 传输封装等
- 基于UDP协议的简单基本视频传输程序的编写
- 无线视频传输任务的进展与问题
- 转:使用Java RTP传输声音和视频的程序(绝对经典)
- 无线视频、音频传输模块的驱动编程(RC5808)
- 基于EasyDarwin的实现无人机远程视频传输--RTSP初始化程序分析
- [转]步入成熟的无线视频应用 英特尔WiDi无线视频传输研究
- 【转】H264 视频文件 帧格式 传输封装等 杂碎
- H264 视频文件 帧格式 传输封装等 杂碎
- 《视频直播技术详解》之二:编码和封装、推流和传输
- 无线高清视频传输设计中需要考虑的几个要点(转贴)
- 基于RTP/RTCP的无线视频传输自适应带宽控制
- H264 视频文件 帧格式 传输封装等 杂碎