http://blog.csdn.net/kickxxx/article/details/6642888
因为我的STVxxx USB camera输出格式是bayer格式,手头上只有YUVTOOLS这个查看工具,没法验证STVxxx在开发板上是否正常工作。
网上找了很久也没找到格式转换工具,最后放弃了,觉得还是写个转换工具比较快。抄写了部分libv4lconvert的代码, 我只验证了
V4L2_PIX_FMT_SGBRG8到V4L2_PIX_FMT_YUV420的转换。
bayer.c
##################################################################################
- /*
- *lib4lconvert,video4linux2formatconversionlib
- *(C)2008HansdeGoede<hdegoede@redhat.com>
- *
- *Thislibraryisfreesoftware;youcanredistributeitand/or
- *modifyitunderthetermsoftheGNULesserGeneralPublic
- *LicenseaspublishedbytheFreeSoftwareFoundation;either
- *version2.1oftheLicense,or(atyouroption)anylaterversion.
- *
- *Thislibraryisdistributedinthehopethatitwillbeuseful,
- *butWITHOUTANYWARRANTY;withouteventheimpliedwarrantyof
- *MERCHANTABILITYorFITNESSFORAPARTICULARPURPOSE.SeetheGNU
- *LesserGeneralPublicLicenseformoredetails.
- *
- *YoushouldhavereceivedacopyoftheGNULesserGeneralPublic
- *Licensealongwiththislibrary;ifnot,writetotheFreeSoftware
- *Foundation,Inc.,51FranklinStreet,Suite500,Boston,MA02110-1335USA
- *
- *Note:originalbayer_to_bgr24codefrom:
- *1394-BasedDigitalCameraControlLibrary
- *
- *Bayerpatterndecodingfunctions
- *
- *WrittenbyDamienDouxchampsandFredericDevernay
- *
- *Notethattheoriginalbayer.cinlibdc1394supportsmanydifferent
- *bayerdecodealgorithms,forlib4lconverttheoneinthisfilehasbeen
- *chosen(andoptimizedabit)andtheotheralgorithm'shavebeenremoved,
- *seebayer.cfromlibdc1394forallsupportedalgorithms
- */
- #include<string.h>
- #include<linux/videodev2.h>
- #include<stdio.h>
- #include"convert.h"
- /**************************************************************
- *Colorconversionfunctionsforcamerasthatcan*
- *outputraw-Bayerpatternimages,suchassomeBaslerand*
- *PointGreycamera.Mostofthealgospresentedherecome*
- *fromhttp://www-ise.stanford.edu/~tingchen/andhavebeen*
- *convertedfromMatlabtoCandextendedtoallelementary*
- *patterns.*
- **************************************************************/
- /*inspiredbyOpenCV'sBayerdecoding*/
- staticvoidv4lconvert_border_bayer_line_to_bgr24(
- constunsignedchar*bayer,constunsignedchar*adjacent_bayer,
- unsignedchar*bgr,intwidth,intstart_with_green,intblue_line)
- {
- intt0,t1;
- if(start_with_green){
- /*Firstpixel*/
- if(blue_line){
- *bgr++=bayer[1];
- *bgr++=bayer[0];
- *bgr++=adjacent_bayer[0];
- }else{
- *bgr++=adjacent_bayer[0];
- *bgr++=bayer[0];
- *bgr++=bayer[1];
- }
- /*Secondpixel*/
- t0=(bayer[0]+bayer[2]+adjacent_bayer[1]+1)/3;
- t1=(adjacent_bayer[0]+adjacent_bayer[2]+1)>>1;
- if(blue_line){
- *bgr++=bayer[1];
- *bgr++=t0;
- *bgr++=t1;
- }else{
- *bgr++=t1;
- *bgr++=t0;
- *bgr++=bayer[1];
- }
- bayer++;
- adjacent_bayer++;
- width-=2;
- }else{
- /*Firstpixel*/
- t0=(bayer[1]+adjacent_bayer[0]+1)>>1;
- if(blue_line){
- *bgr++=bayer[0];
- *bgr++=t0;
- *bgr++=adjacent_bayer[1];
- }else{
- *bgr++=adjacent_bayer[1];
- *bgr++=t0;
- *bgr++=bayer[0];
- }
- width--;
- }
- if(blue_line){
- for(;width>2;width-=2){
- t0=(bayer[0]+bayer[2]+1)>>1;
- *bgr++=t0;
- *bgr++=bayer[1];
- *bgr++=adjacent_bayer[1];
- bayer++;
- adjacent_bayer++;
- t0=(bayer[0]+bayer[2]+adjacent_bayer[1]+1)/3;
- t1=(adjacent_bayer[0]+adjacent_bayer[2]+1)>>1;
- *bgr++=bayer[1];
- *bgr++=t0;
- *bgr++=t1;
- bayer++;
- adjacent_bayer++;
- }
- }else{
- for(;width>2;width-=2){
- t0=(bayer[0]+bayer[2]+1)>>1;
- *bgr++=adjacent_bayer[1];
- *bgr++=bayer[1];
- *bgr++=t0;
- bayer++;
- adjacent_bayer++;
- t0=(bayer[0]+bayer[2]+adjacent_bayer[1]+1)/3;
- t1=(adjacent_bayer[0]+adjacent_bayer[2]+1)>>1;
- *bgr++=t1;
- *bgr++=t0;
- *bgr++=bayer[1];
- bayer++;
- adjacent_bayer++;
- }
- }
- if(width==2){
- /*Secondtolastpixel*/
- t0=(bayer[0]+bayer[2]+1)>>1;
- if(blue_line){
- *bgr++=t0;
- *bgr++=bayer[1];
- *bgr++=adjacent_bayer[1];
- }else{
- *bgr++=adjacent_bayer[1];
- *bgr++=bayer[1];
- *bgr++=t0;
- }
- /*Lastpixel*/
- t0=(bayer[1]+adjacent_bayer[2]+1)>>1;
- if(blue_line){
- *bgr++=bayer[2];
- *bgr++=t0;
- *bgr++=adjacent_bayer[1];
- }else{
- *bgr++=adjacent_bayer[1];
- *bgr++=t0;
- *bgr++=bayer[2];
- }
- }else{
- /*Lastpixel*/
- if(blue_line){
- *bgr++=bayer[0];
- *bgr++=bayer[1];
- *bgr++=adjacent_bayer[1];
- }else{
- *bgr++=adjacent_bayer[1];
- *bgr++=bayer[1];
- *bgr++=bayer[0];
- }
- }
- }
- /*Fromlibdc1394,whichonturnwasbasedonOpenCV'sBayerdecoding*/
- staticvoidbayer_to_rgbbgr24(constunsignedchar*bayer,
- unsignedchar*bgr,intwidth,intheight,unsignedintpixfmt,
- intstart_with_green,intblue_line)
- {
- /*renderthefirstline*/
- v4lconvert_border_bayer_line_to_bgr24(bayer,bayer+width,bgr,width,
- start_with_green,blue_line);
- bgr+=width*3;
- return;
- /*reduceheightby2becauseofthespecialcasetop/bottomline*/
- for(height-=2;height;height--){
- intt0,t1;
- /*(width-2)becauseoftheborder*/
- constunsignedchar*bayer_end=bayer+(width-2);
- if(start_with_green){
- /*OpenCVhasabuginthenextline,whichwas
- t0=(bayer[0]+bayer[width*2]+1)>>1;*/
- t0=(bayer[1]+bayer[width*2+1]+1)>>1;
- /*Writefirstpixel*/
- t1=(bayer[0]+bayer[width*2]+bayer[width+1]+1)/3;
- if(blue_line){
- *bgr++=t0;
- *bgr++=t1;
- *bgr++=bayer[width];
- }else{
- *bgr++=bayer[width];
- *bgr++=t1;
- *bgr++=t0;
- }
- /*Writesecondpixel*/
- t1=(bayer[width]+bayer[width+2]+1)>>1;
- if(blue_line){
- *bgr++=t0;
- *bgr++=bayer[width+1];
- *bgr++=t1;
- }else{
- *bgr++=t1;
- *bgr++=bayer[width+1];
- *bgr++=t0;
- }
- bayer++;
- }else{
- /*Writefirstpixel*/
- t0=(bayer[0]+bayer[width*2]+1)>>1;
- if(blue_line){
- *bgr++=t0;
- *bgr++=bayer[width];
- *bgr++=bayer[width+1];
- }else{
- *bgr++=bayer[width+1];
- *bgr++=bayer[width];
- *bgr++=t0;
- }
- }
- if(blue_line){
- for(;bayer<=bayer_end-2;bayer+=2){
- t0=(bayer[0]+bayer[2]+bayer[width*2]+
- bayer[width*2+2]+2)>>2;
- t1=(bayer[1]+bayer[width]+bayer[width+2]+
- bayer[width*2+1]+2)>>2;
- *bgr++=t0;
- *bgr++=t1;
- *bgr++=bayer[width+1];
- t0=(bayer[2]+bayer[width*2+2]+1)>>1;
- t1=(bayer[width+1]+bayer[width+3]+1)>>1;
- *bgr++=t0;
- *bgr++=bayer[width+2];
- *bgr++=t1;
- }
- }else{
- for(;bayer<=bayer_end-2;bayer+=2){
- t0=(bayer[0]+bayer[2]+bayer[width*2]+
- bayer[width*2+2]+2)>>2;
- t1=(bayer[1]+bayer[width]+bayer[width+2]+
- bayer[width*2+1]+2)>>2;
- *bgr++=bayer[width+1];
- *bgr++=t1;
- *bgr++=t0;
- t0=(bayer[2]+bayer[width*2+2]+1)>>1;
- t1=(bayer[width+1]+bayer[width+3]+1)>>1;
- *bgr++=t1;
- *bgr++=bayer[width+2];
- *bgr++=t0;
- }
- }
- if(bayer<bayer_end){
- /*writesecondtolastpixel*/
- t0=(bayer[0]+bayer[2]+bayer[width*2]+
- bayer[width*2+2]+2)>>2;
- t1=(bayer[1]+bayer[width]+bayer[width+2]+
- bayer[width*2+1]+2)>>2;
- if(blue_line){
- *bgr++=t0;
- *bgr++=t1;
- *bgr++=bayer[width+1];
- }else{
- *bgr++=bayer[width+1];
- *bgr++=t1;
- *bgr++=t0;
- }
- /*writelastpixel*/
- t0=(bayer[2]+bayer[width*2+2]+1)>>1;
- if(blue_line){
- *bgr++=t0;
- *bgr++=bayer[width+2];
- *bgr++=bayer[width+1];
- }else{
- *bgr++=bayer[width+1];
- *bgr++=bayer[width+2];
- *bgr++=t0;
- }
- bayer++;
- }else{
- /*writelastpixel*/
- t0=(bayer[0]+bayer[width*2]+1)>>1;
- t1=(bayer[1]+bayer[width*2+1]+bayer[width]+1)/3;
- if(blue_line){
- *bgr++=t0;
- *bgr++=t1;
- *bgr++=bayer[width+1];
- }else{
- *bgr++=bayer[width+1];
- *bgr++=t1;
- *bgr++=t0;
- }
- }
- /*skip2borderpixels*/
- bayer+=2;
- blue_line=!blue_line;
- start_with_green=!start_with_green;
- }
- /*renderthelastline*/
- v4lconvert_border_bayer_line_to_bgr24(bayer+width,bayer,bgr,width,
- !start_with_green,!blue_line);
- }
- voidv4lconvert_bayer_to_rgb24(constunsignedchar*bayer,
- unsignedchar*bgr,intwidth,intheight,unsignedintpixfmt)
- {
- bayer_to_rgbbgr24(bayer,bgr,width,height,pixfmt,
- pixfmt==V4L2_PIX_FMT_SGBRG8/*startwithgreen*/
- ||pixfmt==V4L2_PIX_FMT_SGRBG8,
- pixfmt!=V4L2_PIX_FMT_SBGGR8/*blueline*/
- &&pixfmt!=V4L2_PIX_FMT_SGBRG8);
- }
- voidv4lconvert_bayer_to_bgr24(constunsignedchar*bayer,
- unsignedchar*bgr,intwidth,intheight,unsignedintpixfmt)
- {
- bayer_to_rgbbgr24(bayer,bgr,width,height,pixfmt,
- pixfmt==V4L2_PIX_FMT_SGBRG8/*startwithgreen*/
- ||pixfmt==V4L2_PIX_FMT_SGRBG8,
- pixfmt==V4L2_PIX_FMT_SBGGR8/*blueline*/
- ||pixfmt==V4L2_PIX_FMT_SGBRG8);
- }
- staticvoidv4lconvert_border_bayer_line_to_y(
- constunsignedchar*bayer,constunsignedchar*adjacent_bayer,
- unsignedchar*y,intwidth,intstart_with_green,intblue_line)
- {
- intt0,t1;
- if(start_with_green){
- /*Firstpixel*/
- if(blue_line){
- *y++=(8453*adjacent_bayer[0]+16594*bayer[0]+
- 3223*bayer[1]+524288)>>15;
- }else{
- *y++=(8453*bayer[1]+16594*bayer[0]+
- 3223*adjacent_bayer[0]+524288)>>15;
- }
- /*Secondpixel*/
- t0=bayer[0]+bayer[2]+adjacent_bayer[1];
- t1=adjacent_bayer[0]+adjacent_bayer[2];
- if(blue_line)
- *y++=(4226*t1+5531*t0+3223*bayer[1]+524288)>>15;
- else
- *y++=(8453*bayer[1]+5531*t0+1611*t1+524288)>>15;
- bayer++;
- adjacent_bayer++;
- width-=2;
- }else{
- /*Firstpixel*/
- t0=bayer[1]+adjacent_bayer[0];
- if(blue_line){
- *y++=(8453*adjacent_bayer[1]+8297*t0+
- 3223*bayer[0]+524288)>>15;
- }else{
- *y++=(8453*bayer[0]+8297*t0+
- 3223*adjacent_bayer[1]+524288)>>15;
- }
- width--;
- }
- if(blue_line){
- for(;width>2;width-=2){
- t0=bayer[0]+bayer[2];
- *y++=(8453*adjacent_bayer[1]+16594*bayer[1]+
- 1611*t0+524288)>>15;
- bayer++;
- adjacent_bayer++;
- t0=bayer[0]+bayer[2]+adjacent_bayer[1];
- t1=adjacent_bayer[0]+adjacent_bayer[2];
- *y++=(4226*t1+5531*t0+3223*bayer[1]+524288)>>15;
- bayer++;
- adjacent_bayer++;
- }
- }else{
- for(;width>2;width-=2){
- t0=bayer[0]+bayer[2];
- *y++=(4226*t0+16594*bayer[1]+
- 3223*adjacent_bayer[1]+524288)>>15;
- bayer++;
- adjacent_bayer++;
- t0=bayer[0]+bayer[2]+adjacent_bayer[1];
- t1=adjacent_bayer[0]+adjacent_bayer[2];
- *y++=(8453*bayer[1]+5531*t0+1611*t1+524288)>>15;
- bayer++;
- adjacent_bayer++;
- }
- }
- if(width==2){
- /*Secondtolastpixel*/
- t0=bayer[0]+bayer[2];
- if(blue_line){
- *y++=(8453*adjacent_bayer[1]+16594*bayer[1]+
- 1611*t0+524288)>>15;
- }else{
- *y++=(4226*t0+16594*bayer[1]+
- 3223*adjacent_bayer[1]+524288)>>15;
- }
- /*Lastpixel*/
- t0=bayer[1]+adjacent_bayer[2];
- if(blue_line){
- *y++=(8453*adjacent_bayer[1]+8297*t0+
- 3223*bayer[2]+524288)>>15;
- }else{
- *y++=(8453*bayer[2]+8297*t0+
- 3223*adjacent_bayer[1]+524288)>>15;
- }
- }else{
- /*Lastpixel*/
- if(blue_line){
- *y++=(8453*adjacent_bayer[1]+16594*bayer[1]+
- 3223*bayer[0]+524288)>>15;
- }else{
- *y++=(8453*bayer[0]+16594*bayer[1]+
- 3223*adjacent_bayer[1]+524288)>>15;
- }
- }
- }
- voidv4lconvert_bayer_to_yuv420(constunsignedchar*bayer,unsignedchar*yuv,
- intwidth,intheight,unsignedintsrc_pixfmt,intyvu)
- {
- intblue_line=0,start_with_green=0,x,y;
- unsignedchar*ydst=yuv;
- unsignedchar*udst,*vdst;
- if(yvu){
- vdst=yuv+width*height;
- udst=vdst+width*height/4;
- }else{
- udst=yuv+width*height;
- vdst=udst+width*height/4;
- }
- printf("bayeraddress(0x%p)",bayer);
- /*Firstcalculatetheuandvplanes2x2pixelsatatime*/
- switch(src_pixfmt){
- caseV4L2_PIX_FMT_SBGGR8:
- for(y=0;y<height;y+=2){
- for(x=0;x<width;x+=2){
- intb,g,r;
- b=bayer[x];
- g=bayer[x+1];
- g+=bayer[x+width];
- r=bayer[x+width+1];
- *udst++=(-4878*r-4789*g+14456*b+4210688)>>15;
- *vdst++=(14456*r-6052*g-2351*b+4210688)>>15;
- }
- bayer+=2*width;
- }
- blue_line=1;
- break;
- caseV4L2_PIX_FMT_SRGGB8:
- for(y=0;y<height;y+=2){
- for(x=0;x<width;x+=2){
- intb,g,r;
- r=bayer[x];
- g=bayer[x+1];
- g+=bayer[x+width];
- b=bayer[x+width+1];
- *udst++=(-4878*r-4789*g+14456*b+4210688)>>15;
- *vdst++=(14456*r-6052*g-2351*b+4210688)>>15;
- }
- bayer+=2*width;
- }
- break;
- caseV4L2_PIX_FMT_SGBRG8:
- for(y=0;y<height;y+=2){
- for(x=0;x<width;x+=2){
- intb,g,r;
- g=bayer[x];
- b=bayer[x+1];
- r=bayer[x+width];
- g+=bayer[x+width+1];
- *udst++=(-4878*r-4789*g+14456*b+4210688)>>15;
- *vdst++=(14456*r-6052*g-2351*b+4210688)>>15;
- }
- bayer+=2*width;
- }
- blue_line=1;
- start_with_green=1;
- break;
- caseV4L2_PIX_FMT_SGRBG8:
- for(y=0;y<height;y+=2){
- for(x=0;x<width;x+=2){
- intb,g,r;
- g=bayer[x];
- r=bayer[x+1];
- b=bayer[x+width];
- g+=bayer[x+width+1];
- *udst++=(-4878*r-4789*g+14456*b+4210688)>>15;
- *vdst++=(14456*r-6052*g-2351*b+4210688)>>15;
- }
- bayer+=2*width;
- }
- start_with_green=1;
- break;
- }
- bayer-=width*height;
- printf("bayeraddress(0x%p)",bayer);
- /*renderthefirstline*/
- v4lconvert_border_bayer_line_to_y(bayer,bayer+width,ydst,width,
- start_with_green,blue_line);
- ydst+=width;
- printf("bayeraddress(0x%p),height(%d)",bayer,height);
- /*reduceheightby2becauseoftheborder*/
- for(height-=2;height;height--){
- intt0,t1;
- /*(width-2)becauseoftheborder*/
- constunsignedchar*bayer_end=bayer+(width-2);
- if(start_with_green){
- t0=bayer[1]+bayer[width*2+1];
- /*Writefirstpixel*/
- t1=bayer[0]+bayer[width*2]+bayer[width+1];
- if(blue_line)
- *ydst++=(8453*bayer[width]+5516*t1+
- 1661*t0+524288)>>15;
- else
- *ydst++=(4226*t0+5516*t1+
- 3223*bayer[width]+524288)>>15;
- /*Writesecondpixel*/
- t1=bayer[width]+bayer[width+2];
- if(blue_line)
- *ydst++=(4226*t1+16594*bayer[width+1]+
- 1611*t0+524288)>>15;
- else
- *ydst++=(4226*t0+16594*bayer[width+1]+
- 1611*t1+524288)>>15;
- bayer++;
- }else{
- /*Writefirstpixel*/
- t0=bayer[0]+bayer[width*2];
- if(blue_line){
- *ydst++=(8453*bayer[width+1]+16594*bayer[width]+
- 1661*t0+524288)>>15;
- }else{
- *ydst++=(4226*t0+16594*bayer[width]+
- 3223*bayer[width+1]+524288)>>15;
- }
- }
- if(blue_line){
- for(;bayer<=bayer_end-2;bayer+=2){
- t0=bayer[0]+bayer[2]+bayer[width*2]+bayer[width*2+2];
- t1=bayer[1]+bayer[width]+bayer[width+2]+bayer[width*2+1];
- *ydst++=(8453*bayer[width+1]+4148*t1+
- 806*t0+524288)>>15;
- t0=bayer[2]+bayer[width*2+2];
- t1=bayer[width+1]+bayer[width+3];
- *ydst++=(4226*t1+16594*bayer[width+2]+
- 1611*t0+524288)>>15;
- }
- }else{
- for(;bayer<=bayer_end-2;bayer+=2){
- t0=bayer[0]+bayer[2]+bayer[width*2]+bayer[width*2+2];
- t1=bayer[1]+bayer[width]+bayer[width+2]+bayer[width*2+1];
- *ydst++=(2113*t0+4148*t1+
- 3223*bayer[width+1]+524288)>>15;
- t0=bayer[2]+bayer[width*2+2];
- t1=bayer[width+1]+bayer[width+3];
- *ydst++=(4226*t0+16594*bayer[width+2]+
- 1611*t1+524288)>>15;
- }
- }
- if(bayer<bayer_end){
- /*Writesecondtolastpixel*/
- t0=bayer[0]+bayer[2]+bayer[width*2]+bayer[width*2+2];
- t1=bayer[1]+bayer[width]+bayer[width+2]+bayer[width*2+1];
- if(blue_line)
- *ydst++=(8453*bayer[width+1]+4148*t1+
- 806*t0+524288)>>15;
- else
- *ydst++=(2113*t0+4148*t1+
- 3223*bayer[width+1]+524288)>>15;
- /*writelastpixel*/
- t0=bayer[2]+bayer[width*2+2];
- if(blue_line){
- *ydst++=(8453*bayer[width+1]+16594*bayer[width+2]+
- 1661*t0+524288)>>15;
- }else{
- *ydst++=(4226*t0+16594*bayer[width+2]+
- 3223*bayer[width+1]+524288)>>15;
- }
- bayer++;
- }else{
- /*writelastpixel*/
- t0=bayer[0]+bayer[width*2];
- t1=bayer[1]+bayer[width*2+1]+bayer[width];
- if(blue_line)
- *ydst++=(8453*bayer[width+1]+5516*t1+
- 1661*t0+524288)>>15;
- else
- *ydst++=(4226*t0+5516*t1+
- 3223*bayer[width+1]+524288)>>15;
- }
- /*skip2borderpixels*/
- bayer+=2;
- blue_line=!blue_line;
- start_with_green=!start_with_green;
- }
- /*renderthelastline*/
- v4lconvert_border_bayer_line_to_y(bayer+width,bayer,ydst,width,
- !start_with_green,!blue_line);
- }
##################################################################################
convert.c
##################################################################################
- #include<stdio.h>
- #include<string.h>
- #include<stdlib.h>
- #include<fcntl.h>
- #include<sys/stat.h>
- #include<linux/videodev2.h>
- #include"convert.h"
- char*g_src_file=NULL;
- char*g_dest_file=NULL;
- intg_in_width=352;
- intg_in_height=292;
- unsignedintg_src_fmt=V4L2_PIX_FMT_SGBRG8;
- //unsignedintg_dest_fmt=V4L2_PIX_FMT_RGB24;
- unsignedintg_dest_fmt=V4L2_PIX_FMT_YUV420;
- intprocess_cmdline(intargc,char**argv)
- {
- inti;
- char*tmp;
- for(i=1;i<argc;i++){
- if(strcmp(argv[i],"-s")==0){
- g_src_file=argv[++i];
- }
- elseif(strcmp(argv[i],"d")==0){
- g_dest_file=strdup(argv[++i]);
- }
- elseif(strcmp(argv[i],"-sf")==0){
- tmp=argv[++i];
- if(strlen(tmp)==4){
- g_src_fmt=v4l2_fourcc(tmp[0],tmp[1],tmp[2],tmp[3]);
- }
- }
- elseif(strcmp(argv[i],"-df")==0){
- tmp=argv[++i];
- if(strlen(tmp)==4){
- g_dest_fmt=v4l2_fourcc(tmp[0],tmp[1],tmp[2],tmp[3]);
- }
- }
- elseif(strcmp(argv[i],"iw")==0){
- g_in_width=atoi(argv[++i]);
- }
- elseif(strcmp(argv[i],"ih")==0){
- g_in_height=atoi(argv[++i]);
- }
- }
- if(g_src_file&&g_dest_file==NULL){
- g_dest_file=malloc(256);
- sprintf(g_dest_file,"%s.out",g_src_file);
- }
- if(g_in_width==0||g_in_height==0){
- }
- }
- intget_file_size(intfd)
- {
- intret;
- structstatsb;
- ret=fstat(fd,&sb);
- if(ret==-1){
- returnret;
- }
- returnsb.st_size;
- }
- intget_bits_per_pixel(unsignedintfmt)
- {
- intret;
- switch(fmt){
- caseV4L2_PIX_FMT_RGB24:
- ret=24;
- break;
- caseV4L2_PIX_FMT_SBGGR8:
- caseV4L2_PIX_FMT_SGBRG8:
- caseV4L2_PIX_FMT_SGRBG8:
- caseV4L2_PIX_FMT_SRGGB8:
- ret=8;
- break;
- caseV4L2_PIX_FMT_YUV420:
- ret=12;
- break;
- caseV4L2_PIX_FMT_YUYV:
- caseV4L2_PIX_FMT_UYVY:
- ret=16;
- break;
- default:
- ret=-1;
- break;
- }
- returnret;
- }
- voidconvert(void*src,void*dest,intwidth,intheight,unsignedintsrc_fmt,unsignedintdest_fmt)
- {
- switch(src_fmt){
- caseV4L2_PIX_FMT_SGBRG8:
- if(dest_fmt==V4L2_PIX_FMT_RGB24){
- v4lconvert_bayer_to_rgb24(src,dest,width,height,src_fmt);
- }
- elseif(dest_fmt==V4L2_PIX_FMT_YUV420){
- v4lconvert_bayer_to_yuv420(src,dest,width,height,src_fmt,0);
- }
- break;
- default:
- break;
- }
- }
- intmain(intargc,char*argv[])
- {
- intret=0;
- intfd_src=0;
- intfd_dest=0;
- intsrc_size=0;
- intdest_size=0;
- intpix_num;
- void*src=NULL;
- void*dest=NULL;
- process_cmdline(argc,argv);
- if(g_src_file==NULL||g_dest_file==NULL){
- ret=-1;
- gotobailout;
- }
- printf("inputfile(%s),outputfile(%s) ",g_src_file,g_dest_file);
- fd_src=open(g_src_file,O_RDONLY);
- if(fd_src==-1){
- ret=-2;
- gotobailout;
- }
- fd_dest=open(g_dest_file,O_RDWR|O_CREAT,0666);
- if(fd_dest==-1){
- ret=-3;
- gotobailout;
- }
- src_size=get_file_size(fd_src);
- if(src_size==-1){
- ret=-4;
- gotobailout;
- }
- pix_num=src_size/(get_bits_per_pixel(g_src_fmt)/8);
- //dest_size=pix_num*get_bytes_per_pixel(g_dest_fmt);
- ret=get_bits_per_pixel(g_dest_fmt);
- dest_size=pix_num*ret/8;
- printf("src_size(%d),dest_size(%d) ",src_size,dest_size);
- src=malloc(src_size);
- dest=malloc(dest_size);
- if(src==NULL||dest==NULL){
- ret=-5;
- gotobailout;
- }
- ret=read(fd_src,src,src_size);
- if(ret!=src_size){
- ret=-6;
- gotobailout;
- }
- convert(src,dest,g_in_width,g_in_height,g_src_fmt,g_dest_fmt);
- printf("writeoutfile,size=%d ",dest_size);
- ret=write(fd_dest,dest,dest_size);
- if(ret!=dest_size){
- ret=-1;
- gotobailout;
- }
- bailout:
- if(src)
- free(src);
- if(dest)
- free(dest);
- if(fd_src)
- close(fd_src);
- if(fd_dest)
- close(fd_dest);
- if(g_dest_file)
- free(g_dest_file);
- printf("ret(%d) ",ret);
- returnret;
- }
##################################################################################
covert.h
##################################################################################
- #ifndef__LIBV4LCONVERT_PRIV_H
- #define__LIBV4LCONVERT_PRIV_H
- #defineV4L2_PIX_FMT_SRGGB8v4l2_fourcc('R','G','G','B')
- voidv4lconvert_bayer_to_rgb24(constunsignedchar*bayer,
- unsignedchar*bgr,intwidth,intheight,unsignedintpixfmt);
- voidv4lconvert_bayer_to_bgr24(constunsignedchar*bayer,
- unsignedchar*bgr,intwidth,intheight,unsignedintpixfmt);
- voidv4lconvert_bayer_to_yuv420(constunsignedchar*bayer,unsignedchar*yuv,
- intwidth,intheight,unsignedintsrc_pixfmt,intyvu);
- #endif/*__LIBV4LCONVERT_PRIV_H*/
##################################################################################
Makefile
##################################################################################
- CONVERT:=convert
- CFLAGS:=-static
- CC=gcc
- $(CONVERT):convert.cbayer.c
- $(CC)-o$@$^$(CFLAGS)
- clean:
- rm-f*.o$(CONVERT)
##################################################################################
RGB32 RGB565转换为YUV444
另外为了在PC显示framebuffer中的数据,写了一个ARGB32或者RGB565到YUV444的转换工具。利用YUVtools显示YUV444图像。
其实可以不用这么麻烦,使用ddms截屏也行。
YUV444是 Y U V分量比为4:4:4,每个像素用24bits表示。
##################################################################################
- #include<stdio.h>
- #include<string.h>
- #include<stdlib.h>
- #include<fcntl.h>
- #include<sys/stat.h>
- #include<linux/videodev2.h>
- char*g_src_file=NULL;
- char*g_dest_file=NULL;
- intg_in_width=720;
- intg_in_height=480;
- /*V4L2_PIX_FMT_BGR32*/
- //unsignedintg_src_fmt=V4L2_PIX_FMT_RGB32;
- unsignedintg_src_fmt=V4L2_PIX_FMT_RGB565;
- /*V4L2_PIX_FMT_YUYVV4L2_PIX_FMT_YVYUV4L2_PIX_FMT_UYVYV4L2_PIX_FMT_VYUY*/
- unsignedintg_dest_fmt=V4L2_PIX_FMT_YUV444;
- staticunsignedcharget_R(unsignedchar*src,unsignedintfmt)
- {
- unsignedcharR;
- switch(fmt){
- caseV4L2_PIX_FMT_RGB32:
- caseV4L2_PIX_FMT_BGR32:
- caseV4L2_PIX_FMT_RGB24:
- R=*(src);
- break;
- caseV4L2_PIX_FMT_RGB565:
- R=(*(src)&0x1F)<<3;
- break;
- caseV4L2_PIX_FMT_SBGGR8:
- caseV4L2_PIX_FMT_SGBRG8:
- caseV4L2_PIX_FMT_SGRBG8:
- caseV4L2_PIX_FMT_YUV420:
- caseV4L2_PIX_FMT_YUV444:
- default:
- R=0;
- break;
- }
- returnR;
- }
- staticunsignedcharget_G(unsignedchar*src,unsignedintfmt)
- {
- unsignedcharG;
- switch(fmt){
- caseV4L2_PIX_FMT_RGB32:
- caseV4L2_PIX_FMT_BGR32:
- caseV4L2_PIX_FMT_RGB24:
- G=*(src+1);
- break;
- caseV4L2_PIX_FMT_RGB565:
- G=((*(src)&0xE0)>>3)|((*(src+1)&0x07)<<5);
- break;
- caseV4L2_PIX_FMT_SBGGR8:
- caseV4L2_PIX_FMT_SGBRG8:
- caseV4L2_PIX_FMT_SGRBG8:
- caseV4L2_PIX_FMT_YUV420:
- caseV4L2_PIX_FMT_YUV444:
- default:
- G=0;
- break;
- }
- returnG;
- }
- staticunsignedcharget_B(unsignedchar*src,unsignedintfmt)
- {
- unsignedcharB;
- switch(fmt){
- caseV4L2_PIX_FMT_RGB32:
- caseV4L2_PIX_FMT_BGR32:
- caseV4L2_PIX_FMT_RGB24:
- B=*(src+2);
- break;
- caseV4L2_PIX_FMT_RGB565:
- B=(*(src+1)&0xF8);
- break;
- caseV4L2_PIX_FMT_SBGGR8:
- caseV4L2_PIX_FMT_SGBRG8:
- caseV4L2_PIX_FMT_SGRBG8:
- caseV4L2_PIX_FMT_YUV420:
- caseV4L2_PIX_FMT_YUV444:
- default:
- B=0;
- break;
- }
- returnB;
- }
- rgb2yuv(char*rgb,char*yuv)
- {
- inti,j;
- unsignedcharR,G,B,*y,*u,*v,*alpha;
- doubleRR,GG,BB;
- unsignedchar*src,*dest;
- for(i=0;i<g_in_height;i++){
- for(j=0;j<g_in_width;j++){
- src=rgb+(i*g_in_width+j)*get_bpp(g_src_fmt)/8;
- dest=yuv+(i*g_in_width+j)*get_bpp(g_dest_fmt)/8;
- R=get_R(src,g_src_fmt);
- G=get_G(src,g_src_fmt);
- B=get_B(src,g_src_fmt);
- /*normalizeto16..235*/
- RR=219*R/255+16;
- GG=219*G/255+16;
- BB=219*B/255+16;
- y=dest;
- u=dest+1;
- v=dest+2;
- //alpha=dest+3;
- *y=(unsignedchar)(0.2991*RR+0.5849*GG+0.1159*BB+0.5);
- *u=(unsignedchar)(-0.1725*RR-0.3372*GG+0.5097*BB+128.5);
- *v=(unsignedchar)(0.5097*RR-0.4254*GG-0.0843*BB+128.5);
- //*alpha=255;
- }
- }
- }
- intprocess_cmdline(intargc,char**argv)
- {
- inti;
- char*tmp;
- for(i=1;i<argc;i++){
- if(strcmp(argv[i],"-s")==0){
- g_src_file=argv[++i];
- }
- elseif(strcmp(argv[i],"-d")==0){
- g_dest_file=strdup(argv[++i]);
- }
- elseif(strcmp(argv[i],"-sf")==0){
- tmp=argv[++i];
- if(strlen(tmp)==4){
- g_src_fmt=v4l2_fourcc(tmp[0],tmp[1],tmp[2],tmp[3]);
- }
- }
- elseif(strcmp(argv[i],"-df")==0){
- tmp=argv[++i];
- if(strlen(tmp)==4){
- g_dest_fmt=v4l2_fourcc(tmp[0],tmp[1],tmp[2],tmp[3]);
- }
- }
- elseif(strcmp(argv[i],"iw")==0){
- g_in_width=atoi(argv[++i]);
- }
- elseif(strcmp(argv[i],"ih")==0){
- g_in_height=atoi(argv[++i]);
- }
- }
- if(g_src_file&&g_dest_file==NULL){
- g_dest_file=malloc(256);
- sprintf(g_dest_file,"%s.out",g_src_file);
- }
- if(g_in_width==0||g_in_height==0){
- }
- }
- intget_bpp(unsignedintfmt)
- {
- intret;
- switch(fmt){
- caseV4L2_PIX_FMT_RGB32:
- caseV4L2_PIX_FMT_BGR32:
- ret=32;
- break;
- caseV4L2_PIX_FMT_RGB24:
- ret=24;
- break;
- caseV4L2_PIX_FMT_RGB565:
- ret=16;
- break;
- caseV4L2_PIX_FMT_SBGGR8:
- caseV4L2_PIX_FMT_SGBRG8:
- caseV4L2_PIX_FMT_SGRBG8:
- ret=8;
- break;
- caseV4L2_PIX_FMT_YUV420:
- ret=12;
- break;
- caseV4L2_PIX_FMT_YUYV:
- caseV4L2_PIX_FMT_UYVY:
- ret=16;
- break;
- caseV4L2_PIX_FMT_YUV444:
- ret=24;
- break;
- default:
- ret=-1;
- break;
- }
- returnret;
- }
- main(intargc,char*argv[])
- {
- intret;
- intsrc_fd,dest_fd;
- intsrc_size,dest_size;
- char*src_buf;
- char*dest_buf;
- process_cmdline(argc,argv);
- if(g_src_file==NULL||g_dest_file==NULL){
- ret=-1;
- gotobailout;
- }
- src_fd=open(g_src_file,O_RDONLY);
- if(src_fd==-1){
- ret=-2;
- gotobailout;
- }
- dest_fd=open(g_dest_file,O_RDWR|O_CREAT,0666);
- if(dest_fd==-1){
- ret=-3;
- gotobailout;
- }
- src_size=g_in_width*g_in_height*get_bpp(g_src_fmt)/8;
- dest_size=g_in_width*g_in_height*get_bpp(g_dest_fmt)/8;
- src_buf=malloc(src_size);
- dest_buf=malloc(dest_size);
- ret=read(src_fd,src_buf,src_size);
- if(ret!=src_size){
- printf("src_size=%d,ret=%d ",src_size,ret);
- ret=-4;
- gotobailout;
- }
- rgb2yuv(src_buf,dest_buf);
- printf("writeoutfile,size=%d ",dest_size);
- ret=write(dest_fd,dest_buf,dest_size);
- if(ret!=dest_size){
- ret=-5;
- gotobailout;
- }
- bailout:
- printf("ret(%d) ",ret);
- returnret;
- }
##################################################################################