文章目录结构

一、V4L2视频采集与H264编码

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编程机实现

1、udp socket: 简单的数据包与视频流传输

2、录像socket服务端

3、Linux C语言的Socket编程例子(TCP和UDP)

三、视频格式

YUY与RGB格式区别

YUV:YUV,分为三个分量,“Y”表示明亮度也就是灰度值;而“U”和“V” 表示的则是色度作用是描述影像色彩及饱和度,用于指定像素的颜色。没有UV信息一样可以显示完整的图像,只不过是黑白的.YUV码流的存储格式其实与其采样的方式密切相关,主流的采样方式有三种,

  1. YUV 4:4:4采样,每一个Y对应一组UV分量,每像素32位

  2. YUV 4:2:2采样,每两个Y共用一组UV分量,每像素16位

  3. 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通道值)




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值