您的位置:首页 > 运维架构 > Linux

Linux中用socket 传输视频

2012-05-12 18:16 423 查看
由于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)

{ 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函数功能:

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/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: