1// Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <Python.h>
6#include <fcntl.h>
7#include <linux/videodev2.h>
8#include <sys/ioctl.h>
9
10static int do_ioctl(int fd, int request, void* arg) {
11  int r;
12  do {
13    r = ioctl(fd, request, arg);
14  } while (-1 == r && EINTR == errno);
15  return r;
16}
17
18static void v4l2_enum_formats(const char *dev, int buf_type,
19                              PyObject *formats) {
20  int fd = open(dev, O_RDWR | O_NONBLOCK, 0);
21  if (fd == -1) return;
22
23  for (int i = 0; ; ++i) {
24    char pixel_format[4];
25    v4l2_fmtdesc format_desc;
26
27    memset(&format_desc, 0, sizeof(format_desc));
28    format_desc.type = (v4l2_buf_type) buf_type;
29    format_desc.index = i;
30    if (-1 == do_ioctl(fd, VIDIOC_ENUM_FMT, &format_desc)) {
31      break;
32    }
33    pixel_format[0] = format_desc.pixelformat & 0xFF;
34    pixel_format[1] = (format_desc.pixelformat >> 8) & 0xFF;
35    pixel_format[2] = (format_desc.pixelformat >> 16) & 0xFF;
36    pixel_format[3] = (format_desc.pixelformat >> 24) & 0xFF;
37    PyObject* item = PyString_FromStringAndSize(pixel_format, 4);
38    PyList_Append(formats, item);
39    Py_DECREF(item);
40  }
41  close(fd);
42}
43
44static PyObject *v4l2_enum_capture_formats(PyObject *self, PyObject *args) {
45  const char *dev;
46  if (!PyArg_ParseTuple(args, "s", &dev))
47    return NULL;
48  PyObject *formats = PyList_New(0);
49  v4l2_enum_formats(dev, V4L2_BUF_TYPE_VIDEO_CAPTURE, formats);
50  v4l2_enum_formats(dev, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, formats);
51  return formats;
52}
53
54static PyObject *v4l2_enum_output_formats(PyObject *self, PyObject *args) {
55  const char *dev;
56  if (!PyArg_ParseTuple(args, "s", &dev))
57    return NULL;
58  PyObject *formats = PyList_New(0);
59  v4l2_enum_formats(dev, V4L2_BUF_TYPE_VIDEO_OUTPUT, formats);
60  v4l2_enum_formats(dev, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, formats);
61  return formats;
62}
63
64/*
65 * Bind Python function names to our C functions
66 */
67static PyMethodDef v4l2_methods[] = {
68    {"enum_capture_formats", v4l2_enum_capture_formats, METH_VARARGS},
69    {"enum_output_formats", v4l2_enum_output_formats, METH_VARARGS},
70    {NULL, NULL}
71};
72
73/*
74 * Python calls this to let us initialize our module
75 */
76PyMODINIT_FUNC initv4l2() {
77  (void) Py_InitModule("v4l2", v4l2_methods);
78}
79