Skip to content

V4L2 Camera Abstraction Layer #40

@RobertPendergrast

Description

@RobertPendergrast

Overview

We want to have a hardware-agnostic abstraction layer over Linux's Video4Linux2 Api. This will wrap all of the V4L2's ioctl calls and provide memory-mapped buffer management for storing images into a single class for our camera fprime components to build upon.

Objective

  • Define a C++ class to wrap the full V4L2 capture pipeline.
  • Support pre-allocated buffer management for image storage.
  • Provide a minimal API for our camera F Prime Components to call.

Essentially, we want to define an abstraction layer for V4L2. Our camera components will use this layer (by instantiating this class on init) to interact with their respective cameras. This is necessary since we have 2 types of cameras (MIPI CSI and Parallel CSI) and we don't want to rewrite code unecessarily.

Note. Do not use any F Prime dependencies in this class.

TODO

  • Define the V4L2Camera class interface in V4L2Camera.hpp
  • Implement device open/close (open(), close(), isOpen())
  • Wrap capability query — verify device supports capture & streaming ([VIDIOC_QUERYCAP](https://www.kernel.org/doc/html/v4.9/media/uapi/v4l/vidioc-querycap.html))
  • Wrap format negotiation — set and get pixel format & resolution ([VIDIOC_S_FMT](https://www.kernel.org/doc/html/v4.9/media/uapi/v4l/vidioc-g-fmt.html), [VIDIOC_G_FMT](https://www.kernel.org/doc/html/v4.9/media/uapi/v4l/vidioc-g-fmt.html))
  • Wrap buffer allocation — request kernel MMAP buffers and mmap() them into userspace ([VIDIOC_REQBUFS](https://www.kernel.org/doc/html/v4.9/media/uapi/v4l/vidioc-reqbufs.html), [VIDIOC_QUERYBUF](https://www.kernel.org/doc/html/v4.9/media/uapi/v4l/vidioc-querybuf.html))
  • Wrap stream start/stop ([VIDIOC_STREAMON](https://www.kernel.org/doc/html/v4.9/media/uapi/v4l/vidioc-streamon.html), [VIDIOC_STREAMOFF](https://www.kernel.org/doc/html/v4.9/media/uapi/v4l/vidioc-streamon.html))
  • Wrap frame queue/dequeue ([VIDIOC_QBUF](https://www.kernel.org/doc/html/v4.12/media/uapi/v4l/vidioc-qbuf.html), [VIDIOC_DQBUF](https://www.kernel.org/doc/html/v4.12/media/uapi/v4l/vidioc-qbuf.html))
  • Implement circular buffer (see options in How to Start) with a requeueBuffer() or releaseFrame() call
  • Write v4l2camera_tester.cpp with a test case per API call for

How to start

  • If unfamiliar with Linux or ioctl calls, take a look at this resource. At a high level, we use ioctl to read and write to kernel drivers. V4L2 exposes these ioctl calls through its API.
  • Read up on the V4L2 API, get an understanding of how it works.
  • Then, write the HAL for each of the ioctl calls listed in the TODO section.
  • Implement the circular buffering. There's a couple of ways you can do this:
  1. You can use a single ring buffer of sufficient size and keep track of pointers to the start of each picture in the ring buffer
  2. Keep a small ring buffer (size <= 5) of pointers image buffers. Keep the image buffers a constant size equal to the max size of an image. Then write the received image to the least recently used buffer.
  • I recommend going with option 2. It's cleaner.
  • Provide a way to delete things from this buffer too.

Testing

  • We can test this on flatsat! Write a v4l2camera_tester.cpp that individually tests each api call.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions