cap_v4l.cpp.trisk.patch

Trisk patch with improvements on v4l capture on opensolaris (cap_v4l.cpp) - Filipe Almeida, 2010-06-02 10:43 am

Download (22.3 kB)

 
trisk/cap_v4l.cpp 2010-06-02 09:38:57.335969021 +0100
154 154
- USE_TEMP_BUFFER fixes the main problem (improper buffer management) and
155 155
  prevents bad images in the first place
156 156

  
157
11th patch: May 9th, 2010, Trisk (ticket #336 - improvements on v4l capture)
158
* Made V4L1 optional
159
* Fixed V4L2 cvInitImageHeader w/h parameters
160
* Fixed V4L2 mmap buffer use to remove memcpy workaround
161
* Fixed V4L2 buffer selection when converting
162
* Added support for OpenSolaris? V4L2
163
* Added support for reading without polling
164
* Added support for V4L2_CAP_READWRITE 
157 165

  
158 166
make & enjoy!
159 167

  
......
202 210

  
203 211
#include "precomp.hpp"
204 212

  
205
#if !defined WIN32 && defined HAVE_CAMV4L
213
#if !defined WIN32 && (defined HAVE_CAMV4L || defined HAVE_CAMV4L2)
206 214

  
207 215
#define CLEAR(x) memset (&(x), 0, sizeof (x))
208 216

  
......
214 222
#include <sys/types.h>
215 223
#include <sys/mman.h>
216 224

  
225
#ifdef HAVE_CAMV4L
217 226
#include <linux/videodev.h>
227
#endif
218 228

  
219 229
#include <string.h>
220 230
#include <stdlib.h>
221
#include <asm/types.h>          /* for videodev2.h */
222 231
#include <assert.h>
223 232
#include <sys/stat.h>
224 233
#include <sys/ioctl.h>
225 234

  
226 235
#ifdef HAVE_CAMV4L2
236
#if defined __linux || defined __linux__
237
#include <asm/types.h>
227 238
#include <linux/videodev2.h>
239
#else
240
#include <sys/ioccom.h>
241
#include <sys/videodev2.h>
242
#endif
228 243
#endif
229 244

  
230 245
/* Defaults - If your board can do better, set it here.  Set for the most common type inputs. */
......
255 270
  size_t  length;
256 271
};
257 272

  
258
static unsigned int n_buffers = 0;
259

  
260 273
/* Additional V4L2 pixelformats support for Sonix SN9C10x base webcams */
261 274
#ifndef V4L2_PIX_FMT_SBGGR8
262 275
#define V4L2_PIX_FMT_SBGGR8  v4l2_fourcc('B','A','8','1') /* 8 BGBG.. GRGR.. */
......
286 299
    int deviceHandle;
287 300
    int bufferIndex;
288 301
    int FirstCapture;
302
    bool devicePollable;
303

  
304
#ifdef HAVE_CAMV4L
305

  
289 306
    struct video_capability capability;
290 307
    struct video_window     captureWindow;
291 308
    struct video_picture    imageProperties;
292 309
    struct video_mbuf       memoryBuffer;
293 310
    struct video_mmap       *mmaps;
294 311
    char *memoryMap;
312
#endif /* HAVE_CAMV4L */
313

  
295 314
    IplImage frame;
296 315

  
297 316
#ifdef HAVE_CAMV4L2
298 317

  
299 318
   /* V4L2 variables */
300 319
   buffer buffers[MAX_V4L_BUFFERS + 1];
320
   unsigned int n_buffers;
301 321
   struct v4l2_capability cap;
302 322
   struct v4l2_input inp;
303 323
   struct v4l2_format form;
