📄 zc030x_v4l.c
字号:
/* struct video_device zc030x_fill = { .owner = THIS_MODULE, .name = "ZC030X Webcam", .type = VID_TYPE_CAPTURE, .hardware = VID_HARDWARE_ZC030X, .fops = pFops, .minor= -1 // minor #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) .initialize = NULL, // initialize #endif };*//* Include headers */#include <linux/module.h>/* Include declarations */#include "zc030x_v4l.h"/* Include camera */#include "zc030x_cameras.h"#include "zc030x_reg.h"/* Check if the palette is valid */inline int zc030x_v4l_checkpalette(int Palette){ return (Palette == VIDEO_PALETTE_RGB24) || (Palette == VIDEO_PALETTE_RGB32)||// (Palette == VIDEO_PALETTE_YUV422)||// (Palette == VIDEO_PALETTE_UYVY) || 0; /* (Palette == VIDEO_PALETTE_RGB32) ||*/}/* Get the palette name */inline const char * zc030x_v4l_getpalettename(int Palette){ if (Palette == VIDEO_PALETTE_RGB24) return "VIDEO_PALETTE_RGB24"; if (Palette == VIDEO_PALETTE_RGB32) return "VIDEO_PALETTE_RGB32"; if (Palette == VIDEO_PALETTE_UYVY) return "VIDEO_PALETTE_UYVY"; if (Palette == VIDEO_PALETTE_YUV422) return "VIDEO_PALETTE_YUV422"; return "internal error !";}/* Get the depth of the pixel */int zc030x_v4l_getdepth(int Palette){ if (Palette == VIDEO_PALETTE_RGB24) return 24; if (Palette == VIDEO_PALETTE_RGB32) return 32; if (Palette == VIDEO_PALETTE_UYVY) return 16; if (Palette == VIDEO_PALETTE_YUV422) return 16; return 0;}/* Functions for pre 2.4.24 kernel compatibility */#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 24)inline void * video_get_drvdata(struct video_device *vdev){ return vdev->priv;}inline void video_set_drvdata(struct video_device *vdev, void *data){ vdev->priv = data;}inline struct video_device *video_device_alloc(void){ struct video_device *vdev; vdev = kmalloc(sizeof(*vdev),GFP_KERNEL); if (NULL == vdev) return NULL; memset(vdev,0,sizeof(*vdev)); return vdev;}inline void video_device_release(struct video_device *vdev){ kfree(vdev);}#endif/* Fill the video dynamic device object */int zc030x_v4l_initdev(struct file_operations * pFops, struct usb_zc030x * pDev, const char * Name, struct usb_device * udev){ /* Check arguments */ if (pFops == NULL || pDev == NULL || Name == NULL) return V4L_Error; /* Okay, init and create the device */ PDEBUG (5, ">> [ZCV4L] Registering video for linux device"); /* Alloc video device (v4l) */ pDev->pVideoDevice = video_device_alloc(); /* Check allocation */ if (pDev->pVideoDevice == NULL) return V4L_Error; /* Fill it with the right value */ memset(pDev->pVideoDevice, 0, sizeof(*pDev->pVideoDevice)); pDev->pVideoDevice->owner = THIS_MODULE; pDev->pVideoDevice->type = VID_TYPE_CAPTURE; pDev->pVideoDevice->hardware = VID_HARDWARE_ZC030X; pDev->pVideoDevice->fops = pFops; pDev->pVideoDevice->minor = -1; /* And save the device name */ strcpy(pDev->pVideoDevice->name, Name); /* Set driver data */#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) pDev->pVideoDevice->dev = &udev->dev;#endif video_set_drvdata(pDev->pVideoDevice, pDev); /* Register video device */ if (video_register_device(pDev->pVideoDevice, VFL_TYPE_GRABBER, -1) < 0) { PDEBUG(4, "Error registering the video device!"); return V4L_Error; } /* Okay, return */ PDEBUG (5, "<< [ZCV4L] Registered as video%d.\n", pDev->pVideoDevice->minor & 0x3F); return V4L_OK;}/* Release video device */int zc030x_v4l_releasedev(struct video_device * pVideoDevice){ /* Check argument */ if (pVideoDevice != NULL) { /* Check if the device is used */ if(pVideoDevice->minor == -1) video_device_release(pVideoDevice); else video_unregister_device(pVideoDevice); } /* Okay return */ return V4L_OK;}/* Video for Linux specific IOCTLs */int zc030x_v4l_ioctl (struct inode *inode, struct file *file, unsigned int cmd, void *arg){ /* Return object */ int ret = -ENOTTY; /* Iterators */ int i = 0; /* Get the video device */ struct video_device *vdev = video_devdata(file); /* And the USB device too */ struct usb_zc030x *dev; /* Debug this function */ PDEBUG(3,">> zc030x_v4l_ioctl()"); /* Check parameter */ if (vdev == NULL) { PDEBUG (2, "vdev is NULL, returning"); return 0; } /* Get USB device too */ dev = video_get_drvdata(vdev); if (dev == NULL) { PDEBUG (2, "dev is NULL, returning"); return 0; } /* Lock device object */ down (&dev->sem); /* Verify that the device wasn't unplugged */ if (!dev->present) { up (&dev->sem); return -ENODEV; } /* Debug this function */ PDEBUG(4,"zc030x - minor %d, cmd 0x%.4x, arg %p",dev->minor, cmd, arg); /* Get the IOCTL command */ switch (cmd) { /* User is asking for capture capabilities */ case VIDIOCGCAP: { /* Convert the argument */ struct video_capability *b = arg; /* Debug it */ PDEBUG (4, "VIDIOCGCAP %p :",b); /* Clear it */ memset(b, 0, sizeof(struct video_capability)); /* Create the card name */ snprintf(b->name, 32, "%s with sensor %s\n", CamList[dev->type_id].Name, SensList[dev->sensor_id].Name); /* Set the type */ b->type = VID_TYPE_CAPTURE; /* The number of channels */ b->channels = 1; /* No audio yet */ b->audios = 0; /* And the size */ /* TODO: Fix this hack *//* b->minwidth = SensorSizeList[dev->sensor_id].Width>>1; b->minheight = SensorSizeList[dev->sensor_id].Height>>1; b->maxwidth = SensorSizeList[dev->sensor_id].Width; b->maxheight = SensorSizeList[dev->sensor_id].Height; */ b->minwidth = currentwidth; b->minheight = currentheight; b->maxwidth = currentwidth; b->maxheight = currentheight; /* Return */ ret = 0; break; } /* Get source channel */ case VIDIOCGCHAN: { /* Convert the argument */ struct video_channel *v = arg; /* Set the name */ snprintf(v->name, 32, "zc030x video bridge\n"); /* No special support */ v->flags = 0; /* No tuner */ v->tuners = 0; /* Set the type */ v->type = VIDEO_TYPE_CAMERA; /* Return */ ret = 0; break; } /* Set source channel */ case VIDIOCSCHAN: { /* Return */ ret = 0; break; } /* Get image properties */ case VIDIOCGPICT: { /* Convert the argument */ struct video_picture *p = arg; /* Set the bit depth of a pixel */ p->depth = 24; /* Set the palette type */ /* Possible values are VIDEO_PALETTE_YUV422 for large pictures */ /* Or VIDEO_PALETTE_RGB24 for smaller one */ p->palette = dev->VideoFormat; p->brightness = dev->Brightness; p->contrast = dev->Contrast; /* Return */ ret = 0; break; } /* Get the subcapture, if any */ case VIDIOCGCAPTURE: { /* Convert the argument */ int *vf = arg; /* Debug this */ PDEBUG (4, "VIDIOCGCAPTURE"); /* No subcapture */ *vf = 0; /* Return */ ret = -EINVAL; break; } /* Set the subcapture */ case VIDIOCSCAPTURE: { /* Not implemented */ ret = -EINVAL; break; } /* Set the capture window */ case VIDIOCSWIN: { /* Convert the argument */ struct video_window *vw = arg; /* Set the return code */ ret = 0; /* Debug this */ PDEBUG (4, "VIDIOCSWIN: width=%d, height=%d, flags=%d",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -