1/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/*
18 * Contains code that is used to capture video frames from a camera device
19 * on Linux. This code uses V4L2 API to work with camera devices, and requires
20 * Linux kernel version at least 2.5
21 */
22
23#include <sys/mman.h>
24#include <sys/stat.h>
25#include <sys/ioctl.h>
26#include "android/camera/camera-capture.h"
27#include "android/camera/camera-format-converters.h"
28
29#define  E(...)    derror(__VA_ARGS__)
30#define  W(...)    dwarning(__VA_ARGS__)
31#define  D(...)    VERBOSE_PRINT(camera,__VA_ARGS__)
32#define  D_ACTIVE  VERBOSE_CHECK(camera)
33
34/* the T(...) macro is used to dump traffic */
35#define  T_ACTIVE   0
36
37#if T_ACTIVE
38#define  T(...)    VERBOSE_PRINT(camera,__VA_ARGS__)
39#else
40#define  T(...)    ((void)0)
41#endif
42
43#define CLEAR(x) memset (&(x), 0, sizeof(x))
44
45/* Pixel format descriptor.
46 * Instances of this descriptor are created during camera device enumeration, and
47 * an instance of this structure describing pixel format chosen for the camera
48 * emulation is saved by the camera factory service to represent an emulating
49 * camera properties.
50 */
51typedef struct QemuPixelFormat {
52    /* Pixel format in V4L2_PIX_FMT_XXX form. */
53    uint32_t        format;
54    /* Frame dimensions supported by this format. */
55    CameraFrameDim* dims;
56    /* Number of frame dimensions supported by this format. */
57    int             dim_num;
58} QemuPixelFormat;
59
60/* Describes a framebuffer. */
61typedef struct CameraFrameBuffer {
62    /* Framebuffer data. */
63    uint8_t*    data;
64    /* Framebuffer data size. */
65    size_t      size;
66} CameraFrameBuffer;
67
68/* Defines type of the I/O used to obtain frames from the device. */
69typedef enum CameraIoType {
70    /* Framebuffers are shared via memory mapping. */
71    CAMERA_IO_MEMMAP,
72    /* Framebuffers are available via user pointers. */
73    CAMERA_IO_USERPTR,
74    /* Framebuffers are to be read from the device. */
75    CAMERA_IO_DIRECT
76} CameraIoType;
77
78typedef struct LinuxCameraDevice LinuxCameraDevice;
79/*
80 * Describes a connection to an actual camera device.
81 */
82struct LinuxCameraDevice {
83    /* Common header. */
84    CameraDevice                header;
85
86    /* Camera device name. (default is /dev/video0) */
87    char*                       device_name;
88    /* Input channel. (default is 0) */
89    int                         input_channel;
90
91    /*
92     * Set by the framework after initializing camera connection.
93     */
94
95    /* Handle to the opened camera device. */
96    int                         handle;
97    /* Device capabilities. */
98    struct v4l2_capability      caps;
99    /* Actual pixel format reported by the device when capturing is started. */
100    struct v4l2_pix_format      actual_pixel_format;
101    /* Defines type of the I/O to use to retrieve frames from the device. */
102    CameraIoType                io_type;
103    /* Allocated framebuffers. */
104    struct CameraFrameBuffer*   framebuffers;
105    /* Actual number of allocated framebuffers. */
106    int                         framebuffer_num;
107};
108
109/* Preferred pixel formats arranged from the most to the least desired.
110 *
111 * More than anything else this array is defined by an existance of format
112 * conversion between the camera supported formats, and formats that are
113 * supported by camera framework in the guest system. Currently, guest supports
114 * only YV12 pixel format for data, and RGB32 for preview. So, this array should
115 * contain only those formats, for which converters are implemented. Generally
116 * speaking, the order in which entries should be arranged in this array matters
117 * only as far as conversion speed is concerned. So, formats with the fastest
118 * converters should be put closer to the top of the array, while slower ones
119 * should be put closer to the bottom. But as far as functionality is concerned,
120 * the orser doesn't matter, and any format can be placed anywhere in this array,
121 * as long as conversion for it exists.
122 */
123static const uint32_t _preferred_formats[] =
124{
125    /* Native format for the emulated camera: no conversion at all. */
126    V4L2_PIX_FMT_YUV420,
127    V4L2_PIX_FMT_YVU420,
128    /* Continue with YCbCr: less math than with RGB */
129    V4L2_PIX_FMT_NV12,
130    V4L2_PIX_FMT_NV21,
131    V4L2_PIX_FMT_YUYV,
132    /* End with RGB. */
133    V4L2_PIX_FMT_RGB32,
134    V4L2_PIX_FMT_RGB24,
135    V4L2_PIX_FMT_RGB565,
136};
137/* Number of entries in _preferred_formats array. */
138static const int _preferred_format_num =
139    sizeof(_preferred_formats)/sizeof(*_preferred_formats);
140
141/*******************************************************************************
142 *                     Helper routines
143 ******************************************************************************/
144
145/* IOCTL wrapper. */
146static int
147_xioctl(int fd, int request, void *arg) {
148  int r;
149  do {
150      r = ioctl(fd, request, arg);
151  } while (-1 == r && EINTR == errno);
152  return r;
153}
154
155/* Frees resource allocated for QemuPixelFormat instance, excluding the instance
156 * itself.
157 */
158static void _qemu_pixel_format_free(QemuPixelFormat* fmt)
159{
160    if (fmt != NULL) {
161        if (fmt->dims != NULL)
162            free(fmt->dims);
163    }
164}
165
166/* Returns an index of the given pixel format in an array containing pixel
167 * format descriptors.
168 * This routine is used to choose a pixel format for a camera device. The idea
169 * is that when the camera service enumerates all pixel formats for all cameras
170 * connected to the host, we need to choose just one, which would be most
171 * appropriate for camera emulation. To do that, the camera service will run
172 * formats, contained in _preferred_formats array against enumerated pixel
173 * formats to pick the first format that match.
174 * Param:
175 *  fmt - Pixel format, for which to obtain the index.
176 *  formats - Array containing list of pixel formats, supported by the camera
177 *      device.
178 *  size - Number of elements in the 'formats' array.
179 * Return:
180 *  Index of the matched entry in the array, or -1 if no entry has been found.
181 */
182static int
183_get_format_index(uint32_t fmt, QemuPixelFormat* formats, int size)
184{
185    int f;
186    for (f = 0; f < size && formats[f].format != fmt; f++);
187    return f < size ? f : -1;
188}
189
190/*******************************************************************************
191 *                     CameraFrameBuffer routines
192 ******************************************************************************/
193
194/* Frees array of framebuffers, depending on the I/O method the array has been
195 * initialized for.
196 * Note that this routine doesn't frees the array itself.
197 * Param:
198 *  fb, num - Array data, and its size.
199 *  io_type - Type of the I/O the array has been initialized for.
200 */
201static void
202_free_framebuffers(CameraFrameBuffer* fb, int num, CameraIoType io_type)
203{
204    if (fb != NULL) {
205        int n;
206
207        switch (io_type) {
208            case CAMERA_IO_MEMMAP:
209                /* Unmap framebuffers. */
210                for (n = 0; n < num; n++) {
211                    if (fb[n].data != NULL) {
212                        munmap(fb[n].data, fb[n].size);
213                        fb[n].data = NULL;
214                        fb[n].size = 0;
215                    }
216                }
217                break;
218
219            case CAMERA_IO_USERPTR:
220            case CAMERA_IO_DIRECT:
221                /* Free framebuffers. */
222                for (n = 0; n < num; n++) {
223                    if (fb[n].data != NULL) {
224                        free(fb[n].data);
225                        fb[n].data = NULL;
226                        fb[n].size = 0;
227                    }
228                }
229                break;
230
231            default:
232                E("%s: Invalid I/O type %d", __FUNCTION__, io_type);
233                break;
234        }
235    }
236}
237
238/*******************************************************************************
239 *                     CameraDevice routines
240 ******************************************************************************/
241
242/* Allocates an instance of LinuxCameraDevice structure.
243 * Return:
244 *  Allocated instance of LinuxCameraDevice structure. Note that this routine
245 *  also sets 'opaque' field in the 'header' structure to point back to the
246 *  containing LinuxCameraDevice instance.
247 */
248static LinuxCameraDevice*
249_camera_device_alloc(void)
250{
251    LinuxCameraDevice* cd;
252
253    ANEW0(cd);
254    memset(cd, 0, sizeof(*cd));
255    cd->header.opaque = cd;
256    cd->handle = -1;
257
258    return cd;
259}
260
261/* Uninitializes and frees CameraDevice structure.
262 */
263static void
264_camera_device_free(LinuxCameraDevice* lcd)
265{
266    if (lcd != NULL) {
267        /* Closing handle will also disconnect from the driver. */
268        if (lcd->handle >= 0) {
269            close(lcd->handle);
270        }
271        if (lcd->device_name != NULL) {
272            free(lcd->device_name);
273        }
274        if (lcd->framebuffers != NULL) {
275            _free_framebuffers(lcd->framebuffers, lcd->framebuffer_num,
276                               lcd->io_type);
277            free(lcd->framebuffers);
278        }
279        AFREE(lcd);
280    } else {
281        E("%s: No descriptor", __FUNCTION__);
282    }
283}
284
285/* Resets camera device after capturing.
286 * Since new capture request may require different frame dimensions we must
287 * reset camera device by reopening its handle. Otherwise attempts to set up new
288 * frame properties (different from the previous one) may fail. */
289static void
290_camera_device_reset(LinuxCameraDevice* cd)
291{
292    struct v4l2_cropcap cropcap;
293    struct v4l2_crop crop;
294
295    /* Free capturing framebuffers first. */
296    if (cd->framebuffers != NULL) {
297        _free_framebuffers(cd->framebuffers, cd->framebuffer_num, cd->io_type);
298        free(cd->framebuffers);
299        cd->framebuffers = NULL;
300        cd->framebuffer_num = 0;
301    }
302
303    /* Reset device handle. */
304    close(cd->handle);
305    cd->handle = open(cd->device_name, O_RDWR | O_NONBLOCK, 0);
306
307    if (cd->handle >= 0) {
308        /* Select video input, video standard and tune here. */
309        cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
310        _xioctl(cd->handle, VIDIOC_CROPCAP, &cropcap);
311        crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
312        crop.c = cropcap.defrect; /* reset to default */
313        _xioctl (cd->handle, VIDIOC_S_CROP, &crop);
314    }
315}
316
317/* Memory maps buffers and shares mapped memory with the device.
318 * Return:
319 *  0 Framebuffers have been mapped.
320 *  -1 A critical error has ocurred.
321 *  1 Memory mapping is not available.
322 */
323static int
324_camera_device_mmap_framebuffer(LinuxCameraDevice* cd)
325{
326    struct v4l2_requestbuffers req;
327    CLEAR(req);
328    req.count   = 4;
329    req.type    = V4L2_BUF_TYPE_VIDEO_CAPTURE;
330    req.memory  = V4L2_MEMORY_MMAP;
331
332    /* Request memory mapped buffers. Note that device can return less buffers
333     * than requested. */
334    if(_xioctl(cd->handle, VIDIOC_REQBUFS, &req)) {
335        if (EINVAL == errno) {
336            D("%s: Device '%s' does not support memory mapping",
337              __FUNCTION__, cd->device_name);
338            return 1;
339        } else {
340            E("%s: VIDIOC_REQBUFS has failed: %s",
341              __FUNCTION__, strerror(errno));
342            return -1;
343        }
344    }
345
346    /* Allocate framebuffer array. */
347    cd->framebuffers = calloc(req.count, sizeof(CameraFrameBuffer));
348    if (cd->framebuffers == NULL) {
349        E("%s: Not enough memory to allocate framebuffer array", __FUNCTION__);
350        return -1;
351    }
352
353    /* Map every framebuffer to the shared memory, and queue it
354     * with the device. */
355    for(cd->framebuffer_num = 0; cd->framebuffer_num < req.count;
356        cd->framebuffer_num++) {
357        /* Map framebuffer. */
358        struct v4l2_buffer buf;
359        CLEAR(buf);
360        buf.type    = V4L2_BUF_TYPE_VIDEO_CAPTURE;
361        buf.memory  = V4L2_MEMORY_MMAP;
362        buf.index   = cd->framebuffer_num;
363        if(_xioctl(cd->handle, VIDIOC_QUERYBUF, &buf) < 0) {
364            E("%s: VIDIOC_QUERYBUF has failed: %s",
365              __FUNCTION__, strerror(errno));
366            return -1;
367        }
368        cd->framebuffers[cd->framebuffer_num].size = buf.length;
369        cd->framebuffers[cd->framebuffer_num].data =
370            mmap(NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED,
371                 cd->handle, buf.m.offset);
372        if (MAP_FAILED == cd->framebuffers[cd->framebuffer_num].data) {
373            E("%s: Memory mapping has failed: %s",
374              __FUNCTION__, strerror(errno));
375            return -1;
376        }
377
378        /* Queue the mapped buffer. */
379        CLEAR(buf);
380        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
381        buf.memory = V4L2_MEMORY_MMAP;
382        buf.index = cd->framebuffer_num;
383        if (_xioctl(cd->handle, VIDIOC_QBUF, &buf) < 0) {
384            E("%s: VIDIOC_QBUF has failed: %s", __FUNCTION__, strerror(errno));
385            return -1;
386        }
387    }
388
389    cd->io_type = CAMERA_IO_MEMMAP;
390
391    return 0;
392}
393
394/* Allocates frame buffers and registers them with the device.
395 * Return:
396 *  0 Framebuffers have been mapped.
397 *  -1 A critical error has ocurred.
398 *  1 Device doesn't support user pointers.
399 */
400static int
401_camera_device_user_framebuffer(LinuxCameraDevice* cd)
402{
403    struct v4l2_requestbuffers req;
404    CLEAR (req);
405    req.count   = 4;
406    req.type    = V4L2_BUF_TYPE_VIDEO_CAPTURE;
407    req.memory  = V4L2_MEMORY_USERPTR;
408
409    /* Request user buffers. Note that device can return less buffers
410     * than requested. */
411    if(_xioctl(cd->handle, VIDIOC_REQBUFS, &req)) {
412        if (EINVAL == errno) {
413            D("%s: Device '%s' does not support user pointers",
414              __FUNCTION__, cd->device_name);
415            return 1;
416        } else {
417            E("%s: VIDIOC_REQBUFS has failed: %s",
418              __FUNCTION__, strerror(errno));
419            return -1;
420        }
421    }
422
423    /* Allocate framebuffer array. */
424    cd->framebuffers = calloc(req.count, sizeof(CameraFrameBuffer));
425    if (cd->framebuffers == NULL) {
426        E("%s: Not enough memory to allocate framebuffer array", __FUNCTION__);
427        return -1;
428    }
429
430    /* Allocate buffers, queueing them wit the device at the same time */
431    for(cd->framebuffer_num = 0; cd->framebuffer_num < req.count;
432        cd->framebuffer_num++) {
433        cd->framebuffers[cd->framebuffer_num].size =
434            cd->actual_pixel_format.sizeimage;
435        cd->framebuffers[cd->framebuffer_num].data =
436            malloc(cd->framebuffers[cd->framebuffer_num].size);
437        if (cd->framebuffers[cd->framebuffer_num].data == NULL) {
438            E("%s: Not enough memory to allocate framebuffer", __FUNCTION__);
439            return -1;
440        }
441
442        /* Queue the user buffer. */
443        struct v4l2_buffer buf;
444        CLEAR(buf);
445        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
446        buf.memory = V4L2_MEMORY_USERPTR;
447        buf.m.userptr = (unsigned long)cd->framebuffers[cd->framebuffer_num].data;
448        buf.length = cd->framebuffers[cd->framebuffer_num].size;
449        if (_xioctl(cd->handle, VIDIOC_QBUF, &buf) < 0) {
450            E("%s: VIDIOC_QBUF has failed: %s", __FUNCTION__, strerror(errno));
451            return -1;
452        }
453    }
454
455    cd->io_type = CAMERA_IO_USERPTR;
456
457    return 0;
458}
459
460/* Allocate frame buffer for direct read from the device.
461 * Return:
462 *  0 Framebuffers have been mapped.
463 *  -1 A critical error has ocurred.
464 *  1 Memory mapping is not available.
465 */
466static int
467_camera_device_direct_framebuffer(LinuxCameraDevice* cd)
468{
469    /* Allocate framebuffer array. */
470    cd->framebuffer_num = 1;
471    cd->framebuffers = malloc(sizeof(CameraFrameBuffer));
472    if (cd->framebuffers == NULL) {
473        E("%s: Not enough memory to allocate framebuffer array", __FUNCTION__);
474        return -1;
475    }
476
477    cd->framebuffers[0].size = cd->actual_pixel_format.sizeimage;
478    cd->framebuffers[0].data = malloc(cd->framebuffers[0].size);
479    if (cd->framebuffers[0].data == NULL) {
480        E("%s: Not enough memory to allocate framebuffer", __FUNCTION__);
481        return -1;
482    }
483
484    cd->io_type = CAMERA_IO_DIRECT;
485
486    return 0;
487}
488
489/* Opens camera device.
490 * Param:
491 *  cd - Camera device descriptor to open the camera for.
492 * Return:
493 *  0 on success, != 0 on failure.
494 */
495static int
496_camera_device_open(LinuxCameraDevice* cd)
497{
498    struct stat st;
499
500    if (stat(cd->device_name, &st)) {
501        return -1;
502    }
503
504    if (!S_ISCHR(st.st_mode)) {
505        E("%s: '%s' is not a device", __FUNCTION__, cd->device_name);
506        return -1;
507    }
508
509    /* Open handle to the device, and query device capabilities. */
510    cd->handle = open(cd->device_name, O_RDWR | O_NONBLOCK, 0);
511    if (cd->handle < 0) {
512        E("%s: Cannot open camera device '%s': %s",
513          __FUNCTION__, cd->device_name, strerror(errno));
514        return -1;
515    }
516    if (_xioctl(cd->handle, VIDIOC_QUERYCAP, &cd->caps) < 0) {
517        if (EINVAL == errno) {
518            E("%s: Camera '%s' is not a V4L2 device",
519              __FUNCTION__, cd->device_name);
520            close(cd->handle);
521            cd->handle = -1;
522            return -1;
523        } else {
524            E("%s: Unable to query capabilities for camera device '%s'",
525              __FUNCTION__, cd->device_name);
526            close(cd->handle);
527            cd->handle = -1;
528            return -1;
529        }
530    }
531
532    /* Make sure that camera supports minimal requirements. */
533    if (!(cd->caps.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
534        E("%s: Camera '%s' is not a video capture device",
535          __FUNCTION__, cd->device_name);
536        close(cd->handle);
537        cd->handle = -1;
538        return -1;
539    }
540
541    return 0;
542}
543
544/* Enumerates frame sizes for the given pixel format.
545 * Param:
546 *  cd - Opened camera device descriptor.
547 *  fmt - Pixel format to enum frame sizes for.
548 *  sizes - Upon success contains an array of supported frame sizes. The size of
549 *      the array is defined by the value, returned from this routine. The caller
550 *      is responsible for freeing memory allocated for this array.
551 * Return:
552 *  On success returns number of entries in the 'sizes' array. On failure returns
553 *  a negative value.
554 */
555static int
556_camera_device_enum_format_sizes(LinuxCameraDevice* cd,
557                                 uint32_t fmt,
558                                 CameraFrameDim** sizes)
559{
560    int n;
561    int sizes_num = 0;
562    int out_num = 0;
563    struct v4l2_frmsizeenum size_enum;
564    CameraFrameDim* arr;
565
566    /* Calculate number of supported sizes for the given format. */
567    for (n = 0; ; n++) {
568        size_enum.index = n;
569        size_enum.pixel_format = fmt;
570        if(_xioctl(cd->handle, VIDIOC_ENUM_FRAMESIZES, &size_enum)) {
571            break;
572        }
573        if (size_enum.type == V4L2_FRMSIZE_TYPE_DISCRETE) {
574            /* Size is in the simpe width, height form. */
575            sizes_num++;
576        } else if (size_enum.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
577            /* Sizes are represented as min/max width and height with a step for
578             * each dimension. Since at the end we want to list each supported
579             * size in the array (that's the only format supported by the guest
580             * camera framework), we need to calculate how many array entries
581             * this will generate. */
582            const uint32_t dif_widths =
583                (size_enum.stepwise.max_width - size_enum.stepwise.min_width) /
584                size_enum.stepwise.step_width + 1;
585            const uint32_t dif_heights =
586                (size_enum.stepwise.max_height - size_enum.stepwise.min_height) /
587                size_enum.stepwise.step_height + 1;
588            sizes_num += dif_widths * dif_heights;
589        } else if (size_enum.type == V4L2_FRMSIZE_TYPE_CONTINUOUS) {
590            /* Special stepwise case, when steps are set to 1. We still need to
591             * flatten this for the guest, but the array may be too big.
592             * Fortunately, we don't need to be fancy, so three sizes would be
593             * sufficient here: min, max, and one in the middle. */
594            sizes_num += 3;
595        }
596
597    }
598    if (sizes_num == 0) {
599        return 0;
600    }
601
602    /* Allocate, and initialize the array of supported entries. */
603    *sizes = (CameraFrameDim*)malloc(sizes_num * sizeof(CameraFrameDim));
604    if (*sizes == NULL) {
605        E("%s: Memory allocation failure", __FUNCTION__);
606        return -1;
607    }
608    arr = *sizes;
609    for (n = 0; out_num < sizes_num; n++) {
610        size_enum.index = n;
611        size_enum.pixel_format = fmt;
612        if(_xioctl(cd->handle, VIDIOC_ENUM_FRAMESIZES, &size_enum)) {
613            /* Errors are not welcome here anymore. */
614            E("%s: Unexpected failure while getting pixel dimensions: %s",
615              __FUNCTION__, strerror(errno));
616            free(arr);
617            return -1;
618        }
619
620        if (size_enum.type == V4L2_FRMSIZE_TYPE_DISCRETE) {
621            arr[out_num].width = size_enum.discrete.width;
622            arr[out_num].height = size_enum.discrete.height;
623            out_num++;
624        } else if (size_enum.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
625            uint32_t w;
626            for (w = size_enum.stepwise.min_width;
627                 w <= size_enum.stepwise.max_width;
628                 w += size_enum.stepwise.step_width) {
629                uint32_t h;
630                for (h = size_enum.stepwise.min_height;
631                     h <= size_enum.stepwise.max_height;
632                     h += size_enum.stepwise.step_height) {
633                    arr[out_num].width = w;
634                    arr[out_num].height = h;
635                    out_num++;
636                }
637            }
638        } else if (size_enum.type == V4L2_FRMSIZE_TYPE_CONTINUOUS) {
639            /* min */
640            arr[out_num].width = size_enum.stepwise.min_width;
641            arr[out_num].height = size_enum.stepwise.min_height;
642            out_num++;
643            /* one in the middle */
644            arr[out_num].width =
645                (size_enum.stepwise.min_width + size_enum.stepwise.max_width) / 2;
646            arr[out_num].height =
647                (size_enum.stepwise.min_height + size_enum.stepwise.max_height) / 2;
648            out_num++;
649            /* max */
650            arr[out_num].width = size_enum.stepwise.max_width;
651            arr[out_num].height = size_enum.stepwise.max_height;
652            out_num++;
653        }
654    }
655
656    return out_num;
657}
658
659/* Enumerates pixel formats, supported by the device.
660 * Note that this routine will enumerate only raw (uncompressed) formats.
661 * Param:
662 *  cd - Opened camera device descriptor.
663 *  fmts - Upon success contains an array of supported pixel formats. The size of
664 *      the array is defined by the value, returned from this routine. The caller
665 *      is responsible for freeing memory allocated for this array.
666 * Return:
667 *  On success returns number of entries in the 'fmts' array. On failure returns
668 *  a negative value.
669 */
670static int
671_camera_device_enum_pixel_formats(LinuxCameraDevice* cd, QemuPixelFormat** fmts)
672{
673    int n, max_fmt;
674    int fmt_num = 0;
675    int out_num = 0;
676    struct v4l2_fmtdesc fmt_enum;
677    QemuPixelFormat* arr;
678
679    /* Calculate number of supported formats. */
680    for (max_fmt = 0; ; max_fmt++) {
681        memset(&fmt_enum, 0, sizeof(fmt_enum));
682        fmt_enum.index = max_fmt;
683        fmt_enum.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
684        if(_xioctl(cd->handle, VIDIOC_ENUM_FMT, &fmt_enum)) {
685            break;
686        }
687        /* Skip the compressed ones. */
688        if ((fmt_enum.flags & V4L2_FMT_FLAG_COMPRESSED) == 0) {
689            fmt_num++;
690        }
691    }
692    if (fmt_num == 0) {
693        return 0;
694    }
695
696    /* Allocate, and initialize array for enumerated formats. */
697    *fmts = (QemuPixelFormat*)malloc(fmt_num * sizeof(QemuPixelFormat));
698    if (*fmts == NULL) {
699        E("%s: Memory allocation failure", __FUNCTION__);
700        return -1;
701    }
702    arr = *fmts;
703    memset(arr, 0, fmt_num * sizeof(QemuPixelFormat));
704    for (n = 0; n < max_fmt && out_num < fmt_num; n++) {
705        memset(&fmt_enum, 0, sizeof(fmt_enum));
706        fmt_enum.index = n;
707        fmt_enum.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
708        if(_xioctl(cd->handle, VIDIOC_ENUM_FMT, &fmt_enum)) {
709            int nn;
710            /* Errors are not welcome here anymore. */
711            E("%s: Unexpected failure while getting pixel format: %s",
712              __FUNCTION__, strerror(errno));
713            for (nn = 0; nn < out_num; nn++) {
714                _qemu_pixel_format_free(arr + nn);
715            }
716            free(arr);
717            return -1;
718        }
719        /* Skip the compressed ones. */
720        if ((fmt_enum.flags & V4L2_FMT_FLAG_COMPRESSED) == 0) {
721            arr[out_num].format = fmt_enum.pixelformat;
722            /* Enumerate frame dimensions supported for this format. */
723            arr[out_num].dim_num =
724                _camera_device_enum_format_sizes(cd, fmt_enum.pixelformat,
725                                                 &arr[out_num].dims);
726            if (arr[out_num].dim_num > 0) {
727                out_num++;
728            } else if (arr[out_num].dim_num < 0) {
729                int nn;
730                E("Unable to enumerate supported dimensions for pixel format %d",
731                  fmt_enum.pixelformat);
732                for (nn = 0; nn < out_num; nn++) {
733                    _qemu_pixel_format_free(arr + nn);
734                }
735                free(arr);
736                return -1;
737            }
738        }
739    }
740
741    return out_num;
742}
743
744/* Collects information about an opened camera device.
745 * The information collected in this routine contains list of pixel formats,
746 * supported by the device, and list of frame dimensions supported by the camera
747 * for each pixel format.
748 * Param:
749 *  cd - Opened camera device descriptor.
750 *  cis - Upon success contains information collected from the camera device.
751 * Return:
752 *  0 on success, != 0 on failure.
753 */
754static int
755_camera_device_get_info(LinuxCameraDevice* cd, CameraInfo* cis)
756{
757    int f;
758    int chosen = -1;
759    QemuPixelFormat* formats = NULL;
760    int num_pix_fmts = _camera_device_enum_pixel_formats(cd, &formats);
761    if (num_pix_fmts <= 0) {
762        return -1;
763    }
764
765    /* Lets see if camera supports preferred formats */
766    for (f = 0; f < _preferred_format_num; f++) {
767        chosen = _get_format_index(_preferred_formats[f], formats, num_pix_fmts);
768        if (chosen >= 0) {
769            break;
770        }
771    }
772    if (chosen < 0) {
773        /* Camera doesn't support any of the chosen formats. Then it doesn't
774         * matter which one we choose. Lets choose the first one. */
775        chosen = 0;
776    }
777
778    cis->device_name = ASTRDUP(cd->device_name);
779    cis->inp_channel = cd->input_channel;
780    cis->pixel_format = formats[chosen].format;
781    cis->frame_sizes_num = formats[chosen].dim_num;
782    /* Swap instead of copy. */
783    cis->frame_sizes = formats[chosen].dims;
784    formats[chosen].dims = NULL;
785    cis->in_use = 0;
786
787    for (f = 0; f < num_pix_fmts; f++) {
788        _qemu_pixel_format_free(formats + f);
789    }
790    free(formats);
791
792    return 0;
793}
794
795/*******************************************************************************
796 *                     CameraDevice API
797 ******************************************************************************/
798
799CameraDevice*
800camera_device_open(const char* name, int inp_channel)
801{
802    struct v4l2_cropcap cropcap;
803    struct v4l2_crop crop;
804    LinuxCameraDevice* cd;
805
806    /* Allocate and initialize the descriptor. */
807    cd = _camera_device_alloc();
808    cd->device_name = name != NULL ? ASTRDUP(name) : ASTRDUP("/dev/video0");
809    cd->input_channel = inp_channel;
810
811    /* Open the device. */
812    if (_camera_device_open(cd)) {
813        _camera_device_free(cd);
814        return NULL;
815    }
816
817    /* Select video input, video standard and tune here. */
818    cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
819    _xioctl(cd->handle, VIDIOC_CROPCAP, &cropcap);
820    crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
821    crop.c = cropcap.defrect; /* reset to default */
822    _xioctl (cd->handle, VIDIOC_S_CROP, &crop);
823
824    return &cd->header;
825}
826
827int
828camera_device_start_capturing(CameraDevice* ccd,
829                              uint32_t pixel_format,
830                              int frame_width,
831                              int frame_height)
832{
833    struct v4l2_format fmt;
834    LinuxCameraDevice* cd;
835    char fmt_str[5];
836    int r;
837
838    /* Sanity checks. */
839    if (ccd == NULL || ccd->opaque == NULL) {
840      E("%s: Invalid camera device descriptor", __FUNCTION__);
841      return -1;
842    }
843    cd = (LinuxCameraDevice*)ccd->opaque;
844    if (cd->handle < 0) {
845      E("%s: Camera device is not opened", __FUNCTION__);
846      return -1;
847    }
848
849    /* Try to set pixel format with the given dimensions. */
850    CLEAR(fmt);
851    fmt.type                = V4L2_BUF_TYPE_VIDEO_CAPTURE;
852    fmt.fmt.pix.width       = frame_width;
853    fmt.fmt.pix.height      = frame_height;
854    fmt.fmt.pix.pixelformat = pixel_format;
855    if (_xioctl(cd->handle, VIDIOC_S_FMT, &fmt) < 0) {
856        memcpy(fmt_str, &pixel_format, 4);
857        fmt_str[4] = '\0';
858        E("%s: Camera '%s' does not support pixel format '%s' with dimensions %dx%d",
859          __FUNCTION__, cd->device_name, fmt_str, frame_width, frame_height);
860        _camera_device_reset(cd);
861        return -1;
862    }
863    /* VIDIOC_S_FMT may has changed some properties of the structure. Make sure
864     * that dimensions didn't change. */
865    if (fmt.fmt.pix.width != frame_width || fmt.fmt.pix.height != frame_height) {
866        memcpy(fmt_str, &pixel_format, 4);
867        fmt_str[4] = '\0';
868        E("%s: Dimensions %dx%d are wrong for pixel format '%s'",
869          __FUNCTION__, frame_width, frame_height, fmt_str);
870        _camera_device_reset(cd);
871        return -1;
872    }
873    memcpy(&cd->actual_pixel_format, &fmt.fmt.pix, sizeof(struct v4l2_pix_format));
874
875    /*
876     * Lets initialize frame buffers, and see what kind of I/O we're going to
877     * use to retrieve frames.
878     */
879
880    /* First, lets see if we can do mapped I/O (as most performant one). */
881    r = _camera_device_mmap_framebuffer(cd);
882    if (r < 0) {
883        /* Some critical error has ocurred. Bail out. */
884        _camera_device_reset(cd);
885        return -1;
886    } else if (r > 0) {
887        /* Device doesn't support memory mapping. Retrieve to the next performant
888         * one: preallocated user buffers. */
889        r = _camera_device_user_framebuffer(cd);
890        if (r < 0) {
891            /* Some critical error has ocurred. Bail out. */
892            _camera_device_reset(cd);
893            return -1;
894        } else if (r > 0) {
895            /* The only thing left for us is direct reading from the device. */
896            if (!(cd->caps.capabilities & V4L2_CAP_READWRITE)) {
897                E("%s: Don't know how to access frames on device '%s'",
898                  __FUNCTION__, cd->device_name);
899                _camera_device_reset(cd);
900                return -1;
901            }
902            r = _camera_device_direct_framebuffer(cd);
903            if (r != 0) {
904                /* Any error at this point is a critical one. */
905                _camera_device_reset(cd);
906                return -1;
907            }
908        }
909    }
910
911    /* Start capturing from the device. */
912    if (cd->io_type != CAMERA_IO_DIRECT) {
913        enum v4l2_buf_type type;
914        type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
915        if (_xioctl (cd->handle, VIDIOC_STREAMON, &type) < 0) {
916            E("%s: VIDIOC_STREAMON on camera '%s' has failed: %s",
917              __FUNCTION__, cd->device_name, strerror(errno));
918            _camera_device_reset(cd);
919            return -1;
920        }
921    }
922    return 0;
923}
924
925int
926camera_device_stop_capturing(CameraDevice* ccd)
927{
928    enum v4l2_buf_type type;
929    LinuxCameraDevice* cd;
930
931    /* Sanity checks. */
932    if (ccd == NULL || ccd->opaque == NULL) {
933      E("%s: Invalid camera device descriptor", __FUNCTION__);
934      return -1;
935    }
936    cd = (LinuxCameraDevice*)ccd->opaque;
937    if (cd->handle < 0) {
938      E("%s: Camera device is not opened", __FUNCTION__);
939      return -1;
940    }
941
942    switch (cd->io_type) {
943        case CAMERA_IO_DIRECT:
944            /* Nothing to do. */
945            break;
946
947        case CAMERA_IO_MEMMAP:
948        case CAMERA_IO_USERPTR:
949            type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
950            if (_xioctl(cd->handle, VIDIOC_STREAMOFF, &type) < 0) {
951	            E("%s: VIDIOC_STREAMOFF on camera '%s' has failed: %s",
952                  __FUNCTION__, cd->device_name, strerror(errno));
953                return -1;
954            }
955            break;
956        default:
957            E("%s: Unknown I/O method: %d", __FUNCTION__, cd->io_type);
958            return -1;
959    }
960
961    /* Reopen the device to reset its internal state. It seems that if we don't
962     * do that, an attempt to reinit the device with different frame dimensions
963     * would fail. */
964    _camera_device_reset(cd);
965
966    return 0;
967}
968
969int
970camera_device_read_frame(CameraDevice* ccd,
971                         ClientFrameBuffer* framebuffers,
972                         int fbs_num,
973                         float r_scale,
974                         float g_scale,
975                         float b_scale,
976                         float exp_comp)
977{
978    LinuxCameraDevice* cd;
979
980    /* Sanity checks. */
981    if (ccd == NULL || ccd->opaque == NULL) {
982      E("%s: Invalid camera device descriptor", __FUNCTION__);
983      return -1;
984    }
985    cd = (LinuxCameraDevice*)ccd->opaque;
986    if (cd->handle < 0) {
987      E("%s: Camera device is not opened", __FUNCTION__);
988      return -1;
989    }
990
991    if (cd->io_type == CAMERA_IO_DIRECT) {
992        /* Read directly from the device. */
993        size_t total_read_bytes = 0;
994        /* There is one framebuffer allocated for direct read. */
995        void* buff = cd->framebuffers[0].data;
996        do {
997            int read_bytes =
998                read(cd->handle, buff + total_read_bytes,
999                     cd->actual_pixel_format.sizeimage - total_read_bytes);
1000            if (read_bytes < 0) {
1001                switch (errno) {
1002                    case EIO:
1003                    case EAGAIN:
1004                        continue;
1005                    default:
1006                        E("%s: Unable to read from the camera device '%s': %s",
1007                          __FUNCTION__, cd->device_name, strerror(errno));
1008                        return -1;
1009                }
1010            }
1011            total_read_bytes += read_bytes;
1012        } while (total_read_bytes < cd->actual_pixel_format.sizeimage);
1013        /* Convert the read frame into the caller's framebuffers. */
1014        return convert_frame(buff, cd->actual_pixel_format.pixelformat,
1015                             cd->actual_pixel_format.sizeimage,
1016                             cd->actual_pixel_format.width,
1017                             cd->actual_pixel_format.height,
1018                             framebuffers, fbs_num,
1019                             r_scale, g_scale, b_scale, exp_comp);
1020    } else {
1021        /* Dequeue next buffer from the device. */
1022        struct v4l2_buffer buf;
1023        int res;
1024        CLEAR(buf);
1025        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1026        buf.memory = cd->io_type == CAMERA_IO_MEMMAP ? V4L2_MEMORY_MMAP :
1027                                                       V4L2_MEMORY_USERPTR;
1028        for (;;) {
1029            const int res = _xioctl(cd->handle, VIDIOC_DQBUF, &buf);
1030            if (res >= 0) {
1031                break;
1032            } else if (errno == EAGAIN) {
1033                return 1;   // Tells the caller to repeat.
1034            } else if (errno != EINTR && errno != EIO) {
1035                E("%s: VIDIOC_DQBUF on camera '%s' has failed: %s",
1036                  __FUNCTION__, cd->device_name, strerror(errno));
1037                return -1;
1038            }
1039        }
1040
1041        /* Convert frame to the receiving buffers. */
1042        res = convert_frame(cd->framebuffers[buf.index].data,
1043                            cd->actual_pixel_format.pixelformat,
1044                            cd->actual_pixel_format.sizeimage,
1045                            cd->actual_pixel_format.width,
1046                            cd->actual_pixel_format.height,
1047                            framebuffers, fbs_num,
1048                            r_scale, g_scale, b_scale, exp_comp);
1049
1050        /* Requeue the buffer back to the device. */
1051        if (_xioctl(cd->handle, VIDIOC_QBUF, &buf) < 0) {
1052            W("%s: VIDIOC_QBUF on camera '%s' has failed: %s",
1053              __FUNCTION__, cd->device_name, strerror(errno));
1054        }
1055
1056        return res;
1057    }
1058}
1059
1060void
1061camera_device_close(CameraDevice* ccd)
1062{
1063    LinuxCameraDevice* cd;
1064
1065    /* Sanity checks. */
1066    if (ccd != NULL && ccd->opaque != NULL) {
1067        cd = (LinuxCameraDevice*)ccd->opaque;
1068        _camera_device_free(cd);
1069    } else {
1070        E("%s: Invalid camera device descriptor", __FUNCTION__);
1071    }
1072}
1073
1074int
1075enumerate_camera_devices(CameraInfo* cis, int max)
1076{
1077    char dev_name[24];
1078    int found = 0;
1079    int n;
1080
1081    for (n = 0; n < max; n++) {
1082        CameraDevice* cd;
1083
1084        sprintf(dev_name, "/dev/video%d", n);
1085        cd = camera_device_open(dev_name, 0);
1086        if (cd != NULL) {
1087            LinuxCameraDevice* lcd = (LinuxCameraDevice*)cd->opaque;
1088            if (!_camera_device_get_info(lcd, cis + found)) {
1089                char user_name[24];
1090                sprintf(user_name, "webcam%d", found);
1091                cis[found].display_name = ASTRDUP(user_name);
1092                cis[found].in_use = 0;
1093                found++;
1094            }
1095            camera_device_close(cd);
1096        } else {
1097            break;
1098        }
1099    }
1100
1101    return found;
1102}
1103