1.開發(fā)板簡介
OK113i-S開發(fā)板采用核心板+底板的結(jié)構(gòu)形式,基于全志T113-i處理器設(shè)計開發(fā),處理器為ARMCortex-A7, RISCV, HiFi4 DSP多核異構(gòu)架構(gòu),主頻1.2GHz,核心板有兩種規(guī)格,分別是512MB DDR3L內(nèi)存加8GB eMMC版本和256MB DDR3L內(nèi)存加256MB SPI Nand版本。OK113i-S開發(fā)板將核心板的功能接口資源豐富、提供多種外設(shè)接口,如網(wǎng)卡、CPU內(nèi)置音頻Codec、ADC、TF Card、LVDS、RGB、WIFI、4G等功能接口。
2.硬件開發(fā)平臺
開發(fā)平臺:Linux-5.4
編譯器:arm-linux-gnueabi-gcc 7.3.1
USB攝像頭
OK113i開發(fā)板
實(shí)現(xiàn)功能:通過OK113i飛凌嵌入式開發(fā)板,采用USB設(shè)備頭,通過V4L2框架實(shí)現(xiàn)視頻圖像采集。創(chuàng)建攝像頭圖像采集線程,搭建HTTP服務(wù)器,固定端口號為8080,建立HTTP長連接,實(shí)現(xiàn)網(wǎng)頁視頻監(jiān)控。
3.功能實(shí)現(xiàn)
1.移植交叉編譯器arm-linux-gnueabi-gcc。
2.移植矢量字庫freetye。
3.初始化攝像頭,通過V4L2驅(qū)動框架實(shí)現(xiàn)攝像頭編程;
4.創(chuàng)建攝像頭采集線程,搭建HTTP服務(wù)器,多線程處理http客戶端數(shù)據(jù)請求,建立http長連接;
5.采用互斥鎖+條件變量方式實(shí)現(xiàn)多線程間資源保護(hù),將攝像頭采集圖像實(shí)時上傳至網(wǎng)頁端;
4.矢量字庫編譯與移植
FreeType 庫是一個完全免費(fèi)(開源)的、高質(zhì)量的且可移植的字體引擎,它提供統(tǒng)一的接口來訪問多種字體格式文件,可以非常方便我們開發(fā)字體顯示相關(guān)的程序功能。它支持單色位圖、反走樣位圖的渲染。 FreeType 庫是高度模塊化的程序庫,雖然它是使用 ANSI C開發(fā),但是采用面向?qū)ο蟮乃枷耄虼耍?FreeType 的用戶可以靈活地對它進(jìn)行裁剪。關(guān)于freetype 的詳細(xì)信息可以參考 freetype 的官方網(wǎng)站:https://www.freetype.org/來獲取更多相關(guān)的信息。
[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 中關(guān)于視頻設(shè)備的內(nèi)核驅(qū)動。在 Linux 中,視頻設(shè)備是設(shè)備文件,可以像訪問普通文件一樣對其進(jìn)行讀寫,攝像頭在/dev/video*下,如果只有一個視頻設(shè)備,通常為/dev/video0。V4L2 是針對 uvc 免驅(qū) usb 設(shè)備的編程框架,主要用于采集 usb 攝像頭等,編程模式如下:
攝像頭初始化示例如下:
/* 攝像頭初始化 返回值:成功返回攝像頭描述符,失敗返回負(fù)數(shù) */ int Video_Init(struct CAMERA *camera) { int video_fd; int i=0; /*1.打開設(shè)備節(jié)點(diǎn)*/ video_fd=open(VIDEO_DEV,O_RDWR); if(video_fd==-1)return -1; /*2.設(shè)置攝像頭格式*/ 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;//圖像數(shù)據(jù)格式y(tǒng)uyv 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.向內(nèi)核請求緩沖區(qū)*/ struct v4l2_requestbuffers reqbuf; memset(&reqbuf,0,sizeof(reqbuf)); reqbuf.count=4;/*緩沖區(qū)個數(shù)*/ reqbuf.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;//視頻捕獲格式 reqbuf.memory=V4L2_MEMORY_MMAP;/*內(nèi)存映射*/ if(ioctl(video_fd,VIDIOC_REQBUFS,&reqbuf))return -3; printf("緩沖區(qū)個數(shù):%dn",reqbuf.count); /*4.將緩沖區(qū)映射到進(jìn)程空間*/ 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.將緩沖區(qū)添加到采集隊列*/ for(i=0;i
6.搭建HTTP服務(wù)器
HTTP 協(xié)議是 Hyper Text Transfer Protocol(超文本傳輸協(xié)議)的縮寫,是用于從萬維網(wǎng)(WWW:World WideWeb )服務(wù)器傳輸超文本到本地瀏覽器的傳送協(xié)議。
HTTP 是基于客戶端/服務(wù)端(C/S)的架構(gòu)模型,通過一個可靠的鏈接來交換信息,是一個無狀態(tài)的請求/響應(yīng)協(xié)議。一個 HTTP"客戶端"是一個應(yīng)用程序(Web 瀏覽器或其他任何客戶端),通過連接到服務(wù)器達(dá)到向服務(wù)器發(fā)送一個或多個 HTTP 的請求的目的。一個 HTTP"服務(wù)器"同樣也是一個應(yīng)用程序通過接收客戶端的請求并向客戶端發(fā)送 HTTP 響應(yīng)數(shù)據(jù)。HTTP 使用統(tǒng)一資源標(biāo)識符(Uniform Resource Identifiers, URI)來傳輸數(shù)據(jù)和建立連接。
HTTP服務(wù)器創(chuàng)建示例:
/*1.創(chuàng)建網(wǎng)絡(luò)套接字*/ sockfd=socket(AF_INET,SOCK_STREAM,0); if(sockfd==-1) { printf("創(chuàng)建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; } /*設(shè)置監(jiān)聽數(shù)量*/ 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);//設(shè)置分離屬性 }
7.網(wǎng)頁視頻監(jiān)控處理
創(chuàng)建攝像頭采集線程,將采集的圖像進(jìn)行JPG格式編碼,挺添加時間水印信息。攝像頭處理線程如下:
/*攝像頭處理函數(shù)*/ void *pth_camera_work(void *arg) { LCD_Init();//LCD初始化 video_fd=Video_Init(&camera);//攝像初始化 if(video_fd0) { printf("攝像頭初始化失敗res=%dn",video_fd); sig_work(2); } unsigned char *rgb_buff=malloc(camera.image_w*camera.image_h*3);//保存RGB顏色數(shù)據(jù) jpg_buffer=malloc(camera.image_w*camera.image_h*3);//保存JPG圖像數(shù)據(jù) 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("攝像頭開始采集數(shù)據(jù)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;/*內(nèi)存映射*/ if(ioctl(video_fd,VIDIOC_DQBUF,&dqbuff))break; //printf("圖像數(shù)據(jù):mamp_buff[%d]=%pn",dqbuff.index,camera.mamp_buff[dqbuff.index]); /*數(shù)據(jù)處理*/ sec=time(NULL); //獲取系統(tǒng)秒單位時間 sec-=8*60*60; localtime_r(&sec,&time_s);//將秒時間轉(zhuǎn)換為時間結(jié)構(gòu)體 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"--基于嵌入式的居家安防報警系統(tǒng)設(shè)計",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 ;/*將緩沖區(qū)添加回采集隊列*/ } close(video_fd); free(rgb_buff); exit(0); }
8.運(yùn)行效果
審核編輯 黃宇
-
嵌入式
+關(guān)注
關(guān)注
5133文章
19502瀏覽量
314333 -
視頻監(jiān)控
+關(guān)注
關(guān)注
17文章
1720瀏覽量
65779 -
飛凌
+關(guān)注
關(guān)注
0文章
134瀏覽量
16381 -
V4L2
+關(guān)注
關(guān)注
0文章
17瀏覽量
4009
發(fā)布評論請先 登錄
技術(shù)帖 | 飛凌嵌入式T113-i開發(fā)板的休眠及喚醒操作

【飛凌 OK113i-C 全志T113-i開發(fā)板】視頻編解碼測試
【飛凌OK113i-S開發(fā)板試用】基于飛凌嵌入式OK113i網(wǎng)頁視頻監(jiān)控項目
雙核Cortex-A7 CPU、64位玄鐵C906 RISC-V CPU,OK113i-S開發(fā)板開發(fā)體驗
飛凌嵌入式全志T113-i開發(fā)板的休眠及喚醒操作
【OK210申請】基于飛凌嵌入式OK210的多媒體播放系統(tǒng)
【OK210申請】基于飛凌嵌入式智能家居系統(tǒng)飛凌嵌入式OK210開發(fā)板申請
【實(shí)戰(zhàn)項目一:嵌入式視頻監(jiān)控系統(tǒng)】【初學(xué)必學(xué)】
【OK210申請】基于arm嵌入式的監(jiān)控智能小車的設(shè)計與實(shí)現(xiàn)
分享一個不錯的基于飛凌嵌入式A40i實(shí)現(xiàn)網(wǎng)約車車載終端方案
飛凌 OK113i-C 全志T113-i開發(fā)板初體驗
如何在飛凌嵌入式T113-i開發(fā)板的Buildroot中移植MQTT協(xié)議?

評論