[GnomeMeeting-devel-list] PWLib V4L2 plugin patch submission request



Hello, guys!

	I have just made the latest CVS gnomemeeting work on a V4L2 camera (sn9c102 based), and this is the outcome of my work. My camera is very cheap and lacks support for lots of options, like color and brightness tuning, so I could not test everything... That's what I have reserved for you to enjoy :)
	This is my first patch submission, please be patient if it doesn't apply properly at the first try. Contact me immediately should you need changes to the file format (or just clean it up :). The patch must be applied to pwlib 1.8.3. Any hints and suggestion for future releases will be appreciated.
	Although this work is far from perfect, I am submitting it anyways, as I know crowds are craving for the V4L2 support needed by recent Bayer-based cameras (good job, Luca! :).
	
	Notes:
	- I tried to add a rudimentary device detection based on the scan of the /dev/v4l directory. The device detection code can conflict with "old" V4L plugin. To work it around, choose the proper device and the V4L2 plugin from Edit/Preferences/Video devices and restart gnomemeeting, or DELETE the V4L plugin if you fancy more drastic approaches :)
	- Some validations have been "mocked" in order to make my poor limp camera work.
	
	Thanks to everyone of you for developing such a great app :)
	
-- 
Ciao,
Nigu
------------------------------------------------------------------
* Nicola Orru' - 49, Rocky Lane - L6 4BA Anfield, Liverpool - UK *
------------------------------------------------------------------
? a.out
? patch_nigu_v4l2_20041023_1_8_3.diff
? video.log
? plugins/pwlib
? samples/audio/obj_linux_x86_d
? samples/audio/obj_linux_x86_r
? samples/dtmftest/obj_linux_x86_d
? samples/dtmftest/obj_linux_x86_r
? samples/threadex/obj_linux_x86_d
? samples/threadex/obj_linux_x86_r
Index: plugins/vidinput_v4l2/vidinput_v4l2.cxx
===================================================================
RCS file: /cvsroot/openh323/pwlib/plugins/vidinput_v4l2/vidinput_v4l2.cxx,v
retrieving revision 1.1
diff -u -r1.1 vidinput_v4l2.cxx
--- plugins/vidinput_v4l2/vidinput_v4l2.cxx	21 Sep 2004 12:54:23 -0000	1.1
+++ plugins/vidinput_v4l2/vidinput_v4l2.cxx	23 Oct 2004 11:56:09 -0000
@@ -33,9 +33,9 @@
  *  - fix the devices detection code using the new code from the V4L1 plugin
  *  - make that code work
  *
- * $Log: vidinput_v4l2.cxx,v $
- * Revision 1.1  2004/09/21 12:54:23  dsandras
- * Added initial port to the new pwlib API/V4L2 API for the video4linux 2 code of Guilhem Tardy. Thanks!
+ * $Log: vidinput_v4l2.cxx,v $
+ * Revision 1.1  2004/09/21 12:54:23  dsandras
+ * Added initial port to the new pwlib API/V4L2 API for the video4linux 2 code of Guilhem Tardy. Thanks!
  *
  * Revision 1.0  2003/03/03 12:27:00  guilhem
  * First build.
@@ -45,7 +45,7 @@
 #pragma implementation "vidinput_v4l2.h"
 
 #include "vidinput_v4l2.h"
-
+ 
 
 PCREATE_VIDINPUT_PLUGIN(V4L2, PVideoInputV4l2Device);
 
@@ -65,7 +65,7 @@
   canSetFrameRate = FALSE;
   isMapped = FALSE;
 }
-
+ 
 PVideoInputV4l2Device::~PVideoInputV4l2Device()
 {
   Close();
@@ -93,7 +93,8 @@
     { "YUV422", V4L2_PIX_FMT_YYUV },
     { "YUV422P", V4L2_PIX_FMT_YUV422P },
     { "JPEG", V4L2_PIX_FMT_JPEG },
-    { "H263", V4L2_PIX_FMT_H263 }
+    { "H263", V4L2_PIX_FMT_H263 },
+    { "SBGGR8", V4L2_PIX_FMT_SBGGR8 }   
 };
 
 
@@ -134,13 +135,14 @@
   videoStreamParm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
   if (::ioctl(videoFd, VIDIOC_G_PARM, &videoStreamParm) < 0)  {
     PTRACE(1,"PVidInDev\tG_PARM failed : " << ::strerror(errno));
-    ::close (videoFd);
-    videoFd = -1;
-    return FALSE;
-
+//    ::close (videoFd);
+//    videoFd = -1;
+//    return FALSE;
+    canSetFrameRate = false;
   } else {
     canSetFrameRate = videoStreamParm.parm.capture.capability & V4L2_CAP_TIMEPERFRAME;
-    PVideoDevice::SetFrameRate (10000000 * videoStreamParm.parm.capture.timeperframe.numerator / videoStreamParm.parm.capture.timeperframe.denominator);
+    if (canSetFrameRate)
+      PVideoDevice::SetFrameRate (10000000 * videoStreamParm.parm.capture.timeperframe.numerator / videoStreamParm.parm.capture.timeperframe.denominator);
   }
   
   return TRUE;
