draw_osd

[中文]

Overview

The DRAW_OSD (On-Screen Display) module overlays OSD elements such as text and icons on video or images. It supports two overlay types: images and fonts, allowing dynamic addition, update, and removal of OSD elements.

Development Intro

The OSD controller is a handle that manages OSD elements. It can create, draw, update, and delete OSD elements.

Supported blend types:
  • Image blend (BLEND_TYPE_IMAGE): Supports ARGB8888 images only

  • Font blend (BLEND_TYPE_FONT): Supports font libraries generated by FontCvt.exe

The OSD controller API supports the following configurations:
  • Blend resource array: Directly display predefined OSD resources, including icons and fonts

  • Current blend info: Current OSD content, display a single icon or font

  • PSRAM usage: Whether to draw in PSRAM

Resources can be generated using the UI tool. For detailed steps, refer to: UI tool usage: <https://docs.bekencorp.com/arminodoc/bk_app/ui_designer/zh_CN/latest/index.html>`_

API Call Flow Overview

The typical OSD usage flow is as follows:

┌─────────────────────────────────────────────────────────────┐
│                   OSD API Call Flow                          │
└─────────────────────────────────────────────────────────────┘

1. Resource Preparation  ──→  Generate font and icon resources using UI tool
                              └─ Generate bk_font.c, bk_img.c, bk_dsc.c, blend.h

2. bk_draw_osd_new()    ──→  Create OSD controller instance
                              └─ Configure resource arrays and drawing parameters

3. OSD Drawing Operations (can be called multiple times)
   │
   ├─ bk_draw_osd_array()    Draw entire OSD array
   ├─ bk_draw_osd_image()    Draw single image
   └─ bk_draw_osd_font()     Draw single font

4. OSD Content Management (optional)
   │
   ├─ bk_draw_osd_add_or_updata()  Add or update OSD content
   └─ bk_draw_osd_remove()         Remove OSD content

5. bk_draw_osd_delete()    ──→  Delete OSD controller instance
                                └─ Release resources

Attention

  • OSD elements can only be drawn after creating the controller

  • After updating or removing OSD content, redraw is needed to take effect

  • All OSD element names must be unique

  • Controller should be deleted promptly after operations to release resources

Complete Usage Example

The following is a complete OSD usage example:

#include <components/bk_draw_osd/bk_draw_osd.h>
#include <components/bk_draw_osd/bk_draw_osd_types.h>
#include "blend.h"  // UI tool generated resource header

#define TAG "osd_demo"

avdk_err_t osd_demo(frame_buffer_t *display_frame)
{
    avdk_err_t ret = AVDK_ERR_OK;
    bk_draw_osd_ctlr_handle_t osd_handle = NULL;

    // Step 1: Create OSD controller
    osd_ctlr_config_t osd_config = {
        .blend_assets = blend_assets,  // Total resource array
        .blend_info = blend_info,      // Default resources to draw
        .draw_in_psram = false         // Draw in SRAM
    };

    ret = bk_draw_osd_new(&osd_handle, &osd_config);
    if (ret != AVDK_ERR_OK) {
        LOGE("bk_draw_osd_new failed: %d\n", ret);
        return ret;
    }
    LOGI("OSD controller created successfully\n");

    // Step 2: Prepare background info
    osd_bg_info_t bg_info = {
        .frame = display_frame,  // Display frame buffer
        .width = 854,            // Visible width
        .height = 480            // Visible height
    };

    // Step 3: Draw OSD array
    ret = bk_draw_osd_array(osd_handle, &bg_info, blend_info);
    if (ret != AVDK_ERR_OK) {
        LOGE("bk_draw_osd_array failed: %d\n", ret);
        bk_draw_osd_delete(osd_handle);
        return ret;
    }
    LOGI("OSD array drawn successfully\n");

    // Step 4: Update OSD content (optional)
    ret = bk_draw_osd_add_or_updata(osd_handle, "clock", "15:30");
    if (ret != AVDK_ERR_OK) {
        LOGE("bk_draw_osd_add_or_updata failed: %d\n", ret);
    }

    // Redraw to apply updates
    ret = bk_draw_osd_array(osd_handle, &bg_info, NULL);

    // Step 5: Delete OSD controller
    ret = bk_draw_osd_delete(osd_handle);
    if (ret != AVDK_ERR_OK) {
        LOGE("bk_draw_osd_delete failed: %d\n", ret);
        return ret;
    }
    osd_handle = NULL;
    LOGI("OSD controller deleted successfully\n");

    return AVDK_ERR_OK;
}

