android 系统下v4l2调用camera,VIDIOC_REQBUFS总是不成功

jshonwang 2013-03-29 12:19:06
最近在android下开放一个获取图片数据的camera程序,用到底层的v4l2调用,总是出现申请帧缓冲的错VIDIOC_REQBUFS调用返回是-1,不知道是哪的问题希望有大牛帮我看看,找出问题,谢谢!下面是我的代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/stat.h>
#include<sys/time.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <asm/types.h>
#include<linux/videodev2.h>
#include "v4l2_capture.h"

int mFd=-1;
struct buffer *mBuffer;
int mBufferNr;
int mWidth;
int mHeight;
int mFormat=V4L2_PIX_FMT_YUV420;
int mFrameSize;
static const int V4L2_BUFFER_NR = 3;
int openDevice(const char *dev, int width, int height)
{
LOGV("begin openv4l2device\n");
struct v4l2_capability cap;
struct v4l2_format fmt;
if(mFd>0)
{
return -13;
}
mFd = open(dev,O_RDWR);
if(mFd<0)
{
LOGE("Error openv4l2de vice\n");
return -1;
}
LOGW("openv4l2device Successed:%d\n",mFd);
memset(&cap, 0, sizeof(cap));
if (ioctl(mFd,VIDIOC_QUERYCAP, &cap) < 0)
{
LOGE("E rror ioctl VIDIOC_QUERYCAP");
return -1;
}
LOGW("VIDIOC_QUERYCAP Successed\n");
if ((cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) == 0)
{
LOGV("video capture not supported. 0x%X", cap.capabilities);
return -1;
}
if ((cap.capabilities & V4L2_CAP_STREAMING) == 0) {
LOGV("Capture device does not support streaming i/o");
return -1;
} // set device format
memset(&fmt, 0x0, sizeof(fmt));
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmt.fmt.pix.width = width;
fmt.fmt.pix.height = height;
fmt.fmt.pix.pixelformat= mFormat;
fmt.fmt.pix.priv= 0;
fmt.fmt.pix.bytesperline =height;
fmt.fmt.pix.sizeimage = 0;
if(ioctl( mFd, VIDIOC_S_FMT, &fmt)<0)
{
LOGE("ErrorioctlDIOC _ S_FMT");
return -1;
}
LOGW("VIDIOC_S_FMT Successed\n");
mWidth =width;
mHeight =height;
mFrameSize= (width* height) << 1;
LOGV("end openv4l2device\n");
return mFd;
}
void closeDevice() {
LOGV("begin closeDevice\n");
stopStreaming();
termMmap();
if (mFd >= 0)
close(mFd);
LOGV("end closeDevice\n");
}
int setStreamParam(int framerate) {
LOGV("begin setStreamParam\n");
struct v4l2_streamparm parm;
int ret;
parm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if ((ret = ioctl(mFd, VIDIOC_G_PARM, &parm)) < 0)
{
LOGE("Error ioctl VIDIOC_G_PARM");
return ret;
}
parm.parm.capture.timeperframe.denominator = framerate;
parm.parm.capture.timeperframe.numerator = 1;
parm.parm.output.timeperframe.denominator = framerate;
parm.parm.output.timeperframe.numerator = 1;
if ((ret = ioctl(mFd, VIDIOC_S_PARM, &parm)) < 0)
LOGE("Error ioctl VIDIOC_S_PARM");
LOGV("end setStreamParam\n");
return ret;
}
int startStreaming() {
LOGV("begin startStreaming\n");
enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
int ret;
if ((ret = ioctl(mFd, VIDIOC_STREAMON, &type)) < 0)
LOGE("Error ioctl VIDIOC_STREAMON");
LOGW("VIDIOC_STREAMON sucessed\n");
LOGV("end startStreaming\n");
return ret;
}
int stopStreaming() {
LOGV("begin stopStreaming\n");
enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
int ret;
if ((ret = ioctl(mFd, VIDIOC_STREAMOFF, &type)) < 0)
LOGE("Error ioctl VIDIOC_STREAMOFF");
LOGW("VIDIOC_STREAMOFF sucessed\n");
LOGV("end stopStreaming\n");
return ret;
}
int grabStreamFrame(struct buffer *outBuffer) {
LOGV("begin grabStreamFrame\n");
struct v4l2_buffer buf;
int ret;
memset(&buf, 0x0, sizeof(buf));
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
if ((ret = ioctl(mFd, VIDIOC_DQBUF, &buf)) < 0) {
LOGE("Error ioctl VIDIOC_DQBUF");
return ret;
} // copy data to output buffer
LOGV("VIDIOC_DQBUF sucessed\n");
outBuffer->length=mBuffer[buf.index].length;
memcpy(outBuffer->start, mBuffer[buf.index].start, mBuffer[buf.index].length);
if ((ret = ioctl(mFd, VIDIOC_QBUF, &buf)) < 0)
LOGE("Error ioctl VIDIOC_QBUF");
LOGW("VIDIOC_QBUF of get sucessed\n");
LOGV("end grabStreamFrame\n");
return ret;
}

int getFormat(int * width, int * height, int * format)
{
LOGV("begin getFormat\n");
struct v4l2_format fmt;
int ret;
memset(&fmt,0,sizeof(fmt));
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

if((ret = ioctl(mFd, VIDIOC_G_FMT,&fmt)) < 0) {
LOGE("Error ioctl VIDIOC_G_FMT\n");
return ret;
}
LOGW("VIDIOC_G_FMT sucessed\n");
* format = fmt.fmt.pix.pixelformat;
* width = fmt.fmt.pix.width;
* height = fmt.fmt.pix.height;
LOGV("end getFormat\n");
return ret;
}

int initMmap(){
LOGV("begin initMmap\n");
struct v4l2_requestbuffers req;
struct v4l2_buffer buf;
unsigned int i;
int out_length=-1;
int ret;
memset(&req, 0x0, sizeof(req));
req.count = V4L2_BUFFER_NR;
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory = V4L2_MEMORY_MMAP;
if ((ret = ioctl(mFd, VIDIOC_REQBUFS, &req)) < 0) {
LOGE("Error ioctl VIDIOC_REQBUFS\n");
return ret;
}
LOGW("VIDIOC_REQBUFS Seccussed\n");
mBuffer = (struct buffer *)calloc(req.count, sizeof(*mBuffer));
for (i = 0; i < req.count; i++) {
memset(&buf, 0, sizeof(buf));
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = i;
if ((ret = ioctl(mFd, VIDIOC_QUERYBUF, &buf)) < 0) {
LOGE("Error ioctl VIDIOC_QUERYBUF");
return ret;
}
LOGW("VIDIOC_QUERYBUF Seccussed\n");
out_length=mBuffer[i].length = buf.length;
LOGW("mBuffer[%d].length\n",i,mBuffer[i].length);
mBuffer[i].start = mmap(NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, mFd, buf.m.offset);
LOGW("mBuffer[%d].length=%d\n",i,mBuffer[i].length);
if (mBuffer[i].start == MAP_FAILED) {
LOGE("Error: Failed to map v4l2 device to memory");
return -1;
}
if ((ioctl(mFd, VIDIOC_QBUF, &buf)) < 0)
{
LOGE("Error ioctl VIDIOC_QBUF");
return -1;
}
LOGW("VIDIOC_QBUF Seccussed\n");
}
mBufferNr = req.count;
LOGW("mBufferNr = req.count%d\n",mBufferNr);
LOGV("end initMmap\n");
return out_length;
}
void termMmap(){
LOGV("begin termMmap\n");
mFd=-1;
if (!mBuffer)
return;
int i=0;
for (i = 0;i < mBufferNr;i++)
{
munmap(mBuffer[i].start, mBuffer[i].length);
}
free(mBuffer);
LOGV("end termMmap\n");
}

...全文
1576 7 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
shencj73 2015-11-06
  • 打赏
  • 举报
回复
你好,请问可以在安卓下用v4l2采集视频吗? 我在安卓手机平板下用用v4l2采集视频,没有找到哪款手机平板支持v4l2,请问你用的那款机器? 希望得到你的帮助,也希望有合作机会。
hhfgoodboy 2015-06-01
  • 打赏
  • 举报
回复
能具体说下哪些参数是硬件相关的吗?
jshonwang 2015-03-17
  • 打赏
  • 举报
回复
已经解决了,这个部分代码跟具体的硬件有关
踏雪乄痕 2014-04-22
  • 打赏
  • 举报
回复
我的出现这个状况了,单独运行的没问题,就是与其他程序一起运行的时候就出现这个问题了。。。
jshonwang 2013-09-13
  • 打赏
  • 举报
回复
有两个方面的问题造成的: 1、硬件方面:摄像头采集数据的大小,也就图片有多大 2、v4l2 参数设置的问题
linuxqc 2013-09-02
  • 打赏
  • 举报
回复
楼主你解决了这个问题么?
ndsceasy 2013-05-28
  • 打赏
  • 举报
回复
我也有这个问题,

80,472

社区成员

发帖
与我相关
我的任务
社区描述
移动平台 Android
androidandroid-studioandroidx 技术论坛(原bbs)
社区管理员
  • Android
  • yechaoa
  • 失落夏天
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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