0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于飞凌嵌入式OK113i网页视频监控项目

嵌入式技术 来源:嵌入式技术 作者:嵌入式技术 2024-01-08 22:57 次阅读

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、ADCTF Card、LVDS、RGB、WIFI、4G等功能接口。

2.硬件开发平台

开发平台:Linux-5.4

编译器:arm-linux-gnueabi-gcc 7.3.1

USB摄像头

OK113i开发板

实现功能:通过OK113i飞凌嵌入式开发板,采用USB设备头,通过V4L2框架实现视频图像采集。创建摄像头图像采集线程,搭建HTTP服务器,固定端口号为8080,建立HTTP长连接,实现网页视频监控。

wKgaomWcCPiAadZLADnMcr04vyA576.pngwKgaomWcCW-AQ7roAFOLMXM97TI381.png

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/来获取更多相关的信息。

wKgZomWcCp2AFpH8AAwzInNqcm4185.png

[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 摄像头等,编程模式如下:

wKgaomWcC2OAHt_-AAKSjArmBCM337.png

摄像头初始化示例如下:

/*

摄像头初始化

返回值:成功返回摄像头描述符,失败返回负数

*/

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;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_QUERYBUF,&quebuff))return -4;

       	camera- >mamp_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.运行效果

wKgaomWcDRiAQ9bcAEe1tnzB810217.png

审核编辑 黄宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 嵌入式
    +关注

    关注

    5056

    文章

    18950

    浏览量

    301485
  • 视频监控
    +关注

    关注

    17

    文章

    1705

    浏览量

    64859
  • 飞凌
    +关注

    关注

    0

    文章

    132

    浏览量

    16076
  • V4L2
    +关注

    关注

    0

    文章

    17

    浏览量

    3877
收藏 人收藏

    评论

    相关推荐

    技术帖 | 飞嵌入式T113-i开发板的休眠及唤醒操作

    嵌入式OK113i-S开发板支持两种休眠方式:freeze和mem。本篇内容小编会为大家介绍如何让飞嵌入式
    的头像 发表于 12-29 08:02 1153次阅读
    技术帖 | 飞<b class='flag-5'>凌</b><b class='flag-5'>嵌入式</b>T<b class='flag-5'>113-i</b>开发板的休眠及唤醒操作

    【飞 OK113i-C 全志T113-i开发板】视频编解码测试

    前言本文测试OK113i-S开发板-视频编解码的功能OK113i-S开发板是支持视频的编解码的,下面是官方介绍的编解码功能T113-i 是一
    发表于 12-25 09:41

    【飞OK113i-S开发板试用】基于飞嵌入式OK113i网页视频监控项目

    :arm-linux-gnueabi-gcc 7.3.1 USB摄像头 OK113i开发板实现功能:通过OK113i嵌入式开发板,采用USB设备头,通过V4L2框架实现
    发表于 01-09 11:31

    双核Cortex-A7 CPU、64位玄铁C906 RISC-V CPU,OK113i-S开发板开发体验

    OK113i网页视频监控项目 实现功能: 通过OK113i
    发表于 01-16 10:07

    嵌入式全志T113-i开发板的休眠及唤醒操作

    嵌入式OK113i-S开发板支持两种休眠方式:freeze和mem。这两种方式可以通过/sys/power/state文件节点进行操作,用户可以通过在该文件节点写入freeze或mem来触发相应
    发表于 01-17 09:29

    OK210申请】基于飞嵌入式OK210的多媒体播放系统

    微博,http://weibo.com/2840996695/profile?topnav=1&amp;wvr=6项目描述:项目名称:基于飞
    发表于 07-06 17:37

    OK210申请】基于飞嵌入式智能家居系统飞嵌入式OK210开发板申请

    3.组员:三名,王亚玲,魏玉娟,张向前4.研发的方向为智能家居嵌入式方向5.本人自小就有对电子又很浓厚的兴趣,在大学研究过微型空调的设计制作,单片机系统,嵌入式,机器人等项目项目描述:
    发表于 07-13 12:03

    【实战项目一:嵌入式视频监控系统】【初学必学】

    网页视频监控系统实战项目(驱动移植部分一)2.【创科之龙】嵌入式网页
    发表于 07-19 18:18

    OK210申请】基于飞嵌入式智能家居系统

    可以用它来开发小软件。项目描述:基于飞嵌入式的智能家居,通过对飞的了解,感觉选择飞
    发表于 07-25 17:19

    OK210申请】基于arm嵌入式监控智能小车的设计与实现

    视频流的读取该项目仍在进行中真的很希望可以获得飞ok210的开发板进行arm平台的移植和后面项目的实现,以及对飞
    发表于 08-03 09:40

    分享一个不错的基于飞嵌入式A40i实现网约车车载终端方案

    分享一个不错的基于飞嵌入式A40i实现网约车车载终端方案
    发表于 12-27 07:18

    OK113i-C 全志T113-i开发板初体验

    All available board: 0. ok113i Choice [ok113i]: 0 All available flash: 0. default 1. nor 2. nand
    发表于 12-14 15:33

    嵌入式T113-i开发板的调屏方法,就是这样简单

    的配备为客户提供了更加多样的选择。今天小编就与大家分享一下为飞嵌入式OK113i-S开发板适配LVDS屏幕的过程。
    的头像 发表于 01-12 11:50 2134次阅读
    飞<b class='flag-5'>凌</b><b class='flag-5'>嵌入式</b>T<b class='flag-5'>113-i</b>开发板的调屏方法,就是这样简单

    如何在飞嵌入式T113-i开发板的Buildroot中移植MQTT协议?

    嵌入式OK113i-S开发板上市一段时间以来收获了很多关注,也成为了许多客户项目选型的优质之选。在实际的项目开发中,工程师朋友们可能会需
    的头像 发表于 01-26 08:02 455次阅读
    如何在飞<b class='flag-5'>凌</b><b class='flag-5'>嵌入式</b>T<b class='flag-5'>113-i</b>开发板的Buildroot中移植MQTT协议?

    嵌入式T113-i开发板的调屏方法

    于飞嵌入式T113-i开发板的调屏问题,需要按照以下步骤进行操作
    的头像 发表于 01-29 16:25 844次阅读