2440 v4l 图片采集 问题

wuzaixiang 2009-03-16 07:15:09
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/types.h>
#include <linux/videodev.h>
#include <malloc.h>

#include <string.h>
#include <sys/time.h>

#define VIDEO_PALETTE_RAW_JPEG 20
#define VIDEO_PALETTE_JPEG 21

#define USB_VIDEO_DEV "/dev/v4l/video0"
#define FILE_NAME "/tmp/1.jpg"
#define STILL_IMAGE -1
#define VIDEO_START 0
#define VIDEO_STOP 1

static int debug = 1;

int get_jpegsize(unsigned char *buf, int size)
{
int i;
for(i = 1024; i < size; i++)
{
if ( (buf[i] == 0xFF)&&(buf[i+1] == 0xD9)) return i+2;//jpeg文件格式中是以0xFF 0xD9结尾的,

//以此判断文件大小
}
return -1;
}

int main(int argc, char *argv[])
{
int usb_camera_fd = -1,framesize=0,jpegsize=0;
char *usb_video_dev = USB_VIDEO_DEV;
char *filename = FILE_NAME;
FILE *fp;
struct video_capability video_caps;
struct video_channel video_chan;
struct video_picture video_pic;
struct video_mbuf video_mbuffer;
struct video_mmap vid_mmap;

unsigned char *mapaddr=NULL,*framebuffer=NULL,*destbuffer=NULL;


usb_camera_fd = open(usb_video_dev,O_RDWR);//打开设备,可读写
if (usb_camera_fd == -1)
{
fprintf(stderr,"Can't open device %s",usb_video_dev);
return 1;
}
/**********************video_capability**************/
if (ioctl(usb_camera_fd,VIDIOCGCAP,&video_caps) == -1)//get videodevice capability 获取设备基本信息
{
perror("Couldn't get videodevice capability");
return -1;
}

if (debug)
{
printf("video name : %s\n",video_caps.name);
printf("video_caps.channels :%d\n",video_caps.channels);
printf("video_caps.type : 0x%x\n",video_caps.type);
printf("video maxwidth : %d\n",video_caps.maxwidth);
printf("video maxheight : %d\n",video_caps.maxheight);
printf("video minwidth : %d\n",video_caps.minwidth);
printf("video minheight : %d\n",video_caps.minheight);
}

/************************video_channel****************/

/*video_chan.channel = video_caps.channels;

if (ioctl(usb_camera_fd,VIDIOCGCHAN,&video_chan) == -1)//获取信号源的属性
{
perror("ioctl (VIDIOCGCAP)");
return -1;
}
if (debug)
{
printf("video channel: %d\n",video_chan.channel);
printf("video channel name: %s\n",video_chan.name);
printf("video channel type: %d\n",video_chan.type);
}*/

/*************************video_picture****************/
if (ioctl(usb_camera_fd,VIDIOCGPICT,&video_pic) == -1)//获取设备采集的图象的各种属性
{
perror("ioctl (VIDIOCGPICT)");
return -1;
}

/*video_pic.palette = VIDEO_PALETTE_JPEG;
video_pic.depth = 8;
video_pic.hue = 50110;
video_pic.whiteness = 41380;

if (ioctl(usb_camera_fd,VIDIOCSPICT,&video_pic) == -1)//设置设备采集的图象的属性
{
perror("ioctl (VIDIOCSPICT)");
//return -1;
}*/

if (debug)
{
printf("video_pic.brightness : %d\n",video_pic.brightness);
printf("video_pic.colour : %d\n",video_pic.colour);
printf("video_pic.contrast : %d\n",video_pic.contrast);
printf("video_pic.depth : %d\n",video_pic.depth);
printf("video_pic.hue : %d\n",video_pic.hue);
printf("video_pic.whiteness : %d\n",video_pic.whiteness);
printf("video_pic.palette : %d\n",video_pic.palette);
}
/************************video_mbuf**********************/
memset(&video_mbuffer,0,sizeof(video_mbuffer));


//初始化video_mbuf,以得到所映射的buffer的信息
if (ioctl(usb_camera_fd,VIDIOCGMBUF,&video_mbuffer) == -1)//video_mbuf
{
perror("ioctl (VIDIOCGMBUF)");
return -1;
}
if (debug)
{
printf("video_mbuffer.frames : %d\n",video_mbuffer.frames);
printf("video_mbuffer.offsets[0] : %d\nvideo_mbuffer.offsets[1] :%d\n",video_mbuffer.offsets [0],video_mbuffer.offsets[1]);
printf("video_mbuffer.size : %d\n",video_mbuffer.size);
}

//将mmap与video_mbuf绑定

mapaddr=(unsigned char *)mmap(0,video_mbuffer.size,PROT_READ,MAP_SHARED,usb_camera_fd, 0);

if (mapaddr < 0)
{
perror("v4l mmap");
return -1;
}
/********************video_mmap*************************/

vid_mmap.width = 320;
vid_mmap.height = 240;
vid_mmap.frame = 0;//单帧采集
vid_mmap.format = VIDEO_PALETTE_JPEG;

/**********************start capture********************///Mmap方式下真正开始视频截取

//若调用成功,开始一帧的截取,是非阻塞的 是否截取完毕留给VIDIOCSYNC来判断
if (ioctl(usb_camera_fd,VIDIOCCAPTURE,VIDEO_START) == -1)
{
perror("ioctl (VIDIOCCAPTURE)");
return -1;
}

/***********************wait for ready*******************///调用VIDIOCSYNC等待一帧截取结束

//若成功,表明一帧截取已完成。可以开始做下一次 VIDIOCMCAPTURE
//frame是当前截取的帧的序号
/*if (ioctl(usb_camera_fd, VIDIOCSYNC, &vid_mmap.frame) == -1)
{
perror("ioctl (VIDIOCSYNC)");
//return -1;
}*/

framesize=320*240>>2;//实际采集到的jpeg图像的大小最多也就十几KB

//获取刚刚采集到的图像数据帧的地址

framebuffer = mapaddr + video_mbuffer.offsets[vid_mmap.frame];

//获取图像的大小

//jpegsize = get_jpegsize(framebuffer, framesize);

if (jpegsize < 0)
{
printf("Can't get size of jpeg picture\n");
return 1;
}

//分配空间,准备将destbuffer 缓冲区中的图像数据写入文件
destbuffer = (unsigned char *)malloc(video_mbuffer.size);
if ( destbuffer == NULL)
{
printf("malloc memory for destbuffer error\n");
return -1;
}
memcpy(destbuffer,framebuffer,video_mbuffer.size);

fp = fopen(filename,"wb");//打开文件
if (!fp)
{
printf("Can't open file %s",filename);
//return -1;
}

fwrite(destbuffer,video_mbuffer.size,1,fp);//写入文件
fclose(fp);//关闭文件

free(destbuffer);//释放空间
munmap(mapaddr,video_mbuffer.size);//取消绑定
close(usb_camera_fd);
return 1;
}

