由于socket在传输时,是对socket文件描述符进行写和读,所以在发送端只需把要保存到文件中的数据写进socket文件里,在接收端只需从socket文件中读去数据就行了。流程如下:
接收端:(server)
创建socket->listen->accept->read(recv)-> decode->display
发送端: (client)
创建socket->connect->capture->encode->write(send)
需要说明的是,上面的流程图只是概念的说明,写、读和编、解码是在一个线程函数里的,为了将来和音频一起传输,视频部分是线程执行。部分程序代码如下:
接收端:(server)
1、main函数功能:
client_fd=receive_init(&server_fd,port);
pthread_create(&dec_tid,NULL, (void *)decode, (void *)&arg);
2、 receive_init函数代码:
int
receive_init(int *sock_fd,int port)
{
int temp_sock_fd;
int err;
err=*sock_fd= socket(AF_INET,SOCK_STREAM,0);
if (err==-1){
perror(”socket”);
return -1;
}
server_addr.sin_family=AF_INET;
server_addr.sin_port=htons(port);
server_addr.sin_addr.s_addr=INADDR_ANY;
err=bind(*sock_fd,(struct sockaddr *)&
server_addr,sizeof(server_addr));
if(err==-1){
printf(”socket bind failed!\n”);
return -1;
}
err=listen(*sock_fd,2);
if (err==-1){
printf(”socket listen failed!\n”);
}
temp_sock_fd=accept(* sock_fd,(struct sockaddr *)NULL,NULL);
return temp_sock_fd;
}
3、decode函数比较复杂,大致内容:配置、申请bitstream空间、接受数据、解码、显示
发送端(client):
1、main函数功能:
pthread_create(&enc_tid,NULL,(void *)encode, (void *)&arg);
2、send_init函数代码
int
send_init(int *sock_fd,char *host_addr,int port)
{
int err;
struct sockaddr_in server_addr;
server_addr.sin_family=AF_INET;
server_addr.sin_port=htons(port);
server_addr.sin_addr.s_addr=inet_addr(host_addr);
*sock_fd=socket(AF_INET,SOCK_STREAM,0);
err=connect(*sock_fd,(struct sockaddr *)&
server_addr,sizeof(server_addr));
if (err==-1){
perror(”connect”);
return -1;
}
return 0;
}
3、encode代码依然很复杂,基本内容:配置、申请bitstream空间、捕获、编码、发送数据
开头提到的延迟和停顿的问题的原因是,在接收端读数据的时候,每次实际上都读了很大很大的值,也即readn(int socket_fd, void *buff, int size) 第三个参数size取得太大,每次都会花很长的时间去读很小的数据,最后把size改成比发送端writen所发送的size稍大一些。汗啊。。。都是因为视频部分太依赖测试代码了,自己没有好好想清楚!
原文出处:http://www.isongzi.com/2009/04/13/socket-video/
又折腾了一段时间,终于把视频传输部分搞定了。基本思路其实很简单,开始时候一直有将近20秒的延迟并且画面之间会有停顿,就是因为一个小问题没有发现。
由于socket在传输时,是对socket文件描述符进行写和读,所以在发送端只需把要保存到文件中的数据写进socket文件里,在接收端只需从socket文件中读去数据就行了。流程如下:
接收端:(server)
创建socket->listen->accept->read(recv)-> decode->display
发送端: (client)
创建socket->connect->capture->encode->write(send)
需要说明的是,上面的流程图只是概念的说明,写、读和编、解码是在一个线程函数里的,为了将来和音频一起传输,视频部分是线程执行。部分程序代码如下:
接收端:(server)
1、main函数功能:
/*服务器端初始化,获得socket描述符-server_fd和cleint_fd,并且等待客户端连接*/
client_fd=receive_init(&server_fd,port);
/*创建接收、解码、显示线程*/
pthread_create(&dec_tid,NULL, (void *)decode, (void *)&arg);
2、 receive_init函数代码:
int
receive_init(int *sock_fd,int port)
{ struct sockaddr_in server_addr;
int temp_sock_fd;
int err;
err=*sock_fd= socket(AF_INET,SOCK_STREAM,0);
if (err==-1){
perror(”socket”);
return -1;
}
server_addr.sin_family=AF_INET;
server_addr.sin_port=htons(port);
server_addr.sin_addr.s_addr=INADDR_ANY;
err=bind(*sock_fd,(struct sockaddr *)&
server_addr,sizeof(server_addr));
if(err==-1){
printf(”socket bind failed!\n”);
return -1;
}
err=listen(*sock_fd,2);
if (err==-1){
printf(”socket listen failed!\n”);
}
temp_sock_fd=accept(* sock_fd,(struct sockaddr *)NULL,NULL);
return temp_sock_fd;
}
3、decode函数比较复杂,大致内容:配置、申请bitstream空间、接受数据、解码、显示
发送端(client):
1、main函数功能:
/*客户端初始化,获得socket描述符-socket_fd,连接服务器*
send_init(&sock_fd,host_addr,port);
/*创建捕获、编码、发送线程*/
pthread_create(&enc_tid,NULL,(void *)encode, (void *)&arg);
2、send_init函数代码
int
send_init(int *sock_fd,char *host_addr,int port)
{
int err;
/*init server address*/
struct sockaddr_in server_addr;
server_addr.sin_family=AF_INET;
server_addr.sin_port=htons(port);
server_addr.sin_addr.s_addr=inet_addr(host_addr);
*sock_fd=socket(AF_INET,SOCK_STREAM,0);
/*connect to server*/
err=connect(*sock_fd,(struct sockaddr *)&
server_addr,sizeof(server_addr));
if (err==-1){
perror(”connect”);
return -1;
}
return 0;
}
3、encode代码依然很复杂,基本内容:配置、申请bitstream空间、捕获、编码、发送数据
开头提到的延迟和停顿的问题的原因是,在接收端读数据的时候,每次实际上都读了很大很大的值,也即readn(int socket_fd, void *buff, int size) 第三个参数size取得太大,每次都会花很长的时间去读很小的数据,最后把size改成比发送端writen所发送的size稍大一些。汗啊。。。都是因为视频部分太依赖测试代码了,自己没有好好想清楚!
问题的解决多亏了一专业程序员的指点啊,讨论、修改了一晚上,其实只需改个参数的大小。结论:经验太重要了。。。
http://blog.sina.com.cn/s/blog_4da4ea3c0100q6z3.html
http://blog.163.com/hao_ff/blog/static/5287416200910291944445/