Detailed API Description

Code Flow

1. Resource Preparation

Files generated by the UI tool include 4 files:

  • bk_font.c Font resources

  • bk_img.c Image resources

  • bk_dsc.c Resource array

  • blend.h Header file

The file bk_dsc.c defines the resource array blend_assets, which contains OSD resources (fonts and images).

  • name is the tag of the font/icon group. Elements sharing the same tag have the same position.

  • content is the actual overlay content and can be changed (e.g., strings, image names).

// All resources
const blend_info_t blend_assets[] =
{
    {.name = "clock", .addr = &font_clock, .content = "12:30"},
    {.name = "date",  .addr = &font_dates, .content = "Wed, Feb 26, 2025"},
    {.name = "ver",   .addr = &font_ver, .content = "v 1.0.0"},
    {.name = "wifi", .addr = &img_wifi_rssi0, .content = "wifi0"},
    {.name = "wifi", .addr = &img_wifi_rssi1, .content = "wifi1"},
    {.name = "wifi", .addr = &img_wifi_rssi2, .content = "wifi2"},
    {.name = "wifi", .addr = &img_wifi_rssi3, .content = "wifi3"},
    {.name = "wifi", .addr = &img_wifi_rssi4, .content = "wifi4"},
    {.name = "battery", .addr = &img_battery1, .content = "battery1"},
    {.name = "weather", .addr = &img_cloudy_to_sunny, .content = "cloudy_to_sunny"},
    {.addr = NULL},    // The last element must be NULL and is the only NULL element
};
// Default blend resources
const blend_info_t blend_info[] =
{
    {.name = "clock", .addr = &font_clock, .content = ""},
    {.name = "ver",   .addr = &font_ver, .content = "v 1.0.0"},
    {.name = "wifi", .addr = &img_wifi_rssi0, .content = "wifi0"},
    {.name = "weather", .addr = &img_cloudy_to_sunny, .content = "cloudy_to_sunny"},
    {.addr = NULL},
};

Font and icon structure examples are shown below. All parameters are autogenerated by the UI designer:

GUI_CONST_STORAGE bk_blend_t font_clock =
{
    .version = 0,                          // blend software version
    .blend_type = BLEND_TYPE_FONT,          // blend type
    .name = "clock",                        // blend name (group tag)
    .width = CLOCK_LOGO_W,                  // text width
    .height = CLOCK_LOGO_H,                  // text height
    .xpos = 0,                               // text x (relative to canvas background)
    .ypos = 0,                               // text y (relative to canvas background)
    .font =
    {
        .font_digit_type = font_digit_Roboto53, // font type
        .color = FONT_COLOR,                    // font color
    },
};

GUI_CONST_STORAGE bk_blend_t img_wifi_rssi0 =
{
    .version = 0,                            // blend software version
    .blend_type = BLEND_TYPE_IMAGE,          // blend type
    .name = "wifi",                          // blend name (group tag)
    .width = WIFI_WIDTH,                     // image width
    .height = WIFI_HEIGHT,                   // image height
    .xpos = WIFI_XPOS,                       // image x (relative to canvas background)
    .ypos = WIFI_YPOS,                       // image y (relative to canvas background)
    .image =
    {
        .format = ARGB8888,                      // image format
        .data_len = WIFI_WIDTH * WIFI_HEIGHT * 4, // image data length
        .data = wifi_0_argb8888                  // image data
    },
};

2. bk_draw_osd_new - Create OSD Controller

Description:

Create an OSD controller instance, initialize resources and allocate drawing memory. The controller automatically allocates a buffer based on the largest OSD element (width × height × 4 bytes).

Function Prototype:

