linux yuv转换工具,video4linux——包含yuv转rgb

# include < stdio. h>

# include < stdlib. h>

# include < unistd. h>

# include < linux/ videodev. h>

# include < sys/ ioctl. h>

# include < fcntl. h>

# include < linux/ fb. h>

# include < sys/ mman. h>

# include < linux/ delay. h>

# include < time . h>

# define ERR_FRAME_BUFFER    1

# define ERR_VIDEO_OPEN        2

# define ERR_VIDEO_GCAP        3

# define ERR_VIDEO_GPIC        4

# define ERR_VIDEO_SPIC        5

# define ERR_SYNC            6

# define ERR_FRAME_USING 7

# define ERR_GET_FRAME 8

typedef struct     _fb_v4l

{

int fbfd ;

struct fb_var_screeninfo vinfo;

struct fb_fix_screeninfo finfo;

char * fbp;

int fd;

struct video_capability capability;

struct video_buffer      buffer;

struct video_window      window;

struct video_channel      channel[ 8] ;

struct video_picture      picture;

struct video_tuner      tuner;

struct video_audio      audio[ 8] ;

struct video_mmap      mmap;

struct video_mbuf      mbuf;

unsigned char      * map ;

int frame_current;

int frame_using[ VIDEO_MAX_FRAME] ;

} fb_v41;

struct file_header

{

unsigned short bfType; // Picture tpye, must set to 19778

int bfSize; // The file size in bytes

int bfRev; // Reserved

int bfOffBits; // the offset from the beginning of the file to the bitmap data.

} __attribute__ ( ( packed) ) ;

struct info_header

{

int biSize; // info_header's size in bytes

int biWidth; // width in pixels

int biHeight; //height in pixels

short biPlanes; //the number of planes of the target device

short biBitCount; //the number of bits per pixel

int biCompression; //the type of compression

int biSizeImage; //

int biXPelsPerMeter; //usually set to zero

int biYPelsPerMeter; //usually set to zero

int biClrUsed; //the number of colors used in the bitmap

int biClrImportant;

} __attribute__ ( ( packed) ) ;

struct bmp_file

{

struct file_header header;

struct info_header info;

unsigned char bits[ 640* 480* 3] ;

} __attribute__ ( ( packed) ) ;

# define V4L_FILE "/dev/video0"

int get_grab_frame( fb_v41 * vd, int frame)

{

if ( vd- > frame_using[ frame] )

{

fprintf ( stderr , "get_grab_frame: frame %d is already used./n" , frame) ;

return ERR_FRAME_USING;

}

vd- > mmap. frame = frame;

if ( ioctl( vd- > fd, VIDIOCMCAPTURE, & ( vd- > mmap) ) < 0)

{

perror ( "v4l_grab_frame" ) ;

return ERR_GET_FRAME;

}

vd- > frame_using[ frame] = 1;

vd- > frame_current = frame;

return 0;

}

int get_first_frame( fb_v41 * vd)

{

int ret;

vd- > frame_current = 0;

ret = get_grab_frame( vd, 0 ) ;

if ( ret< 0 )

return ret;

if ( ioctl( vd- > fd, VIDIOCSYNC, & ( vd- > frame_current) ) < 0)

{

perror ( "v4l_grab_sync" ) ;

return ERR_SYNC;

}

vd- > frame_using[ vd- > frame_current] = 0 ;

return ( 0) ;

}

int get_next_frame( fb_v41 * vd)

{

int ret;

vd- > frame_current ^= 1;

ret = get_grab_frame( vd, vd- > frame_current) ;

if ( ret < 0 )

return ret;

if ( ioctl( vd- > fd, VIDIOCSYNC, & ( vd- > frame_current) ) < 0)

{

perror ( "v4l_grab_sync" ) ;

return ERR_SYNC;

}

vd- > frame_using[ vd- > frame_current] = 0 ;

return 0;

}

unsigned char * get_frame_address( fb_v41 * vd)

{

return ( vd- > map + vd- > mbuf. offsets[ vd- > frame_current] ) ;

}

int open_video( char * fileptr, fb_v41 * vd , int dep, int pal, int width, int height)

{

if ( ( vd- > fd = open ( fileptr, O_RDWR) ) < 0)

{

perror ( "v4l_open:" ) ;

return ERR_VIDEO_OPEN;

}

if ( ioctl( vd- > fd, VIDIOCGCAP, & ( vd- > capability) ) < 0)

{

perror ( "v4l_get_capability:" ) ;

return ERR_VIDEO_GCAP;

}

if ( ioctl( vd- > fd, VIDIOCGPICT, & ( vd- > picture) ) < 0)

{

perror ( "v4l_get_picture" ) ;

return ERR_VIDEO_GPIC;

}

vd- > picture. palette = pal;

vd- > picture. depth = dep;

vd- > mmap. format = pal;

if ( ioctl( vd- > fd, VIDIOCSPICT, & ( vd- > picture) ) < 0)

{

perror ( "v4l_set_palette" ) ;

return ERR_VIDEO_SPIC;

}

vd- > mmap. width = width;

vd- > mmap. height = height;

vd- > mmap. format = vd- > picture. palette;

vd- > frame_current = 0;

vd- > frame_using[ 0] = 0;

vd- > frame_using[ 1] = 0;

if ( ioctl( vd- > fd, VIDIOCGMBUF, & ( vd- > mbuf) ) < 0)

{

perror ( "v4l_get_mbuf" ) ;

return - 1;

}

vd- > map = mmap( 0, vd- > mbuf. size, PROT_READ| PROT_WRITE, MAP_SHARED, vd- > fd, 0) ;

if ( vd- > map < 0)

{

perror ( "v4l_mmap_init:mmap" ) ;

return - 1;

}

printf ( "The video device was opened successfully./n" ) ;

return 0;

}

static void cvt_420p_to_rgb( int width, int height, const unsigned char * src, unsigned char * dst)

{

int r, g, b;

int rdif, gdif, bdif, y;

int yy, uu, vv;

int xoff, yoff;

int numpix = width* height;

unsigned char * pout = dst + width* height* 3;

for ( yoff= 0; yoff< height; yoff+ + )

{

for ( xoff= 0; xoff< width; xoff+ + )

{

yy = * ( src+ yoff* 640+ xoff) ;

uu = * ( src+ ( yoff/ 2) * 320+ xoff/ 2+ numpix) ;

vv = * ( src+ ( yoff/ 2) * 320+ xoff/ 2+ numpix+ numpix/ 4) ;

uu - = 128;

vv - = 128;

r = yy + vv + ( ( vv* 103) > > 8) ;

g = yy - ( ( uu* 88) > > 8) - ( ( vv* 183) > > 8) ;

b = yy + uu + ( ( uu* 198) > > 8) ;

if ( r> 255) { r = 255; }

if ( g> 255) { g = 255; }

if ( b> 255) { b = 255; }

if ( r< 0) { r = 0; }

if ( g< 0) { g = 0; }

if ( b< 0) { b = 0; }

* pout = ( unsigned char ) b;

pout- - ;

* pout = ( unsigned char ) r;

pout- - ;

* pout = ( unsigned char ) g;

pout- - ;

}

}

}

int main( void )

{

fb_v41 vd;

int ret, i;

int k= 0;

unsigned char * imageptr;

struct bmp_file myfile;

int fd;

printf ( "sizeof short is %d/n" , sizeof ( short ) ) ;

myfile. header. bfType = 19778;

myfile. header. bfSize = sizeof ( struct bmp_file) ;

myfile. header. bfRev = 0;

myfile. header. bfOffBits = 54;

myfile. info. biSize = 0x28;

myfile. info. biWidth = 640;

myfile. info. biHeight = 480;

myfile. info. biPlanes = 1;

myfile. info. biBitCount = 24;

myfile. info. biCompression = 0;

myfile. info. biSizeImage = 0;

myfile. info. biClrUsed = 256* 256* 256;

myfile. info. biClrImportant = 0;

myfile. info. biXPelsPerMeter = 2048;

myfile. info. biYPelsPerMeter = 2048;

fd = open ( "./first.bmp" , O_RDWR) ;

if ( fd < 0)

{

printf ( "open file error!/n" ) ;

return 0;

}

ret = open_video( V4L_FILE, & vd, 24, VIDEO_PALETTE_YUV420P, 640, 480) ;

if ( ret )

{

printf ( "Open video failed!/n" ) ;

goto err;

}

printf ( vd. capability. name) ;

printf ( ", Type:%d/n" , vd. capability. type) ;

printf ( "Maxwidth:%d,Maxheight:%d/n" , vd. capability. maxwidth , vd. capability. maxheight) ;

printf ( "Minwidth:%d,Minheight:%d/n" , vd. capability. minwidth, vd. capability. minheight) ;

printf ( "Channels:%d,Audios:%d/n" , vd. capability. channels, vd. capability. audios) ;

for ( i= 0; i< 10; i+ + )

{

imageptr = ( unsigned char * ) get_frame_address( & vd ) ;

if ( get_next_frame( & vd ) ! = 0 )

{

goto err;

}

printf ( "i = %d/n" , i) ;

}

cvt_420p_to_rgb( 640, 480, imageptr, myfile. bits) ;

write ( fd, & myfile, sizeof ( struct bmp_file) ) ;

err:

if ( vd. fbfd)

close ( vd. fbfd) ;

if ( vd. fd)

close ( vd. fd) ;

exit ( 0) ;

return 0;

}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值