Linux中用socket 传输视频

117 篇文章 4 订阅
106 篇文章 3 订阅

由于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/

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值