如何实现LCD显示摄像头图像(1)

本文介绍了如何在Linux系统中实现LCD显示摄像头图像,主要涉及摄像头数据读出的步骤,包括初始化、打开设备、设置格式、mmap映射、streaming模式处理以及读写操作。重点解析了v2l4.c中的初始化函数,讲解了ioctl()系统调用在设备特性查询、格式设置及buffer管理中的应用。
摘要由CSDN通过智能技术生成
摄像头数据的读出

首先需要将摄像头采集到的数据读出,那么就需要摄像头采集到数据的基本格式以及相关操作函数:

typedef struct VideoDevice {
   
    int iFd;
    int iPixelFormat;
    int iWidth;
    int iHeight;

    int iVideoBufCnt;
    int iVideoBufMaxLen;
    int iVideoBufCurIndex;
    unsigned char *pucVideBuf[NB_BUFFER];

    /* 函数 */
    PT_VideoOpr ptOPr;
}T_VideoDevice, *PT_VideoDevice;

函数结构体:

typedef struct VideoOpr {
   
    char *name;
    int (*InitDevice)(char *strDevName, PT_VideoDevice ptVideoDevice);
    int (*ExitDevice)(PT_VideoDevice ptVideoDevice);
    int (*GetFrame)(PT_VideoDevice ptVideoDevice, PT_VideoBuf ptVideoBuf);
    int (*PutFrame)(PT_VideoDevice ptVideoDevice, PT_VideoBuf ptVideoBuf);
    int (*StartDevice)(PT_VideoDevice ptVideoDevice);
    int (*StopDevice)(PT_VideoDevice ptVideoDevice);
}T_VideoOpr, *PT_VideoOpr;

包括初始化,退出函数,从队列中获取buffer的函数以及将buffer放回队列的函数,还应该包括开启设备的函数以及停止设备工作的函数。·以上函数的实现都在v2l4.c中实现,下面就要实现这些函数。

v2l4.c的实现
static int V4l2InitDevice(char *strDevName, PT_VideoDevice ptVideoDevice)
{
   
    int i;
    int iFd;
    int iError;
    struct v4l2_capability tV4l2Cap;
	struct v4l2_fmtdesc tFmtDesc;
    struct v4l2_format  tV4l2Fmt;
    struct v4l2_requestbuffers tV4l2ReqBuffs;
    struct v4l2_buffer tV4l2Buf;

    int iLcdWidth;
    int iLcdHeigt;
    int iLcdBpp;

    iFd = open(strDevName, O_RDWR);
    if (iFd < 0)
    {
   
        DBG_PRINTF("can not open %s\n", strDevName);
        return -1;
    }
    ptVideoDevice->iFd = iFd;

    iError = ioctl(iFd, VIDIOC_QUERYCAP, &tV4l2Cap);
    memset(&tV4l2Cap, 0, sizeof(struct v4l2_capability));
    iError = ioctl(iFd, VIDIOC_QUERYCAP, &tV4l2Cap);      // 为什么调用两次
    if (iError) {
   
    	DBG_PRINTF("Error opening device %s: unable to query device.\n", strDevName);
    	goto err_exit;
    }

    if (!(tV4l2Cap.capabilities & V4L2_CAP_VIDEO_CAPTURE))
    {
   
    	DBG_PRINTF("%s is not a video capture device\n", strDevName);
        goto err_exit;
    }

	if (tV4l2Cap.capabilities & V4L2_CAP_STREAMING) {
   
	    DBG_PRINTF("%s supports streaming i/o\n", strDevName);
	}
    
	if (tV4l2Cap.capabilities & V4L2_CAP_READWRITE) {
   
	    DBG_PRINTF("%s supports read i/o\n", strDevName);
	}

	memset(&tFmtDesc, 0, sizeof(tFmtDesc));
	tFmtDesc.index = 0;
	tFmtDesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	while ((iError = ioctl(iFd, VIDIOC_ENUM_FMT, &tFmtDesc)) == 0) {
   
        if (isSupportThisFormat(tFmtDesc.pixelformat))
        {
   
            ptVideoDevice->iPixelFormat = tFmtDesc.pixelformat;
            break;
        }
		tFmtDesc.index++;
	}

    if (!ptVideoDevice->iPixelFormat)
    {
   
    	DBG_PRINTF("can not support the format of this device\n");
        goto err_exit;        
    }

    
    /* set format in */
    GetDispResolution(&iLcdWidth, &iLcdHeigt, &iLcdBpp);
    memset(&tV4l2Fmt, 0, sizeof(struct v4l2_format));
    tV4l2Fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    tV4l2Fmt.fmt.pix.pixelformat = ptVideoDevice->iPixelFormat;
    tV4l2Fmt.fmt.pix.width       = iLcdWidth;
    tV4l2Fmt.fmt.pix.height      = iLcdHeigt;
    tV4l2Fmt.fmt.pix.field       = V4L2_FIELD_ANY;

    /* 如果驱动程序发现无法某些参数(比如分辨率),
     * 它会调整这些参数, 并且返回给应用程序
     */
    iError = ioctl(iFd, VIDIOC_S_FMT
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值