voutputfb_web_logo

VOutputFb C++ library

v1.1.0

Table of contents

Overview

VOutputFb C++ library provides simple interface to write video frame to framebuffer in Linux OS. It depends only on open source Frame library (describes video frame class and pixel formats, source code included, Apache 2.0 license). The library supports C++17 standard and works only on Linux with framebuffer API support.

Versions

Table 1 - Library versions.

Version Release date What’s new
1.0.0 18.06.2024 First version.
1.1.0 19.07.2024 - CMake updated.
- Test application and example updated.
- Frame submodule updated.

Library files

The library is supplied only by source code. The user is given a set of files in the form of a CMake project (repository). The repository structure is shown below:

CMakeLists.txt ------------- Main CMake file of the library.
3rdparty ------------------- Folder with third-party libraries.
    CMakeLists.txt --------- CMake file to include third-party libraries.
    Frame ------------------ Folder with Frame library source code.
src ------------------------ Folder with library source code.
    CMakeLists.txt --------- CMake file of the library.
    VOutputFb.h ------------ Main library header file.
    VOutputFbVersion.h ----- Header file with library version.
    VOutputFbVersion.h.in -- File for CMake to generate version header.
    VOutputFb.cpp ---------- C++ implementation file.
test ----------------------- Folder for test application files.
    CMakeLists.txt --------- CMake file for test application.
    main.cpp --------------- Source C++ file of test application.
example -------------------- Folder for example application files.
    CMakeLists.txt --------- CMake file for example application.
    main.cpp --------------- Source C++ file of example application.

VOutputFb class description

VOutputFb class declaration

VOutputFb class declared in VOutputFb.h file. Class declaration:

namespace cr
{
namespace video
{
/// Frame buffer video output class.
class VOutputFb
{
public:

    /// Get library version.
    static std::string getVersion();

    /// Class destructor.
    ~VOutputFb();

    /// Initialize frame buffer. 
    bool init(std::string device = "/dev/fb0");

    /// Write video frame to device.
    bool write(Frame& frame);

    /// Close device.
    void close();

    /// Get frame buffer width and height.
    bool getResolution(int& width, int& height);
};
}
}

getVersion method

The getVersion() method returns string of current version of VOutputFb class. Method declaration:

static std::string getVersion();

Method can be used without VOutputFb class instance:

std::cout << "VOutputFb class version: " << cr::video::VOutputFb::getVersion();

Console output:

VOutputFb class version: 1.1.0

init method

The init(…) method initializes video output device. Method open device file (default “/dev/fb0”), checks frame buffer format (must be BGR24 or BGR565) and initializes frame buffer.

bool init(std::string device = "/dev/fb0");
Parameter Value
device Frame buffer device name.

Returns: TRUE if the video device open or FALSE if not (device not open or pixel format not BGR24 and not BGR565).

write method

The write(…) method writes video frame to video device. Method checks input frame format (must be BGR24) and resolution (width and height must be equivalent to frame buffer resolution). Use should control resolution (actual resolution can be obtained with getResolution(…) method after initialization) of frame buffer and should put frame with appropriate resolution. If frame buffer has format BGR565 the method will perform conversion from BGR24 to BGR565.

bool write(Frame& frame);
Parameter Value
frame Frame class object. Only BGR24 format is supported.

Returns: TRUE if the video frame is written to device or FALSE if not.

close method

The close() method closes output device. Method declaration:

void close();

getResolution method

The getResolution(…) method return actual frame buffer resolution. It can be used only after initialization (init(…) method). Method declaration:

bool getResolution(int& width, int& height);
Parameter Value
width Frame buffer width.
width Frame buffer height.

Returns: TRUE if resolution provided or FALSE if not.

Build and connect to your project

Typical commands to build VOutputFb library:

cd VOutputFb
mkdir build
cd build
cmake ..
make

If you want connect VOutputFb library to your CMake project as source code you can make follow. For example, if your repository has structure:

CMakeLists.txt
src
    CMakeList.txt
    yourLib.h
    yourLib.cpp

Create folder 3rdparty in your repository. Copy repository folder VOutputFb to 3rdparty folder. New structure of your repository:

CMakeLists.txt
src
    CMakeList.txt
    yourLib.h
    yourLib.cpp
3rdparty
    VOutputFb

Create CMakeLists.txt file in 3rdparty folder. CMakeLists.txt should contain:

cmake_minimum_required(VERSION 3.13)

################################################################################
## 3RD-PARTY
## dependencies for the project
################################################################################
project(3rdparty LANGUAGES CXX)

################################################################################
## SETTINGS
## basic 3rd-party settings before use
################################################################################
# To inherit the top-level architecture when the project is used as a submodule.
SET(PARENT ${PARENT}_YOUR_PROJECT_3RDPARTY)
# Disable self-overwriting of parameters inside included subdirectories.
SET(${PARENT}_SUBMODULE_CACHE_OVERWRITE OFF CACHE BOOL "" FORCE)

################################################################################
## CONFIGURATION
## 3rd-party submodules configuration
################################################################################
SET(${PARENT}_SUBMODULE_VOUTPUT_FB                      ON  CACHE BOOL "" FORCE)
if (${PARENT}_SUBMODULE_VOUTPUT_FB)
    SET(${PARENT}_VOUTPUT_FB                            ON  CACHE BOOL "" FORCE)
    SET(${PARENT}_VOUTPUT_FB_TEST                       OFF CACHE BOOL "" FORCE)
    SET(${PARENT}_VOUTPUT_FB_EXAMPLE                    OFF CACHE BOOL "" FORCE)
endif()

################################################################################
## INCLUDING SUBDIRECTORIES
## Adding subdirectories according to the 3rd-party configuration
################################################################################
if (${PARENT}_SUBMODULE_VOUTPUT_FB)
    add_subdirectory(VOutputFb)
endif()

File 3rdparty/CMakeLists.txt adds folder VOutputFb to your project and excludes test application (VOutputFb class test applications) from compiling. Your repository new structure will be:

CMakeLists.txt
src
    CMakeList.txt
    yourLib.h
    yourLib.cpp
3rdparty
    CMakeLists.txt
    VOutputFb

Next you need include folder 3rdparty in main CMakeLists.txt file of your repository. Add string at the end of your main CMakeLists.txt:

add_subdirectory(3rdparty)

Next you have to include VOutputFb library in your src/CMakeLists.txt file:

target_link_libraries(${PROJECT_NAME} VOutputFb)

Simple example

Below is the code for a simple application for streaming generated video frames to /dev/video4 device.

#include <iostream>
#include <thread>
#include <chrono>
#include "VOutputFb.h"

int main()
{
    // Open video device.
    cr::video::VOutputFb videoOutput;
    if(!videoOutput.init("/dev/fb"))
        return -1;

    // Get frame buffer resolution.
    int width, height = 0;
    if(!videoOutput.getResolution(width, height))
        return -1;
    std::cout << "Resolution: " << width << "x" << height << std::endl;
    
    // Create BGR frame with certain resolution which is must
    // be equal to the frame buffer resolution.
    cr::video::Frame frame(width, height, cr::video::Fourcc::BGR24);

    // Main loop.
    uint8_t value = 0;
    while (true)
    {
        // Fill image by color.
        memset(frame.data, value++, frame.size);

        // Write frame to device.
        if(!videoOutput.write(frame))
            std::cerr << "Cant' write frame" << std::endl; 

        std::this_thread::sleep_for(std::chrono::milliseconds(33));
    }
    return 1;
}

Test application

VOutputFb/test folder contains the test application which demonstrates the use of the VOutputFb class. The application creates artificial video frames and streams them to franebuffer device. Test application allows you to set image size and frame buffer device name. Test application output will look like this:

VOutputFb v1.1.0 test

Set video device (1 - default /dev/fb0): /dev/fb0
Frame buffer resolution: 1280x720
Frame: 0
Frame: 1
...

RPI configuration

This section describes set up process for Raspberry PI Zero 2W single board computer. In order to obtain composite video output on Raspberry Pi Zero 2W, you need to add the following lines to the /boot/config.txt (or /boot/firmware/config.txt if you have bookworn OS) file:

  • Composite PAL:

      dtoverlay=vc4-kms-v3d,composite
      sdtv_mode=2
      sdtv_aspect=1
      hdmi_force_hotplug=0
      hdmi_ignore_hotplug=1
      enable_tvout=1
    

    Ensure that you do not have multiple dtoverlay=vc4-kms-v3d lines.

    And append following line to kernel command line in /boot/cmdline.txt (or /boot/firmware/cmdline.txt if you have Bookworm Debian OS) file (before other content):

      video=Composite-1:720x576-24@25 vc4.tv_norm=PAL
    
  • HDMI PAL RESOLUTION:

    only kernel command line in /boot/cmdline.txt (or /boot/firmware/cmdline.txt if you have Bookworm Debian OS) file:

      vc4.tv_norm=PAL video=HDMI-A-1:720x576M-24@60D
    

If if you want to use different resolution, you can just change the resolution in the video=Composite-1:720x576-24@25 or video=HDMI-A-1:720x576M-24@60D and remove vc4.tv_norm=PAL. After that, you need to reboot the Raspberry Pi Zero 2W.