# System Utilities

[中文]

GMF-Core provides two groups of general-purpose modules outside the main framework: the OS abstraction layer (OAL) and helpers. The former consolidates OS/IDF-related system calls into a unified interface for compatibility across different versions; the latter provides small utilities such as URI parsing and EIGHTCC capability identifiers, for reuse by elements and upper-layer applications.

This document covers the usage interfaces of both groups. For the main framework objects (pipeline, element, payload, port), see GMF Pipeline and Task Scheduling, GMF Elements, and Data Flow.

## OS Abstraction Layer

Located in the `oal/` directory. Any GMF code involving memory, mutexes, threads, and other system calls accesses them through OAL rather than calling FreeRTOS or IDF APIs directly. OAL internally routes to the concrete implementation based on “target platform + compile switches,” so the same framework code can run on ESP-IDF while leaving an abstraction layer for future migration to other RTOSes.

### Memory Allocation

`esp_gmf_oal_malloc` / `esp_gmf_oal_calloc` / `esp_gmf_oal_realloc` share the same names and semantics as the standard C interfaces, with one difference: when PSRAM is enabled, the framework selects internal RAM or PSRAM based on strategy without requiring application code to make the decision. `esp_gmf_oal_calloc_inner()` forces allocation in internal RAM, for latency-sensitive scenarios.

    void *buf = esp_gmf_oal_calloc(1, size);
    if (!buf) {
        return ESP_GMF_ERR_MEMORY_LACK;
    }
    /* ... */
    esp_gmf_oal_free(buf);

For aligned allocation, use `esp_gmf_oal_malloc_align()`; `align` must be a power of 2 or 0.

### PSRAM Status

Three query interfaces allow code to sense PSRAM availability and alignment requirements:

- `esp_gmf_oal_mem_spiram_is_enabled()`: whether PSRAM is enabled in the current firmware

- `esp_gmf_oal_mem_spiram_stack_is_enabled()`: whether placing task stacks in PSRAM is allowed

- `esp_gmf_oal_get_spiram_cache_align()`: the alignment in bytes required by the PSRAM cache

When a custom element needs DMA across the PSRAM boundary, use `esp_gmf_oal_get_spiram_cache_align()` to retrieve the alignment value and fill it into the `buf_addr_aligned` / `buf_size_aligned` fields of `ESP_GMF_ELEMENT_*_PORT_ATTR_SET`, to avoid cache coherency issues.

### Mutex and Thread

OAL wraps FreeRTOS mutex and task interfaces into a more concise API:

- `esp_gmf_oal_mutex_create` / `lock` / `unlock` / `destroy`: recursive mutex

- `esp_gmf_oal_thread_create` / `delete`: task creation (`delete` accepts a NULL handle)

The thread interface takes an `esp_gmf_oal_thread_t` configuration (stack size, priority, CPU core, whether to use external SPI RAM stack), consistent with the `esp_gmf_task_config_t` fields nested in `esp_gmf_task_cfg_t`. When integrating tasks and pipelines, the OAL thread interface is generally not called directly; it is used indirectly via `esp_gmf_task_init()`.

### Debug Helpers

`ESP_GMF_MEM_SHOW(tag)` prints heap memory status at the current location. `esp_gmf_oal_sys_get_real_time_stats` outputs runtime task statistics, useful for diagnosing insufficient stack or high CPU usage. Both interfaces automatically embed the “call-site information” into the log via macros or functions, so line numbers do not need to be filled in manually during debugging.

## URI Parsing

`esp_gmf_uri_parser` splits a `scheme://host[:port]/path?query` format string into individual fields; IO elements use this to determine which specific implementation to select. Typical usage:

    esp_gmf_uri_t info = { 0 };
    esp_gmf_uri_parse("http://server:8080/song.mp3?token=abc", &info);
    /* info.scheme = "http", info.host = "server", info.path = "/song.mp3" */
    esp_gmf_uri_free(&info);

