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

linux 下V4L的使用例子

2010-07-01 16:38 190 查看
#include <stdio.h>

#include <string.h>

#include <errno.h>

#include <fcntl.h>

#include <sys/mman.h>

#include <linux/videodev.h>

#include<sys/types.h>

#define VIDEO_PALETTE_RAW_JPEG 20

#define VIDEO_PALETTE_JPEG 21

#ifdef ANDROID_ENV

#define LOG LOGV

#else

#define LOG printf

#endif

#define CAPTURE_FILE "/tmp/catchpic.jpg"

typedef struct _v4ldevice

{int fd;//设备号

struct video_capability capability;

struct video_channel channel[10];

struct video_picture picture;

struct video_clip clip;

struct video_window window;

struct video_capture capture;

struct video_buffer buffer;

struct video_mmap mmap;

struct video_mbuf mbuf;

struct video_unit unit;

unsigned char *map;//mmap方式获取数据时,数据的首地址

pthread_mutex_t mutex;

int frame;

int framestat[2];

int overlay;

}v4ldevice;

int v4lgetcapability(v4ldevice *vd)

{

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

LOG("an error happen when get capability");

return -1;

}

// Print capability infomations

LOG("Capability Informations:/n");

LOG(" name: %s/n", vd->capability.name);

LOG(" type: %d/n", vd->capability.type);

// LOG(" channel: %d/n", vd->capability.channel);

LOG(" maxwidth: %d/n", vd->capability.maxwidth);

LOG(" maxheight: %08X/n", vd->capability.maxheight);

LOG(" minwidth: %d/n", vd->capability.minwidth);

LOG(" minheight: %08X/n", vd->capability.minheight);

return 0;

}

int v4lgetmbuf(v4ldevice *vd)

{

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

LOG("v4lgetmbuf:VIDIOCGMBUF");

return -1;

}

return 0;

}

unsigned char *v4lgetaddress(v4ldevice *vd)

{

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

}

int v4lopen(char *name, v4ldevice *vd)

{

int i;

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

return -1;

}

if(v4lgetcapability(vd))

return -1;

}

int v4lgrabinit(v4ldevice *vd, int width, int height)

{

vd->mmap.width = width;

vd->mmap.height = height;

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

vd->frame = 0;

vd->framestat[0] = 0;

vd->framestat[1] = 0;

return 0;

}

int v4lmmap(v4ldevice *vd)

{

if(v4lgetmbuf(vd)<0)

return -1;

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

return -1;

}

return 0;

}

int v4lgrabstart(v4ldevice *vd, int frame)

{

vd->mmap.frame = frame;

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

return -1;

}

vd->framestat[frame] = 1;

return 0;

}

int v4lsync(v4ldevice *vd, int frame)

{

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

return -1;

}

vd->framestat[frame] = 0;

return 0;

}

int v4lcapture(v4ldevice *vd, int frame)

{

vd->mmap.frame = frame;

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

return -1;

}

vd->framestat[frame] = 1;

}

//static void dump_to_file(const char *fname, char *buf, int *size){

//};

static void dump_to_file(const char *fname, char *buf, long int size)

{

int nw, cnt = 0;

int written = 0;

LOG("/n=========opening file [%s]+++++++++++/n", fname);

int fd = open(fname, O_RDWR | O_CREAT);

if (fd < 0) {

LOG("failed to create file [%s]: %s", fname, strerror(errno));

return;

}

LOG("/n=============writing %d bytes to file [%s]/n++++++++++++", size, fname);

while (written < size) {

nw = write(fd,

buf + written,

size - written);

if (nw < 0) {

LOG("failed to write to file [%s]: %s",

fname, strerror(errno));

break;

}

written += nw;

cnt++;

}

LOG("done writing %d bytes to file [%s] in %d passes/n",

size, fname, cnt);

close(fd);

}

int main(){

char* devicename="/dev/video0";

char* buffer;

v4ldevice device;

int width = 640;

int height = 480;

int frame = 0;

v4lopen("/dev/video0",&device);//打开设备

//v4lgetcapability(&device);

int ret;

// read information in video_picture

memset(&(device.picture),0,sizeof(device.picture));

ret=ioctl(device.fd, VIDIOCGPICT, &(device.picture));

if (ret < 0) {

LOG("VIDIOCGPICT failed (%d)/n", ret);

return ret;

}

LOG("/n jaylin add original picture Informations:/n");

LOG(" depth: %d/n", device.picture.depth);

LOG(" palette: %d/n", device.picture.palette);

//set capture attributes

device.picture.palette = VIDEO_PALETTE_JPEG;//different camera has different palette

device.picture.depth = 8;

if(ioctl(device.fd,VIDIOCSPICT,&(device.picture)) == -1)

{

LOG("Cann't set the picture attributes!");

close(device.fd);

exit(6);

}

//read information in video_picture

ioctl(device.fd, VIDIOCGPICT, &(device.picture));

if (ret < 0) {

LOG("VIDIOCGPICT failed (%d)/n", ret);

return ret;

}

LOG("/n jaylin add after set pictures attributes Informations:/n");

LOG(" depth: %d/n", device.picture.depth);

LOG(" palette: %d/n", device.picture.palette);

v4lgrabinit(&device,width,height);//初始化设备,定义获取的影像的大小

v4lmmap(&device);//内存映射

v4lgrabstart(&device,frame);//开始获取影像

//while(1){

v4lsync(&device,frame);//等待传完一帧

frame = (frame+1)%2;//下一帧的frame

v4lcapture(&device,frame);//获取下一帧

buffer = (char*)v4lgetaddress(&device);//得到这一帧的地址

//buffer给出了图像的首地址,你可以选择将图像显示或保存......

//图像的大小为 width*height*2

long int size = 640*480*1;

dump_to_file(CAPTURE_FILE,buffer,size);

munmap(device.map, device.mbuf.size);

//}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: