Qt摄像头应用程序无法获取帧数据的问题

笑strive 2014-03-11 04:20:16
移植到开发板中的时候,运行应用程序,运行到ioctl(fd,VIDIOC_DQBUF, &queue_buf)== -1时,程序死了,不执行下去了,但是在pc上可以正常的运行,请问一下是什么原因导致的呢?如何才能解决这样的问题呢?
#include "videodevice.h"
#include "common.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <asm/types.h>
#include <linux/videodev2.h>

#define FILE_VIDEO "/dev/video0"


VideoDevice::VideoDevice(QString dev_name)
{
this->dev_name = dev_name;
this->fd = -1;
this->buffers = NULL;
this->n_buffers = 0;
this->index = -1;

if(open_device() == FALSE)
{
close_device();
}
else{printf("open_device sucessful\n");}

if(init_device() == FALSE)
{
close_device();
}
else{printf("init_device sucessful\n");}
if(start_capturing() == FALSE)
{
stop_capturing();
close_device();
}
else{printf("start_capturing sucessful\n");}
}

VideoDevice::~VideoDevice()
{
if(stop_capturing() == FALSE)
{
}
if(uninit_device() == FALSE)
{
}
if(close_device() == FALSE)
{
}
}
int VideoDevice::open_device()
{
fd = open(FILE_VIDEO,O_RDWR);
if(fd == -1)
{
printf("Error opening V4L interface\n");
return FALSE;
}
else{printf("sucessful opening V4L interface\n");}
return TRUE;
}

int VideoDevice::close_device()
{
if( close(fd) == FALSE)
{
printf("Error closing V4L interface\n");
return FALSE;
}
else{printf("sucessful closing V4L");}
return TRUE;
}

int VideoDevice::init_device()
{
v4l2_capability cap;
v4l2_format fmt;
v4l2_streamparm setfps;

if(ioctl(fd, VIDIOC_QUERYCAP, &cap) == -1)
{
printf("Error opening device %s: unable to query device.\n",FILE_VIDEO);
return FALSE;
}
else
{
printf("driver:\t\t%s\n",cap.driver);
printf("card:\t\t%s\n",cap.card);
printf("bus_info:\t%s\n",cap.bus_info);
printf("version:\t%d\n",cap.version);
printf("capabili ties:\t%x\n",cap.capabilities);

if ((cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) == V4L2_CAP_VIDEO_CAPTURE)
{
printf("Device %s: supports capture.\n",FILE_VIDEO);
}

if ((cap.capabilities & V4L2_CAP_STREAMING) == V4L2_CAP_STREAMING)
{
printf("Device %s: supports streaming.\n",FILE_VIDEO);
}
}

//set fmt
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
fmt.fmt.pix.height = 240;
fmt.fmt.pix.width = 320;
fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;

if(ioctl(fd, VIDIOC_S_FMT, &fmt) == -1)
{
printf("Unable to set format\n");
return FALSE;
}
else{printf("format1 sucessful\n");}
if(ioctl(fd, VIDIOC_G_FMT, &fmt) == -1)
{
printf("Unable to get format\n");
return FALSE;
}
else{printf("format2 sucessful\n");}


//set fps
setfps.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
setfps.parm.capture.timeperframe.numerator = 1;
setfps.parm.capture.timeperframe.denominator = 10;

if(ioctl(fd, VIDIOC_S_PARM, &setfps) == -1)
{
printf("Unable to set frame rate\n");
return FALSE;
}
else
{
printf("set fps OK!\n");
}

if(ioctl(fd, VIDIOC_G_PARM, &setfps) == -1)
{
printf("Unable to get frame rate\n");
return FALSE;
}
else
{
printf("get fps OK!\n");
printf("timeperframe.numerator:\t%d\n",setfps.parm.capture.timeperframe.numerator);
printf("timeperframe.denominator:\t%d\n",setfps.parm.capture.timeperframe.denominator);

}

//mmap
if(init_mmap() == FALSE )
{
printf("cannot mmap!\n");
return FALSE;

}
else{printf("mmap sucessful\n");}

return TRUE;
}

int VideoDevice::init_mmap()
{
v4l2_requestbuffers req;

req.count = 2;
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory = V4L2_MEMORY_MMAP;

if(ioctl(fd, VIDIOC_REQBUFS, &req) == -1)
{
return FALSE;
}

if(req.count < 2)
{
return FALSE;
}

buffers = (buffer*)calloc(req.count, sizeof(*buffers));

if(!buffers)
{
return FALSE;
}

for(n_buffers = 0; n_buffers < req.count; ++n_buffers)
{
v4l2_buffer buf;
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = n_buffers;

if(ioctl(fd, VIDIOC_QUERYBUF, &buf) == -1)
{
return FALSE;
}

buffers[n_buffers].length = buf.length;
buffers[n_buffers].start =
mmap(NULL, // start anywhere// allocate RAM*4
buf.length,
PROT_READ | PROT_WRITE,
MAP_SHARED,
fd, buf.m.offset);

if(MAP_FAILED == buffers[n_buffers].start)
{

return FALSE;
}
}
printf("mmap sucessful");
return TRUE;

}