......
391 411

  
392 412
}; /* End icvInitCapture_V4L */
393 413

  
414
#ifdef HAVE_CAMV4L
394 415
static int
395 416
try_palette(int fd,
396 417
            struct video_picture *cam_pic,
......
407 428
    return 1;
408 429
  return 0;
409 430
}
431
#endif /* HAVE_CAMV4L */
410 432

  
411 433
#ifdef HAVE_CAMV4L2
412 434

  
......
431 453
}
432 454

  
433 455
#endif /* HAVE_CAMV4L2 */
456
#ifdef HAVE_CAMV4L
434 457

  
435
static int try_init_v4l(CvCaptureCAM_V4L* capture, char *deviceName)
458
static int try_init_v4l(CvCaptureCAM_V4L* capture, const char *deviceName)
436 459
{
437 460

  
438 461
  // if detect = -1 then unable to open device
......
474 497

  
475 498
}
476 499

  
500
#endif /* HAVE_CAMV4L */
477 501
#ifdef HAVE_CAMV4L2
478 502

  
479
static int try_init_v4l2(CvCaptureCAM_V4L* capture, char *deviceName)
503
static int try_init_v4l2(CvCaptureCAM_V4L* capture, const char *deviceName)
480 504
{
481 505

  
482 506
  // if detect = -1 then unable to open device
......
491 515
  capture->deviceHandle = open (deviceName, O_RDWR /* required */ | O_NONBLOCK, 0);
492 516

  
493 517

  
494

  
495 518
  if (capture->deviceHandle == 0)
496 519
  {
497 520
    detect = -1;
......
510 533
    }
511 534
      else
512 535
    {
536

  
537
#ifdef HAVE_CAMV4L
513 538
      CLEAR (capture->capability);
514 539
      capture->capability.type = capture->cap.capabilities;
515 540

  
......
518 543
      {
519 544
        detect = 1;
520 545
      }
546
#else
547
      detect = 1;
548
#endif /* HAVE_CAMV4L */
549

  
521 550
    }
522 551
  }
523 552

  
......
544 573
  else
545 574

  
546 575
#ifdef HAVE_JPEG
547
#ifdef __USE_GNU
548
      /* support for MJPEG is only available with libjpeg and gcc,
549
	 because it's use libjepg and fmemopen()
550
      */
551 576
  if (try_palette_v4l2(capture, V4L2_PIX_FMT_MJPEG) == 0 ||
552 577
      try_palette_v4l2(capture, V4L2_PIX_FMT_JPEG) == 0)
553 578
  {
......
555 580
  }
556 581
  else
557 582
#endif
558
#endif
559 583

  
560 584
  if (try_palette_v4l2(capture, V4L2_PIX_FMT_YUYV) == 0)
561 585
  {
......
590 614
}
591 615

  
592 616
#endif /* HAVE_CAMV4L2 */
617
#ifdef HAVE_CAMV4L
593 618

  
594 619
static int autosetup_capture_mode_v4l(CvCaptureCAM_V4L* capture)
595 620
{
......
624 649

  
625 650
}
626 651

  
652
#endif /* HAVE_CAMV4L */
627 653
#ifdef HAVE_CAMV4L2
628 654

  
629 655
static void v4l2_scan_controls_enumerate_menu(CvCaptureCAM_V4L* capture)
......
648 674
static void v4l2_scan_controls(CvCaptureCAM_V4L* capture)
649 675
{
650 676

  
651
  __u32 ctrl_id;
677
  unsigned int ctrl_id;
652 678

  
653 679
  for (ctrl_id = V4L2_CID_BASE;
654 680
       ctrl_id < V4L2_CID_LASTP1;
......
794 820

  
795 821
}
796 822

  
797
static int _capture_V4L2 (CvCaptureCAM_V4L *capture, char *deviceName)
823
static int init_read_v4l2 (CvCaptureCAM_V4L *capture)
824
{
825
   unsigned int size = capture->form.fmt.pix.sizeimage;
826

  
827
   capture->buffers[0].start = malloc( size );
828
   if (!capture->buffers[0].start) {
829
       perror ("malloc");
830
       return -1;
831
   }
832
   capture->buffers[0].length = size;
833

  
834
   capture->buffers[MAX_V4L_BUFFERS].start = malloc( size );
835
   if (!capture->buffers[MAX_V4L_BUFFERS].start) {
836
       perror ("malloc");
837
       return -1;
838
   }
839
   capture->buffers[MAX_V4L_BUFFERS].length = size;
840

  
841
   capture->n_buffers = 0;
842

  
843
   return 0;
844
}
845

  
846
static int init_mmap_v4l2 (CvCaptureCAM_V4L *capture, const char *deviceName)
847
{
848
   unsigned int buffer_number = DEFAULT_V4L_BUFFERS;
849

  
850
   CLEAR (capture->req);
851

  
852
   try_again:
853

  
854
   capture->req.count = buffer_number;
855
   capture->req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
856
   capture->req.memory = V4L2_MEMORY_MMAP;
857

  
858
   if (-1 == xioctl (capture->deviceHandle, VIDIOC_REQBUFS, &capture->req))
859
   {
860
       if (EINVAL == errno)
861
       {
862
         fprintf (stderr, "%s does not support memory mapping\n", deviceName);
863
       } else {
864
         perror ("VIDIOC_REQBUFS");
865
       }
866
       return -1;
867
   }
868

  
869
   if (capture->req.count < buffer_number)
870
   {
871
       if (buffer_number == 1)
872
       {
873
           fprintf (stderr, "Insufficient buffer memory on %s\n", deviceName);
874

  
875
           return -1;
876
       } else {
877
         buffer_number--;
878
	 fprintf (stderr, "Insufficient buffer memory on %s -- decreaseing buffers\n", deviceName);
879

  
880
	 goto try_again;
881
       }
882
   }
883

  
884
   for (unsigned int n_buffers = 0; n_buffers < capture->req.count; ++n_buffers)
885
   {
886
       struct v4l2_buffer buf;
887

  
888
       CLEAR (buf);
889

  
890
       buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
891
       buf.memory = V4L2_MEMORY_MMAP;
892
       buf.index = n_buffers;
893

  
894
       if (-1 == xioctl (capture->deviceHandle, VIDIOC_QUERYBUF, &buf)) {
895
           perror ("VIDIOC_QUERYBUF");
896
           return -1;
897
       }
898

  
899
       capture->buffers[n_buffers].length = buf.length;
900
       capture->buffers[n_buffers].start =
901
         mmap (NULL /* start anywhere */,
902
               buf.length,
903
               PROT_READ | PROT_WRITE /* required */,
904
               MAP_SHARED /* recommended */,
905
               capture->deviceHandle, buf.m.offset);
906

  
907
       if (MAP_FAILED == capture->buffers[n_buffers].start) {
908
           perror ("mmap");
909
           return -1;
910
       }
911
   }
912

  
913
   unsigned int size = capture->form.fmt.pix.sizeimage;
914

  
915
   capture->buffers[MAX_V4L_BUFFERS].start = malloc( size );
916
   if (!capture->buffers[MAX_V4L_BUFFERS].start) {
917
       perror ("malloc");
918
       return -1;
919
   }
920
   capture->buffers[MAX_V4L_BUFFERS].length = size;
921

  
922
   capture->n_buffers = capture->req.count;
923

  
924
   return 0;
925
}
926

  
927
static int _capture_V4L2 (CvCaptureCAM_V4L *capture, const char *deviceName)
798 928
{
799 929
   int detect_v4l2 = 0;
800 930

  
......
870 1000
       return -1;
871 1001
   }
872 1002

  
873
   if (V4L2_SUPPORT == 0)
874
   {
875
   }
876

  
877 1003
   if (autosetup_capture_mode_v4l2(capture) == -1)
878 1004
       return -1;
879 1005

  
......
892 1018
   if (capture->form.fmt.pix.sizeimage < min)
893 1019
       capture->form.fmt.pix.sizeimage = min;
894 1020

  
895
   CLEAR (capture->req);
896

  
897
   unsigned int buffer_number = DEFAULT_V4L_BUFFERS;
898

  
899
   try_again:
900

  
901
   capture->req.count = buffer_number;
902
   capture->req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
903
   capture->req.memory = V4L2_MEMORY_MMAP;
904

  
905
   if (-1 == xioctl (capture->deviceHandle, VIDIOC_REQBUFS, &capture->req))
906
   {
907
       if (EINVAL == errno)
908
       {
909
         fprintf (stderr, "%s does not support memory mapping\n", deviceName);
910
       } else {
911
         perror ("VIDIOC_REQBUFS");
912
       }
913
       /* free capture, and returns an error code */
914
       icvCloseCAM_V4L (capture);
915
       return -1;
916
   }
917

  
918
   if (capture->req.count < buffer_number)
919
   {
920
       if (buffer_number == 1)
921
       {
922
           fprintf (stderr, "Insufficient buffer memory on %s\n", deviceName);
923

  
924
           /* free capture, and returns an error code */
925
           icvCloseCAM_V4L (capture);
926
           return -1;
927
       } else {
928
         buffer_number--;
929
	 fprintf (stderr, "Insufficient buffer memory on %s -- decreaseing buffers\n", deviceName);
930

  
931
	 goto try_again;
932
       }
933
   }
934

  
935
   for (n_buffers = 0; n_buffers < capture->req.count; ++n_buffers)
936
   {
937
       struct v4l2_buffer buf;
938

  
939
       CLEAR (buf);
940

  
941
       buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
942
       buf.memory = V4L2_MEMORY_MMAP;
943
       buf.index = n_buffers;
944

  
945
       if (-1 == xioctl (capture->deviceHandle, VIDIOC_QUERYBUF, &buf)) {
946
           perror ("VIDIOC_QUERYBUF");
947

  
948
           /* free capture, and returns an error code */
949
           icvCloseCAM_V4L (capture);
1021
   if (capture->cap.capabilities & V4L2_CAP_STREAMING) {
1022
       if (-1 == init_mmap_v4l2(capture, deviceName)) {
1023
           icvCloseCAM_V4L(capture);
950 1024
           return -1;
951 1025
       }
952

  
953
       capture->buffers[n_buffers].length = buf.length;
954
       capture->buffers[n_buffers].start =
955
         mmap (NULL /* start anywhere */,
956
               buf.length,
957
               PROT_READ | PROT_WRITE /* required */,
958
               MAP_SHARED /* recommended */,
959
               capture->deviceHandle, buf.m.offset);
960

  
961
       if (MAP_FAILED == capture->buffers[n_buffers].start) {
962
           perror ("mmap");
963

  
964
           /* free capture, and returns an error code */
965
           icvCloseCAM_V4L (capture);
1026
   } else {
1027
       if (capture->cap.capabilities & V4L2_CAP_READWRITE) {
1028
           if (-1 == init_read_v4l2(capture)) {
1029
               icvCloseCAM_V4L(capture);
1030
               return -1;
1031
           }
1032
       } else {
1033
           fprintf( stderr, "HIGHGUI ERROR: V4L2: device %s does not support either memory mapped or read/write I/O.\n",deviceName);
1034
           icvCloseCAM_V4L(capture);
966 1035
           return -1;
967 1036
       }
968

  
969
       if (n_buffers == 0) {
970
	 capture->buffers[MAX_V4L_BUFFERS].start = malloc( buf.length );
971
	 capture->buffers[MAX_V4L_BUFFERS].length = buf.length;
972
       }
973 1037
   }
974 1038

  
975 1039
   /* Set up Image data */
976 1040
   cvInitImageHeader( &capture->frame,
977
                      cvSize( capture->captureWindow.width,
978
                              capture->captureWindow.height ),
1041
                      cvSize( capture->form.fmt.pix.width,
1042
                              capture->form.fmt.pix.height ),
979 1043
                      IPL_DEPTH_8U, 3, IPL_ORIGIN_TL, 4 );
980 1044
   /* Allocate space for RGBA data */
981 1045
   capture->frame.imageData = (char *)cvAlloc(capture->frame.imageSize);
......
984 1048
}; /* End _capture_V4L2 */
985 1049

  
986 1050
#endif /* HAVE_CAMV4L2 */
1051
#ifdef HAVE_CAMV4L
987 1052

  
988
static int _capture_V4L (CvCaptureCAM_V4L *capture, char *deviceName)
1053
static int _capture_V4L (CvCaptureCAM_V4L *capture, const char *deviceName)
989 1054
{
990 1055
   int detect_v4l = 0;
991 1056

  
......
1103 1168
   return 1;
1104 1169
}; /* End _capture_V4L */
1105 1170

  
1171
#endif /* HAVE_CAMV4L */
1172

  
1106 1173
static CvCaptureCAM_V4L * icvCaptureFromCAM_V4L (int index)
1107 1174
{
1108 1175
   static int autoindex;
......
1152 1219
       icvCloseCAM_V4L(capture);
1153 1220
       V4L2_SUPPORT = 0;
1154 1221
#endif  /* HAVE_CAMV4L2 */
1222
#ifdef HAVE_CAMV4L
1155 1223
       if (_capture_V4L (capture, deviceName) == -1) {
1156 1224
           icvCloseCAM_V4L(capture);
1157 1225
           return NULL;
1158 1226
       }
1227
#endif  /* HAVE_CAMV4L */
1159 1228
#ifdef HAVE_CAMV4L2
1160 1229
   } else {
1161 1230
       V4L2_SUPPORT = 1;
......
1168 1237
#ifdef HAVE_CAMV4L2
1169 1238

  
1170 1239
static int read_frame_v4l2(CvCaptureCAM_V4L* capture) {
1240
    if (-1 == read(capture->deviceHandle,
1241
                   capture->buffers[0].start,
1242
                   capture->buffers[0].length)) {
1243
        switch (errno) {
1244
        case EAGAIN:
1245
            return 0;
1246

  
1247
        case EIO:
1248
        default:
1249
            /* display the error and stop processing */
1250
            perror ("read");
1251
            return 1;
1252
        }
1253
    }
1254
    capture->bufferIndex = 0;
1255

  
1256
    return 1;
1257
}
1258

  
1259
static int mmap_read_frame_v4l2(CvCaptureCAM_V4L* capture) {
1171 1260
    struct v4l2_buffer buf;
1172 1261

  
1173 1262
    CLEAR (buf);
......
1197 1286
        }
1198 1287
   }
1199 1288

  
1200
   assert(buf.index < capture->req.count);
1289
   assert(buf.index < capture->n_buffers);
1201 1290

  
1202
   memcpy(capture->buffers[MAX_V4L_BUFFERS].start,
1203
	  capture->buffers[buf.index].start,
1204
	  capture->buffers[MAX_V4L_BUFFERS].length );
1205
   capture->bufferIndex = MAX_V4L_BUFFERS;
1291
   capture->bufferIndex = buf.index;
1206 1292
   //printf("got data in buff %d, len=%d, flags=0x%X, seq=%d, used=%d)\n",
1207 1293
   //	  buf.index, buf.length, buf.flags, buf.sequence, buf.bytesused);
1208 1294

  
1209
   if (-1 == xioctl (capture->deviceHandle, VIDIOC_QBUF, &buf))
1210
       perror ("VIDIOC_QBUF");
1211

  
1212 1295
   return 1;
1213 1296
}
1214 1297

  
......
1218 1301
    count = 1;
1219 1302

  
1220 1303
    while (count-- > 0) {
1221
        for (;;) {
1304
        for (; capture->devicePollable == true;) {
1222 1305
            fd_set fds;
1223 1306
            struct timeval tv;
1224 1307
            int r;
......
1233 1316
            r = select (capture->deviceHandle+1, &fds, NULL, NULL, &tv);
1234 1317

  
1235 1318
            if (-1 == r) {
1236
                if (EINTR == errno)
1319
                if (EINTR == errno || EAGAIN == errno)
1237 1320
                    continue;
1238

  
1239
                perror ("select");
1321
                if (ENXIO == errno)
1322
		    capture->devicePollable = false;
1323
		else
1324
                    perror ("select");
1240 1325
            }
1241 1326

  
1242 1327
            if (0 == r) {
......
1245 1330
                /* end the infinite loop */
1246 1331
                break;
1247 1332
            }
1333
        }
1248 1334

  
1335
        if (capture->n_buffers != 0) {
1336
            if (mmap_read_frame_v4l2 (capture))
1337
                break;
1338
        } else {
1249 1339
            if (read_frame_v4l2 (capture))
1250 1340
                break;
1251 1341
        }
......
1267 1357
      if (V4L2_SUPPORT == 1)
1268 1358
      {
1269 1359

  
1270
        for (capture->bufferIndex = 0;
1271
             capture->bufferIndex < ((int)capture->req.count);
1272
             ++capture->bufferIndex)
1360
        for (unsigned int n_buffers = 0; n_buffers < capture->n_buffers; ++n_buffers)
1273 1361
        {
1274 1362

  
1275 1363
          struct v4l2_buffer buf;
......
1278 1366

  
1279 1367
          buf.type        = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1280 1368
          buf.memory      = V4L2_MEMORY_MMAP;
1281
          buf.index       = (unsigned long)capture->bufferIndex;
1369
          buf.index       = (unsigned long)n_buffers;
1282 1370

  
1283 1371
          if (-1 == xioctl (capture->deviceHandle, VIDIOC_QBUF, &buf)) {
1284
              perror ("VIDIOC_QBUF");
1372
              perror ("VIDIOC_QBUF1373");
1285 1373
              return 0;
1286 1374
          }
1287 1375
        }
1288 1376

  
1289
        /* enable the streaming */
1290
        capture->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1291
        if (-1 == xioctl (capture->deviceHandle, VIDIOC_STREAMON,
1292
                          &capture->type)) {
1293
            /* error enabling the stream */
1294
            perror ("VIDIOC_STREAMON");
1295
            return 0;
1296
        }
1377
        if (capture->n_buffers != 0) {
1378
            /* enable the streaming */
1379
            capture->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1380
            if (-1 == xioctl (capture->deviceHandle, VIDIOC_STREAMON,
1381
                              &capture->type)) {
1382
                /* error enabling the stream */
1383
                perror ("VIDIOC_STREAMON");
1384
                return 0;
1385
            }
1386
	}
1297 1387
      } else
1298 1388
#endif /* HAVE_CAMV4L2 */
1299 1389
      {
1390
#ifdef HAVE_CAMV4L
1300 1391

  
1301 1392
        for (capture->bufferIndex = 0;
1302 1393
         capture->bufferIndex < (capture->memoryBuffer.frames-1);
......
1313 1404
          }
1314 1405
        }
1315 1406

  
1407
#else
1408
        return 0;
1409
#endif /* HAVE_CAMV4L */
1316 1410
      }
1317 1411

  
1318
#if defined(V4L_ABORT_BADJPEG) && defined(HAVE_CAMV4L2)
1412
#if defined V4L_ABORT_BADJPEG && defined HAVE_CAMV4L2
1319 1413
     if (V4L2_SUPPORT == 1)
1320 1414
     {
1321 1415
        // skip first frame. it is often bad -- this is unnotied in traditional apps,
......
1338 1432
   } else
1339 1433
#endif /* HAVE_CAMV4L2 */
1340 1434
   {
1435
#ifdef HAVE_CAMV4L
1341 1436

  
1342 1437
     capture->mmaps[capture->bufferIndex].frame  = capture->bufferIndex;
1343 1438
     capture->mmaps[capture->bufferIndex].width  = capture->captureWindow.width;
......
1355 1450
        capture->bufferIndex = 0;
1356 1451
     }
1357 1452

  
1453
#endif /* HAVE_CAMV4L */
1358 1454
   }
1359 1455

  
1360 1456
   return(1);
......
2006 2102
  unsigned char *addr;
2007 2103

  
2008 2104
  if (!init_done) {
2009
    /* do sonix_decompress_init first! */
2010
    return -1;
2105
    sonix_decompress_init();
2011 2106
  }
2012 2107

  
2013 2108
  bitpos = 0;
......
2074 2169
  if (V4L2_SUPPORT == 0)
2075 2170
#endif /* HAVE_CAMV4L2 */
2076 2171
  {
2172
#ifdef HAVE_CAMV4L
2077 2173

  
2078 2174
    /* [FD] this really belongs here */
2079 2175
    if (ioctl(capture->deviceHandle, VIDIOCSYNC, &capture->mmaps[capture->bufferIndex].frame) == -1) {
2080 2176
      fprintf( stderr, "HIGHGUI ERROR: V4L: Could not SYNC to video stream. %s\n", strerror(errno));
2081 2177
    }
2082 2178

  
2179
#else
2180
    return 0;
2181
#endif /* HAVE_CAMV4L */
2083 2182
  }
2084 2183

  
2085 2184
   /* Now get what has already been captured as a IplImage return */
......
2104 2203
  } else
2105 2204
#endif /* HAVE_CAMV4L2 */
2106 2205
  {
2206
#ifdef HAVE_CAMV4L
2107 2207

  
2108 2208
    if((capture->frame.width != capture->mmaps[capture->bufferIndex].width)
2109 2209
      || (capture->frame.height != capture->mmaps[capture->bufferIndex].height)) {
......
2115 2215
       capture->frame.imageData = (char *)cvAlloc(capture->frame.imageSize);
2116 2216
    }
2117 2217

  
2218
#endif /* HAVE_CAMV4L */
2118 2219
  }
2119 2220

  
2120 2221
#ifdef HAVE_CAMV4L2
......
2140 2241
                       (unsigned char*)capture->frame.imageData);