@@ -190,6 +192,9 @@
     PTRACE(6,"PVidInDev\tstart streaming, fd=" << videoFd);
 
     struct v4l2_buffer buf;
+    buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+    buf.index = 0;
+
     if (::ioctl(videoFd, VIDIOC_QBUF, &buf) < 0) {
       PTRACE(3,"PVidInDev\tVIDIOC_QBUF failed : " << ::strerror(errno));
       return FALSE;
@@ -282,24 +287,25 @@
 
 PStringList PVideoInputV4l2Device::GetInputDeviceNames()
 {
-  PDirectory procVideo("/proc/video/dev");
-  PStringList devList;
-
+  PDirectory procVideo("/dev/v4l");
+  PStringList devList; 
   devList.RemoveAll ();
   if (procVideo.Exists()) {
-    if (procVideo.Open(PFileInfo::RegularFile)) {
+   cerr << "Looking for device in /dev/v4l\n";
+   if (procVideo.Open(PFileInfo::CharDevice)) {
       do {
 	PString entry = procVideo.GetEntryName();
 
-	if (entry.Left(7) == "capture") {
-	  PString thisDevice = "/dev/video" + entry.Mid(7);
+	if (1) { //entry.Left(7) == "capture") {
+		PString thisDevice = "/dev/v4l/" + entry; //= "/dev/video" + entry.Mid(7);
 	  int videoFd;
 
 	  if ((videoFd = ::open(thisDevice, O_RDONLY)) >= 0) {
 	    struct v4l2_capability videoCaps;
+		cerr << "device found " << entry << "\n";
 
-	    if (::ioctl(videoFd, VIDIOC_QUERYCAP, &videoCaps) >= 0 &&
-		videoCaps.capabilities == V4L2_CAP_VIDEO_CAPTURE) {
+	    if (::ioctl(videoFd, VIDIOC_QUERYCAP, &videoCaps) >= 0 ||
+		(videoCaps.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
 	      devList.AppendString(thisDevice);
 	    }
 	    ::close(videoFd);
@@ -359,8 +365,10 @@
   videoEnumStd.index = 0;
   while (1) {
     if (::ioctl(videoFd, VIDIOC_ENUMSTD, &videoEnumStd) < 0) {
-      PTRACE(1,"VideoInputDevice\tEnumStd failed : " << ::strerror(errno));    
-      return FALSE;
+      PTRACE(1,"VideoInputDevice\tEnumStd failed : " << ::strerror(errno));
+      //return FALSE;
+      videoEnumStd.id = V4L2_STD_PAL;
+      break; // ????
     }
     if (videoEnumStd.id == fmt[newFormat].code) {
       break;
@@ -371,7 +379,7 @@
   // set the video standard
   if (::ioctl(videoFd, VIDIOC_S_STD, &videoEnumStd.id) < 0) {
     PTRACE(1,"VideoInputDevice\tS_STD failed : " << ::strerror(errno));
-    return FALSE;
+    // return FALSE;
   }
 
   PTRACE(6,"PVidInDev\tset video format \"" << fmt[newFormat].name << "\", fd=" << videoFd);
@@ -480,6 +488,7 @@
   }
 
   frameBytes = videoFormat.fmt.pix.sizeimage;
+  PTRACE(1,"Frame size = "<<frameBytes);
 
   PTRACE(6,"PVidInDev\tset colour format \"" << newFormat << "\", fd=" << videoFd);
 
@@ -494,17 +503,18 @@
 {
   if (!PVideoDevice::SetFrameRate(rate)) {
     PTRACE(3,"PVidInDev\tSetFrameRate failed for rate " << rate);
-    return FALSE;
+    return TRUE;
   }
 
   if (canSetFrameRate) {
+
     videoStreamParm.parm.capture.timeperframe.numerator = 10000000;
     videoStreamParm.parm.capture.timeperframe.denominator = (rate ? rate : 1);
 
     // set the stream parameters
     if (::ioctl(videoFd, VIDIOC_S_PARM, &videoStreamParm) < 0)  {
       PTRACE(1,"PVidInDev\tS_PARM failed : "<< ::strerror(errno));
-      return FALSE;
+      return TRUE;
     }
 
     PTRACE(6,"PVidInDev\tset frame rate " << rate << "fps, fd=" << videoFd);
@@ -520,6 +530,11 @@
 					       unsigned & maxHeight) 
 {
   /* Not used in V4L2 */
+	minWidth=0;
+	maxWidth=65535;
+	minHeight=0;
+	maxHeight=65535;
+	
   return FALSE;
 }
 
@@ -734,8 +749,10 @@
   while (bytesRead < 0 && errno == EINTR);
 
   if (bytesRead < 0) {
-    PTRACE(1,"PVidInDev\tread failed");
-    return FALSE;
+    PTRACE(1,"PVidInDev\tread failed (read = "<<bytesRead<< " expected " << frameBytes <<")");
+//    return FALSE;
+    perror("PVidInDev");
+    bytesRead = frameBytes;
   }
 
   if ((PINDEX)bytesRead != frameBytes) {
Index: plugins/vidinput_v4l2/vidinput_v4l2.h
===================================================================
RCS file: /cvsroot/openh323/pwlib/plugins/vidinput_v4l2/vidinput_v4l2.h,v
retrieving revision 1.1
diff -u -r1.1 vidinput_v4l2.h
--- plugins/vidinput_v4l2/vidinput_v4l2.h	21 Sep 2004 12:54:23 -0000	1.1
+++ plugins/vidinput_v4l2/vidinput_v4l2.h	23 Oct 2004 11:56:10 -0000
@@ -11,7 +11,9 @@
 
 #include <linux/videodev.h>
 
-
+#ifndef V4L2_PIX_FMT_SBGGR8
+#define V4L2_PIX_FMT_SBGGR8  v4l2_fourcc('B','A','8','1') /*  8  BGBG.. GRGR.. */
+#endif
 class PVideoInputV4l2Device: public PVideoInputDevice
 {
 
Index: src/ptlib/common/vconvert.cxx
===================================================================
RCS file: /cvsroot/openh323/pwlib/src/ptlib/common/vconvert.cxx,v
retrieving revision 1.36
diff -u -r1.36 vconvert.cxx
--- src/ptlib/common/vconvert.cxx	21 Sep 2004 13:01:08 -0000	1.36
+++ src/ptlib/common/vconvert.cxx	23 Oct 2004 11:56:11 -0000
@@ -189,6 +189,14 @@
       unsigned w, unsigned h
     ) : PColourConverter(srcFmt, dstFmt, w, h) { }
 
+    BOOL SBGGR8toYUV420P(
+      const BYTE * srgb,
+      BYTE * rgb,
+      PINDEX * bytesReturned,
+      unsigned rgbIncrement,
+      BOOL flipVertical,
+      BOOL flipBR
+    ) const;
     BOOL SBGGR8toRGB(
       const BYTE * srgb,
       BYTE * rgb,
@@ -889,6 +897,20 @@
 
 #define LIMIT(x) (unsigned char) (((x > 0xffffff) ? 0xff0000 : ((x <= 0xffff) ? 0 : x & 0xff0000)) >> 16)
 
+BOOL PStandardColourConverter::SBGGR8toYUV420P(const BYTE * src,
+                                            BYTE * dst,
+                                            PINDEX * bytesReturned,
+                                            unsigned rgbIncrement,
+					    BOOL     flipVertical,
+                                            BOOL     flipBR) const
+{
+	BYTE * tempDest=(BYTE*)malloc(3*srcFrameWidth*srcFrameHeight);
+	SBGGR8toRGB(src, tempDest, bytesReturned, 3, FALSE , FALSE);
+        BOOL r = RGBtoYUV420P(tempDest, dst, bytesReturned, 3, flipVertical, flipBR);
+	free(tempDest);
+	return r;
+}
+
 BOOL PStandardColourConverter::SBGGR8toRGB(const BYTE * src,
                                             BYTE * dst,
                                             PINDEX * bytesReturned,
@@ -1071,7 +1093,12 @@
 
 PSTANDARD_COLOUR_CONVERTER(SBGGR8,RGB24)
 {
-  return SBGGR8toRGB(srcFrameBuffer, dstFrameBuffer, bytesReturned, 3, !doVFlip, FALSE);
+  return SBGGR8toRGB(srcFrameBuffer, dstFrameBuffer, bytesReturned, 3, doVFlip, TRUE);
+}
+
+PSTANDARD_COLOUR_CONVERTER(SBGGR8,YUV420P)
+{
+  return SBGGR8toYUV420P(srcFrameBuffer, dstFrameBuffer, bytesReturned, 3, doVFlip, TRUE);
 }
 
 PSTANDARD_COLOUR_CONVERTER(YUV420P,RGB24)
Index: src/ptlib/common/videoio.cxx
===================================================================
RCS file: /cvsroot/openh323/pwlib/src/ptlib/common/videoio.cxx,v
retrieving revision 1.49
diff -u -r1.49 videoio.cxx
--- src/ptlib/common/videoio.cxx	16 Aug 2004 06:40:59 -0000	1.49
+++ src/ptlib/common/videoio.cxx	23 Oct 2004 11:56:13 -0000
@@ -451,7 +451,8 @@
   { "Grey",     8 },
   { "GreyF",    8 },
   { "UYVY422", 16 },
-  { "UYV444",  24 }
+  { "UYV444",  24 },
+  { "SBGGR8",   8 }
 };
 
 

Attachment: pgpgxS2xNQL8v.pgp
Description: PGP signature



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]