video_device ops in user_space
2017-06-14 00:50
423 查看
#include "ccameradevice.h"
#include <QDebug>
CCameraDevice::CCameraDevice():
m_fdMedia(-1),
m_fdCcdc(-1),
m_fdCam(-1),
m_fdCap(-1),
m_fdDis(-1),
m_fdResizer(-1),
m_fdResizerIn(-1),
m_fdResizerOut(-1)
{
memset(m_vbic,0,sizeof(VideoBufferInfo)*3);
memset(m_vbid,0,sizeof(VideoBufferInfo)*3);
memset(m_resizerInBuff,0,sizeof(VideoBufferInfo)*VIDEO_BUFFER_NUMS);
memset(m_resizerOutBuff,0,sizeof(VideoBufferInfo)*VIDEO_BUFFER_NUMS);
}
CCameraDevice::~CCameraDevice()
{
}
int CCameraDevice::initialLink(int fd)
{
#ifdef RUN_ON_EMBEDDEDSYSTEM
int i;
int resizerIn=0, resizerOut=0, resizer=0;
struct media_link_desc link;
for(i = 0; i < 20; i++)
{
struct media_entity_desc entity;
memset(&entity,0,sizeof(entity));
entity.id = i | MEDIA_ENTITY_ID_FLAG_NEXT;
if (ioctl(fd, MEDIA_IOC_ENUM_ENTITIES, &entity) == -1)
{
//qDebug()<<"initialLink:ioctl MEDIA_IOC_ENUM_ENTITIES failed";
break;
}
if (!strcmp(entity.name, "OMAP3 ISP resizer input"))
{
resizerIn = entity.id;
}
else if (!strcmp(entity.name, "OMAP3 ISP resizer output"))
{
resizerOut = entity.id;
}
else if (!strcmp(entity.name, "OMAP3 ISP resizer"))
{
resizer = entity.id;
}
}
memset(&link, 0, sizeof(link));
link.flags |= MEDIA_LINK_FLAG_ENABLED;
link.source.entity = resizerIn;
link.source.index = 0; /* Only 1 pad */
link.source.flags = MEDIA_PAD_FLAG_OUTPUT;
link.sink.entity = resizer;
link.sink.index = 0; /* Sink pad of resizer, 0 */
link.sink.flags = MEDIA_PAD_FLAG_INPUT;
if (ioctl(fd, MEDIA_IOC_SETUP_LINK, &link) == -1)
{
qDebug()<<"initialLink:ioctl MEDIA_IOC_SETUP_LINK resizerIn failed";
return -1;
}
memset(&link, 0, sizeof(link));
link.flags |= MEDIA_LINK_FLAG_ENABLED;
link.source.entity = resizer;
link.source.index = 1; /* Source pad of CCDC: 1 */
link.source.flags = MEDIA_PAD_FLAG_OUTPUT;
link.sink.entity = resizerOut;
link.sink.index = 0;
link.sink.flags = MEDIA_PAD_FLAG_INPUT;
if (ioctl(fd, MEDIA_IOC_SETUP_LINK, &link) == -1)
{
qDebug()<<"initialLink:ioctl MEDIA_IOC_SETUP_LINK resizerOut failed";
return -1;
}
#endif
return 0;
}
int CCameraDevice::initialMediaLinks(int fd)
{
#ifdef RUN_ON_EMBEDDEDSYSTEM
int video = 0, camera = 0, ccdc = 0;
int resizerIn=0, resizerOut=0, resizer=0;
struct media_link_desc link;
int i;
/* 找到媒体设备 */
for(i = 0; i < 20; i++)
{
struct media_entity_desc entity;
memset(&entity,0,sizeof(entity));
entity.id = i | MEDIA_ENTITY_ID_FLAG_NEXT;
if (ioctl(fd, MEDIA_IOC_ENUM_ENTITIES, &entity) == -1)
{
break;
}
if (!strcmp(entity.name, "OMAP3 ISP CCDC output"))
{
video = entity.id;
}
else if (!strcmp(entity.name, "adv7280 3-0020"))
{
camera = entity.id;
}
else if (!strcmp(entity.name, "OMAP3 ISP CCDC"))
{
ccdc = entity.id;
}
else if (!strcmp(entity.name, "OMAP3 ISP resizer input"))
{
resizerIn = entity.id;
}
else if (!strcmp(entity.name, "OMAP3 ISP resizer output"))
{
resizerOut = entity.id;
}
else if (!strcmp(entity.name, "OMAP3 ISP resizer"))
{
resizer = entity.id;
}
}
/* 连接摄像头和ccdc */
memset(&link, 0, sizeof(link));
link.flags |= MEDIA_LINK_FLAG_ENABLED;
link.source.entity = camera;
link.source.index = 0; /* Only 1 pad */
link.source.flags = MEDIA_PAD_FLAG_OUTPUT;
link.sink.entity = ccdc;
link.sink.index = 0; /* Sink pad of CCDC, 0 */
link.sink.flags = MEDIA_PAD_FLAG_INPUT;
if (ioctl(fd, MEDIA_IOC_SETUP_LINK, &link) == -1)
{
qDebug()<<"initialMediaLinks:ioctl MEDIA_IOC_SETUP_LINK camera failed";
return -1;
}
/* 连接ccdc和视频节点 */
memset(&link, 0, sizeof(link));
link.flags |= MEDIA_LINK_FLAG_ENABLED;
link.source.entity = ccdc;
link.source.index = 1; /* Source pad of CCDC: 1 */
link.source.flags = MEDIA_PAD_FLAG_OUTPUT;
link.sink.entity = video;
link.sink.index = 0;
link.sink.flags = MEDIA_PAD_FLAG_INPUT;
if (ioctl(fd, MEDIA_IOC_SETUP_LINK, &link) == -1)
{
qDebug()<<"initialMediaLinks:ioctl MEDIA_IOC_SETUP_LINK ccdc failed";
return -1;
}
memset(&link, 0, sizeof(link));
link.flags |= MEDIA_LINK_FLAG_ENABLED;
link.source.entity = resizerIn;
link.source.index = 0; /* Only 1 pad */
link.source.flags = MEDIA_PAD_FLAG_OUTPUT;
link.sink.entity = resizer;
link.sink.index = 0; /* Sink pad of resizer, 0 */
link.sink.flags = MEDIA_PAD_FLAG_INPUT;
if (ioctl(fd, MEDIA_IOC_SETUP_LINK, &link) == -1)
{
qDebug()<<"initialMediaLinks:ioctl MEDIA_IOC_SETUP_LINK resizerIn failed";
return -1;
}
memset(&link, 0, sizeof(link));
link.flags |= MEDIA_LINK_FLAG_ENABLED;
link.source.entity = resizer;
link.source.index = 1; /* Source pad of CCDC: 1 */
link.source.flags = MEDIA_PAD_FLAG_OUTPUT;
link.sink.entity = resizerOut;
link.sink.index = 0;
link.sink.flags = MEDIA_PAD_FLAG_INPUT;
if (ioctl(fd, MEDIA_IOC_SETUP_LINK, &link) == -1)
{
qDebug()<<"initialMediaLinks:ioctl MEDIA_IOC_SETUP_LINK resizerOut failed";
return -1;
}
#endif
return 0;
}
int CCameraDevice::initialResizerFormat(int fdresizer_in, int fdresizer_out , int fdresizer,int width,int height)
{
#ifdef RUN_ON_EMBEDDEDSYSTEM
struct v4l2_subdev_format fmt;
struct v4l2_format vfmt;
memset(&vfmt,0,sizeof(vfmt));
vfmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
if(ioctl(fdresizer_in, VIDIOC_G_FMT, &vfmt)==-1)
{
qDebug()<<"initialResizerFormat:ioctl VIDIOC_G_FMT fdresizer_in failed";
return -1;
}
vfmt.fmt.pix.width = width;
vfmt.fmt.pix.height = height;
vfmt.fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
vfmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
if(ioctl(fdresizer_in, VIDIOC_S_FMT, &vfmt)==-1)
{
qDebug()<<"initialResizerFormat:ioctl VIDIOC_S_FMT fdresizer_in failed";
return -1;
}
memset(&fmt, 0, sizeof(fmt));
fmt.pad = 0;
fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
fmt.format.code = V4L2_MBUS_FMT_UYVY8_1X16;
fmt.format.width = width;
fmt.format.height = height;
fmt.format.colorspace = V4L2_COLORSPACE_SMPTE170M;
fmt.format.field = V4L2_FIELD_INTERLACED;
if(ioctl(fdresizer, VIDIOC_SUBDEV_S_FMT, &fmt)==-1)
{
qDebug()<<"initialResizerFormat:ioctl VIDIOC_SUBDEV_S_FMT fdresizer failed";
return -1;
}
memset(&fmt, 0, sizeof(fmt));
fmt.pad = 1;
fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
fmt.format.code = V4L2_MBUS_FMT_UYVY8_1X16;
fmt.format.width = RESIZER_WO;
fmt.format.height = RESIZER_HO;
fmt.format.colorspace = V4L2_COLORSPACE_SMPTE170M;
fmt.format.field = V4L2_FIELD_INTERLACED;
if(ioctl(fdresizer, VIDIOC_SUBDEV_S_FMT, &fmt)==-1)
{
qDebug()<<"initialResizerFormat:ioctl VIDIOC_SUBDEV_S_FMT fdresizer failed";
return -1;
}
memset(&vfmt,0,sizeof(vfmt));
vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if(ioctl(fdresizer_out, VIDIOC_G_FMT, &vfmt)==-1)
{
qDebug()<<"initialResizerFormat:ioctl VIDIOC_G_FMT fdresizer_out failed";
return -1;
}
vfmt.fmt.pix.width = RESIZER_WO;
vfmt.fmt.pix.height = RESIZER_HO;
vfmt.fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if(ioctl(fdresizer_out, VIDIOC_S_FMT, &vfmt)==-1)
{
qDebug()<<"initialResizerFormat:ioctl VIDIOC_S_FMT fdresizer_out failed";
return -1;
}
#endif
return 0;
}
int CCameraDevice::initialResizer()
{
#ifdef RUN_ON_EMBEDDEDSYSTEM
int ret, type;
m_fdResizerIn= open("/dev/video5", O_RDWR);
if (m_fdResizerIn == -1)
{
qDebug()<<"initialResizer:open m_fdResizerIn error";
goto error;
}
m_fdResizerOut= open("/dev/video6", O_RDWR);
if (m_fdResizerOut == -1)
{
qDebug()<<"initialResizer:open m_fdResizerOut error";
goto error;
}
m_fdResizer= open("/dev/v4l-subdev4", O_RDWR);
if (m_fdResizer == -1)
{
qDebug()<<"initialResizer:open m_fdResizer error";
goto error;
}
ret = initialLink(m_fdMedia);
if (-1==ret)
{
qDebug()<<"initialResizer:initialLink error";
goto error;
}
if (-1==initialResizerFormat(m_fdResizerIn, m_fdResizerOut , m_fdResizer,IMAGE_WIDTH,IMAGE_HEIGHT))
{
qDebug()<<"initialResizer:setUpResizerFormat error";
goto error;
}
if (initialDisplayBuffer(m_fdResizerIn, m_resizerInBuff, 4) == -1)
{
qDebug()<<"initialResizer:m_fdResizerIn setupCameraCaptureBuffer error";
goto error;
}
type=V4L2_BUF_TYPE_VIDEO_OUTPUT;
if (ioctl(m_fdResizerIn, VIDIOC_STREAMON, &type) ==-1)
{
qDebug()<<"initialResizer:ioctl VIDIOC_STREAMON m_fdResizerIn failed";
goto error;
}
if (initialCameraCaptureBuffer(m_fdResizerOut, m_resizerOutBuff, 4) == -1)
{
qDebug()<<"initialResizer:m_fdResizerOut setupCameraCaptureBuffer error";
goto error;
}
type= V4L2_BUF_TYPE_VIDEO_CAPTURE;
if (ioctl(m_fdResizerOut, VIDIOC_STREAMON, &type) ==-1)
{
qDebug()<<"initialResizer:ioctl VIDIOC_STREAMON m_fdResizerOut error";
goto error;
}
#endif
return 0;
error:
close(m_fdResizerOut);
close(m_fdResizerIn);
close(m_fdResizer);
return -1;
}
void CCameraDevice::slotChangeCameraChannel()
{
static bool flag=true;
if(flag)
{
if(m_fdCap!=-1&&m_fdCcdc!=-1&&m_fdCam!=-1)
{
initialCameraCaptureFormat(m_fdCap,m_fdCcdc,m_fdCam,ADV7180_INPUT_CVBS_AIN1);
flag=!flag;
}
}
else
{
if(m_fdCap!=-1&&m_fdCcdc!=-1&&m_fdCam!=-1)
{
initialCameraCaptureFormat(m_fdCap,m_fdCcdc,m_fdCam,ADV7180_INPUT_CVBS_AIN4);
flag=!flag;
}
}
}
int CCameraDevice::initialCameraCaptureFormat(int videoFd, int ccdcFd, int cameraFd,int channel)
{
#ifdef RUN_ON_EMBEDDEDSYSTEM
struct v4l2_subdev_format fmt;
struct v4l2_format vfmt;
struct v4l2_subdev_routing route;
/* 设置ccdc采集格式 */
memset(&fmt, 0, sizeof(fmt));
fmt.pad = 0;
fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
fmt.format.code = V4L2_MBUS_FMT_UYVY8_2X8;
fmt.format.width = IMAGE_WIDTH;
fmt.format.height = IMAGE_HEIGHT;
fmt.format.colorspace = V4L2_COLORSPACE_SMPTE170M;
fmt.format.field = V4L2_FIELD_INTERLACED;
if(ioctl(ccdcFd, VIDIOC_SUBDEV_S_FMT, &fmt)==-1)
{
qDebug()<<"initialCameraCaptureFormat:ioctl VIDIOC_SUBDEV_S_FMT ccdc failed";
return -1;
}
memset(&fmt, 0, sizeof(fmt));
fmt.pad = 1;
fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
fmt.format.code = V4L2_MBUS_FMT_UYVY8_2X8;
fmt.format.width = IMAGE_WIDTH;
fmt.format.height = IMAGE_HEIGHT;
fmt.format.colorspace = V4L2_COLORSPACE_SMPTE170M;
fmt.format.field = V4L2_FIELD_INTERLACED;
if(ioctl(ccdcFd, VIDIOC_SUBDEV_S_FMT, &fmt)==-1)
{
qDebug()<<"initialCameraCaptureFormat:ioctl VIDIOC_SUBDEV_S_FMT ccdc failed";
return -1;
}
/* select the camera input channel */
// int camera_in_channel_tbl[] = {ADV7180_INPUT_CVBS_AIN4, ADV7180_INPUT_CVBS_AIN1};
// route.input = camera_in_channel_tbl[CGlobal::getCameraModel()];
route.input=channel;
route.output = 0; //useless
route.config = 0; //useless
if(ioctl(cameraFd, VIDIOC_SUBDEV_S_ROUTING, &route)==-1)
{
qDebug()<<"initialCameraCaptureFormat:ioctl VIDIOC_SUBDEV_S_ROUTING camera failed";
return -1;
}
/* 设置摄像头采集格式 */
memset(&fmt, 0, sizeof(fmt));
fmt.pad = 0;
fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
fmt.format.code = V4L2_MBUS_FMT_UYVY8_2X8;
fmt.format.width = IMAGE_WIDTH;
fmt.format.height = IMAGE_HEIGHT;
fmt.format.colorspace = V4L2_COLORSPACE_SMPTE170M;
fmt.format.field = V4L2_FIELD_INTERLACED;
if(ioctl(cameraFd, VIDIOC_SUBDEV_S_FMT, &fmt)==-1)
{
qDebug()<<"initialCameraCaptureFormat:ioctl VIDIOC_SUBDEV_S_FMT camera failed";
return -1;
}
/* 设置视频节点采集格式 */
memset(&vfmt,0,sizeof(vfmt));
vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if(ioctl(videoFd, VIDIOC_G_FMT, &vfmt)==-1)
return -1;
vfmt.fmt.pix.width = IMAGE_WIDTH;
vfmt.fmt.pix.height = IMAGE_HEIGHT;
vfmt.fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if(ioctl(videoFd, VIDIOC_S_FMT, &vfmt)==-1)
{
qDebug()<<"initialCameraCaptureFormat:ioctl VIDIOC_S_FMT video failed";
return -1;
}
if(ioctl(videoFd, VIDIOC_G_FMT, &vfmt)==-1)
{
qDebug()<<"initialCameraCaptureFormat:ioctl VIDIOC_S_FMT video failed";
return -1;
}
if(vfmt.fmt.pix.pixelformat != V4L2_PIX_FMT_UYVY)
{
qDebug()<<"initialCameraCaptureFormat:vfmt.fmt.pix.pixelformat != V4L2_PIX_FMT_UYVY";
return -1;
}
#endif
return 0;
}
int CCameraDevice::initialCameraCaptureBuffer(int fd, VideoBufferInfo *vbi, int num)
{
#ifdef RUN_ON_EMBEDDEDSYSTEM
struct v4l2_requestbuffers reqbuf;
struct v4l2_buffer buf;
reqbuf.count = num;
reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
reqbuf.memory = V4L2_MEMORY_MMAP;
if(ioctl(fd, VIDIOC_REQBUFS, &reqbuf)==-1)
{
qDebug()<<"initialCameraCaptureBuffer:ioctl VIDIOC_REQBUFS failed";
return -1;
}
if (num != (int)reqbuf.count)
{
return -1;
}
num = (int)reqbuf.count;
memset(&buf, 0, sizeof(buf));
for (int i = 0; i < num; i++)
{
buf.type = reqbuf.type;
buf.index = i;
buf.memory = reqbuf.memory;
if(ioctl(fd, VIDIOC_QUERYBUF, &buf)==-1)
{
qDebug()<<"initialCameraCaptureBuffer:ioctl VIDIOC_QUERYBUF failed";
goto ERROR;
}
vbi[i].length = buf.length;
vbi[i].index = i;
vbi[i].start = (char*)mmap(NULL, buf.length, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, buf.m.offset);
if (vbi[i].start == MAP_FAILED)
{
num = i;
goto ERROR;
}
memset((void *) vbi[i].start, 0x80, vbi[i].length);
if(ioctl(fd, VIDIOC_QBUF, &buf)==-1)
{
num = i + 1;
goto ERROR;
}
}
#endif
return 0;
ERROR:
for (int j = 0; j < num; j++)
{
munmap(vbi[j].start, vbi[j].length);
}
num = 0;
return -1;
}
int CCameraDevice::initialDisplayFormat(int fd)
{
#ifdef RUN_ON_EMBEDDEDSYSTEM
struct v4l2_format fmt;
memset(&fmt,0,sizeof(fmt));
fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
if (ioctl(fd, VIDIOC_G_FMT, &fmt)==-1)
{
qDebug()<<"initialDisplayFormat:ioctl VIDIOC_G_FMT error";
return -1;
}
fmt.fmt.pix.width = DISP_WIDTH;
fmt.fmt.pix.height = DISP_HEIGHT;
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
if (ioctl(fd, VIDIOC_S_FMT, &fmt)==-1)
{
qDebug()<<"initialDisplayFormat:ioctl VIDIOC_S_FMT error";
return -1;
}
if (ioctl(fd, VIDIOC_G_FMT, &fmt)==-1)
{
qDebug()<<"initialDisplayFormat:ioctl VIDIOC_G_FMT error";
return -1;
}
if (fmt.fmt.pix.pixelformat != V4L2_PIX_FMT_UYVY)
{
qDebug()<<"initialDisplayFormat:fmt.fmt.pix.pixelformat != V4L2_PIX_FMT_UYVY";
return -1;
}
#endif
return 0;
}
int CCameraDevice::initialDisplayBuffer(int fd, VideoBufferInfo *vbi, int num)
{
#ifdef RUN_ON_EMBEDDEDSYSTEM
struct v4l2_requestbuffers reqbuf;
struct v4l2_buffer buf;
reqbuf.count = num;
reqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
reqbuf.memory = V4L2_MEMORY_MMAP;
if(ioctl(fd, VIDIOC_REQBUFS, &reqbuf)==-1)
{
qDebug()<<"initialDisplayBuffer:ioctl VIDIOC_REQBUFS error";
return -1;
}
if (num != (int)reqbuf.count)
{
return -1;
}
num = (int)reqbuf.count;
memset(&buf, 0, sizeof(buf));
for (int i = 0; i < num; i++)
{
buf.type = reqbuf.type;
buf.index = i;
buf.memory = reqbuf.memory;
if(ioctl(fd, VIDIOC_QUERYBUF, &buf)==-1)
goto ERROR;
vbi[i].length = buf.length;
vbi[i].index = i;
vbi[i].start = (char*)mmap(NULL, buf.length, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, buf.m.offset);
if (vbi[i].start == MAP_FAILED)
{
num = i;
goto ERROR;
}
memset((void *) vbi[i].start, 0x80, vbi[i].length);
if(ioctl(fd, VIDIOC_QBUF, &buf)==-1)
{
qDebug()<<"initialDisplayBuffer:ioctl VIDIOC_QBUF error";
num = i + 1;
goto ERROR;
}
}
#endif
return 0;
ERROR:
for (int j = 0; j < num; j++)
{
munmap(vbi[j].start, vbi[j].length);
}
num = 0;
return -1;
}
int CCameraDevice::initialVideoColorKey(int fd, unsigned int key)
{
#ifdef RUN_ON_EMBEDDEDSYSTEM
struct v4l2_format fmt;
struct v4l2_framebuffer framebuffer;
fmt.type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
if (ioctl(fd, VIDIOC_G_FMT, &fmt) == -1)
{
qDebug()<<"initialVideoColorKey:ioctl VIDIOC_QBUF error";
return -1;
}
fmt.fmt.win.chromakey = key;
if (ioctl(fd, VIDIOC_S_FMT, &fmt) == -1)
{
qDebug()<<"initialVideoColorKey:ioctl VIDIOC_S_FMT error";
return -1;
}
if (ioctl(fd, VIDIOC_G_FBUF, &framebuffer) == -1)
{
qDebug()<<"initialVideoColorKey:ioctl VIDIOC_G_FBUF error";
return -1;
}
framebuffer.flags |= V4L2_FBUF_FLAG_CHROMAKEY;
framebuffer.flags &= ~V4L2_FBUF_FLAG_SRC_CHROMAKEY;
if (ioctl(fd, VIDIOC_S_FBUF, &framebuffer) == -1)
{
qDebug()<<"initialVideoColorKey:ioctl VIDIOC_S_FBUF error";
return -1;
}
#endif
return 0;
}
bool CCameraDevice::initialCamera()
{
#ifdef RUN_ON_EMBEDDEDSYSTEM
int type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
//media
m_fdMedia = open("/dev/media0", O_RDWR);
if (m_fdMedia == -1)
{
qDebug()<<"initialCamera:open media error";
return false;
}
if (initialMediaLinks(m_fdMedia) == -1)
{
qDebug()<<"initialCamera:setupMediaLinks error";
return false;
}
//ccdc camera video
m_fdCcdc = open("/dev/v4l-subdev2", O_RDWR);
if (m_fdCcdc == -1)
{
qDebug()<<"initialCamera:open ccdc error";
return false;
}
m_fdCam = open("/dev/v4l-subdev8", O_RDWR);
if (m_fdCam == -1)
{
qDebug()<<"initialCamera:open cam error";
return false;
}
m_fdCap = open("/dev/video2", O_RDWR);
if (m_fdCap == -1)
{
qDebug()<<"initialCamera:open video capture error";
return false;
}
if (initialResizer() == -1)
{
qDebug()<<"initialCamera:initResizer error";
return false;
}
if (initialCameraCaptureFormat(m_fdCap,m_fdCcdc,m_fdCam,ADV7180_INPUT_CVBS_AIN4) == -1)
{
qDebug()<<"initialCamera:setupCameraCaptureFormat error";
return false;
}
if (initialCameraCaptureBuffer(m_fdCap, m_vbic, 3) == -1)
{
qDebug()<<"initialCamera:setupCameraCaptureBuffer error";
close(m_fdCap);
return false;
}
if (ioctl(m_fdCap, VIDIOC_STREAMON, &type) ==-1)
{
qDebug()<<"initialCamera:m_fdCap VIDIOC_STREAMON error";
return false;
}
//display
m_fdDis = open("/dev/video7", O_RDWR);
if (m_fdDis == -1)
{
qDebug()<<"initialCamera:open display video err";
return false;
}
if (initialDisplayFormat(m_fdDis) == -1)
{
qDebug()<<"initialCamera:setupDisplayFormat error";
return false;
}
if (initialDisplayBuffer(m_fdDis, m_vbid, 3) == -1)
{
qDebug()<<"initialCamera:setupDisplayBuffer error";
return false;
}
if (initialVideoColorKey(m_fdDis, 0x090909) == -1)
{
qDebug()<<"initialCamera:setVideoColorKey error";
return false;
}
type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
if (ioctl(m_fdDis, VIDIOC_STREAMON, &type) ==-1)
{
qDebug()<<"initialCamera:fdDis VIDIOC_STREAMON error";
return false;
}
#endif
return true;
}
bool CCameraDevice::showVideo()
{
#ifdef RUN_ON_EMBEDDEDSYSTEM
if (m_fdCap == -1)
{
return false;
}
if (m_fdDis == -1)
{
return false;
}
struct v4l2_buffer captureBuff;
struct v4l2_buffer displayBuff;
struct v4l2_buffer resizerInbuff;
struct v4l2_buffer resizerOutbuff;
captureBuff.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
captureBuff.index = 0;
captureBuff.memory = V4L2_MEMORY_MMAP;
if (ioctl(m_fdCap, VIDIOC_DQBUF, &captureBuff) == -1)
{
qDebug()<<"showVideo:ioctl fdCap VIDIOC_DQBUF error";
return false;
}
resizerInbuff.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
resizerInbuff.index = 0;
resizerInbuff.memory = V4L2_MEMORY_MMAP;
if (ioctl(m_fdResizerIn, VIDIOC_DQBUF, &resizerInbuff) ==-1)
{
qDebug()<<"showVideo:ioctl m_fdResizerIn VIDIOC_DQBUF error";
return false;
}
memcpy((unsigned char*)m_resizerInBuff[resizerInbuff.index].start, m_vbic[captureBuff.index].start, m_vbic[captureBuff.index].length);
if (ioctl(m_fdResizerIn, VIDIOC_QBUF, &resizerInbuff) ==-1)
{
qDebug()<<"showVideo:ioctl m_fdResizerIn VIDIOC_QBUF error";
return false;
}
if (ioctl(m_fdCap, VIDIOC_QBUF, &captureBuff) == -1)
{
qDebug()<<"showVideo:ioctl fdCap VIDIOC_QBUF error";
return false;
}
resizerOutbuff.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
resizerOutbuff.index = 0;
resizerOutbuff.memory = V4L2_MEMORY_MMAP;
if (ioctl(m_fdResizerOut, VIDIOC_DQBUF, &resizerOutbuff) == -1)
{
qDebug()<<"showVideo:ioctl m_fdresizerOut VIDIOC_DQBUF error";
return false;
}
displayBuff.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
displayBuff.index = 0;
displayBuff.memory = V4L2_MEMORY_MMAP;
if (ioctl(m_fdDis, VIDIOC_DQBUF, &displayBuff) ==-1)
{
qDebug()<<"showVideo:ioctl m_fdDis VIDIOC_DQBUF error";
return false;
}
memcpy((unsigned char*)m_vbid[displayBuff.index].start, m_resizerOutBuff[resizerOutbuff.index].start, m_resizerOutBuff[resizerOutbuff.index].length);
if (ioctl(m_fdDis, VIDIOC_QBUF, &displayBuff) ==-1)
{
qDebug()<<"showVideo:ioctl m_fdDis VIDIOC_QBUF error";
return false;
}
if (ioctl(m_fdResizerOut, VIDIOC_QBUF, &resizerOutbuff) == -1)
{
qDebug()<<"showVideo:ioctl m_fdResizerOut VIDIOC_QBUF error";
return false;
}
#endif
return true;
}
bool CCameraDevice::getVideo(unsigned char *imageData)
{
#ifdef RUN_ON_EMBEDDEDSYSTEM
if (m_fdCap == -1)
{
return false;
}
struct v4l2_buffer captureBuff;
captureBuff.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
captureBuff.index = 0;
captureBuff.memory = V4L2_MEMORY_MMAP;
if (ioctl(m_fdCap, VIDIOC_DQBUF, &captureBuff) == -1)
{
qDebug()<<"getVideo:ioctl fdCap VIDIOC_DQBUF error";
return false;
}
memcpy(imageData, m_vbic[captureBuff.index].start , IMAGE_WIDTH*IMAGE_HEIGHT*2 );
if (ioctl(m_fdCap, VIDIOC_QBUF, &captureBuff) == -1)
{
qDebug()<<"getVideo:ioctl fdCap VIDIOC_QBUF error";
return false;
}
#endif
return true;
}
#include <QDebug>
CCameraDevice::CCameraDevice():
m_fdMedia(-1),
m_fdCcdc(-1),
m_fdCam(-1),
m_fdCap(-1),
m_fdDis(-1),
m_fdResizer(-1),
m_fdResizerIn(-1),
m_fdResizerOut(-1)
{
memset(m_vbic,0,sizeof(VideoBufferInfo)*3);
memset(m_vbid,0,sizeof(VideoBufferInfo)*3);
memset(m_resizerInBuff,0,sizeof(VideoBufferInfo)*VIDEO_BUFFER_NUMS);
memset(m_resizerOutBuff,0,sizeof(VideoBufferInfo)*VIDEO_BUFFER_NUMS);
}
CCameraDevice::~CCameraDevice()
{
}
int CCameraDevice::initialLink(int fd)
{
#ifdef RUN_ON_EMBEDDEDSYSTEM
int i;
int resizerIn=0, resizerOut=0, resizer=0;
struct media_link_desc link;
for(i = 0; i < 20; i++)
{
struct media_entity_desc entity;
memset(&entity,0,sizeof(entity));
entity.id = i | MEDIA_ENTITY_ID_FLAG_NEXT;
if (ioctl(fd, MEDIA_IOC_ENUM_ENTITIES, &entity) == -1)
{
//qDebug()<<"initialLink:ioctl MEDIA_IOC_ENUM_ENTITIES failed";
break;
}
if (!strcmp(entity.name, "OMAP3 ISP resizer input"))
{
resizerIn = entity.id;
}
else if (!strcmp(entity.name, "OMAP3 ISP resizer output"))
{
resizerOut = entity.id;
}
else if (!strcmp(entity.name, "OMAP3 ISP resizer"))
{
resizer = entity.id;
}
}
memset(&link, 0, sizeof(link));
link.flags |= MEDIA_LINK_FLAG_ENABLED;
link.source.entity = resizerIn;
link.source.index = 0; /* Only 1 pad */
link.source.flags = MEDIA_PAD_FLAG_OUTPUT;
link.sink.entity = resizer;
link.sink.index = 0; /* Sink pad of resizer, 0 */
link.sink.flags = MEDIA_PAD_FLAG_INPUT;
if (ioctl(fd, MEDIA_IOC_SETUP_LINK, &link) == -1)
{
qDebug()<<"initialLink:ioctl MEDIA_IOC_SETUP_LINK resizerIn failed";
return -1;
}
memset(&link, 0, sizeof(link));
link.flags |= MEDIA_LINK_FLAG_ENABLED;
link.source.entity = resizer;
link.source.index = 1; /* Source pad of CCDC: 1 */
link.source.flags = MEDIA_PAD_FLAG_OUTPUT;
link.sink.entity = resizerOut;
link.sink.index = 0;
link.sink.flags = MEDIA_PAD_FLAG_INPUT;
if (ioctl(fd, MEDIA_IOC_SETUP_LINK, &link) == -1)
{
qDebug()<<"initialLink:ioctl MEDIA_IOC_SETUP_LINK resizerOut failed";
return -1;
}
#endif
return 0;
}
int CCameraDevice::initialMediaLinks(int fd)
{
#ifdef RUN_ON_EMBEDDEDSYSTEM
int video = 0, camera = 0, ccdc = 0;
int resizerIn=0, resizerOut=0, resizer=0;
struct media_link_desc link;
int i;
/* 找到媒体设备 */
for(i = 0; i < 20; i++)
{
struct media_entity_desc entity;
memset(&entity,0,sizeof(entity));
entity.id = i | MEDIA_ENTITY_ID_FLAG_NEXT;
if (ioctl(fd, MEDIA_IOC_ENUM_ENTITIES, &entity) == -1)
{
break;
}
if (!strcmp(entity.name, "OMAP3 ISP CCDC output"))
{
video = entity.id;
}
else if (!strcmp(entity.name, "adv7280 3-0020"))
{
camera = entity.id;
}
else if (!strcmp(entity.name, "OMAP3 ISP CCDC"))
{
ccdc = entity.id;
}
else if (!strcmp(entity.name, "OMAP3 ISP resizer input"))
{
resizerIn = entity.id;
}
else if (!strcmp(entity.name, "OMAP3 ISP resizer output"))
{
resizerOut = entity.id;
}
else if (!strcmp(entity.name, "OMAP3 ISP resizer"))
{
resizer = entity.id;
}
}
/* 连接摄像头和ccdc */
memset(&link, 0, sizeof(link));
link.flags |= MEDIA_LINK_FLAG_ENABLED;
link.source.entity = camera;
link.source.index = 0; /* Only 1 pad */
link.source.flags = MEDIA_PAD_FLAG_OUTPUT;
link.sink.entity = ccdc;
link.sink.index = 0; /* Sink pad of CCDC, 0 */
link.sink.flags = MEDIA_PAD_FLAG_INPUT;
if (ioctl(fd, MEDIA_IOC_SETUP_LINK, &link) == -1)
{
qDebug()<<"initialMediaLinks:ioctl MEDIA_IOC_SETUP_LINK camera failed";
return -1;
}
/* 连接ccdc和视频节点 */
memset(&link, 0, sizeof(link));
link.flags |= MEDIA_LINK_FLAG_ENABLED;
link.source.entity = ccdc;
link.source.index = 1; /* Source pad of CCDC: 1 */
link.source.flags = MEDIA_PAD_FLAG_OUTPUT;
link.sink.entity = video;
link.sink.index = 0;
link.sink.flags = MEDIA_PAD_FLAG_INPUT;
if (ioctl(fd, MEDIA_IOC_SETUP_LINK, &link) == -1)
{
qDebug()<<"initialMediaLinks:ioctl MEDIA_IOC_SETUP_LINK ccdc failed";
return -1;
}
memset(&link, 0, sizeof(link));
link.flags |= MEDIA_LINK_FLAG_ENABLED;
link.source.entity = resizerIn;
link.source.index = 0; /* Only 1 pad */
link.source.flags = MEDIA_PAD_FLAG_OUTPUT;
link.sink.entity = resizer;
link.sink.index = 0; /* Sink pad of resizer, 0 */
link.sink.flags = MEDIA_PAD_FLAG_INPUT;
if (ioctl(fd, MEDIA_IOC_SETUP_LINK, &link) == -1)
{
qDebug()<<"initialMediaLinks:ioctl MEDIA_IOC_SETUP_LINK resizerIn failed";
return -1;
}
memset(&link, 0, sizeof(link));
link.flags |= MEDIA_LINK_FLAG_ENABLED;
link.source.entity = resizer;
link.source.index = 1; /* Source pad of CCDC: 1 */
link.source.flags = MEDIA_PAD_FLAG_OUTPUT;
link.sink.entity = resizerOut;
link.sink.index = 0;
link.sink.flags = MEDIA_PAD_FLAG_INPUT;
if (ioctl(fd, MEDIA_IOC_SETUP_LINK, &link) == -1)
{
qDebug()<<"initialMediaLinks:ioctl MEDIA_IOC_SETUP_LINK resizerOut failed";
return -1;
}
#endif
return 0;
}
int CCameraDevice::initialResizerFormat(int fdresizer_in, int fdresizer_out , int fdresizer,int width,int height)
{
#ifdef RUN_ON_EMBEDDEDSYSTEM
struct v4l2_subdev_format fmt;
struct v4l2_format vfmt;
memset(&vfmt,0,sizeof(vfmt));
vfmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
if(ioctl(fdresizer_in, VIDIOC_G_FMT, &vfmt)==-1)
{
qDebug()<<"initialResizerFormat:ioctl VIDIOC_G_FMT fdresizer_in failed";
return -1;
}
vfmt.fmt.pix.width = width;
vfmt.fmt.pix.height = height;
vfmt.fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
vfmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
if(ioctl(fdresizer_in, VIDIOC_S_FMT, &vfmt)==-1)
{
qDebug()<<"initialResizerFormat:ioctl VIDIOC_S_FMT fdresizer_in failed";
return -1;
}
memset(&fmt, 0, sizeof(fmt));
fmt.pad = 0;
fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
fmt.format.code = V4L2_MBUS_FMT_UYVY8_1X16;
fmt.format.width = width;
fmt.format.height = height;
fmt.format.colorspace = V4L2_COLORSPACE_SMPTE170M;
fmt.format.field = V4L2_FIELD_INTERLACED;
if(ioctl(fdresizer, VIDIOC_SUBDEV_S_FMT, &fmt)==-1)
{
qDebug()<<"initialResizerFormat:ioctl VIDIOC_SUBDEV_S_FMT fdresizer failed";
return -1;
}
memset(&fmt, 0, sizeof(fmt));
fmt.pad = 1;
fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
fmt.format.code = V4L2_MBUS_FMT_UYVY8_1X16;
fmt.format.width = RESIZER_WO;
fmt.format.height = RESIZER_HO;
fmt.format.colorspace = V4L2_COLORSPACE_SMPTE170M;
fmt.format.field = V4L2_FIELD_INTERLACED;
if(ioctl(fdresizer, VIDIOC_SUBDEV_S_FMT, &fmt)==-1)
{
qDebug()<<"initialResizerFormat:ioctl VIDIOC_SUBDEV_S_FMT fdresizer failed";
return -1;
}
memset(&vfmt,0,sizeof(vfmt));
vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if(ioctl(fdresizer_out, VIDIOC_G_FMT, &vfmt)==-1)
{
qDebug()<<"initialResizerFormat:ioctl VIDIOC_G_FMT fdresizer_out failed";
return -1;
}
vfmt.fmt.pix.width = RESIZER_WO;
vfmt.fmt.pix.height = RESIZER_HO;
vfmt.fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if(ioctl(fdresizer_out, VIDIOC_S_FMT, &vfmt)==-1)
{
qDebug()<<"initialResizerFormat:ioctl VIDIOC_S_FMT fdresizer_out failed";
return -1;
}
#endif
return 0;
}
int CCameraDevice::initialResizer()
{
#ifdef RUN_ON_EMBEDDEDSYSTEM
int ret, type;
m_fdResizerIn= open("/dev/video5", O_RDWR);
if (m_fdResizerIn == -1)
{
qDebug()<<"initialResizer:open m_fdResizerIn error";
goto error;
}
m_fdResizerOut= open("/dev/video6", O_RDWR);
if (m_fdResizerOut == -1)
{
qDebug()<<"initialResizer:open m_fdResizerOut error";
goto error;
}
m_fdResizer= open("/dev/v4l-subdev4", O_RDWR);
if (m_fdResizer == -1)
{
qDebug()<<"initialResizer:open m_fdResizer error";
goto error;
}
ret = initialLink(m_fdMedia);
if (-1==ret)
{
qDebug()<<"initialResizer:initialLink error";
goto error;
}
if (-1==initialResizerFormat(m_fdResizerIn, m_fdResizerOut , m_fdResizer,IMAGE_WIDTH,IMAGE_HEIGHT))
{
qDebug()<<"initialResizer:setUpResizerFormat error";
goto error;
}
if (initialDisplayBuffer(m_fdResizerIn, m_resizerInBuff, 4) == -1)
{
qDebug()<<"initialResizer:m_fdResizerIn setupCameraCaptureBuffer error";
goto error;
}
type=V4L2_BUF_TYPE_VIDEO_OUTPUT;
if (ioctl(m_fdResizerIn, VIDIOC_STREAMON, &type) ==-1)
{
qDebug()<<"initialResizer:ioctl VIDIOC_STREAMON m_fdResizerIn failed";
goto error;
}
if (initialCameraCaptureBuffer(m_fdResizerOut, m_resizerOutBuff, 4) == -1)
{
qDebug()<<"initialResizer:m_fdResizerOut setupCameraCaptureBuffer error";
goto error;
}
type= V4L2_BUF_TYPE_VIDEO_CAPTURE;
if (ioctl(m_fdResizerOut, VIDIOC_STREAMON, &type) ==-1)
{
qDebug()<<"initialResizer:ioctl VIDIOC_STREAMON m_fdResizerOut error";
goto error;
}
#endif
return 0;
error:
close(m_fdResizerOut);
close(m_fdResizerIn);
close(m_fdResizer);
return -1;
}
void CCameraDevice::slotChangeCameraChannel()
{
static bool flag=true;
if(flag)
{
if(m_fdCap!=-1&&m_fdCcdc!=-1&&m_fdCam!=-1)
{
initialCameraCaptureFormat(m_fdCap,m_fdCcdc,m_fdCam,ADV7180_INPUT_CVBS_AIN1);
flag=!flag;
}
}
else
{
if(m_fdCap!=-1&&m_fdCcdc!=-1&&m_fdCam!=-1)
{
initialCameraCaptureFormat(m_fdCap,m_fdCcdc,m_fdCam,ADV7180_INPUT_CVBS_AIN4);
flag=!flag;
}
}
}
int CCameraDevice::initialCameraCaptureFormat(int videoFd, int ccdcFd, int cameraFd,int channel)
{
#ifdef RUN_ON_EMBEDDEDSYSTEM
struct v4l2_subdev_format fmt;
struct v4l2_format vfmt;
struct v4l2_subdev_routing route;
/* 设置ccdc采集格式 */
memset(&fmt, 0, sizeof(fmt));
fmt.pad = 0;
fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
fmt.format.code = V4L2_MBUS_FMT_UYVY8_2X8;
fmt.format.width = IMAGE_WIDTH;
fmt.format.height = IMAGE_HEIGHT;
fmt.format.colorspace = V4L2_COLORSPACE_SMPTE170M;
fmt.format.field = V4L2_FIELD_INTERLACED;
if(ioctl(ccdcFd, VIDIOC_SUBDEV_S_FMT, &fmt)==-1)
{
qDebug()<<"initialCameraCaptureFormat:ioctl VIDIOC_SUBDEV_S_FMT ccdc failed";
return -1;
}
memset(&fmt, 0, sizeof(fmt));
fmt.pad = 1;
fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
fmt.format.code = V4L2_MBUS_FMT_UYVY8_2X8;
fmt.format.width = IMAGE_WIDTH;
fmt.format.height = IMAGE_HEIGHT;
fmt.format.colorspace = V4L2_COLORSPACE_SMPTE170M;
fmt.format.field = V4L2_FIELD_INTERLACED;
if(ioctl(ccdcFd, VIDIOC_SUBDEV_S_FMT, &fmt)==-1)
{
qDebug()<<"initialCameraCaptureFormat:ioctl VIDIOC_SUBDEV_S_FMT ccdc failed";
return -1;
}
/* select the camera input channel */
// int camera_in_channel_tbl[] = {ADV7180_INPUT_CVBS_AIN4, ADV7180_INPUT_CVBS_AIN1};
// route.input = camera_in_channel_tbl[CGlobal::getCameraModel()];
route.input=channel;
route.output = 0; //useless
route.config = 0; //useless
if(ioctl(cameraFd, VIDIOC_SUBDEV_S_ROUTING, &route)==-1)
{
qDebug()<<"initialCameraCaptureFormat:ioctl VIDIOC_SUBDEV_S_ROUTING camera failed";
return -1;
}
/* 设置摄像头采集格式 */
memset(&fmt, 0, sizeof(fmt));
fmt.pad = 0;
fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
fmt.format.code = V4L2_MBUS_FMT_UYVY8_2X8;
fmt.format.width = IMAGE_WIDTH;
fmt.format.height = IMAGE_HEIGHT;
fmt.format.colorspace = V4L2_COLORSPACE_SMPTE170M;
fmt.format.field = V4L2_FIELD_INTERLACED;
if(ioctl(cameraFd, VIDIOC_SUBDEV_S_FMT, &fmt)==-1)
{
qDebug()<<"initialCameraCaptureFormat:ioctl VIDIOC_SUBDEV_S_FMT camera failed";
return -1;
}
/* 设置视频节点采集格式 */
memset(&vfmt,0,sizeof(vfmt));
vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if(ioctl(videoFd, VIDIOC_G_FMT, &vfmt)==-1)
return -1;
vfmt.fmt.pix.width = IMAGE_WIDTH;
vfmt.fmt.pix.height = IMAGE_HEIGHT;
vfmt.fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if(ioctl(videoFd, VIDIOC_S_FMT, &vfmt)==-1)
{
qDebug()<<"initialCameraCaptureFormat:ioctl VIDIOC_S_FMT video failed";
return -1;
}
if(ioctl(videoFd, VIDIOC_G_FMT, &vfmt)==-1)
{
qDebug()<<"initialCameraCaptureFormat:ioctl VIDIOC_S_FMT video failed";
return -1;
}
if(vfmt.fmt.pix.pixelformat != V4L2_PIX_FMT_UYVY)
{
qDebug()<<"initialCameraCaptureFormat:vfmt.fmt.pix.pixelformat != V4L2_PIX_FMT_UYVY";
return -1;
}
#endif
return 0;
}
int CCameraDevice::initialCameraCaptureBuffer(int fd, VideoBufferInfo *vbi, int num)
{
#ifdef RUN_ON_EMBEDDEDSYSTEM
struct v4l2_requestbuffers reqbuf;
struct v4l2_buffer buf;
reqbuf.count = num;
reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
reqbuf.memory = V4L2_MEMORY_MMAP;
if(ioctl(fd, VIDIOC_REQBUFS, &reqbuf)==-1)
{
qDebug()<<"initialCameraCaptureBuffer:ioctl VIDIOC_REQBUFS failed";
return -1;
}
if (num != (int)reqbuf.count)
{
return -1;
}
num = (int)reqbuf.count;
memset(&buf, 0, sizeof(buf));
for (int i = 0; i < num; i++)
{
buf.type = reqbuf.type;
buf.index = i;
buf.memory = reqbuf.memory;
if(ioctl(fd, VIDIOC_QUERYBUF, &buf)==-1)
{
qDebug()<<"initialCameraCaptureBuffer:ioctl VIDIOC_QUERYBUF failed";
goto ERROR;
}
vbi[i].length = buf.length;
vbi[i].index = i;
vbi[i].start = (char*)mmap(NULL, buf.length, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, buf.m.offset);
if (vbi[i].start == MAP_FAILED)
{
num = i;
goto ERROR;
}
memset((void *) vbi[i].start, 0x80, vbi[i].length);
if(ioctl(fd, VIDIOC_QBUF, &buf)==-1)
{
num = i + 1;
goto ERROR;
}
}
#endif
return 0;
ERROR:
for (int j = 0; j < num; j++)
{
munmap(vbi[j].start, vbi[j].length);
}
num = 0;
return -1;
}
int CCameraDevice::initialDisplayFormat(int fd)
{
#ifdef RUN_ON_EMBEDDEDSYSTEM
struct v4l2_format fmt;
memset(&fmt,0,sizeof(fmt));
fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
if (ioctl(fd, VIDIOC_G_FMT, &fmt)==-1)
{
qDebug()<<"initialDisplayFormat:ioctl VIDIOC_G_FMT error";
return -1;
}
fmt.fmt.pix.width = DISP_WIDTH;
fmt.fmt.pix.height = DISP_HEIGHT;
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
if (ioctl(fd, VIDIOC_S_FMT, &fmt)==-1)
{
qDebug()<<"initialDisplayFormat:ioctl VIDIOC_S_FMT error";
return -1;
}
if (ioctl(fd, VIDIOC_G_FMT, &fmt)==-1)
{
qDebug()<<"initialDisplayFormat:ioctl VIDIOC_G_FMT error";
return -1;
}
if (fmt.fmt.pix.pixelformat != V4L2_PIX_FMT_UYVY)
{
qDebug()<<"initialDisplayFormat:fmt.fmt.pix.pixelformat != V4L2_PIX_FMT_UYVY";
return -1;
}
#endif
return 0;
}
int CCameraDevice::initialDisplayBuffer(int fd, VideoBufferInfo *vbi, int num)
{
#ifdef RUN_ON_EMBEDDEDSYSTEM
struct v4l2_requestbuffers reqbuf;
struct v4l2_buffer buf;
reqbuf.count = num;
reqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
reqbuf.memory = V4L2_MEMORY_MMAP;
if(ioctl(fd, VIDIOC_REQBUFS, &reqbuf)==-1)
{
qDebug()<<"initialDisplayBuffer:ioctl VIDIOC_REQBUFS error";
return -1;
}
if (num != (int)reqbuf.count)
{
return -1;
}
num = (int)reqbuf.count;
memset(&buf, 0, sizeof(buf));
for (int i = 0; i < num; i++)
{
buf.type = reqbuf.type;
buf.index = i;
buf.memory = reqbuf.memory;
if(ioctl(fd, VIDIOC_QUERYBUF, &buf)==-1)
goto ERROR;
vbi[i].length = buf.length;
vbi[i].index = i;
vbi[i].start = (char*)mmap(NULL, buf.length, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, buf.m.offset);
if (vbi[i].start == MAP_FAILED)
{
num = i;
goto ERROR;
}
memset((void *) vbi[i].start, 0x80, vbi[i].length);
if(ioctl(fd, VIDIOC_QBUF, &buf)==-1)
{
qDebug()<<"initialDisplayBuffer:ioctl VIDIOC_QBUF error";
num = i + 1;
goto ERROR;
}
}
#endif
return 0;
ERROR:
for (int j = 0; j < num; j++)
{
munmap(vbi[j].start, vbi[j].length);
}
num = 0;
return -1;
}
int CCameraDevice::initialVideoColorKey(int fd, unsigned int key)
{
#ifdef RUN_ON_EMBEDDEDSYSTEM
struct v4l2_format fmt;
struct v4l2_framebuffer framebuffer;
fmt.type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
if (ioctl(fd, VIDIOC_G_FMT, &fmt) == -1)
{
qDebug()<<"initialVideoColorKey:ioctl VIDIOC_QBUF error";
return -1;
}
fmt.fmt.win.chromakey = key;
if (ioctl(fd, VIDIOC_S_FMT, &fmt) == -1)
{
qDebug()<<"initialVideoColorKey:ioctl VIDIOC_S_FMT error";
return -1;
}
if (ioctl(fd, VIDIOC_G_FBUF, &framebuffer) == -1)
{
qDebug()<<"initialVideoColorKey:ioctl VIDIOC_G_FBUF error";
return -1;
}
framebuffer.flags |= V4L2_FBUF_FLAG_CHROMAKEY;
framebuffer.flags &= ~V4L2_FBUF_FLAG_SRC_CHROMAKEY;
if (ioctl(fd, VIDIOC_S_FBUF, &framebuffer) == -1)
{
qDebug()<<"initialVideoColorKey:ioctl VIDIOC_S_FBUF error";
return -1;
}
#endif
return 0;
}
bool CCameraDevice::initialCamera()
{
#ifdef RUN_ON_EMBEDDEDSYSTEM
int type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
//media
m_fdMedia = open("/dev/media0", O_RDWR);
if (m_fdMedia == -1)
{
qDebug()<<"initialCamera:open media error";
return false;
}
if (initialMediaLinks(m_fdMedia) == -1)
{
qDebug()<<"initialCamera:setupMediaLinks error";
return false;
}
//ccdc camera video
m_fdCcdc = open("/dev/v4l-subdev2", O_RDWR);
if (m_fdCcdc == -1)
{
qDebug()<<"initialCamera:open ccdc error";
return false;
}
m_fdCam = open("/dev/v4l-subdev8", O_RDWR);
if (m_fdCam == -1)
{
qDebug()<<"initialCamera:open cam error";
return false;
}
m_fdCap = open("/dev/video2", O_RDWR);
if (m_fdCap == -1)
{
qDebug()<<"initialCamera:open video capture error";
return false;
}
if (initialResizer() == -1)
{
qDebug()<<"initialCamera:initResizer error";
return false;
}
if (initialCameraCaptureFormat(m_fdCap,m_fdCcdc,m_fdCam,ADV7180_INPUT_CVBS_AIN4) == -1)
{
qDebug()<<"initialCamera:setupCameraCaptureFormat error";
return false;
}
if (initialCameraCaptureBuffer(m_fdCap, m_vbic, 3) == -1)
{
qDebug()<<"initialCamera:setupCameraCaptureBuffer error";
close(m_fdCap);
return false;
}
if (ioctl(m_fdCap, VIDIOC_STREAMON, &type) ==-1)
{
qDebug()<<"initialCamera:m_fdCap VIDIOC_STREAMON error";
return false;
}
//display
m_fdDis = open("/dev/video7", O_RDWR);
if (m_fdDis == -1)
{
qDebug()<<"initialCamera:open display video err";
return false;
}
if (initialDisplayFormat(m_fdDis) == -1)
{
qDebug()<<"initialCamera:setupDisplayFormat error";
return false;
}
if (initialDisplayBuffer(m_fdDis, m_vbid, 3) == -1)
{
qDebug()<<"initialCamera:setupDisplayBuffer error";
return false;
}
if (initialVideoColorKey(m_fdDis, 0x090909) == -1)
{
qDebug()<<"initialCamera:setVideoColorKey error";
return false;
}
type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
if (ioctl(m_fdDis, VIDIOC_STREAMON, &type) ==-1)
{
qDebug()<<"initialCamera:fdDis VIDIOC_STREAMON error";
return false;
}
#endif
return true;
}
bool CCameraDevice::showVideo()
{
#ifdef RUN_ON_EMBEDDEDSYSTEM
if (m_fdCap == -1)
{
return false;
}
if (m_fdDis == -1)
{
return false;
}
struct v4l2_buffer captureBuff;
struct v4l2_buffer displayBuff;
struct v4l2_buffer resizerInbuff;
struct v4l2_buffer resizerOutbuff;
captureBuff.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
captureBuff.index = 0;
captureBuff.memory = V4L2_MEMORY_MMAP;
if (ioctl(m_fdCap, VIDIOC_DQBUF, &captureBuff) == -1)
{
qDebug()<<"showVideo:ioctl fdCap VIDIOC_DQBUF error";
return false;
}
resizerInbuff.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
resizerInbuff.index = 0;
resizerInbuff.memory = V4L2_MEMORY_MMAP;
if (ioctl(m_fdResizerIn, VIDIOC_DQBUF, &resizerInbuff) ==-1)
{
qDebug()<<"showVideo:ioctl m_fdResizerIn VIDIOC_DQBUF error";
return false;
}
memcpy((unsigned char*)m_resizerInBuff[resizerInbuff.index].start, m_vbic[captureBuff.index].start, m_vbic[captureBuff.index].length);
if (ioctl(m_fdResizerIn, VIDIOC_QBUF, &resizerInbuff) ==-1)
{
qDebug()<<"showVideo:ioctl m_fdResizerIn VIDIOC_QBUF error";
return false;
}
if (ioctl(m_fdCap, VIDIOC_QBUF, &captureBuff) == -1)
{
qDebug()<<"showVideo:ioctl fdCap VIDIOC_QBUF error";
return false;
}
resizerOutbuff.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
resizerOutbuff.index = 0;
resizerOutbuff.memory = V4L2_MEMORY_MMAP;
if (ioctl(m_fdResizerOut, VIDIOC_DQBUF, &resizerOutbuff) == -1)
{
qDebug()<<"showVideo:ioctl m_fdresizerOut VIDIOC_DQBUF error";
return false;
}
displayBuff.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
displayBuff.index = 0;
displayBuff.memory = V4L2_MEMORY_MMAP;
if (ioctl(m_fdDis, VIDIOC_DQBUF, &displayBuff) ==-1)
{
qDebug()<<"showVideo:ioctl m_fdDis VIDIOC_DQBUF error";
return false;
}
memcpy((unsigned char*)m_vbid[displayBuff.index].start, m_resizerOutBuff[resizerOutbuff.index].start, m_resizerOutBuff[resizerOutbuff.index].length);
if (ioctl(m_fdDis, VIDIOC_QBUF, &displayBuff) ==-1)
{
qDebug()<<"showVideo:ioctl m_fdDis VIDIOC_QBUF error";
return false;
}
if (ioctl(m_fdResizerOut, VIDIOC_QBUF, &resizerOutbuff) == -1)
{
qDebug()<<"showVideo:ioctl m_fdResizerOut VIDIOC_QBUF error";
return false;
}
#endif
return true;
}
bool CCameraDevice::getVideo(unsigned char *imageData)
{
#ifdef RUN_ON_EMBEDDEDSYSTEM
if (m_fdCap == -1)
{
return false;
}
struct v4l2_buffer captureBuff;
captureBuff.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
captureBuff.index = 0;
captureBuff.memory = V4L2_MEMORY_MMAP;
if (ioctl(m_fdCap, VIDIOC_DQBUF, &captureBuff) == -1)
{
qDebug()<<"getVideo:ioctl fdCap VIDIOC_DQBUF error";
return false;
}
memcpy(imageData, m_vbic[captureBuff.index].start , IMAGE_WIDTH*IMAGE_HEIGHT*2 );
if (ioctl(m_fdCap, VIDIOC_QBUF, &captureBuff) == -1)
{
qDebug()<<"getVideo:ioctl fdCap VIDIOC_QBUF error";
return false;
}
#endif
return true;
}
相关文章推荐
- [中英对照]User-Space Device Drivers in Linux: A First Look | 初识Linux用户态设备驱动程序
- [中英对照]Device Drivers in User Space: A Case for Network Device Driver | 用户态设备驱动: 以网卡驱动为例
- DMA in user space (uio dma) //code analysis
- FUSE(Filesystem in Userspace)简介和使用
- use WinDbg running in kernel mode to set breakpoints in user space
- 编译选项导致死机(Unaligned userspace access in "XXX.exe" )
- Linux Filesystem in Userspace(FUSE)
- Writing a Real Driver -- In User Space
- linux i2c access in kernel and user space
- FUSE - implementing filesystems in user space
- Call KernelIoControl in user space in WINCE6.0
- FUSE(Filesystem in USErspace)
- 142.The user SCOTT owns the CUST table that is placed in the SALES tablespace. The user SCOTT opens
- FUSE(Filesystem in userspace)(用户空间文件系统),user-space框架简单介绍
- fuse : Filesystem in Userspace
- FUSE(Filesystem in Userspace)简介和使用
- V4L2源代码之旅二:V4L2 sub-device userspace API
- Warning: Unknown: write failed: No space left on device (28) in Unknown on line 0
- Linux Filesystem in Userspace(FUSE)
- Checkpoint/Restore in Userspace(CRIU)的安装与使用(CentOS 7.2)