int VideoDevice::start_capturing()
{
unsigned int i;
for(i = 0; i < n_buffers; ++i)
{
v4l2_buffer buf;
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory =V4L2_MEMORY_MMAP;
buf.index = i;
if(-1 == ioctl(fd, VIDIOC_QBUF, &buf))
{
return FALSE;
}
}

v4l2_buf_type type;
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

if(-1 == ioctl(fd, VIDIOC_STREAMON, &type))
{
return FALSE;
}
printf("start_caturing sucessful\n");
return TRUE;
}

int VideoDevice::stop_capturing()
{
v4l2_buf_type type;
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

if(ioctl(fd, VIDIOC_STREAMOFF, &type) == -1)
{
return FALSE;
}
printf("stop_capturing sucessful");
return TRUE;
}

int VideoDevice::uninit_device()
{
unsigned int i;

for(i = 0; i < n_buffers; ++i)
{
if(-1 == munmap(buffers[i].start, buffers[i].length))
{
printf("munmap error\n");
return FALSE;
}

}

delete buffers;
printf("uninit_device() sucessful\n");
return TRUE;
}

int VideoDevice::get_frame(unsigned char ** yuv_buffer_pointer, size_t* len)
{
printf("1\n");
v4l2_buffer queue_buf;
printf("2\n");
memset(&queue_buf, 0, sizeof(queue_buf));
queue_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
printf("3\n");
queue_buf.memory = V4L2_MEMORY_MMAP;
printf("4\n");
queue_buf.index = index;
printf("0\n");

if(ioctl(fd, VIDIOC_DQBUF, &queue_buf) == -1)
{
printf("VIDIOC_DQBUF failed\n");
return FALSE;
}
printf("5\n");

*yuv_buffer_pointer = (unsigned char *)buffers[queue_buf.index].start;
printf("6\n");
*len = buffers[queue_buf.index].length;
printf("7\n");
index = queue_buf.index;
printf("8\n");
printf("get_frame sucessful\n");

return TRUE;

}

int VideoDevice::unget_frame()
{
if(index != -1)
{
v4l2_buffer queue_buf;
queue_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
queue_buf.memory = V4L2_MEMORY_MMAP;
queue_buf.index = index;

if(ioctl(fd, VIDIOC_QBUF, &queue_buf) == -1)
{
return FALSE;
}
return TRUE;
}
printf("unget_frame sucessful\n");
return FALSE;
}

#include "ui_widget.h"
#include "widget.h"
#include "common.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <sys/stat.h>
#include <fcntl.h>


#define TOTALFRAMES 151
#define CAPTURE_IDLE 0
#define CAPTURE_START 1
#define CAPTURE_STOP 2
#define CAPTURE_COMPRESS 3

char last_state = 2;
char state = 0;
long framecnt=0;
char yuvfilename[11] = {'r','c','q','0','0','0','.','y','u','v','\0'};
static int sum=0;


Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
vd = new VideoDevice(tr("/dev/video0"));

frame = new QImage(rgb_buffer,320,240,QImage::Format_RGB888);

printf("frame sucessful\n");

rs = vd->get_frame(&yuv_buffer_pointer,&len);

printf("%d\n",rs);

yuvfile = fopen(yuvfilename,"wb+");

rs = write420();

fclose(yuvfile);


convert_yuv_to_rgb_buffer();


frame->loadFromData(rgb_buffer,320 * 240 * 3);
frame->save("000.bmp");
ui->label->setPixmap(QPixmap::fromImage(*frame,Qt::AutoColor));

rs = vd->unget_frame();

//timer = new QTimer(this);
//connect(timer,SIGNAL(timeout()),this,SLOT(update()));
//timer->start(500);

}

Widget::~Widget()
{
delete ui;

//delete frame;
//delete [] Y_frame;
//delete [] Cr_frame;
//delete [] Cb_frame;
}
int Widget::write420()
{
int x,y;
long int index1 =0;

if (yuv_buffer_pointer[0] == '\0')
{
return -1;
}
//change to YUV420 by rcq
// YUV420 and YUV411
for(x=0;x<320;x++)
{
for(y=0;y<240;y++)
{
Y_frame[index1]=yuv_buffer_pointer[2*index1];
index1++;
}
}

index1=0;
for(x=0;x<240;x++,x++)
{
for(y=0;y<320;y++,y++)
{
Cb_frame[index1]=yuv_buffer_pointer[(x*320+y)*2+1];
Cr_frame[index1]=yuv_buffer_pointer[(x*240+y)*2+3];
index1++;
}
}

fwrite(Y_frame, 76800, 1, yuvfile);
fwrite(Cb_frame,19200, 1, yuvfile);
fwrite(Cr_frame,19200, 1, yuvfile);

framecnt++;
printf("writed frame %ld\n",framecnt);
}

...全文
144 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

16,216

社区成员

发帖
与我相关
我的任务
社区描述
Qt 是一个跨平台应用程序框架。通过使用 Qt,您可以一次性开发应用程序和用户界面,然后将其部署到多个桌面和嵌入式操作系统,而无需重复编写源代码。
社区管理员
  • Qt
  • 亭台六七座
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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