2141 2242

  
2142 2243
#ifdef HAVE_JPEG
2143
#ifdef __USE_GNU
2144
    /* support for MJPEG is only available with libjpeg and gcc,
2145
       because it's use libjepg and fmemopen()
2146
    */
2147 2244
    if (PALETTE_MJPEG == 1)
2148 2245
      if (!mjpeg_to_rgb24(capture->form.fmt.pix.width,
2149 2246
			  capture->form.fmt.pix.height,
......
2153 2250
			  (unsigned char*)capture->frame.imageData))
2154 2251
	return 0;
2155 2252
#endif
2156
#endif
2157 2253

  
2158 2254
    if (PALETTE_YUYV == 1)
2159 2255
	yuyv_to_rgb24(capture->form.fmt.pix.width,
......
2177 2273

  
2178 2274
    if (PALETTE_SN9C10X == 1)
2179 2275
    {
2180
      sonix_decompress_init();
2181

  
2182 2276
      sonix_decompress(capture->form.fmt.pix.width,
2183 2277
                       capture->form.fmt.pix.height,
2184 2278
                       (unsigned char*)capture->buffers[capture->bufferIndex].start,
2185
                       (unsigned char*)capture->buffers[(capture->bufferIndex+1) % capture->req.count].start);
2279
                       (unsigned char*)capture->buffers[MAX_V4L_BUFFERS].start);
2186 2280

  
2187 2281
      bayer2rgb24(capture->form.fmt.pix.width,
2188 2282
                  capture->form.fmt.pix.height,
2189
                  (unsigned char*)capture->buffers[(capture->bufferIndex+1) % capture->req.count].start,
2283
                  (unsigned char*)capture->buffers[MAX_V4L_BUFFERS].start,
2190 2284
                  (unsigned char*)capture->frame.imageData);
2191 2285
    }
