系统工具

[English]

GMF-Core 在框架主体之外提供两组通用模块:操作系统抽象层(OAL)和辅助工具(helpers)。前者把操作系统 / IDF 相关的系统调用收敛到统一接口,便于兼容不同版本;后者提供 URI 解析、EIGHTCC 能力标识等小工具,供处理单元与上层应用复用。

本篇覆盖这两组模块的使用接口。框架主要对象(处理链(pipeline)、处理单元(element)、数据载体(payload)、数据端口(port))见 GMF 处理链与任务调度GMF 处理单元数据流转

操作系统抽象层

位于 oal/ 目录。任何 GMF 代码涉及内存、互斥锁、线程等系统调用都通过 OAL 访问,而不是直接调用 FreeRTOS 或 IDF 的 API。OAL 内部按”目标平台 + 编译开关”路由到具体实现,因此同一份框架代码既可以运行在 ESP-IDF 上,也为后续迁移到其他 RTOS 留出抽象层。

内存分配

esp_gmf_oal_malloc / esp_gmf_oal_calloc / esp_gmf_oal_realloc 与标准 C 接口同名同义,区别在于:开启 PSRAM 时框架会按策略选择内部 RAM 或 PSRAM 分配,而不需要应用代码做判断。esp_gmf_oal_calloc_inner() 强制使用内部 RAM,用于对延迟敏感的场景。

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

带对齐的分配用 esp_gmf_oal_malloc_align()align 必须是 2 的幂或 0。

PSRAM 状态

三个查询接口让代码能感知 PSRAM 的可用性与对齐要求:

自定义处理单元需要跨 PSRAM 边界 DMA 时,用 esp_gmf_oal_get_spiram_cache_align() 取出对齐值,填入 ESP_GMF_ELEMENT_*_PORT_ATTR_SETbuf_addr_aligned / buf_size_aligned 字段,避免缓存一致性问题。

互斥锁与线程

OAL 把 FreeRTOS 的 mutex 与 task 接口包成更简洁的 API:

  • esp_gmf_oal_mutex_create / lock / unlock / destroy:递归互斥锁

  • esp_gmf_oal_thread_create / delete:任务创建(delete 接受 NULL 句柄)

线程接口接收一个 esp_gmf_oal_thread_t 配置(栈大小、优先级、CPU 核心、是否使用外部 SPI RAM 栈),与 esp_gmf_task_cfg_t 中嵌套使用的 esp_gmf_task_config_t 字段一致。执行线程与处理链集成时一般不直接调 OAL 线程接口,而是通过 esp_gmf_task_init() 间接使用。

调试辅助

ESP_GMF_MEM_SHOW(tag) 在当前位置打印堆内存状态。esp_gmf_oal_sys_get_real_time_stats 输出运行时任务统计,便于排查栈不足或 CPU 占用偏高。这两个接口都用宏或函数把”调用点信息”自动带进日志,调试时不需要手填行号。

URI 解析

esp_gmf_uri_parserscheme://host[:port]/path?query 格式的字符串解析为各个字段,外部接口(IO)处理单元据此判断需要选择的具体实现。典型调用:

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);

解析结果中的字符串是从源字符串复制出的副本,使用结束后必须调用 esp_gmf_uri_free() 释放。注册池(pool)的 esp_gmf_pool_get_io_tag_by_url() 内部使用同一解析器;自定义外部接口实现 get_score 回调评估 URL 时,也建议复用此模块。

EIGHTCC 能力标识

EIGHTCC(Eight Character Code,八字符代码)用 8 个 ASCII 字符标识处理单元能力类别。能力描述(capability)通过 cap_eightcc 声明处理单元属于哪一类能力,例如音频解码、音频混音、视频缩放或视频叠加。EIGHTCC 描述”能做什么”,FourCC 描述”处理什么媒体格式”;FourCC 的定义见 GMF FourCC