The strings in the parsed result are copies made from the source string; `esp_gmf_uri_free()` must be called after use to release them. The pool’s `esp_gmf_pool_get_io_tag_by_url()` uses the same parser internally; when a custom IO implements the `get_score` callback to evaluate a URL, it is also recommended to reuse this module.

## EIGHTCC Capability Identifiers

EIGHTCC (Eight Character Code) uses 8 ASCII characters to identify the capability category of an element. Capability descriptions declare via `cap_eightcc` which category of capability an element belongs to, such as audio decoding, audio mixing, video scaling, or video overlay. EIGHTCC describes “what can be done” while FourCC describes “what media format is processed”; for FourCC definitions, see GMF FourCC.

`esp_gmf_caps_def.h` defines common EIGHTCCs organized into audio and video categories.

Audio Capabilities

- `ESP_GMF_CAPS_AUDIO_DECODER` / `ESP_GMF_CAPS_AUDIO_ENCODER`: Audio decoding / encoding

- `ESP_GMF_CAPS_AUDIO_RATE_CONVERT` / `ESP_GMF_CAPS_AUDIO_CHANNEL_CONVERT` / `ESP_GMF_CAPS_AUDIO_BIT_CONVERT`: Sample rate, channel count, and bit depth conversion

- `ESP_GMF_CAPS_AUDIO_EQUALIZER` / `ESP_GMF_CAPS_AUDIO_MIXER` / `ESP_GMF_CAPS_AUDIO_SONIC` / `ESP_GMF_CAPS_AUDIO_FADE`: Common audio effects

- `ESP_GMF_CAPS_AUDIO_AEC` / `ESP_GMF_CAPS_AUDIO_NS` / `ESP_GMF_CAPS_AUDIO_AGC` / `ESP_GMF_CAPS_AUDIO_VAD` / `ESP_GMF_CAPS_AUDIO_WWE` / `ESP_GMF_CAPS_AUDIO_VCMD`: AI speech front-end capabilities

- `ESP_GMF_CAPS_AUDIO_DRC` / `ESP_GMF_CAPS_AUDIO_MBC`: Dynamic range processing

Video Capabilities

- `ESP_GMF_CAPS_VIDEO_DECODER` / `ESP_GMF_CAPS_VIDEO_ENCODER`: Video decoding / encoding

- `ESP_GMF_CAPS_VIDEO_COLOR_CONVERT`: Color format conversion

- `ESP_GMF_CAPS_VIDEO_CROP` / `ESP_GMF_CAPS_VIDEO_ROTATE` / `ESP_GMF_CAPS_VIDEO_SCALE`: Cropping, rotation, and scaling

- `ESP_GMF_CAPS_VIDEO_OVERLAY` / `ESP_GMF_CAPS_VIDEO_FPS_CVT`: Overlay and frame rate conversion

Mutual conversion between string and numeric forms is done via the `STR_2_EIGHTCC` / `EIGHTCC_2_STR` macros; when adding custom capability identifiers, reuse these two macros rather than concatenating bytes directly.

## API Reference

Header files covered in this document:

- `esp_gmf_oal_mem.h`: Memory allocation and PSRAM status queries

- `esp_gmf_oal_mutex.h`: Mutex

- `esp_gmf_oal_thread.h`: Thread wrapper

- `esp_gmf_oal_sys.h`: Runtime statistics and system helpers

- `esp_gmf_uri_parser.h`: URI parsing

- `esp_gmf_caps_def.h`: EIGHTCC capability identifiers

### Header File

- gmf_core/oal/include/esp_gmf_oal_mem.h

### Functions

void *esp_gmf_oal_malloc(size_t size)

  Allocate memory of a specified size.

  Parameters:

    size – [in] Size of memory to allocate, in bytes

  Returns:

    - Pointer to allocated memory on success

    - NULL if an error occurs

