您的位置:首页 > 运维架构 > Linux

APUE linux下 sys/ioctl.h 作用

2016-07-05 11:32 459 查看
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: