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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值