⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 patch-linux-2.4.22-qcamvc-1.0.6

📁 VC编写的USB QuickCam驱动程序,实现四种视频格式在linux下的编码,信号来自摄像源
💻 6
📖 第 1 页 / 共 5 页
字号:
++  if (!qcamvc->frame_buf) {+    if ((retval = allocate_frame_buf(qcamvc))) {+      return 0;+    }+  }+  +  pos = (unsigned long)(qcamvc->frame_buf);+  while (size > 0) {+    page = kvirt_to_pa(pos);+    if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED)) {+      up(&qcamvc->busy);+      return -EAGAIN;+    }+    start += PAGE_SIZE;+    pos += PAGE_SIZE;+    if (size > PAGE_SIZE)+      size -= PAGE_SIZE;+    else+      size = 0;+  }+  up(&qcamvc->busy);+  return 0;+  +}+/**********************************************************************+ *+ * Memory management+ *+ * This is a shameless copy from the USB-cpia driver (linux kernel+ * version 2.3.29 or so, I have no idea what this code actually does ;).+ * Actually it seems to be a copy of a shameless copy of the bttv-driver.+ * Or that is a copy of a shameless copy of ... (To the powers: is there+ * no generic kernel-function to do this sort of stuff?)+ *+ * Yes, it was a shameless copy from the bttv-driver. IIRC, Alan says+ * there will be one, but apparentely not yet - jerdfelt+ *+ **********************************************************************/++/* Given PGD from the address space's page table, return the kernel+ * virtual mapping of the physical memory mapped at ADR.+ */+static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr)+{+  unsigned long ret = 0UL;+  pmd_t *pmd;+  pte_t *ptep, pte;+  +  if (!pgd_none(*pgd)) {+    pmd = pmd_offset(pgd, adr);+    if (!pmd_none(*pmd)) {+			ptep = pte_offset(pmd, adr);+			pte = *ptep;+			if (pte_present(pte)) {+			  ret = (unsigned long) page_address(pte_page(pte));+			  ret |= (adr & (PAGE_SIZE-1));+			}+    }+  }+  return ret;+}++#if LINUX_VERSION_CODE < 0x020400+#define virt_to_page(kaddr) (MAP_NR(kaddr))+#endif++static void *rvmalloc(unsigned long size)+{+	void *mem;+	unsigned long adr, page;+	size += (PAGE_SIZE - 1);+	size &= ~(PAGE_SIZE - 1);++	mem = vmalloc_32(size);+	if (!mem)+		return NULL;++	memset(mem, 0, size);+	adr = (unsigned long) mem;+	while (size > 0) {+		page = kvirt_to_pa(adr);+		mem_map_reserve(virt_to_page(__va(page)));+		adr += PAGE_SIZE;+		if (size > PAGE_SIZE)+			size -= PAGE_SIZE;+		else+			size = 0;+	}++	return mem;+}++static void rvfree(void *mem, unsigned long size)+{+  unsigned long adr, page;+  if (!mem)+    return;+  +  size += (PAGE_SIZE - 1);+  size &= ~(PAGE_SIZE - 1);+  +  adr = (unsigned long) mem;+  while (size > 0) {+    page = kvirt_to_pa(adr);+    mem_map_unreserve(virt_to_page(__va(page)));+    adr += PAGE_SIZE;+    if (size > PAGE_SIZE)+      size -= PAGE_SIZE;+    else+      size = 0;+  }+	vfree(mem);+}++static int allocate_frame_buf(struct qcamvc *qcamvc)+{+  int i;+  qcamvc->frame_buf = rvmalloc(QUICKCAM_NUMFRAMES * QUICKCAM_MAX_SIZE);+  if (!qcamvc->frame_buf)+    return -ENOBUFS;+  +  for (i = 0; i < QUICKCAM_NUMFRAMES; i++)+    qcamvc->frame[i].data = qcamvc->frame_buf + i * QUICKCAM_MAX_SIZE;+  +  return 0;+}++static int free_frame_buf(struct  qcamvc *qcamvc)+{+  int i;+	+  rvfree(qcamvc->frame_buf, QUICKCAM_NUMFRAMES * QUICKCAM_MAX_SIZE);+  qcamvc->frame_buf = 0;+  for (i=0; i < QUICKCAM_NUMFRAMES; i++)+    qcamvc->frame[i].data = NULL;+  return 0;+}++static void inline free_frames(struct qcamvc_frame frame[QUICKCAM_NUMFRAMES])+{+	int i;++	for (i=0; i < QUICKCAM_NUMFRAMES; i++)+		frame[i].state = FRAME_UNUSED;+	return;+}++/* Here we want the physical address of the memory.+ * This is used when initializing the contents of the+ * area and marking the pages as reserved.+ */+static inline unsigned long kvirt_to_pa(unsigned long adr)+{+  unsigned long va, kva, ret;+  +  va = VMALLOC_VMADDR(adr);+  kva = uvirt_to_kva(pgd_offset_k(va), va);+  ret = __pa(kva);+  return ret;+}++#endif /* USE_MMAP */++static int qcamvc_vioctl(struct video_device *dev, unsigned int cmd, void *arg)+{+  struct qcamvc *qcamvc = dev->priv;++  if (down_interruptible(&qcamvc->busy))+    return -EINTR;+++  switch(cmd)+    {+      +      /* Return capability */+    case VIDIOCGCAP:+      {+	if (copy_to_user(arg, &qcamvc->vcap, sizeof(struct video_capability)))+	  {+	    up(&qcamvc->busy);+	    return -EFAULT;+	  }+	up(&qcamvc->busy);+	return 0;+      }+      +      /* Video channel ioctl */+    case VIDIOCGCHAN:+      {+	if (copy_to_user(arg, &qcamvc->vchan, sizeof(struct video_channel)))+	  {+	    up(&qcamvc->busy);+	    return -EFAULT;+	  }+	up(&qcamvc->busy);+	return 0;+      }+      +    case VIDIOCSCHAN:+      {+	int v;+	if(copy_from_user(&v, arg,sizeof(int)))+	  {+	    up(&qcamvc->busy);+	    return -EFAULT;+	  }+	if(v!=0)+	  {+	    up(&qcamvc->busy);+	    return -EINVAL;+	  }+	up(&qcamvc->busy);+	return 0;+      }+      +      /* Video picture ioctl */+    case VIDIOCGPICT:+      {+	if (copy_to_user(arg, &qcamvc->vpic, sizeof(struct video_picture)))+	  {+	    up(&qcamvc->busy);+	    return -EFAULT;+	  }+	up(&qcamvc->busy);	+	return 0;+      }+      +    case VIDIOCSPICT:+      {+	struct video_picture p;+	+	if(copy_from_user(&p, arg, sizeof(struct video_picture)))+	  {+	    up(&qcamvc->busy);+	    return -EFAULT;+	  }+	+	if (p.depth != 24 || p.palette != VIDEO_PALETTE_RGB24)+	  {+	    up(&qcamvc->busy);+	    return -EINVAL;+	  }+	+	if (p.brightness >> 8 != qcamvc->brightness)+	  {+	    qcamvc->brightness = p.brightness >> 8;+	    qcamvc_set_brightness(qcamvc,qcamvc->brightness);+	  }+	+	if (p.whiteness >> 8 != qcamvc->exposure)+	  {+	    qcamvc->exposure = p.whiteness >> 8;+	    qcamvc_set_exposure(qcamvc,qcamvc->exposure);+	  }+	+	if (p.contrast != qcamvc->vpic.contrast)+	  {+	    qcamvc->blue_hue = p.contrast >> 8;+	    qcamvc->hue_calc=0;+	  }++	if (p.hue != qcamvc->vpic.hue)+	  {+	    qcamvc->red_hue = p.hue >> 8;+	    qcamvc->hue_calc=0;+	  }++	if (p.colour  != qcamvc->vpic.colour)+	  {+	    qcamvc->santrast = p.colour >> 8;+	    qcamvc->hue_calc=0;+	  }+	+	qcamvc->vpic = p;++	up(&qcamvc->busy);+	return 0;+      }+      +      /* Capture window ioctl */+   case VIDIOCSWIN:+     {+       struct video_window vw;+	 int res = qcamvc->res;+	   +	   if(copy_from_user(&vw, arg,sizeof(struct video_window)))+	     {+	       up(&qcamvc->busy);+	       return -EFAULT;+	     }+	   +	   if(vw.flags)+	     {+	       printk("1\n");+	       up(&qcamvc->busy);+	       return -EINVAL;+	     }+		   +	   if(vw.clipcount)+	     {+	       printk("2\n");+	       up(&qcamvc->busy);+	       return -EINVAL;+	     }+		       +	if(vw.height<MIN_HEIGHT || vw.height>MAX_HEIGHT)+	  {+	    printk("Want to set %dx%d 3\n",vw.width, vw.height);+	    up(&qcamvc->busy);+	    return -EINVAL;+	  }+ +	if(vw.width<MIN_WIDTH || vw.width>MAX_WIDTH)+	  {+	    printk("Want to set %dx%d 4\n",vw.width, vw.height);+	    up(&qcamvc->busy);+	    return -EINVAL;+	  }++	if(vw.width>=160 && vw.height>=120)+	  {+	    res=R160x120;+	  }+	if(vw.width>=176 && vw.height>=144)+	  {+	    res=R176x144;+	  }+	if(vw.width>=320 && vw.height>=240)+	  {+	    res=R320x240;+	  }+	if(vw.width>=352 && vw.height>=288)+	  {+	    res=R352x288;+	  }+	qcamvc_set_res(qcamvc, res);+	up(&qcamvc->busy);+	return 0;+      }+      +    case VIDIOCGWIN:+      {+	struct video_window vw;+	+	memset(&vw, 0, sizeof(struct video_window));+	vw.width  = qcamvc->width;+	vw.height = qcamvc->height;+	vw.flags  = 0;+	+	if(copy_to_user(arg, &vw, sizeof(struct video_window)))+	  {+	    up(&qcamvc->busy);+	    return -EFAULT;+	  }+	up(&qcamvc->busy);+	return 0;+      }+#ifdef USE_MMAP      +      /* mmap interface */+    case VIDIOCGMBUF:+      {+        struct video_mbuf vm;+        int i;+	+	memset(&vm, 0, sizeof(struct video_mbuf));+	vm.size = qcamvc->width * qcamvc->height *+	  3 * QUICKCAM_NUMFRAMES;+	vm.frames = QUICKCAM_NUMFRAMES;+	+	for (i = 0; i < QUICKCAM_NUMFRAMES ; i++)+	  vm.offsets[i] = qcamvc->width * qcamvc->height *+	    3  * i;+	+	if (copy_to_user((void *)arg, (void *)&vm, sizeof(struct video_mbuf)))+	  {+	    up(&qcamvc->busy);+	    return -EFAULT;+	  }+	up(&qcamvc->busy);+	return 0;+      }+      +    case VIDIOCSYNC:+      {+        int frame;+	+        if (copy_from_user((void *)&frame, arg, sizeof(int)))+	  {+	    up(&qcamvc->busy);+	    return -EFAULT;+	  }+	+	if (frame<0 || frame >= QUICKCAM_NUMFRAMES )+	  {+	    up(&qcamvc->busy);+	    return -EINVAL;+	  }+	+	switch (qcamvc->frame[frame].state) +	  {+	  case FRAME_UNUSED:+	  case FRAME_READY:+	  case FRAME_GRABBING:+	    {+	      printk("sync to unused frame %d\n", frame);+	      up(&qcamvc->busy);+	      return -EINVAL;+	    }+	    +	  case FRAME_DONE:+	    qcamvc->frame[frame].state = FRAME_UNUSED;+	  }+	up(&qcamvc->busy);+	return 0;+      }+      +    case VIDIOCMCAPTURE:+      {+	struct video_mmap vm;+	+	if (copy_from_user((void *)&vm, (void *)arg, sizeof(struct video_mmap)))+	  {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -