Apply maemo2 patch
[opencv] / otherlibs / highgui / cvcap_v4l.cpp
index 4199f45..e47f279 100644 (file)
@@ -219,8 +219,8 @@ make & enjoy!
 #endif
 
 /* Defaults - If your board can do better, set it here.  Set for the most common type inputs. */
-#define DEFAULT_V4L_WIDTH  640
-#define DEFAULT_V4L_HEIGHT 480
+#define DEFAULT_V4L_WIDTH  320
+#define DEFAULT_V4L_HEIGHT 240
 
 #define CHANNEL_NUMBER 1
 #define MAX_CAMERAS 8
@@ -261,7 +261,6 @@ int  PALETTE_BGR24 = 0,
 
 typedef struct CvCaptureCAM_V4L
 {
-    CvCaptureVTable* vtable;
     int deviceHandle;
     int bufferIndex;
     int FirstCapture;
@@ -321,16 +320,6 @@ static int icvSetVideoSize( CvCaptureCAM_V4L* capture, int w, int h);
 
 static int numCameras = 0;
 static int indexList = 0; 
-CvCaptureVTable captureCAM_V4L_vtable =
-{
-    6,
-    (CvCaptureCloseFunc)icvCloseCAM_V4L,
-    (CvCaptureGrabFrameFunc)icvGrabFrameCAM_V4L,
-    (CvCaptureRetrieveFrameFunc)icvRetrieveFrameCAM_V4L,
-    (CvCaptureGetPropertyFunc)icvGetPropertyCAM_V4L,
-    (CvCaptureSetPropertyFunc)icvSetPropertyCAM_V4L,
-    (CvCaptureGetDescriptionFunc)0
-};
 
 #ifdef HAVE_CAMV4L2
 
@@ -355,7 +344,7 @@ static int xioctl( int fd, int request, void *arg)
    If it fails on the first attempt of /dev/video0, then check if /dev/video is valid.
    Returns the global numCameras with the correct value (we hope) */
 
-void icvInitCapture_V4L() {
+static void icvInitCapture_V4L() {
    int deviceHandle;
    int CameraNumber;
    char deviceName[MAX_DEVICE_DRIVER_NAME];
@@ -379,7 +368,7 @@ void icvInitCapture_V4L() {
       
 }; /* End icvInitCapture_V4L */
 
-int
+static int
 try_palette(int fd,
             struct video_picture *cam_pic,
             int pal,
@@ -398,7 +387,7 @@ try_palette(int fd,
 
 #ifdef HAVE_CAMV4L2
 
-int try_palette_v4l2(CvCaptureCAM_V4L* capture, unsigned long colorspace)
+static int try_palette_v4l2(CvCaptureCAM_V4L* capture, unsigned long colorspace)
 {
   CLEAR (capture->form);
 
@@ -420,7 +409,7 @@ int try_palette_v4l2(CvCaptureCAM_V4L* capture, unsigned long colorspace)
 
 #endif /* HAVE_CAMV4L2 */
 
-int try_init_v4l(CvCaptureCAM_V4L* capture, char *deviceName)
+static int try_init_v4l(CvCaptureCAM_V4L* capture, char *deviceName)
 {
 
   // if detect = -1 then unable to open device
@@ -464,7 +453,7 @@ int try_init_v4l(CvCaptureCAM_V4L* capture, char *deviceName)
 
 #ifdef HAVE_CAMV4L2
 
-int try_init_v4l2(CvCaptureCAM_V4L* capture, char *deviceName)
+static int try_init_v4l2(CvCaptureCAM_V4L* capture, char *deviceName)
 {
 
   // if detect = -1 then unable to open device
@@ -513,7 +502,7 @@ int try_init_v4l2(CvCaptureCAM_V4L* capture, char *deviceName)
 
 }
 
-int autosetup_capture_mode_v4l2(CvCaptureCAM_V4L* capture)
+static int autosetup_capture_mode_v4l2(CvCaptureCAM_V4L* capture)
 {
   if (try_palette_v4l2(capture, V4L2_PIX_FMT_BGR24) == 0)
   {
@@ -587,7 +576,7 @@ int autosetup_capture_mode_v4l2(CvCaptureCAM_V4L* capture)
 
 #endif /* HAVE_CAMV4L2 */
 
-int autosetup_capture_mode_v4l(CvCaptureCAM_V4L* capture)
+static int autosetup_capture_mode_v4l(CvCaptureCAM_V4L* capture)
 {
 
   if(ioctl(capture->deviceHandle, VIDIOCGPICT, &capture->imageProperties) < 0) {
@@ -622,7 +611,7 @@ int autosetup_capture_mode_v4l(CvCaptureCAM_V4L* capture)
 
 #ifdef HAVE_CAMV4L2
 
-void v4l2_scan_controls_enumerate_menu(CvCaptureCAM_V4L* capture)
+static void v4l2_scan_controls_enumerate_menu(CvCaptureCAM_V4L* capture)
 {
 //  printf (" Menu items:\n");
   CLEAR (capture->querymenu);
@@ -641,7 +630,7 @@ void v4l2_scan_controls_enumerate_menu(CvCaptureCAM_V4L* capture)
   }
 }
 
-void v4l2_scan_controls(CvCaptureCAM_V4L* capture)
+static void v4l2_scan_controls(CvCaptureCAM_V4L* capture)
 {
 
   __u32 ctrl_id;
@@ -856,7 +845,8 @@ static int _capture_V4L2 (CvCaptureCAM_V4L *capture, char *deviceName)
    if (autosetup_capture_mode_v4l2(capture) == -1)
        return -1;
 
-   icvSetVideoSize(capture, DEFAULT_V4L_WIDTH, DEFAULT_V4L_HEIGHT);
+   /* default capture size is already set */
+//   icvSetVideoSize(capture, DEFAULT_V4L_WIDTH, DEFAULT_V4L_HEIGHT);
 
    unsigned int min;
 
@@ -872,10 +862,14 @@ static int _capture_V4L2 (CvCaptureCAM_V4L *capture, char *deviceName)
        capture->form.fmt.pix.sizeimage = min;
 
    CLEAR (capture->req);
+   
+   unsigned int buffer_number = 4;
 
-   capture->req.count               = 4;
-   capture->req.type                = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-   capture->req.memory              = V4L2_MEMORY_MMAP;
+   try_again:
+   
+   capture->req.count = buffer_number;
+   capture->req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+   capture->req.memory = V4L2_MEMORY_MMAP;
 
    if (-1 == xioctl (capture->deviceHandle, VIDIOC_REQBUFS, &capture->req))
    {
@@ -890,13 +884,20 @@ static int _capture_V4L2 (CvCaptureCAM_V4L *capture, char *deviceName)
        return -1;
    }
 
-   if (capture->req.count < 4)
+   if (capture->req.count < buffer_number)
    {
-       fprintf (stderr, "Insufficient buffer memory on %s\n", deviceName);
+       if (buffer_number == 1)
+       {
+           fprintf (stderr, "Insufficient buffer memory on %s\n", deviceName);
 
-       /* free capture, and returns an error code */
-       icvCloseCAM_V4L (capture);
-       return -1;
+           /* free capture, and returns an error code */
+           icvCloseCAM_V4L (capture);
+           return -1;
+       } else {
+         buffer_number--;
+        
+        goto try_again;
+       }
    }
 
    for (n_buffers = 0; n_buffers < capture->req.count; ++n_buffers)
@@ -1064,7 +1065,7 @@ static int _capture_V4L (CvCaptureCAM_V4L *capture, char *deviceName)
    return 1;
 }; /* End _capture_V4L */
 
-CvCapture * cvCaptureFromCAM_V4L (int index)
+static CvCaptureCAM_V4L * icvCaptureFromCAM_V4L (int index)
 {
    static int autoindex=0;
 
@@ -1106,7 +1107,6 @@ CvCapture * cvCaptureFromCAM_V4L (int index)
    memset(capture,0,sizeof(CvCaptureCAM_V4L));
    /* Present the routines needed for V4L funtionality.  They are inserted as part of
       the standard set of cv calls promoting transparency.  "Vector Table" insertion. */
-   capture->vtable = &captureCAM_V4L_vtable;
    capture->FirstCapture = 1;
    
 #ifdef HAVE_CAMV4L2
@@ -1124,7 +1124,7 @@ CvCapture * cvCaptureFromCAM_V4L (int index)
    }
 #endif  /* HAVE_CAMV4L2 */
 
-   return (CvCapture *)capture;
+   return capture;
 }; /* End icvOpenCAM_V4L */
 
 #ifdef HAVE_CAMV4L2
@@ -2024,7 +2024,7 @@ static IplImage* icvRetrieveFrameCAM_V4L( CvCaptureCAM_V4L* capture) {
   {
 
     /* [FD] this really belongs here */
-    if (ioctl(capture->deviceHandle, VIDIOCSYNC, &capture->mmaps[capture->bufferIndex]) == -1) {
+    if (ioctl(capture->deviceHandle, VIDIOCSYNC, &capture->mmaps[capture->bufferIndex].frame) == -1) {
       fprintf( stderr, "HIGHGUI ERROR: V4L: Could not SYNC to video stream. %s\n", strerror(errno));
     }
 
@@ -2032,7 +2032,7 @@ static IplImage* icvRetrieveFrameCAM_V4L( CvCaptureCAM_V4L* capture) {
 
    /* Now get what has already been captured as a IplImage return */
 
-   /* First, reallocate imageData if the frame sized changed */
+   /* First, reallocate imageData if the frame size changed */
 
 #ifdef HAVE_CAMV4L2
 
@@ -2394,9 +2394,9 @@ static int icvSetVideoSize( CvCaptureCAM_V4L* capture, int w, int h) {
     /* Get window info again, to get the real value */
     if (-1 == xioctl (capture->deviceHandle, VIDIOC_G_FMT, &capture->form))
     {
-      fprintf(stderr, "HIGHGUI ERROR: V4L/V4L2: Could not obtain specifics of capture window.\n\n");
+      fprintf(stderr, "HIGHGUI WARNING: V4L/V4L2: Could not obtain specifics of capture window.\n\n");
 
-      icvCloseCAM_V4L(capture);
+//      icvCloseCAM_V4L(capture);
 
       return 0;
     }
@@ -2681,4 +2681,70 @@ static void icvCloseCAM_V4L( CvCaptureCAM_V4L* capture ){
    }
 };
 
+
+class CvCaptureCAM_V4L_CPP : CvCapture
+{
+public:
+    CvCaptureCAM_V4L_CPP() { captureV4L = 0; }
+    virtual ~CvCaptureCAM_V4L_CPP() { close(); }
+
+    virtual bool open( int index );
+    virtual void close();
+
+    virtual double getProperty(int);
+    virtual bool setProperty(int, double);
+    virtual bool grabFrame();
+    virtual IplImage* retrieveFrame();
+protected:
+
+    CvCaptureCAM_V4L* captureV4L;
+};
+
+bool CvCaptureCAM_V4L_CPP::open( int index )
+{
+    close();
+    captureV4L = icvCaptureFromCAM_V4L(index);
+    return captureV4L != 0;
+}
+
+void CvCaptureCAM_V4L_CPP::close()
+{
+    if( captureV4L )
+    {
+        icvCloseCAM_V4L( captureV4L );
+        cvFree( &captureV4L );
+    }
+}
+
+bool CvCaptureCAM_V4L_CPP::grabFrame()
+{
+    return captureV4L ? icvGrabFrameCAM_V4L( captureV4L ) != 0 : false;
+}
+
+IplImage* CvCaptureCAM_V4L_CPP::retrieveFrame()
+{
+    return captureV4L ? icvRetrieveFrameCAM_V4L( captureV4L ) : 0;
+}
+
+double CvCaptureCAM_V4L_CPP::getProperty( int propId )
+{
+    return captureV4L ? icvGetPropertyCAM_V4L( captureV4L, propId ) : 0.0;
+}
+
+bool CvCaptureCAM_V4L_CPP::setProperty( int propId, double value )
+{
+    return captureV4L ? icvSetPropertyCAM_V4L( captureV4L, propId, value ) != 0 : false;
+}
+
+CvCapture* cvCreateCameraCapture_V4L( int index )
+{
+    CvCaptureCAM_V4L_CPP* capture = new CvCaptureCAM_V4L_CPP;
+
+    if( capture->open( index ))
+        return (CvCapture*)capture;
+
+    delete capture;
+    return 0;
+}
+
 #endif