avdk_err_t bk_draw_osd_new(bk_draw_osd_ctlr_handle_t *handle, const osd_ctlr_config_t *config);

Parameters:

  • handle: [Output] Pointer to OSD controller handle

  • config: [Input] Pointer to OSD controller configuration structure

Configuration Members:

  • blend_assets: Total blend resource array

  • blend_info: Default resources to draw (can be NULL)

  • draw_in_psram: Allocate drawing buffer in PSRAM (true) or SRAM (false)

Return Values:

  • AVDK_ERR_OK: Success

  • AVDK_ERR_NOMEM: Memory allocation failed

  • AVDK_ERR_INVAL: Invalid parameter

Usage Notes:

  • blend_assets must end with {.addr = NULL}

  • If blend_info is NULL, no content is automatically drawn

  • PSRAM suitable for large OSD elements, SRAM is faster

  • Buffer size = max(width) × max(height) × 4 bytes (ARGB8888)

Example:

bk_draw_osd_ctlr_handle_t osd_handle = NULL;

osd_ctlr_config_t osd_config = {
    .blend_assets = blend_assets,
    .blend_info = blend_info,
    .draw_in_psram = false
};

avdk_err_t ret = bk_draw_osd_new(&osd_handle, &osd_config);
if (ret != AVDK_ERR_OK) {
    LOGE("Failed to create OSD controller: %d\n", ret);
    return ret;
}
LOGI("OSD controller created: %p\n", osd_handle);

For detailed descriptions of the following APIs (bk_draw_osd_array, bk_draw_osd_image, bk_draw_osd_font, bk_draw_osd_add_or_updata, bk_draw_osd_remove, bk_draw_osd_delete), please refer to the Chinese documentation with similar structure and parameters.

Usage Recommendations and Notes

Resource Configuration:

  1. Resource array must end with {.addr = NULL} as terminator

  2. OSD element name identifies element groups; multiple elements can share the same name

  3. OSD element content must be unique to distinguish resources under the same name

  4. Image blending only supports ARGB8888 format

  5. Font blending requires FontCvt.exe tool generated font libraries

  6. UI tool usage: https://docs.bekencorp.com/arminodoc/bk_app/ui_designer/zh_CN/latest/index.html

Coordinates and Dimensions:

  1. All OSD element coordinates (xpos, ypos) are relative to background frame origin (0,0)

  2. OSD element (xpos + width) must not exceed background frame width

  3. OSD element (ypos + height) must not exceed background frame height

  4. Out-of-bounds coordinates cause drawing failure or display anomalies

Memory Management:

  1. OSD controller creation automatically allocates drawing buffer

  2. Buffer size determined by largest OSD element in resource array

  3. PSRAM suitable for large OSD elements; SRAM is faster but limited

  4. Delete controller promptly when no longer needed

Dynamic Updates:

  1. bk_draw_osd_add_or_updata or bk_draw_osd_remove only modify memory array

  2. Must call bk_draw_osd_array again to apply changes to display

  3. Updating content searches for matching name and content, then replaces

  4. Removing name deletes all elements with that name

Performance Optimization:

  1. Reuse same background frame if OSD content doesn’t change frequently

  2. For dynamic content (e.g., clock), only update changed parts

  3. Use PSRAM drawing for many OSD elements to avoid SRAM shortage

  4. Drawing order affects layering; later drawn elements overlay earlier ones

DMA2D Integration:

  1. OSD drawing internally uses DMA2D for image blending

  2. Ensure DMA2D hardware resources are available

  3. Image formats must be correct for DMA2D operations

  4. OSD controller can coexist with DMA2D controller

OSD API Function List

Controller Management:

  • bk_draw_osd_new: Create OSD controller instance

  • bk_draw_osd_delete: Delete OSD controller instance, release resources

OSD Drawing Operations:

  • bk_draw_osd_array: Draw entire OSD resource array

  • bk_draw_osd_image: Draw single image OSD element

  • bk_draw_osd_font: Draw single font OSD element

OSD Content Management:

  • bk_draw_osd_add_or_updata: Add or update OSD element content

  • bk_draw_osd_remove: Remove OSD element by name