1、socket发送一帧MJPG格式的流:
2、保存的照片格式为jpeg,文件后缀为.jpg
3、通过x264库实现yuv格式编码为h264的视频
也可使用librtmp发布H.264码流(通过RTMP)主要包括:初始化RTMP,建立RTMP协议中的NetConnection和NetStream,从内存中读取NAL单元,解码SPS获得视频的宽\高\帧率,发送NAL,如果是关键帧,则在发送该帧之前先发送SPS和PPS,发送RTMP数据RTMPPacke,关闭RTMP连接,关闭RTMP和Socket。
二 Http协议
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG;//彩色空间
//判断客户端要什么类型的数据
if(strstr(head,"action=snap") != NULL)
{
printf("action:sanpshot\n");
clients++;//已连接客户端线程数+1
printf("cilents:%d\n",clients);
action = 0;
}
else if(strstr(head,"action=stream") != NULL)
{
printf("action:stream\n");
clients++;
printf("cilents:%d\n",clients);
action = 1;
}
else
{
printf("unknown action\n");
out_addr_port(&caddr);
th_exit(sockfd);
}
//http响应由3部分组成,分别是:状态行、消息报头、响应正文
memset(head,0,BUFFER_LEN);
sprintf(head,"HTTP/1.0 200 OK\r\n"\ //状态行
"Connection: Keep-Alive\r\n"\
"Server: Network camera\r\n"\
"Cache-Control: no-cache,no-store,must-revalidate,pre-check=0,max-age=0\r\n"\
"Pragma: no-cache\r\n"\
"Content-Type: multipart/x-mixed-replace;boundary=KK\r\n");
printf("----------server_head-----------\n");
write(STDOUT_FILENO,head,strlen(head));
if(write(sockfd,head,strlen(head)) != strlen(head))
{
fprintf(stderr,"write: %s\n",strerror(errno));
}
printf("-----------head_end-------------\n");
}
while(1)
{
sprintf(head,"\r\n--KK\r\n"\
"Content-Type: image/jpeg\n"\
"Content-Length: %d\n\n",buffer[okindex].length+432);
size = write(sockfd,head,strlen(head));
if(size != strlen(head))
{
//错误返回-1,errno = 32
break;
}
pthread_mutex_lock(&mutex);//上锁
pthread_cond_wait(&cond,&mutex);//等待
printf("---tid:0x%lx--length:%d--sockfd:%d---\n",tid,buffer[okindex].length+432,sockfd);
print_picture(sockfd,tmp_buf,buffer[okindex].length);
pthread_mutex_unlock(&mutex);//解锁
//若只取一张图片则跳出循环
if(!action)
break;
}
out_addr_port(&caddr);
clients--;
th_exit(sockfd);
}
int lis_acc(int max_lis)
{
listen(s_sockfd,10);//开始接受客户端请求,等待队列长度为10
pthread_t th;
int err;
err = pthread_create(&th,&attr,th_getframe,NULL);
if(err < 0)
{
fprintf(stderr,"pthread_create: %s\n",strerror(err));
return -1;
}
struct sockaddr_in caddr;
socklen_t clen = sizeof(caddr);
int sockfd;
while(1)
{
memset(&caddr,0,clen);
sockfd = accept(s_sockfd,(struct sockaddr*)&caddr,&clen);//获得连接请求并建立连接
if(sockfd < 0)
{
fprintf(stderr,"accept: %s\n",strerror(errno));
}
else
{
out_addr_port(&caddr);
printf(" connected\tsockfd: %d clients:%d\n",sockfd,clients);
fflush(stdout);
err = pthread_create(&th,&attr,th_service,(void*)sockfd);
if(err < 0)
{
fprintf(stderr,"pthread_create: %s\n",strerror(err));
continue;
}
}
}
}
二、socket编程机实现
3、Linux C语言的Socket编程例子(TCP和UDP)
三、视频格式
YUY与RGB格式区别
YUV:YUV,分为三个分量,“Y”表示明亮度也就是灰度值;而“U”和“V” 表示的则是色度作用是描述影像色彩及饱和度,用于指定像素的颜色。没有UV信息一样可以显示完整的图像,只不过是黑白的.YUV码流的存储格式其实与其采样的方式密切相关,主流的采样方式有三种,
YUV 4:4:4采样,每一个Y对应一组UV分量,每像素32位
YUV 4:2:2采样,每两个Y共用一组UV分量,每像素16位
YUV 4:2:0采样,每四个Y共用一组UV分量,每像素16位
RGB:都是采用R(Red)、G(Green)、B(Blue)相加混色的原理
RGB24 每个像素用24位表示,RGB分量各使用8位
RGB32 每个像素用32位表示,RGB分量各使用8位(剩下8位不用)
ARGB32 每个像素用32位表示,RGB分量各使用8位(剩下的8位用于表示Alpha通道值)