2192 2286

  
......
2194 2288
    {
2195 2289
       sgbrg2rgb24(capture->form.fmt.pix.width,
2196 2290
                  capture->form.fmt.pix.height,
2197
                  (unsigned char*)capture->buffers[(capture->bufferIndex+1) % capture->req.count].start,
2291
                  (unsigned char*)capture->buffers[capture->bufferIndex].start,
2198 2292
                  (unsigned char*)capture->frame.imageData);
2199 2293
    }
2200 2294

  
2201 2295
  } else
2202 2296
#endif /* HAVE_CAMV4L2 */
2203 2297
  {
2298
#ifdef HAVE_CAMV4L
2204 2299

  
2205 2300
    switch(capture->imageProperties.palette) {
2206 2301
      case VIDEO_PALETTE_RGB24:
......
2234 2329
        return 0;
2235 2330
    }
2236 2331

  
2332
#endif /* HAVE_CAMV4L */
2333
  }
2334

  
2335
#ifdef HAVE_CAMV4L2
2336
  if (capture->n_buffers != 0) {
2337
      struct v4l2_buffer buf;
2338

  
2339
      CLEAR (buf);
2340

  
2341
      buf.type        = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2342
      buf.memory      = V4L2_MEMORY_MMAP;
2343
      buf.index       = (unsigned long)capture->bufferIndex;
2344

  
2345
      if (-1 == xioctl (capture->deviceHandle, VIDIOC_QBUF, &buf))
2346
	      perror ("VIDIOC_QBUF2347");
2237 2347
  }