esp_gmf_caps_def.h 按音频与视频两类定义常见 EIGHTCC。

音频能力

  • ESP_GMF_CAPS_AUDIO_DECODER / ESP_GMF_CAPS_AUDIO_ENCODER:音频解码 / 编码

  • ESP_GMF_CAPS_AUDIO_RATE_CONVERT / ESP_GMF_CAPS_AUDIO_CHANNEL_CONVERT / ESP_GMF_CAPS_AUDIO_BIT_CONVERT:采样率、声道数、位深转换

  • ESP_GMF_CAPS_AUDIO_EQUALIZER / ESP_GMF_CAPS_AUDIO_MIXER / ESP_GMF_CAPS_AUDIO_SONIC / ESP_GMF_CAPS_AUDIO_FADE:常规音频效果

  • 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 语音前端能力

  • ESP_GMF_CAPS_AUDIO_DRC / ESP_GMF_CAPS_AUDIO_MBC:动态范围处理

视频能力

  • 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:叠加与帧率转换

字符串与数值的相互转换通过 STR_2_EIGHTCC / EIGHTCC_2_STR 宏完成;新增自定义能力标识时复用这两个宏,避免直接拼接字节。

API 参考

本篇涉及的头文件:

  • esp_gmf_oal_mem.h:内存分配与 PSRAM 状态查询

  • esp_gmf_oal_mutex.h:互斥锁

  • esp_gmf_oal_thread.h:线程封装

  • esp_gmf_oal_sys.h:运行时统计与系统辅助

  • esp_gmf_uri_parser.h:URI 解析

  • esp_gmf_caps_def.h:EIGHTCC 能力标识

Header File

Functions

void *esp_gmf_oal_malloc(size_t size)

Allocate memory of a specified size.

参数:

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

返回:

  • 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.

参数:
  • align[in] Memory alignment in bytes (must be a power of 2 or 0)

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

返回:

  • Pointer to aligned memory on success

  • NULL if an error occurs

void esp_gmf_oal_free(void *ptr)

Free allocated memory.

参数:

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.

参数:
  • nmemb[in] Number of elements to allocate

  • size[in] Size of each element, in bytes

返回:

  • 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.

参数:
  • nmemb[in] Number of elements to allocate

  • size[in] Size of each element, in bytes

返回:

  • 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.

参数:
  • 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.

参数:
  • ptr[in] Pointer to previously allocated memory

  • size[in] New size of memory block, in bytes

返回:

  • 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.

参数:

str[in] String to duplicate

返回:

  • 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.

返回:

  • 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.

返回:

  • 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.

返回:

  • 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

Functions

void *esp_gmf_oal_mutex_create(void)

Allocates and initializes a new mutex object for synchronization.

返回:

  • 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.

参数:

mutex[in] Pointer to the mutex to destroy

返回:

  • 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.

参数:

mutex[in] Pointer to the mutex to lock

返回:

  • 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.

参数:

mutex[in] Pointer to the mutex to unlock

返回:

  • 0 on success

  • Negative value if an error occurs

Header File

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.

备注

  • 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

参数:
  • 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)

返回:

  • 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.

参数:

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

返回:

  • ESP_GMR_ERR_OK Operation successful

Type Definitions

typedef void *esp_gmf_oal_thread_t

Header File

Functions

int esp_gmf_oal_sys_get_tick_by_time_ms(int ms)

Get system ticks based on the given millisecond value.

参数:

ms[in] Time in milliseconds

返回:

  • The corresponding system ticks

int64_t esp_gmf_oal_sys_get_time_ms(void)

Retrieve the current system time in milliseconds.

返回:

  • 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.

备注

  • 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

参数:
  • elapsed_time_ms[in] Time period for the CPU usage measurement in milliseconds

  • markdown[in] Whether print use markdown format

返回:

  • 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

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()`.
参数:
  • 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

返回:

  • 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.
参数:

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

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

此文档对您有帮助吗?