ioctl()是I/O操作的杂货箱,很多事情都要依靠它来完成。除了摄像头,视频采集卡之类的与video相关的操作其实也都与此类似

 

Linux查看摄像头参数的小程序(转)

 

http://blog.chinaunix.net/u/270/showart_315616.html 在linux下做和video相关的事情必定要涉及到video for linux层,简写做v4l,这个程序就是基于这个API层写的。之所以写这个小程序主要是因为通过lsusb命令只能看到类似 venderID,productID之类的参数,而看不到其他的涉及摄像头本身的一些参数。程序中主要使用到的是ioctl()系统调 用,ioctl()是I/O操作的杂货箱,很多事情都要依靠它来完成。除了摄像头,视频采集卡之类的与video相关的操作其实也都与此类似。以下给出程 序的源代码,以供以后会涉及到这方面的兄弟参考。程序本身的功能其实很简单,所以也不一一解说。里面只涉及到少量unix下C编程的知识,若有疑问请参阅 相关资料。

/* Program: qc_test.c
* Author: Rockins
* Date: Mar 3,2005
* Compile command: gcc -o qc_test qc_test.c
* IMPORTANT:You can freely distribute this programme under LGPL License.
* If you haven't had a copy of LGPL,you can get it from FSF organization.
*/

#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <linux/videodev.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <signal.h>

#define MAXLINE 256

char errMsg[MAXLINE];

char* deviceName = "/dev/video0";
int deviceHandle = 0;
struct video_capability capability;
struct video_channel    queryChannel;
struct video_window    queryWindow;
struct video_picture    queryPicture;


//function:sig_brk(),signal handle,close deviceHandle then exit,if press CTL-C or CTL-/
//param:signo,the signal number
//return:void

static void
sig_brk(int signo)
{
if (signo == SIGINT)
{
      fprintf(stderr,"terminated by CTL-C/n");
      close(deviceHandle);
      exit(-1);
}
if (signo == SIGQUIT)
{
      fprintf(stderr,"terminated by CTL-///n");
      close(deviceHandle);
      exit(-1);
}
return ;
}



//function:err_exit(),called when an error occured
//param:char* err_msg
//return:-1

static void
err_exit(char *err_msg)
{
printf(err_msg);
if (errno != 0)
   perror("error:");
close(deviceHandle);
exit(-1);
}


/
//function:main(),do everything
//return:0 if success,else -1