2348
#endif /* HAVE_CAMV4L2 */
2238 2349

  
2239 2350
   return(&capture->frame);
2240 2351
}
......
2358 2469
  } else
2359 2470
#endif /* HAVE_CAMV4L2 */
2360 2471
  {
2472
#ifdef HAVE_CAMV4L
2361 2473

  
2362 2474
    int retval = -1;
2363 2475

  
......
2413 2525
    /* all was OK, so convert to 0.0 - 1.0 range, and return the value */
2414 2526
    return float (retval) / 0xFFFF;
2415 2527

  
2528
#else
2529
    return -1;
2530
#endif /* HAVE_CAMV4L */
2416 2531
  }
2417 2532

  
2418 2533
};
......
2482 2597
  } else
2483 2598
#endif /* HAVE_CAMV4L2 */
2484 2599
  {
2600
#ifdef HAVE_CAMV4L
2485 2601

  
2486 2602
    if (capture==0) return 0;
2487 2603
     if (w>capture->capability.maxwidth) {
......
2506 2622

  
2507 2623
     capture->FirstCapture = 1;
2508 2624

  
2625
#endif /* HAVE_CAMV4L */
2509 2626
  }
2510 2627

  
2511 2628
  return 0;
......
2641 2758
  } else
2642 2759
#endif /* HAVE_CAMV4L2 */
2643 2760
  {
2761
#ifdef HAVE_CAMV4L
2644 2762

  
2645 2763
    int v4l_value;
2646 2764

  
......
2683 2801
       icvCloseCAM_V4L(capture);
2684 2802
       return -1;
2685 2803
    }
