V4L2 Drivers for Camera interfacing - cu-ecen-aeld/buildroot-assignments-base GitHub Wiki

Introduction

Video4Linux2 (V4L2) drivers play a pivotal role in facilitating seamless camera integration within the Linux environment. These drivers, supporting a wide array of hardware such as USB webcams and TV tuners, empower developers to effortlessly implement video capture functionalities in their projects. Notably, V4L2 is prized for its independence, requiring no additional packages, and offers versatility in application, making it a valuable asset in camera interfacing in linux. If you intend to include this in the buildroot as part of the application package, you only require a glibc toolchain for compiling the code, and there are no additional dependencies. (-> make menuconfig(inside buildroot) > toolchain > C library > glibc).

Implementation Steps

In Prof Sam's starter code, there's a sequence of functions you need to know for setting up, capturing, and closing a camera using V4L2 drivers. I forked Sam's code and tweaked it for my project, so here's a rundown of what each function does and how they were crucial in making the camera work seamlessly in my application.

  1. Open Device : This function, open_device, does the initial setup to open the camera device. It checks if the specified device, usually "/dev/video0," exists and is of the right type. If everything checks out, it opens the device for reading and writing, allowing subsequent operations like capturing video frames. If there's any issue during this process, it prints an error message and exits the program, ensuring a smooth initialization of the camera.

  2. Init device : The init_device function sets up the camera device for video capture. It checks the capabilities of the device, ensuring it supports video capture and streaming. The function also configures specific parameters like exposure mode and time, selects the video input and standard, and sets the pixel format. Additionally, it initializes memory mapping for efficient data handling. This function essentially prepares the camera for smooth video capturing in a specified format and configuration. If any configuration fails, it exits the program with an error message.

  3. Start Capturing : The start_capturing function initiates the video capturing process. It iterates through allocated memory buffers, preparing them for capturing video frames. For each buffer, it sets the buffer type, memory type, and index. Once the buffers are queued for capturing using VIDIOC_QBUF, the function signals the start of the video stream with VIDIOC_STREAMON. Essentially, this function kicks off the camera to start capturing video frames, making the system ready for efficient video data acquisition. If any issues occur during this process, it exits the program with an error message.

The 1, 2 and 3 functions above are part of the camera_init

  1. Capture Picture : The capture_pic function is responsible for capturing a single video frame from the camera. It uses the select system call to wait for the availability of data from the camera within a specified timeout. Once data is ready, it calls the frames_reading function to process and handle the captured frame. If there's a timeout or any issues during the process, it prints an error message and exits the program, ensuring a smooth capture of video frames. The capture_pic internally calls the continuous_transformation and transformation_color_conversion to convert YUYV to RGB. The result RGB frame is stored in bigbuffer.

In step 4, the pixel data from the camera is stored in the bigbuffer. The subsequent action is determined by the specific user or application code. Users have the flexibility to choose how to handle this pixel data. They can opt to save it locally on an SD card, implementing a process like this. Alternatively, they may decide to transmit the data via sockets, utilizing a mechanism similar to my project. The choice between saving locally or transmitting via sockets depends on the user's particular project requirements and desired functionality.

The below 5, 6 and 7 functions are part of the camera off sequence. Once the user has finished reading frames from the camera, it's crucial to follow the below sequence to ensure the proper closure of the camera:

  1. stop_capturing : The stop_capturing function is responsible for stopping the video capturing process. It sets the buffer type to video capture and issues the VIDIOC_STREAMOFF ioctl command to halt the streaming of video data. This function ensures a controlled and proper termination of the video capture, preventing any issues or data corruption. If there are any errors during this process, it exits the program with an error message to maintain the integrity of the video capture system.

  2. unint device : The uninit_device function is responsible for cleaning up and releasing resources allocated during the initialization of the camera device.

  3. close device : A simple syscall to close the camera fd.

References Used/Leverage code

Original V4L2 open source reference : here and here

Prof. Sam's code : here

Adapted Sam's code for frame capture and dump project. The code will capture images and dump them on sd card in 'frames' folder : here

My project where I used sockets to trasfer image data instead of directly dumping on SD card : here