void *esp_gmf_oal_malloc_align(uint8_t align, size_t size)

  Allocate memory with specified alignment.

  Parameters:

    - align – [in] Memory alignment in bytes (must be a power of 2 or 0)

    - size – [in] Size of memory to allocate, in bytes

  Returns:

    - Pointer to aligned memory on success

    - NULL if an error occurs

void esp_gmf_oal_free(void *ptr)

  Free allocated memory.

  Parameters:

    ptr – [in] Pointer to the memory to free

void *esp_gmf_oal_calloc(size_t nmemb, size_t size)

  Allocate zero-initialized memory, if SPI RAM is enabled, memory may be allocated there.

  Parameters:

    - nmemb – [in] Number of elements to allocate

    - size – [in] Size of each element, in bytes

  Returns:

    - Pointer to allocated and zero-initialized memory on success

    - NULL if an error occurs

void *esp_gmf_oal_calloc_inner(size_t nmemb, size_t size)

  Allocate zero-initialized memory in internal memory.

  Parameters:

    - nmemb – [in] Number of elements to allocate

    - size – [in] Size of each element, in bytes

  Returns:

    - Pointer to allocated and zero-initialized memory on success

    - NULL if an error occurs

void esp_gmf_oal_mem_print(const char *tag, int line, const char *func)

  Print the current heap memory status.

  Parameters:

    - tag – [in] Log tag identifier

    - line – [in] Line number where the function is called

    - func – [in] Name of the function making the call

void *esp_gmf_oal_realloc(void *ptr, size_t size)

  Reallocate memory to a new size, if SPI RAM is enabled, the memory may be allocated there.

  Parameters:

    - ptr – [in] Pointer to previously allocated memory

    - size – [in] New size of memory block, in bytes

  Returns:

    - Pointer to the reallocated memory block on success

    - NULL if an error occurs

char *esp_gmf_oal_strdup(const char *str)

  Duplicate a string in newly allocated memory.

  Parameters:

    str – [in] String to duplicate

  Returns:

    - Pointer to the duplicated string in allocated memory

    - NULL if an error occurs

bool esp_gmf_oal_mem_spiram_is_enabled(void)

  Check if SPI RAM is enabled.

  Returns:

    - true if SPI RAM is enabled

    - false if SPI RAM is not enabled

bool esp_gmf_oal_mem_spiram_stack_is_enabled(void)

  Check if stack allocation on external SPI RAM is enabled.

  Returns:

    - true if stack allocation on SPI RAM is enabled

    - false if stack allocation on SPI RAM is not enabled

uint8_t esp_gmf_oal_get_spiram_cache_align(void)

  Get SPI RAM cache alignment.

  Returns:

    - Alignment SPI RAM cache alignment

### Macros

ESP_GMF_OAL_ALIGN_UP(num, align)

ESP_GMF_OAL_ALIGN_BYTES_VALID(align)

ESP_GMF_MEM_SHOW(x)

### Header File

- gmf_core/oal/include/esp_gmf_oal_mutex.h

### Functions

void *esp_gmf_oal_mutex_create(void)

  Allocates and initializes a new mutex object for synchronization.

  Returns:

    - Pointer to the newly created mutex on success

    - NULL if the mutex creation fails

int esp_gmf_oal_mutex_destroy(void *mutex)

  Destroy a mutex.

  Parameters:

    mutex – [in] Pointer to the mutex to destroy

  Returns:

    - 0 on success

    - Negative value if an error occurs

int esp_gmf_oal_mutex_lock(void *mutex)

  Acquires a lock on the specified mutex, blocking if necessary until the lock becomes available.

  Parameters:

    mutex – [in] Pointer to the mutex to lock

  Returns:

    - 0 on success

    - Negative value if an error occurs

int esp_gmf_oal_mutex_unlock(void *mutex)

  Releases the lock held on the specified mutex, allowing other threads to acquire the lock.

  Parameters:

    mutex – [in] Pointer to the mutex to unlock

  Returns:

    - 0 on success

    - Negative value if an error occurs

### Header File

- gmf_core/oal/include/esp_gmf_oal_thread.h

### Functions

esp_gmf_err_t esp_gmf_oal_thread_create(esp_gmf_oal_thread_t *p_handle, const char *name, void (*main_func)(void *arg), void *arg, uint32_t stack, int prio, bool stack_in_ext, int core_id)

  This function creates a new thread, specifying its properties like name, priority, stack size, and the core to which it should be pinned.

  Note

  - Please apply the ./idf_patches/idf_v3.3/4.x_freertos.patch first

  - Please enable support for external RAM and `Allow external memory as an argument to xTaskCreateStatic` to be able to use external memory for task stack, namely `CONFIG_SPIRAM_BOOT_INIT=y` and `CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY=y`

  Parameters:

    - p_handle – [out] Pointer to the thread handle that will be created

    - name – [in] The name of the thread

    - main_func – [in] The main function that the thread will execute

    - arg – [in] Argument to pass to the thread’s main function

    - stack – [in] The size of the stack (in bytes) to allocate for the thread

    - prio – [in] The priority of the thread

    - stack_in_ext – [in] If true, the stack will be allocated in external memory

    - core_id – [in] The core to pin the thread to (-1 for no pinning)

  Returns:

    - ESP_GMF_ERR_OK Operation successful

    - ESP_GMF_ERR_FAIL Operation failed, usually due to insufficient memory for creating a new thread

esp_gmf_err_t esp_gmf_oal_thread_delete(esp_gmf_oal_thread_t p_handle)

  Delete an existing GMF OAL thread.

  Parameters:

    p_handle – [in] Pointer to the thread handle to be deleted

  Returns:

    - ESP_GMR_ERR_OK Operation successful

### Type Definitions

typedef void *esp_gmf_oal_thread_t

### Header File

- gmf_core/oal/include/esp_gmf_oal_sys.h

### Functions

int esp_gmf_oal_sys_get_tick_by_time_ms(int ms)

  Get system ticks based on the given millisecond value.

  Parameters:

    ms – [in] Time in milliseconds

  Returns:

    - The corresponding system ticks

int64_t esp_gmf_oal_sys_get_time_ms(void)

  Retrieve the current system time in milliseconds.

  Returns:

    - The system time in milliseconds

esp_gmf_err_t esp_gmf_oal_sys_get_real_time_stats(int elapsed_time_ms, bool markdown)

  Print CPU usage statistics of tasks over a specified time period.

          This function measures and prints the CPU usage of tasks over a given
          period (in milliseconds) by calling `uxTaskGetSystemState()` twice,
          with a delay in between. The CPU usage is then calculated based on the
          difference in task run times before and after the delay.

  Note

  - If tasks are added or removed during the delay, their statistics will not be included in the final report

  - To minimize inaccuracies caused by delays, this function should be called from a high-priority task

  - In dual-core mode, each core will account for up to 50% of the total runtime

  Parameters:

    - elapsed_time_ms – [in] Time period for the CPU usage measurement in milliseconds

    - markdown – [in] Whether print use markdown format

  Returns:

    - ESP_GMF_ERR_OK On success

    - ESP_GMF_ERR_MEMORY_LACK No memory for operation

    - ESP_GMF_ERR_NOT_ENOUGH More memory is needed for uxTaskGetSystemState

    - ESP_GMF_ERR_FAIL On failure

### Macros

FALL_THROUGH

### Header File

- gmf_core/helpers/include/esp_gmf_uri_parser.h

### Functions

int esp_gmf_uri_parse(const char *uri_str, esp_gmf_uri_t **uri_out)

  Parses a URI string and populates a esp_gmf_uri_t structure with its components.

          This function takes a URI string as input, parses it, and allocates and populates a
          `esp_gmf_uri_t` structure with the parsed components. The caller is responsible for
          freeing the allocated memory using `esp_gmf_uri_free()`.

  Parameters:

    - uri_str – [in] The URI string to be parsed

    - uri_out – [out] Pointer to the `esp_gmf_uri_t` structure where the parsed URI components will be stored

  Returns:

    - 0 On success

    - Non-zero Error code on failure

