repair default keyframe load, tweak init default histogram threshold
[goodguy/history.git] / cinelerra-5.1 / cinelerra / devicev4l2base.C
index 31a009b38fb9ea3b6c40303957dc646acfb4b6f6..9e3fd129ac023ff88c2792009b0798abfc01be59 100644 (file)
@@ -2,24 +2,25 @@
 /*
  * CINELERRA
  * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
- * 
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- * 
+ *
  */
 
 
+#ifdef HAVE_VIDEO4LINUX2
 
 #include "bctimer.h"
 #include "channel.h"
@@ -41,9 +42,7 @@
 #include <errno.h>
 #include <fcntl.h>
 
-#ifdef HAVE_VIDEO4LINUX2
 #include <linux/videodev2.h>
-#endif
 #include <sys/ioctl.h>
 #include <sys/mman.h>
 
@@ -127,6 +126,8 @@ DeviceV4L2Base::DeviceV4L2Base()
        qbfrs_lock = new Mutex("DeviceV4L2Base::qbfrs_lock");
        video_lock = new Condition(0, "DeviceV4L2Base::video_lock", 1);
        dev_fd = -1;
+       iwidth = 0;
+       iheight = 0;
        color_model = -1;
        device_buffers = 0;
        device_channel = 0;
@@ -222,7 +223,7 @@ int DeviceV4L2Base::get_sources()
                struct v4l2_input arg;
                memset(&arg, 0, sizeof(arg));
                arg.index = i;
-                       
+
                if(ioctl(vfd, VIDIOC_ENUMINPUT, &arg) < 0) break;
                Channel *channel = video_device->new_input_source((char*)arg.name);
                channel->device_index = i;
@@ -293,7 +294,7 @@ int DeviceV4L2Base::v4l2_open(int color_model)
 // if( (cap.capabilities & V4L2_CAP_READWRITE)     ) printf("READWRITE ");
 // if( (cap.capabilities & V4L2_CAP_ASYNCIO)       ) printf("ASYNCIO ");
 // if( (cap.capabilities & V4L2_CAP_STREAMING)     ) printf("STREAMING ");
-// printf("\n"); 
+// printf("\n");
 
        int config_width = video_device->in_config->w;
        int config_height = video_device->in_config->h;
@@ -303,7 +304,7 @@ int DeviceV4L2Base::v4l2_open(int color_model)
        unsigned int best_format = 0;
        int best_merit = 0;
        int best_color_model = -1;
