普通文本  |  79行  |  2.3 KB

// Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <Python.h>
#include <fcntl.h>
#include <linux/videodev2.h>
#include <sys/ioctl.h>

static int do_ioctl(int fd, int request, void* arg) {
  int r;
  do {
    r = ioctl(fd, request, arg);
  } while (-1 == r && EINTR == errno);
  return r;
}

static void v4l2_enum_formats(const char *dev, int buf_type,
                              PyObject *formats) {
  int fd = open(dev, O_RDWR | O_NONBLOCK, 0);
  if (fd == -1) return;

  for (int i = 0; ; ++i) {
    char pixel_format[4];
    v4l2_fmtdesc format_desc;

    memset(&format_desc, 0, sizeof(format_desc));
    format_desc.type = (v4l2_buf_type) buf_type;
    format_desc.index = i;
    if (-1 == do_ioctl(fd, VIDIOC_ENUM_FMT, &format_desc)) {
      break;
    }
    pixel_format[0] = format_desc.pixelformat & 0xFF;
    pixel_format[1] = (format_desc.pixelformat >> 8) & 0xFF;
    pixel_format[2] = (format_desc.pixelformat >> 16) & 0xFF;
    pixel_format[3] = (format_desc.pixelformat >> 24) & 0xFF;
    PyObject* item = PyString_FromStringAndSize(pixel_format, 4);
    PyList_Append(formats, item);
    Py_DECREF(item);
  }
  close(fd);
}

static PyObject *v4l2_enum_capture_formats(PyObject *self, PyObject *args) {
  const char *dev;
  if (!PyArg_ParseTuple(args, "s", &dev))
    return NULL;
  PyObject *formats = PyList_New(0);
  v4l2_enum_formats(dev, V4L2_BUF_TYPE_VIDEO_CAPTURE, formats);
  v4l2_enum_formats(dev, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, formats);
  return formats;
}

static PyObject *v4l2_enum_output_formats(PyObject *self, PyObject *args) {
  const char *dev;
  if (!PyArg_ParseTuple(args, "s", &dev))
    return NULL;
  PyObject *formats = PyList_New(0);
  v4l2_enum_formats(dev, V4L2_BUF_TYPE_VIDEO_OUTPUT, formats);
  v4l2_enum_formats(dev, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, formats);
  return formats;
}

/*
 * Bind Python function names to our C functions
 */
static PyMethodDef v4l2_methods[] = {
    {"enum_capture_formats", v4l2_enum_capture_formats, METH_VARARGS},
    {"enum_output_formats", v4l2_enum_output_formats, METH_VARARGS},
    {NULL, NULL}
};

/*
 * Python calls this to let us initialize our module
 */
PyMODINIT_FUNC initv4l2() {
  (void) Py_InitModule("v4l2", v4l2_methods);
}