void esp_gmf_uri_free(esp_gmf_uri_t *uri)

  Frees the memory allocated for a esp_gmf_uri_t object.

          This function releases all dynamically allocated memory associated with the URI components
          within the given `esp_gmf_uri_t` structure. After calling this function, the URI pointer will be invalid.

  Parameters:

    uri – [in] Pointer to the `esp_gmf_uri_t` object to be freed

### Structures

struct esp_gmf_uri_t

  Structure representing a parsed URI.

          This structure holds different components of a URI such as scheme, userinfo,
          host, port, path, query, etc. Each field corresponds to a specific part of the URI

  Public Members

  char *scheme

    The scheme of the URI (e.g., “http”, “https”)

  char *userinfo

    The userinfo component (optional, may include username and password)

  char *username

    The username part of the userinfo, if present

  char *password

    The password part of the userinfo, if present

  char *host

    The host (e.g., domain name or IP address)

  int port

    The port number (optional, if not specified, defaults to scheme’s standard port)

  char *path

    The path component of the URI

  char *query

    The query string of the URI (optional, starts after ‘?’ in URL)

  char *fragment

    The fragment identifier (optional, starts after ‘#’ in URL)

### Header File

- gmf_core/helpers/include/esp_gmf_caps_def.h

### Functions

static inline uint64_t gmf_str_to_cc(const char *str, int max_len)

static inline void gmf_eightcc_to_str(uint64_t eightcc, char out[9])

### Macros

STR_2_EIGHTCC(str)

STR_2_FOURTCC(str)

EIGHTCC_2_STR(eightcc)

ESP_GMF_CAPS_AUDIO_DECODER

ESP_GMF_CAPS_AUDIO_ENCODER

ESP_GMF_CAPS_AUDIO_ALC

ESP_GMF_CAPS_AUDIO_BIT_CONVERT

ESP_GMF_CAPS_AUDIO_CHANNEL_CONVERT

ESP_GMF_CAPS_AUDIO_RATE_CONVERT

ESP_GMF_CAPS_AUDIO_MIXER

ESP_GMF_CAPS_AUDIO_EQUALIZER

ESP_GMF_CAPS_AUDIO_SONIC

ESP_GMF_CAPS_AUDIO_FADE

ESP_GMF_CAPS_AUDIO_DEINTERLEAVE

ESP_GMF_CAPS_AUDIO_INTERLEAVE

ESP_GMF_CAPS_AUDIO_AEC

ESP_GMF_CAPS_AUDIO_NS

ESP_GMF_CAPS_AUDIO_AGC

ESP_GMF_CAPS_AUDIO_VAD

ESP_GMF_CAPS_AUDIO_DOA

ESP_GMF_CAPS_AUDIO_WWE

ESP_GMF_CAPS_AUDIO_VCMD

ESP_GMF_CAPS_AUDIO_DRC

ESP_GMF_CAPS_AUDIO_MBC

ESP_GMF_CAPS_AUDIO_MUXER

ESP_GMF_CAPS_AUDIO_HOWL

ESP_GMF_CAPS_VIDEO_DECODER

ESP_GMF_CAPS_VIDEO_ENCODER

ESP_GMF_CAPS_VIDEO_COLOR_CONVERT

ESP_GMF_CAPS_VIDEO_CROP

ESP_GMF_CAPS_VIDEO_ROTATE

ESP_GMF_CAPS_VIDEO_SCALE

ESP_GMF_CAPS_VIDEO_OVERLAY

ESP_GMF_CAPS_VIDEO_FPS_CVT

Was this page helpful?

- Thank you! We received your feedback.
- If you have any comments, fill in Espressif Documentation Feedback Form.

- We value your feedback.
- Let us know how we can improve this page by filling in Espressif Documentation Feedback Form.