open: fd = open("/dev/v4l/video0", O_RDONLY);
fd为文件句柄,失败时返回负值。
read: i = read(fd, buf, image_width*image_height*2);
成功时返回读取的字节数,失败时返回负值。
mmap: buf = (__u8 *)mmap(0, vm.size, PROT_READ, MAP_SHARED, fd, 0);
失败时返回-1。vm为video_mbuf结构体,通过调用ioctl的VIDIOCGMBUF获得vm.size
ioctl: ioctl(fd, VIDIOCCAPTURE, VIDEO_START);
成功时返回0;失败时返回负值。
ioctl函数支持的命令如下:(定义位于/include/linux/videodev.h)
Opcode Input type Description
VIDIOCGCAP struct video_capability 可获得当前摄像头支持的采集图像的最大值以及最小值
VIDIOCGWIN struct video_window 获得捕获源的大小
VIDIOCSWIN struct video_window 设置捕获源的大小
一般为640*480
VIDIOCGCAPTURE struct video_capture 获得目标图像大小
VIDIOCSCAPTURE struct video_capture 设置目标图像大小
(不得超过源大小)
VIDIOCGPICT struct video_picture 获得采集图像的颜色模式
VIDIOCSPICT struct video_picture 设置采集图像的颜色模式,
VIDIOCCAPTURE STILL_IMAGE
VIDEO_START
VIDEO_STOP 开始/停止捕获。这三个宏需要自己定义,其值分别为:-1,0,1
STILL_IMAGE:捕获一帧后停止
VIDIOCGMBUF struct video_mbuf 获得缓冲区的大小,用于mmap

注:采集参数的设置要在VIDEO_START之前执行,即执行VIDIOCCAPTURE时参数为VIDEO_START(或者STILL_IMAGE)时,才会检查更新硬件寄存器的设置。



上面是我的源码。下面是驱动开发接口

但是运行后怎么都得不到图片啊。

各位大侠帮小弟看看吧。。
...全文
861 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
whitefang234 2010-10-26
  • 打赏
  • 举报
回复
除了9楼 上面的全是一帮庸才~~~
satanwxd 2010-06-29
  • 打赏
  • 举报
回复
你说的这个东西不知道你做好了没有,我有些问题想和你交流,我基本上可以显示图片,而且也实现扫频了。但是现在对于网络发包出现一点问题。我看了你调用的get_picturesize函数了,这个可以直接算出你jpeg包的大小。但是我试过后发现图片还是有问题,而且还有不少的噪声。
对于你上述的问题我有一些意见可以给你。第一,你的摄像头支持jpeg格式的设置吗?第二。如果支持的话,这部分是有硬件压缩还是软件压缩,因为如果你是前者的话,你必须有驱动支持。简单来说,你可以先设置你的摄像头为位图方式去采集,例如bmp=24,rgb=16来设这你的摄像头。
kyzf 2010-04-01
  • 打赏
  • 举报
回复
先采用 串口打印 等方式 调测试下 你对应图片采集的驱动吧。

看驱动是否正确,。

比如你可以拿一张 全黑 和全白的图片,看看 你的驱动采集的数据是否正确吧。
tianpeijun123 2010-04-01
  • 打赏
  • 举报
回复
你的驱动的问题把,用的是什么 系统呢?或者系统与驱动的接口?
fpcc 2010-04-01
  • 打赏
  • 举报
回复
你得先证明驱动程序是正确的,然后再写程序.测试方法也很简单,找一个小程序测试下就可以了.
solomon_大卫 2010-03-31
  • 打赏
  • 举报
回复
不知道驱动的模块是不是正确的。驱动模块代码你也没有出来,就给了接口怎么弄啊 核心东西都没有。你那个程序是只是应用程序调用别人的接口的。如果驱动模块是正确的 你只要细心点应该就可以了
armed 2010-03-30
  • 打赏
  • 举报
回复
开什么玩笑,把一堆的源代码贴上来,谁愿意看呀~~~

zmy12007 2010-03-27
  • 打赏
  • 举报
回复
我也正想做这个呢,要是你把问题解决一下告诉我一下,我的msn:zmy12006#hotmail.com,我用的mini2440
驱动的位置好像跟你有点不一样
wuzaixiang 2009-03-16
  • 打赏
  • 举报
回复
没人帮忙么。。5555555
wuzaixiang 2009-03-16
  • 打赏
  • 举报
回复
没人帮忙么。。5555555

21,616

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 驱动开发/核心开发
社区管理员
  • 驱动开发/核心开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