V4L2超詳細(xì)講解_第1頁
V4L2超詳細(xì)講解_第2頁
V4L2超詳細(xì)講解_第3頁
已閱讀5頁,還剩10頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、內(nèi)文內(nèi)容主要來源于網(wǎng)絡(luò)定義V4L2(VideoForLinuxTwo)是內(nèi)核提供給應(yīng)用程序訪問音、視頻驅(qū)動的統(tǒng)一接口。1. 工作流程:打開設(shè)備一檢查和設(shè)置設(shè)備屬性一設(shè)置幀格式一設(shè)置一種輸入輸出方法(緩沖區(qū)管理)循環(huán)獲取數(shù)據(jù)關(guān)閉設(shè)備。2. 設(shè)備的打開和關(guān)閉:#includeintopen(constchar*device_name,intflags);#includeintclose(intfd);例:intfd=open(/dev/video0”,O_RDWR);/打開設(shè)備close(fd);/關(guān)閉設(shè)備注意:V4L2的相關(guān)定義包含在頭文件中.查詢設(shè)備屬性:VIDIOC_QUERYCAP相關(guān)函數(shù)

2、:intioctl(intfd,intrequest,structv4l2_capability*argp);相關(guān)結(jié)構(gòu)體:structv4l2_capabilityu8driver16;/驅(qū)動名字u8card32;/設(shè)備名字u8bus_info32;/設(shè)備在系統(tǒng)中的位置u32version;/驅(qū)動版本號u32capabilities;/設(shè)備支持的操作u32reserved4;/保留字段;capabilities常用值:V4L2_CAP_VIDEO_CAPTURE/是否支持圖像獲取例:顯示設(shè)備信息structv4l2_capabilitycap;ioctl(fd,VIDIOC_QUERYCAP,

3、&cap);printf(“DriverName:%snCardName:%snBusinfo:%snDriverVersion:%u.%u.%un,cap.driver,cap.card,cap.bus_info,(cap.version6)&0XFF(cap.version8)&0XFFcap.version&0XFF;設(shè)置視頻的制式和幀格式制式包括PAL,NTSC相關(guān)函數(shù):intioctl(幀的格式個包括寬度和高度等。intfd,intrequest,structv4l2_fmtdesc*argp);intioctl(相關(guān)結(jié)構(gòu)體:v4l2_cropcapv4l2_cropcapv4l2_

4、cropcapintfd,intrequest,structv4l2_format*argp);結(jié)構(gòu)體用來設(shè)置攝像頭的捕捉能力,在捕捉上視頻時應(yīng)先先設(shè)置的type域,再通過VIDIO_CROPCAP操作命令獲取設(shè)備捕捉能力的參數(shù),結(jié)構(gòu)體中,包括bounds(最大捕捉方框的左上角坐標(biāo)和寬高),defrect保存于(默認(rèn)捕捉方框的左上角坐標(biāo)和寬高)等。v4l2_format結(jié)構(gòu)體用來設(shè)置攝像頭的視頻制式、幀格式等,在設(shè)置這個參數(shù)時應(yīng)先填v4l2_format的各個域,如type(傳輸流類型),fmt.pix.width(寬),fmt.pix.heigth(高),fmt.pix.field(采樣區(qū)域

5、,如隔行采樣),fmt.pix.pixelformat(樣類型,如YUV4:2:2),然后通過VIDIO_S_FMT操作命令設(shè)置視頻捕捉格式。如下圖所示:5.1查詢并顯示所有支持的格式:VIDIOCENUMFMT相關(guān)函數(shù):intioctl(intfd,intrequest,structv4l2_fmtdesc*argp);相關(guān)結(jié)構(gòu)體:structv4l2fmtdesc(u32index;/要查詢的格式序號,應(yīng)用程序設(shè)置enumv4l2_buf_typetype;/幀類型,應(yīng)用程序設(shè)置u32flags;/是否為壓縮格式u8description32;/格式名稱u32pixelformat;/格式

6、u32reserved4;/保留;例:顯示所有支持的格式structv4l2_fmtdescfmtdesc;fmtdesc.index=0;fmtdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTUFpEi;ntf(Supportformat:n);while(ioctl(fd,VIDIOC_ENUM_FMT,&fmtdesc)!=-1)(printf(t%d.%sn,fmtdesc.index+1,fmtdesc.description);fmtdesc.index+;5.2查看或設(shè)置當(dāng)前格式:VIDIOC_G_FMT,VIDIOC_S_FMT檢查是否支持某種格式:VIDI

7、OC_TRY_FMT相關(guān)函數(shù):intioctl(intfd,intrequest,structv4l2_format*argp);相關(guān)結(jié)構(gòu)體:structv4l2_formatenumv4l2_buf_typetype;/幀類型,應(yīng)用程序設(shè)置unionfmtstructv4l2_pix_formatpix;/視頻設(shè)備使用structv4l2_windowwin;structv4l2_vbi_formatvbi;structv4l2_sliced_vbi_formatsliced;u8raw_data200;一;structv4l2_pix_formatu32width;/幀寬,單位像素u32h

8、eight;/幀高,單位像素u32pixelformat;/幀格式enumv4l2_fieldfield;u32bytesperline;u32sizeimage;enumv4l2_colorspacecolorspace;u32priv;例:顯示當(dāng)前幀的相關(guān)信息structv4l2_formatfmt;fmt.type=V4L2_BUF_TYPE_VIDEO_CAPTURoctl(fd,VIDIOC_G_FMT,&fmt);printf(“Currentdataformatinformation:ntwidth:%dntheight:%dnfmt.fmt.pix.width,fmt.fmt.

9、pix.height);structv4l2_fmtdescfmtdesc;fmtdesc.index=0;fmtdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;while(ioctl(fd,VIDIOC_ENUM_FMT,&fmtdesc)!=-1)if(fmtdesc.pixelformat&fmt.fmt.pix.pixelformat)printf(tformat:%sn”,fmtdesc.description);break;fmtdesc.index+;例:檢查是否支持某種幀格式structv4l2_formatfmt;fmt.type=V4L2_BUF

10、_TYPE_VIDEO_CAPTURE;fmt.fmt.pix.pixelformat=V4L2_PIX_FMT_RGB32;if(ioctl(fd,VIDIOC_TRY_FMT,&fmt)=-1)if(errno=EINVAL)printf(“notsupportformatRGB32!n”);6.圖像的縮放VIDIOC_CROPCAP相關(guān)函數(shù):intioctl(intfd,intrequest,structv4l2_cropcap*argp);intioctl(intfd,intrequest,structv4l2_crop*argp);intioctl(intfd,intrequest,

11、conststructv4l2_crop*argp);相關(guān)結(jié)構(gòu)體:Cropping和scaling主要指的是圖像的取景范圍及圖片的比例縮放的支持。Crop就是把得到的數(shù)據(jù)作一定的裁剪和伸縮,裁剪可以只取樣我們可以得到的圖像大小的一部分,剪裁的主要參數(shù)是位置、長度、寬度。而scale的設(shè)置是通過VIDIOC_G_FMT和VIDIOC_S_FMT來獲得和設(shè)置當(dāng)前的image的長度,寬度來實現(xiàn)的。看下圖我們可以假設(shè)bounds是sensor最大能捕捉到的圖像范圍,而defrect是設(shè)備默認(rèn)的最大取樣范圍,這個可以通過VIDIOC_CROPCAP的ioctl來獲得設(shè)備的crap相關(guān)的屬性v4l2_cr

12、opcap,其中的bounds就是這個bounds,其實就是上限。每個設(shè)備都有個默認(rèn)的取樣范圍,就是defrect,就是defaultrect的意思,它比bounds要小一些。這個范圍也是通過VIDIOC_CROPCAP的ioctl來獲得的v4l2_cropcap結(jié)構(gòu)中的defrect來表示的,我們可以通過VIDIOC_G_CROP和VIDIOC_S_CROP來獲取和設(shè)置設(shè)備當(dāng)前的crop設(shè)置。6.1設(shè)置設(shè)備捕捉能力的參數(shù)相關(guān)函數(shù):intioctl(intfd,intrequest,structv4l2_cropcap*argp);相關(guān)結(jié)構(gòu)體:structv4l2_cropcapenumv4l

13、2_buf_typetype;/數(shù)據(jù)流的類型,應(yīng)用程序設(shè)置structv4l2_rectbounds;/這是camera的鏡頭能捕捉到的窗口大小的局限structv4l2_rectdefrect;/定義默認(rèn)窗口大小,包括起點位置及長,寬的大小,大小以像素為單位structv4l2_fractpixelaspect;/定義了圖片的寬高比;6.2設(shè)置窗口取景參數(shù)VIDIOC_G_CROPffiVIDIOC_S_CROP相關(guān)函數(shù):intioctl(intfd,intrequest,structv4l2_crop*argp);intioctl(intfd,intrequest,conststructv

14、4l2_crop*argp);相關(guān)結(jié)構(gòu)體:structv4l2_crop(enumv4l2_buf_typetype;/應(yīng)用程序設(shè)置structv4l2_rectc;videoInputsandOutputsVIDIOC_G_INPUT和VIDIOC_S_INPUT用來查詢和選則當(dāng)前的input,一個video設(shè)備節(jié)點可能對應(yīng)多個視頻源,比如saf7113可以最多支持四路cvbs輸入,如果上層想在四個cvbs視頻輸入間切換,那么就要調(diào)用ioctl(fd,VIDIOC_S_INPUT,&input)來切換。VIDIOC_G_INPUTandVIDIOC_G_OUTPUT返回當(dāng)前的videoinp

15、ut和output的index.相關(guān)函數(shù):intioctl(intfd,intrequest,structv4l2_input*argp);相關(guān)結(jié)構(gòu)體:structv4l2_input(_u32index;/*Whichinput*/_u8name32;/*Label*/_u32type;/*Typeofinput*/_u32audioset;/*Associatedaudios(bitfield)*/_u32tuner;/*Associatedtuner*/v4l2_std_idstd;_u32status;_u32reserved4;T我們可以通過VIDIOC_ENUMINPUTandVI

16、DIOC_ENUMOUTPUT別列舉一個input或者output的信息,我們使用一個v4l2_input結(jié)構(gòu)體來存放查詢結(jié)果,這個結(jié)構(gòu)體中有一個index域用來指定你索要查詢的是第幾個input/ouput,如果你所查詢的這個input是當(dāng)前正在使用的,那么在v4l2_input還會包含一些當(dāng)前的狀態(tài)信息,如果所查詢的input/output不存在,那么回返回EINVAL錯誤,所以,我們通過循環(huán)查找,直到返回錯誤來遍歷所有的input/output.VIDIOC_G_INPUTandVIDIOC_G_OUTPUT返回當(dāng)前的videoinput和output的index.例:列舉當(dāng)前輸入視頻所

17、支持的視頻格式structv4l2_inputinput;structv4l2_standardstandard;memset(&input,0,sizeof(input);/首先獲得當(dāng)前輸入的index,注意只是index,要獲得具體的信息,就的調(diào)用列舉操作if(-1=ioctl(fd,VIDIOC_G_INPUT,&input.index)perror(”VIDIOC_G_INPUT);exit(EXIT_FAILURE);/調(diào)用歹0舉操作,獲得input.index對應(yīng)的輸入的具體信息if(-1=ioctl(fd,VIDIOC_ENUMINPUT,&input)perror(”VIDIO

18、C_ENUM_INPUT;exit(EXIT_FAILURE);printf(”Currentinput%ssupports:n”,);memset(&standard,0,sizeof(standard);standard.index=0;/歹0舉所有的所支持的standard,如果standard.id與當(dāng)前input的input.std有共同的bitflag,意味著當(dāng)前的輸入支持這個standard,這樣將所有驅(qū)動所支持的standard歹U舉一個遍,就可以找到該輸入所支持的所有standard了。while(0=ioctl(fd,VIDIOC_ENUMSTD,&st

19、andard)if(standard.id&input.std)printf(”sn”,);standard.index+;/*EINVALindicatestheendoftheenumeration,whichcannotbeemptyunlessthisdevicefallsundertheUSBexception.*/if(errno!=EINVAL|standard.index=0)perror(”VIDIOC_ENUMSTD;exit(EXIT_FAILURE);Videostandards相關(guān)函數(shù):v4l2_std_idstd_id;/這個就是個64bi

20、t得數(shù)intioctl(intfd,intrequest,structv4l2_standard*argp);相關(guān)結(jié)構(gòu)體:typedefu64v4l2_std_id;structv4l2_standardu32index;v4l2_std_idid;u8name24;structv4l2_fractframeperiod;/*Frames,notfields*/u32framelines;u32reserved4;當(dāng)然世界上現(xiàn)在有多個視頻標(biāo)準(zhǔn),如NTSCPAL他們又細(xì)分為好多種,那么我們的設(shè)備輸入/輸出究竟支持什么樣的標(biāo)準(zhǔn)呢?我們的當(dāng)前在使用的輸入和輸出正在使用的是哪個標(biāo)準(zhǔn)呢?index,然后

21、查出它的屬性,的信息進(jìn)行個集合,而這個我們怎么設(shè)置我們的某個輸入輸出使用的標(biāo)準(zhǔn)呢?這都是有方法的。查詢我們的輸入支持什么標(biāo)準(zhǔn),首先就得找到當(dāng)前的這個輸入的在其屬性里面可以得到該輸入所支持的標(biāo)準(zhǔn),將它所支持的各個標(biāo)準(zhǔn)與所有的標(biāo)準(zhǔn)比較,就可以獲知所支持的各個標(biāo)準(zhǔn)的屬性。一個輸入所支持的標(biāo)準(zhǔn)應(yīng)該是一集合是用bit與的方式用一個64位數(shù)字表示。因此我們所查到的是一個數(shù)字。這個就Example:Informationaboutthecurrentvideostandardv4l2_std_idstd_id;/是個64bit得數(shù)structv4l2_standardstandard;/VIDIOC_G_S

22、T就是獲得當(dāng)前輸入使用的standard,不過這里只是得到了該標(biāo)準(zhǔn)的id/即flag,還沒有得到其具體的屆性信息,具體的屆性信息要通過列舉操作來得到。if(-1=ioctl(fd,VIDIOC_G_STD,&std_id)/獲得了當(dāng)前輸入使用的standard/NotewhenVIDIOC_ENUMSTDWaysreturnsEINVALthisisnovideodevice/oritfallsundertheUSBexception,andVIDIOC_G_STDeturningEINVAL/isnoerror.perror(”VIDIOC_G_STD);exit(EXIT_FAILURE)

23、;memset(&standard,0,sizeof(standard);standard.index=0;/從第一個開始歹U舉/VIDIOC_ENUMSTffi來列舉所支持的所有的video標(biāo)準(zhǔn)的信息,不過要先給standard/結(jié)構(gòu)的index域制定一個數(shù)值,所歹U舉的標(biāo)準(zhǔn)的信息屆性包含在standard里面,/如果我們所列舉的標(biāo)準(zhǔn)和std_id有共同的bit,那么就意味著這個標(biāo)準(zhǔn)就是當(dāng)前輸/入所使用的標(biāo)準(zhǔn),這樣我們就得到了當(dāng)前輸入使用的標(biāo)準(zhǔn)的屆性信息while(0=ioctl(fd,VIDIOC_ENUMSTD,&standard)if(standard.id&std_id)printf

24、(”Currentvideostandard:%sn”,);exit(EXIT_SUCCESS);standard.index+;/*EINVALindicatestheendoftheenumeration,whichcannotbeemptyunlessthisdevicefallsundertheUSBexception.*/if(errno=EINVAL|standard.index=0)perror(”VIDIOC_ENUMSTD;exit(EXIT_FAILURE);申請和管理緩沖區(qū)應(yīng)用程序和設(shè)備有三種交換數(shù)據(jù)的方法,直接read/write、內(nèi)存映射(m

25、emorymapping)和用戶指針。這里只討論內(nèi)存映射(memorymapping)。9.1向設(shè)備申請緩沖區(qū)VIDIOC_REQBUFS相關(guān)函數(shù):intioctl(intfd,intrequest,structv4l2_requestbuffers*argp);相關(guān)結(jié)構(gòu)體:structv4l2_requestbuffersu32count;/緩沖區(qū)內(nèi)緩沖幀的數(shù)目enumv4l2_buf_typetype;/緩沖幀數(shù)據(jù)格式enumv4l2_memorymemory;/區(qū)別是內(nèi)存映射還是用戶指針方式u32reserved2;注:enumv4l2_memoyV4L2_MEMORY_MMAP,V4L

26、2_MEMORY_USERPTR);/count,type,memory都要應(yīng)用程序設(shè)置例:申請一個擁有四個緩沖幀的緩沖區(qū)structv4l2_requestbuffersreq;req.count=4;req.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;req.memory=V4L2_MEMORY_MMAP;ioctl(fd,VIDIOC_REQBUFS,&req);9.2獲取緩沖幀的地址,長度:VIDIOC_QUERYBUF相關(guān)函數(shù):intioctl(intfd,intrequest,structv4l2_buffer*argp);相關(guān)結(jié)構(gòu)體:structv4l2_b

27、ufferu32index;/buffer序號enumv4l2_buf_typetype;/buffer類型u32byteused;/buffer中已使用的字節(jié)數(shù)u32flags;/區(qū)分是MMAF是USERPTRenumv4l2_fieldfield;structtimevaltimestamp;/獲取第一個字節(jié)時的系統(tǒng)時間structv4l2_timecodetimecode;u32sequence;/隊歹U中的序號enumv4l2_memorymemory;/IO方式,被應(yīng)用程序設(shè)置unionmu32offset;/緩沖幀地址,只對MMAPt效unsignedlonguserptr;u32

28、length;/緩沖幀長度u32input;u32reserved;;9.3內(nèi)存映射MMAP及定義一個結(jié)構(gòu)體來映射每個緩沖幀。相關(guān)結(jié)構(gòu)體:structbuffervoid*start;unsignedintlength;*buffers;相關(guān)函數(shù):#includevoid*mmapVoid*addr,size_tlength,intprot,intflags,intfd,off_toffset)/addr映射起始地址,一般為NULL,讓內(nèi)核自動選擇/length被映射內(nèi)存塊的長度/prot標(biāo)志映射后能否被讀寫,其值為PROT_EXEC,PROT_READ,PROT_WRITE,PROT_NON

29、E/flags確定此內(nèi)存映射能否被其他進(jìn)程共享,MAP_SHARED,MAP_PRIVATE/fd,offset,確定被映射的內(nèi)存地址返回成功映射后的地址,不成功返回MAP_FAILED(void*)-1)相關(guān)函數(shù):intmunmap(void*addr,size_tlength);/斷開映射/addr為映射后的地址,length為映射后的內(nèi)存長度例:將四個已申請到的緩沖幀映射到應(yīng)用程序,用buffers指針記錄。buffers=(buffer*)calloc(req.count,sizeof(*buffers);if(!buffers)/映射fprintf(stderr,Outofmemory/n);exit(EXIT_FAILURE);for(unsignedintn_buffers=0;n_buffersreq.count;+n_buffers)(structv4l2_bufferbuf;memset(&buf,0,sizeof(buf);buf.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;buf.memory=V4L2_MEMORY_MMAP;buf.index=n_buffers;/查詢序號為n_buffers的緩沖區(qū),得到其起始物理地址和大小if(-

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論