系统工具
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 的可用性与对齐要求:
esp_gmf_oal_mem_spiram_is_enabled():当前固件是否启用了 PSRAMesp_gmf_oal_mem_spiram_stack_is_enabled():是否允许把任务栈放在 PSRAMesp_gmf_oal_get_spiram_cache_align():PSRAM cache 的对齐字节数
自定义处理单元需要跨 PSRAM 边界 DMA 时,用 esp_gmf_oal_get_spiram_cache_align() 取出对齐值,填入 ESP_GMF_ELEMENT_*_PORT_ATTR_SET 的 buf_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_parser 将 scheme://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 xTaskCreateStaticto be able to use external memory for task stack, namelyCONFIG_SPIRAM_BOOT_INIT=yandCONFIG_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_tstructure 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_tobject 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)
-
char *scheme
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