2804
#else
2805
    return -1;
2806
#endif /* HAVE_CAMV4L */
2686 2807
  }
2687 2808

  
2688 2809
  /* all was OK */
......
2745 2866
     if (V4L2_SUPPORT == 0)
2746 2867
#endif /* HAVE_CAMV4L2 */
2747 2868
     {
2869
#ifdef HAVE_CAMV4L
2748 2870

  
2749 2871
       if (capture->mmaps)
2750 2872
         free(capture->mmaps);
2751 2873
       if (capture->memoryMap)
2752 2874
         munmap(capture->memoryMap, capture->memoryBuffer.size);
2753 2875

  
2876
#endif /* HAVE_CAMV4L */
2754 2877
     }
2755 2878
#ifdef HAVE_CAMV4L2
2756 2879
     else {
2757 2880
       capture->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2758
       if (ioctl(capture->deviceHandle, VIDIOC_STREAMOFF, &capture->type) < 0) {
2759
           perror ("Unable to stop the stream.");
2881
       if (capture->n_buffers != 0) {
2882
           if (ioctl(capture->deviceHandle, VIDIOC_STREAMOFF, &capture->type) < 0) {
2883
               perror ("Unable to stop the stream.");
2884
           }
2760 2885
       }
2761 2886

  
2762
       for (unsigned int n_buffers = 0; n_buffers < capture->req.count; ++n_buffers)
2887
       if (capture->buffers[MAX_V4L_BUFFERS].start != NULL)
2763 2888
       {
2764
           if (-1 == munmap (capture->buffers[n_buffers].start, capture->buffers[n_buffers].length)) {
2889
    	   free(capture->buffers[MAX_V4L_BUFFERS].start);
2890
    	   capture->buffers[MAX_V4L_BUFFERS].start = NULL;
2891
       }
2892

  
2893
       for (unsigned int n_buffers = 0; n_buffers < capture->n_buffers; ++n_buffers)
2894
       {
2895
           if (-1 == munmap ((char *)capture->buffers[n_buffers].start, capture->buffers[n_buffers].length)) {
2765 2896
               perror ("munmap");
2766 2897
           }
2767 2898
       }
2768 2899

  
2769
       if (capture->buffers[MAX_V4L_BUFFERS].start)
2900
       if (capture->n_buffers == 0)
2770 2901
       {
2771
    	   free(capture->buffers[MAX_V4L_BUFFERS].start);
2772
    	   capture->buffers[MAX_V4L_BUFFERS].start = 0;
2902
    	   free(capture->buffers[0].start);
2903
    	   capture->buffers[0].start = NULL;
2773 2904
       }
2774 2905
     }
2775 2906
#endif /* HAVE_CAMV4L2 */
......
2848 2979
    return 0;
2849 2980
}
2850 2981

  
2851
#endif
2982
#endif /* !WIN32 && (HAVE_CAMV4L || HAVE_CAMV4L2) */