1.开发板简介
ok113i-s开发板采用核心板+底板的结构形式,基于全志t113-i处理器设计开发,处理器为armcortex-a7, riscv, hifi4 dsp多核异构架构,主频1.2ghz,核心板有两种规格,分别是512mb ddr3l内存加8gb emmc版本和256mb ddr3l内存加256mb spi nand版本。ok113i-s开发板将核心板的功能接口资源丰富、提供多种外设接口,如网卡、cpu内置音频codec、adc、tf card、lvds、rgb、wifi、4g等功能接口。
2.硬件开发平台
开发平台:linux-5.4
编译器:arm-linux-gnueabi-gcc 7.3.1
usb摄像头
ok113i开发板
实现功能:通过ok113i飞凌嵌入式开发板,采用usb设备头,通过v4l2框架实现视频图像采集。创建摄像头图像采集线程,搭建http服务器,固定端口号为8080,建立http长连接,实现网页视频监控。
3.功能实现
1.移植交叉编译器arm-linux-gnueabi-gcc。
2.移植矢量字库freetye。
3.初始化摄像头,通过v4l2驱动框架实现摄像头编程;
4.创建摄像头采集线程,搭建http服务器,多线程处理http客户端数据请求,建立http长连接;
5.采用互斥锁+条件变量方式实现多线程间资源保护,将摄像头采集图像实时上传至网页端;
4.矢量字库编译与移植
freetype 库是一个完全免费(开源)的、高质量的且可移植的字体引擎,它提供统一的接口来访问多种字体格式文件,可以非常方便我们开发字体显示相关的程序功能。它支持单色位图、反走样位图的渲染。 freetype 库是高度模块化的程序库,虽然它是使用 ansi c开发,但是采用面向对象的思想,因此, freetype 的用户可以灵活地对它进行裁剪。关于freetype 的详细信息可以参考 freetype 的官方网站:https://www.freetype.org/来获取更多相关的信息。
[wbyq@wbyq src_pack]$ tar xvf /mnt/hgfs/ubuntu/software_pack/freetype-2.4.10.tar.bz2[wbyq@wbyq src_pack]$ cd freetype-2.4.10/[wbyq@wbyq freetype-2.4.10]$ ./configure --prefix=$pwd/_install --host=arm-linux[wbyq@wbyq freetype-2.4.10]$ make && make install
5.v4l2摄像头编程
v4l2 是 video for linux2 的简称,为 linux 中关于视频设备的内核驱动。在 linux 中,视频设备是设备文件,可以像访问普通文件一样对其进行读写,摄像头在/dev/video*下,如果只有一个视频设备,通常为/dev/video0。v4l2 是针对 uvc 免驱 usb 设备的编程框架,主要用于采集 usb 摄像头等,编程模式如下:
摄像头初始化示例如下:
/*摄像头初始化返回值:成功返回摄像头描述符,失败返回负数*/int video_init(struct camera *camera){ int video_fd; int i=0; /*1.打开设备节点*/ video_fd=open(video_dev,o_rdwr); if(video_fd==-1)return -1; /*2.设置摄像头格式*/ struct v4l2_format format; memset(&format,0,sizeof(format)); format.type=v4l2_buf_type_video_capture;//视频捕获格式 format.fmt.pix.width=800; format.fmt.pix.height=480; format.fmt.pix.pixelformat=v4l2_pix_fmt_yuyv;//图像数据格式yuyv if(ioctl(video_fd,vidioc_s_fmt,&format))return -2; printf(图像尺寸:%d * %dn,format.fmt.pix.width,format.fmt.pix.height); camera- >image_w=format.fmt.pix.width; camera- >image_h=format.fmt.pix.height; /*3.向内核请求缓冲区*/ struct v4l2_requestbuffers reqbuf; memset(&reqbuf,0,sizeof(reqbuf)); reqbuf.count=4;/*缓冲区个数*/ reqbuf.type=v4l2_buf_type_video_capture;//视频捕获格式 reqbuf.memory=v4l2_memory_mmap;/*内存映射*/ if(ioctl(video_fd,vidioc_reqbufs,&reqbuf))return -3; printf(缓冲区个数:%dn,reqbuf.count); /*4.将缓冲区映射到进程空间*/ struct v4l2_buffer quebuff; for(i=0;imamp_buff[i]=mmap(null,quebuff.length,prot_read|prot_write,map_shared,video_fd,quebuff.m.offset); printf(buff[%d]=%pn,i,camera- >mamp_buff[i]); camera- >mmap_size=quebuff.length; } /*5.将缓冲区添加到采集队列*/ for(i=0;i< reqbuf.count;i++) { memset(&quebuff,0,sizeof(quebuff)); quebuff.index=i;//缓冲区数组下标 quebuff.type=v4l2_buf_type_video_capture;//视频捕获格式 quebuff.memory=v4l2_memory_mmap;/*内存映射*/ if(ioctl(video_fd,vidioc_qbuf,&quebuff))return -5; } /*6.开启摄像头*/ int type=v4l2_buf_type_video_capture;//视频捕获格式 if(ioctl(video_fd,vidioc_streamon,&type))return -6; return video_fd;}
6.搭建http服务器
http 协议是 hyper text transfer protocol(超文本传输协议)的缩写,是用于从万维网(www:world wideweb )服务器传输超文本到本地浏览器的传送协议。
http 是基于客户端/服务端(c/s)的架构模型,通过一个可靠的链接来交换信息,是一个无状态的请求/响应协议。一个 http客户端是一个应用程序(web 浏览器或其他任何客户端),通过连接到服务器达到向服务器发送一个或多个 http 的请求的目的。一个 http服务器同样也是一个应用程序通过接收客户端的请求并向客户端发送 http 响应数据。http 使用统一资源标识符(uniform resource identifiers, uri)来传输数据和建立连接。
http服务器创建示例:
/*1.创建网络套接字*/ sockfd=socket(af_inet,sock_stream,0); if(sockfd==-1) { printf(创建socket套接字失败n); return 0; } /*允许绑定已使用的端口号*/ int on = 1; setsockopt(sockfd, sol_socket, so_reuseaddr, &on, sizeof(on)); /*2.绑定端口号*/ struct sockaddr_in addr= { .sin_family=af_inet,//ipv4 .sin_port=htons(http_server_port),//端口号 .sin_addr.s_addr=inaddr_any,//本地所有ip }; if(bind(sockfd,(struct sockaddr*)&addr,sizeof(addr))) { printf(绑定端口号失败n); return 0; } /*设置监听数量*/ listen(sockfd,100); /*等待客户端连接*/ struct sockaddr_in c_addr; socklen_t addrlen=sizeof(c_addr); int c_fd; int *p; while(1) { c_fd=accept(sockfd, (struct sockaddr *)&c_addr,&addrlen); if(c_fd==-1)continue; printf(%d 客户端连接成功%s:%dn,c_fd,inet_ntoa(c_addr.sin_addr),ntohs(c_addr.sin_port)); p=malloc(sizeof(int)); *p=c_fd; pthread_create(&pthid,null,pth_work,p); pthread_detach(pthid);//设置分离属性 }
7.网页视频监控处理
创建摄像头采集线程,将采集的图像进行jpg格式编码,挺添加时间水印信息。摄像头处理线程如下:
/*摄像头处理函数*/void *pth_camera_work(void *arg){ lcd_init();//lcd初始化 video_fd=video_init(&camera);//摄像初始化 if(video_fd< 0) { printf(摄像头初始化失败res=%dn,video_fd); sig_work(2); } unsigned char *rgb_buff=malloc(camera.image_w*camera.image_h*3);//保存rgb颜色数据 jpg_buffer=malloc(camera.image_w*camera.image_h*3);//保存jpg图像数据 if(rgb_buff==null || jpg_buffer==null) { close(video_fd); sig_work(2); } if(initconfig_freetype(simkai.ttf))//矢量字库初始化失败 { close(video_fd); sig_work(2); } printf(摄像头开始采集数据n); struct v4l2_buffer dqbuff; time_t sec; struct tm time_s; char buff[100]; wchar_t wcs[200]; struct imagedecodinginfo imagedata; imagedata.width=camera.image_w; imagedata.height=camera.image_h; while(1) { memset(&dqbuff,0,sizeof(dqbuff)); dqbuff.type=v4l2_buf_type_video_capture;//视频捕获格式 dqbuff.memory=v4l2_memory_mmap;/*内存映射*/ if(ioctl(video_fd,vidioc_dqbuf,&dqbuff))break; //printf(图像数据:mamp_buff[%d]=%pn,dqbuff.index,camera.mamp_buff[dqbuff.index]); /*数据处理*/ sec=time(null); //获取系统秒单位时间 sec-=8*60*60; localtime_r(&sec,&time_s);//将秒时间转换为时间结构体 strftime(buff,sizeof(buff),%y/%m/%d %k:%m:%s,&time_s); swprintf(wcs,sizeof(wcs),l时间:%s,buff); yuv_to_rgb(camera.mamp_buff[dqbuff.index],rgb_buff,camera.image_w,camera.image_h); imagedata.rgb=rgb_buff; lcd_drawtext(10,10,35,l凌嵌入式ok113i,camera.image_w,camera.image_h,rgb_buff); lcd_drawtext(350,410,25,l--基于嵌入式的居家安防报警系统设计,camera.image_w,camera.image_h,rgb_buff); lcd_drawtext(10,50,29,wcs,camera.image_w,camera.image_h,rgb_buff); lcd_image(&imagedata);//图像显示 if(hasr051_stat)//jpg图片保存 { strftime(buff,sizeof(buff),%y%m%d%k%m%s,&time_s); char file_name[100]; snprintf(file_name,sizeof(file_name),photo/%s.jpg,buff); //printf(buff=%sn,buff); savejpgimage(rgb_buff,camera.image_w,camera.image_h,file_name);//保存jpg图片 } pthread_mutex_lock(&fastmutex);//互斥锁上锁 jpg_image_size=rgb_to_jpeg(camera.image_w,camera.image_h,camera.image_w*camera.image_h*3,rgb_buff,jpg_buffer,80); pthread_cond_broadcast(&cond);//广播唤醒所有线程 pthread_mutex_unlock(&fastmutex);//互斥锁上锁 if(ioctl(video_fd,vidioc_qbuf,&dqbuff))break ;/*将缓冲区添加回采集队列*/ } close(video_fd); free(rgb_buff); exit(0);}
8.运行效果
蔚来汽车与博世集团签署战略合作协议
指纹识别芯片龙头谈全球战略
5G元年中日两国共同布局视频行业的进展如何
FTTx网络终端设备的后备供电保障的解决方案
纸张表面瑕疵检测系统的工作原理
基于飞凌嵌入式OK113i网页视频监控项目
华为表示不会放弃安全更新
推动射频和微波设计的UAS SWaP约束
努比亚居然邀请竞争对手参加发布会
运动控制器之追剪应用Demo
Niantic与华纳兄弟互动娱乐公司合作 推出新款AR手游
电子元器件选型参数与原则
Arm在物联网市场怎么啦?
用于微电网应用的固态变压器的设计
兆易创新推出GD32A490系列车规级MCU新品
英特尔与赛灵思争夺世界最大FPGA 将共同推动科技和文明的延续
智能电销机器人有效解决了企业电话销售的痛点
激光雷达与视觉算法谁会是自动驾驶的未来?
AI医疗正在改变现有的医疗方式
MIPS科技公司任命Sandeep Vij为新任首席执行官