int
main(int argc,char *argv[])
{

///
//HERE open the QuickCam device
///
deviceHandle = open (deviceName, O_RDWR);
if (deviceHandle == -1)
{ //cannot open the "/dev/video0"
   sprintf(errMsg,"cannot open %s:",deviceName);
   err_exit(errMsg);
}
printf("open %s success./n",deviceName);

/
//HERE register signal handle for CTL-C and CTL-/
/
if (signal(SIGINT,sig_brk) == SIG_ERR)
{
      sprintf(errMsg,"cannot register signal handle for SIGINT/n");
      err_exit(errMsg);
}

if (signal(SIGQUIT,sig_brk) == SIG_ERR)
{
      sprintf(errMsg,"cannot register signal handle for SIGQUIT/n");
      err_exit(errMsg);
}

///
//HERE query QuickCam for its capability
//
if (ioctl(deviceHandle,VIDIOCGCAP,&capability) == -1)
{ //query capability failed
   sprintf(errMsg,"query capability failed./n");
   err_exit(errMsg);
}

printf("query capability success./n");
printf("/tname = %s./n",capability.name);
if (capability.type & VID_TYPE_CAPTURE)
   printf("/ttype = VID_TYPE_CAPTURE./n");
if (capability.type & VID_TYPE_TUNER)
   printf("/ttype = VID_TYPE_TUNER./n");
if (capability.type & VID_TYPE_SCALES)
   printf("/ttype = VID_TYPE_SCALES./n");
if (capability.type & VID_TYPE_MONOCHROME)
   printf("/ttype = VID_TYPE_MONOCHROME./n");
if (capability.type & VID_TYPE_SUBCAPTURE)
   printf("/ttype = VID_TYPE_SUBCAPTURE./n");
printf("/tchannels = %d/n",capability.channels);
if (capability.audios != 0)
   printf("/taudios = %d/n",capability.audios);
printf("/tmaxwidth = %d,maxheight = %d/n",capability.maxwidth,capability.maxheight);
printf("/tminwidth = %d,minheight = %d/n",capability.minwidth,capability.minheight);

//
//HERE query QuickCam for available channels
//
int i = 0;
while (i < capability.channels)
{
   queryChannel.channel = i++;
   if (ioctl(deviceHandle,VIDIOCGCHAN,&queryChannel) == -1)
   { //query channel failed
    printf("query channel %d failed./n",queryChannel.channel);
    continue;
   }

   //then,query channel success
   printf("channel %d is available./n",queryChannel.channel);
   printf("/tchannel name = %s./n",queryChannel.name);
   if (queryChannel.tuners != 0)
    printf("/tchannel tuners = %d./n",queryChannel.tuners);
   if (queryChannel.flags & VIDEO_VC_TUNER)
    printf("/tVIDEO_VC_TUNER = channel has tuners./n");
   if (queryChannel.flags & VIDEO_VC_AUDIO)
    printf("/tVIDEO_VC_AUDIO = channel has audio./n");

   if (queryChannel.type & VIDEO_TYPE_TV)
    printf("/tVIDEO_TYPE_TV = channel is a TV input./n");
   if (queryChannel.type & VIDEO_TYPE_CAMERA)
    printf("/tVIDEO_TYPE_CAMERA = channel is a camera./n");

   printf("/tchannel norm = %d./n",queryChannel.norm);
}

//
//HERE query QuickCam for window property,i.e, x,y,width and height
//
if (ioctl(deviceHandle,VIDIOCGWIN,&queryWindow) == -1)
{ //query window failed
   sprintf(errMsg,"query window failed./n");
   err_exit(errMsg);
}

printf("query window success./n");
printf("/tx = %d,y = %d./n",queryWindow.x,queryWindow.y);
printf("/twidth = %d,height = %d./n",queryWindow.width,queryWindow.height);

/
//HERE query QuickCam for picture property,i.e,brightness,contrast,depth and palette
/
char* palette_mode;
if (ioctl(deviceHandle,VIDIOCGPICT,&queryPicture) == -1)
{ //query picture failed
   sprintf(errMsg,"query picture failed./n");
   err_exit(errMsg);
}

//then,query picture success
printf("query picture success./n");
printf("/tbrightness = %d./n",queryPicture.brightness);
printf("/tcontrast = %d./n",queryPicture.contrast);
if (queryPicture.depth == 15)
   palette_mode = "VIDEO_PALETTE_RGB555";
else if (queryPicture.depth == 16)
   palette_mode = "VIDEO_PALETTE_RGB565";
else if (queryPicture.depth == 24)
   palette_mode = "VIDEO_PALETTE_RGB24";
else if (queryPicture.depth == 32)
   palette_mode = "VIDEO_PALETTE_RGB32";
printf("/tdepth = %d,palette = %s/n",queryPicture.depth,palette_mode);

///
//HERE close deviceHandle,then main() return
///
close(deviceHandle);
return 0;
}

以上代码在运行linux内核的PC平台和嵌入式开发板上产生的结果如下(目标为罗技QuickCam Express摄像头):

open /dev/video0 success.
query capability success.
name = Logitech QuickCam USB.
type = VID_TYPE_CAPTURE.
type = VID_TYPE_SUBCAPTURE.
channels = 1
maxwidth = 352,maxheight = 292
minwidth = 32,minheight = 32
channel 0 is available.
channel name = Camera.
VIDEO_TYPE_CAMERA = channel is a camera.
channel norm = 0.
query window success.
x = 0,y = 0.
width = 352,height = 292.
query picture success.
brightness = 32768.
contrast = 32768.
depth = 24,palette = VIDEO_PALETTE_RGB24


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/mcy478643968/archive/2010/10/26/5966351.aspx

GitHub 加速计划 / li / linux-dash
6
1
下载
A beautiful web dashboard for Linux
最近提交(Master分支:3 个月前 )
186a802e added ecosystem file for PM2 4 年前
5def40a3 Add host customization support for the NodeJS version 4 年前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