-       int best_area = 1;
+       int best_area = INT_MAX;
        int driver = video_device->in_config->driver;
 
        for( int i=0; i<20; ++i ) {
@@ -320,15 +321,16 @@ int DeviceV4L2Base::v4l2_open(int color_model)
                int cmodel = -1;
                switch(fmt.pixelformat)
                {
-               case V4L2_PIX_FMT_UYVY:    cmodel = BC_UVY422;  merit = 4;  break;
                case V4L2_PIX_FMT_YUYV:    cmodel = BC_YUV422;  merit = 4;  break;
+               case V4L2_PIX_FMT_UYVY:    cmodel = BC_UVY422;  merit = 4;  break;
                case V4L2_PIX_FMT_Y41P:    cmodel = BC_YUV411P; merit = 1;  break;
                case V4L2_PIX_FMT_YVU420:  cmodel = BC_YUV420P; merit = 3;  break;
                case V4L2_PIX_FMT_YUV422P: cmodel = BC_YUV422P; merit = 4;  break;
                case V4L2_PIX_FMT_RGB24:   cmodel = BC_RGB888;  merit = 6;  break;
                case V4L2_PIX_FMT_MJPEG:
                        cmodel = BC_COMPRESSED;
-                       merit = driver == VIDEO4LINUX2JPEG ? 7 : 0;
+                       merit = driver == VIDEO4LINUX2JPEG ||
+                               driver == CAPTURE_JPEG_WEBCAM ? 7 : 0;
                        break;
                case V4L2_PIX_FMT_MPEG:
                        cmodel = BC_YUV420P;
@@ -353,12 +355,9 @@ int DeviceV4L2Base::v4l2_open(int color_model)
                        printf("%dx%d",w,h);
                        int area = w * h;
                        if( area > config_area ) continue;
-                       int diff0 = area - best_area;
-                       if( diff0 < 0 ) diff0 = -diff0;
-                       int diff1 = area - config_area;
-                       if( diff1 < 0 ) diff1 = -diff1;
-                       if( diff1 < diff0 ) {
-                               best_area = area;
+                       int diff = abs(area-config_area);
+                       if( diff < best_area ) {
+                               best_area = diff;
                                best_width = w;
                                best_height = h;
                        }
@@ -382,24 +381,28 @@ int DeviceV4L2Base::v4l2_open(int color_model)
                        best_format = cmodel_to_device(color_model);
                        break;
                }
-               printf(_("DeviceV4L2Base::v4l2_open "
-                       " attempting format %4.4s\n"), (char *)&best_format);
+               printf("DeviceV4L2Base::v4l2_open ");
+               printf(_(" attempting format %4.4s\n"),
+                       (char *)&best_format);
        }
        if(driver == VIDEO4LINUX2JPEG && best_format != V4L2_PIX_FMT_MJPEG)
        {
-               printf(_("DeviceV4L2Base::v4l2_open jpeg driver"
-                       " and best_format not mjpeg (%4.4s)\n"), (char *)&best_format);
+               printf("DeviceV4L2Base::v4l2_open ");
+               printf(_("jpeg driver and best_format not mjpeg (%4.4s)\n"),
+                       (char *)&best_format);
                return 1;
        }
        if(driver == VIDEO4LINUX2MPEG && best_format != V4L2_PIX_FMT_MPEG)
        {
-               printf(_("DeviceV4L2Base::v4l2_open mpeg driver"
-                       " and best_format not mpeg (%4.4s)\n"),(char *)&best_format);
+               printf("DeviceV4L2Base::v4l2_open ");
+               printf(_("mpeg driver and best_format not mpeg (%4.4s)\n"),
+                       (char *)&best_format);
                return 1;
        }
        if(config_width != best_width || config_height != best_height)
        {
-               printf(_("DeviceV4L2Base::v4l2_open  config geom %dx%d != %dx%d best_geom\n"),
+               printf("DeviceV4L2Base::v4l2_open ");
+               printf(_("config geom %dx%d != %dx%d best_geom\n"),
                        config_width, config_height, best_width, best_height);
        }
 
@@ -413,8 +416,8 @@ int DeviceV4L2Base::v4l2_open(int color_model)
        {
                v4l2_parm.parm.capture.capturemode |= V4L2_CAP_TIMEPERFRAME;
                v4l2_parm.parm.capture.timeperframe.numerator = 1;
-               v4l2_parm.parm.capture.timeperframe.denominator = 
-                       (unsigned long)((float)1 / 
+               v4l2_parm.parm.capture.timeperframe.denominator =
+                       (unsigned long)((float)1 /
                        video_device->frame_rate * 10000000);
                if(vioctl(VIDIOC_S_PARM, &v4l2_parm) < 0)
                        perror("DeviceV4L2Base::v4l2_open VIDIOC_S_PARM");
@@ -423,6 +426,7 @@ int DeviceV4L2Base::v4l2_open(int color_model)
                        perror("DeviceV4L2Base::v4l2_open VIDIOC_G_PARM");
        }
 
+       printf("v4l2 s_fmt %dx%d %4.4s\n", best_width, best_height, (char*)&best_format);
 // Set up data format
        struct v4l2_format v4l2_params;
        memset(&v4l2_params, 0, sizeof(v4l2_params));
@@ -444,12 +448,12 @@ int DeviceV4L2Base::v4l2_open(int color_model)
                         (char*)&v4l2_params.fmt.pix.pixelformat, (char*)&best_format);
                return 1;
        }
-       if( (int)v4l2_params.fmt.pix.width != best_width ||
-           (int)v4l2_params.fmt.pix.height != best_height )
+       iwidth = v4l2_params.fmt.pix.width;
+       iheight = v4l2_params.fmt.pix.height;
+       if( iwidth != best_width || iheight != best_height )
        {
                printf("DeviceV4L2Base::v4l2_open  set geom %dx%d != %dx%d best_geom\n",
-                       v4l2_params.fmt.pix.width, v4l2_params.fmt.pix.height,
-                       best_width, best_height);
+                       iwidth, iheight, best_width, best_height);
                return 1;
        }
 
@@ -791,8 +795,6 @@ int DeviceV4L2Base::start_dev()
        memset(device_buffers, 0, bfr_count*sizeof(device_buffers[0]));
 
 //printf("DeviceV4L2Base::start_dev color_model=%d\n", color_model);
-       int iwidth = video_device->in_config->w;
-       int iheight = video_device->in_config->h;
        int y_offset = 0, line_size = -1;
        int u_offset = 0, v_offset = 0;
 
@@ -949,3 +951,4 @@ void DeviceV4L2Base::run()
        }
 }
 
+#endif