# 数据流转

[English]

本篇介绍数据在处理单元（element）之间的流转方式，涵盖数据载体（payload）的字段与所有权、数据端口（port）的 acquire-release 协议、外部接口（IO）在处理链首尾的衔接行为，以及字节缓存（cache）。

处理单元（element）的生命周期、端口属性、能力描述（capability）与运行时方法（method）见 GMF 处理单元。处理链（pipeline）编排、执行线程（task）调度、生命周期与控制接口见 GMF 处理链与任务调度。数据总线（data bus）四种实现及其选型见 数据总线。整体架构与对象关系参考 GMF-Core 概览。

## 数据载体、数据端口

每个处理单元对外只暴露两个数据接口：输入数据端口与输出数据端口。数据在数据端口之间以 `esp_gmf_payload_t` 的形式传递，处理单元不负责分配缓冲区，也不负责跨线程同步，只需按一套 acquire-release 协议读写数据。

一次 `process` 中数据的完整流动如下，以一条 `Decoder → Resample` 处理链为例。

            sequenceDiagram
        participant T as 执行线程
        participant E as resample
        participant IP as in_port
        participant OP as out_port
        participant D as 下游

        T->>+E: process()
        E->>+IP: acquire_in(size)
        IP-->>-E: 输入数据载体 in
        E->>+OP: acquire_out(size)
        OP-->>-E: 输出数据载体 out
        Note over E: 处理输入并生成输出
        E->>OP: release_out(out)
        OP->>D: 提交输出数据载体
        E->>IP: release_in(in)
        E-->>-T: ok

以上序列包含两条规则。第一，`acquire_in` 返回的数据载体在 `release_in` 之前仍归当前处理单元使用，端口会通过引用计数或下层实现维持这段数据的有效性；处理单元不需要自行处理跨线程同步。第二，`release_out` 提交输出数据载体。对块型数据端口，提交过程通常不拷贝数据，而是把数据载体交给下游输入端口或下层数据队列，一份数据可以穿越整条处理链而不产生中间拷贝。

acquire-release 是 GMF-Core 数据通路的基础协议，下面分别展开数据载体与数据端口的细节。

## 数据载体

### 字段

`esp_gmf_payload_t` 定义在 `esp_gmf_payload.h`，字段如下。

字段 | 类型 | 含义
--- | --- | ---
`buf` | `uint8_t*` | 指向数据缓冲区
`buf_length` | `size_t` | 缓冲区总长度
`valid_size` | `size_t` | 缓冲区中有效数据的长度
`is_done` | `bool` | 流结束标志，最后一块数据置 1，触发处理链进入 `FINISHED`
`pts` | `uint64_t` | 显示时间戳，用于音视频同步
`needs_free` | `uint8_t` | 1 位位域，指示 `buf` 是否需要在数据载体销毁时自动释放
`meta_flag` | `uint8_t` | 7 位位域，目前定义了 `ESP_GMF_META_FLAG_AUD_RECOVERY_PLC` 用于标记通过丢包补偿恢复的音频帧

### 生命周期与所有权

处理单元代码中的数据载体表现为一个 `esp_gmf_payload_t` * 指针。所有权在 acquire-release 期间属于当前处理单元，归还后回到数据端口与数据总线管理。使用时遵循三条规则：

- 不要自行 free：acquire 得到的数据载体由数据端口管理，处理单元只能读写 `buf` 内容，不能调用 `esp_gmf_payload_delete`。

- valid_size 由写方设置：申请到一块输出数据载体后，处理单元写入数据并把实际写入的字节数填到 `valid_size`，下游据此判断有多少有效数据。

- acquire 与 release 成对：即使处理过程出错也必须 release，否则数据端口进入泄漏状态，后续调用会耗尽缓冲区。

处理单元自己分配数据载体的场景（较少见，典型是源头外部接口处理单元）可以用 `esp_gmf_payload_new()` 或 `esp_gmf_payload_new_with_len()` 显式创建，在不再引用时用 `esp_gmf_payload_delete()` 释放。需要满足 PSRAM cache 对齐时用 `esp_gmf_payload_realloc_aligned_buf()`。

### is_done 与 pts

`is_done` 是处理链从 `RUNNING` 自然过渡到 `FINISHED` 的信号。外部接口处理单元读到文件末尾时把 `is_done` 置 1 随数据载体下发，下游处理单元依次处理完带结束标记的数据载体后，逐级触发 close。

`pts` 是显示时间戳，通常由源头处理单元填充。中间处理单元按需更新或直接透传。接近播放端的处理单元据此做音视频同步。

## 数据端口

### 方向与类型

每个数据端口由两个属性定义。

方向：`ESP_GMF_PORT_DIR_IN` 表示输入数据端口（从上游读取数据载体），`ESP_GMF_PORT_DIR_OUT` 表示输出数据端口（向下游写入数据载体）。每个处理单元有一个输入数据端口和一个输出数据端口。

类型：字节型和块型两种，对应两种数据交换策略。

- `ESP_GMF_PORT_TYPE_BYTE`（字节型）让处理单元按任意字节数读写，框架负责必要时的内部拷贝与拼接。适合解码器解析协议头这类需要精确定长访问的场景。

- `ESP_GMF_PORT_TYPE_BLOCK`（块型）一次访问一整块，不做拷贝，只在数据端口之间传递缓冲区地址。适合处理整帧视频或批量 PCM，性能更高但可配置性较低。

### acquire-release 协议

数据端口对外暴露四个 API，成对使用形成 acquire-release 访问协议。以 `acquire_in` 为例说明完整签名：

    esp_gmf_err_io_t esp_gmf_port_acquire_in(
        esp_gmf_port_handle_t   handle,
        esp_gmf_payload_t     **load,
        uint32_t                wanted_size,
        int                     wait_ticks);

四个参数的作用：

- `handle` 是输入数据端口句柄。

- `load` 是输出参数，调用返回后 `*load` 指向一块准备好供读取的数据载体。

- `wanted_size` 是处理单元期望获取的数据长度。对源头外部接口或绑定数据总线的数据端口，底层实现会按该值准备数据；对已经由上游处理单元提交到输入数据端口的数据载体，端口会直接返回当前数据载体，实际有效长度以 `(*load)->valid_size` 为准。

- `wait_ticks` 是等待超时时间，单位为系统 tick。`ESP_GMF_MAX_DELAY` 表示无限等待，`0` 表示立即返回。

返回值类型是 `esp_gmf_err_io_t`：

返回码 | 值 | 含义
--- | --- | ---
`ESP_GMF_IO_OK` | `>= 0` | 成功，值表示实际读到的字节数
`ESP_GMF_IO_FAIL` | -1 | 操作失败
`ESP_GMF_IO_TIMEOUT` | -2 | 等待超时
`ESP_GMF_IO_ABORT` | -3 | 被 `esp_gmf_db_abort` 或执行线程 stop 主动中止

处理单元代码处理返回值的模板：

    esp_gmf_payload_t *in_load = NULL;
    esp_gmf_err_io_t ret = esp_gmf_port_acquire_in(in_port, &in_load, 1024, ESP_GMF_MAX_DELAY);
    if (ret == ESP_GMF_IO_ABORT) {
        return ESP_GMF_JOB_ERR_ABORT;
    } else if (ret < 0) {
        return ESP_GMF_JOB_ERR_FAIL;
    }
    /* 使用 in_load->buf, in_load->valid_size */

四个 API 成对工作：

- 读入侧：`acquire_in` 获取可读数据载体，处理单元消费后 `release_in` 归还

- 写出侧：`acquire_out` 获取可写数据载体，处理单元填充后 `release_out` 提交

process 中的典型调用顺序是先 `acquire_in` 获取输入，再 `acquire_out` 准备输出缓冲区，处理完后先 `release_out` 提交下游，最后 `release_in` 归还输入。先申请 out 再处理，可以在下游阻塞时提前等待，避免处理完成后才发现输出端口不可用。

acquire 与 release 必须成对出现，即使处理过程出错也要 release。框架提供了几个辅助宏简化错误路径：

    ESP_GMF_PORT_ACQUIRE_IN_CHECK(TAG, ret, err, goto ACQ_FAIL);
    ESP_GMF_PORT_RELEASE_IN_CHECK(TAG, ret, err, goto REL_FAIL);

这些宏把返回值检查和错误分支收敛到一行。

### 共享缓冲区管理

GMF 通过两种机制减少内存占用，避免不必要的数据拷贝。

引用计数

旁路或原地处理的处理单元，可将同一份数据载体直接传递给下游处理单元或用户应用。每增加一个使用者，数据端口的 `ref_count` 加一；对应 `release_in` / `release_out` 完成后减一。计数归零时，端口调用下层 `release` 回调回收缓冲区。共享行为由数据端口的 `is_shared` 标志控制，可通过 `esp_gmf_port_enable_payload_share()` 开启或关闭（默认可共享）。

            flowchart LR
        Source --> Bypass
        Bypass --> User["用户"]
        Bypass --> Downstream["下游处理单元"]

上述流程中始终共享同一份数据，无需额外拷贝。

缓冲区复用（AB Buffer）

需要生成新输出数据的处理单元，框架通过 `is_shared` 在各处理单元之间复用数据载体缓冲区。以处理链 `A → B → C` 为例：

    A → B → C

- A 输出 Buffer A。

- B 以 Buffer A 为输入，处理后写入 Buffer B。

- B 完成后，Buffer A 可被回收并再次分配。

- C 以 Buffer B 为输入，其输出可复用已释放的 Buffer A。

数据沿处理链推进时，Buffer A 与 Buffer B 交替复用。处理链包含多个处理单元时，通常只需两块工作缓冲区即可完成流转，降低内存消耗。

处理单元在初始化时会声明输入输出数据端口的约束，例如端口类型、对齐要求和每次 acquire 推荐的数据量。端口属性属于处理单元配置，完整说明见 GMF 处理单元。

数据端口对应的数据队列由数据总线负责。GMF-Core 提供四种数据总线（ringbuffer / fifo / block / pbuf），数据端口在创建时绑定其中一种，处理单元代码看到的接口完全一致。四种实现的取舍与流控接口见 数据总线。

## 外部接口（IO）

外部接口（`esp_gmf_io_t`）是处理链首尾的特殊处理单元，承担文件、网络、编解码器等外部数据源的读写。除基础的 `open` / `acquire` / `release` / `close` 外，还支持异步模式：由 `io_process` 执行线程将数据写入内部数据总线，调用方从缓存读取，以平滑 HTTP 下载等速率波动；可通过 `esp_gmf_io_speed_stats_t` 获取即时与平均传输速率（Kbps）。此外还提供数据源切换、中断恢复等高级控制接口。

### 同步与异步两种工作模式

外部接口在创建时通过 `esp_gmf_io_cfg_t` 配置工作模式。

同步模式：`thread.stack = 0` 且不配置 `buffer_cfg`。`esp_gmf_io_acquire_read` 直接在调用线程上下文中执行底层外部接口操作（例如 `fread`）。优点是延迟低、内存占用小；缺点是调用方必须能容忍外部接口操作存在较长阻塞（例如网络读）。

异步模式：`thread.stack > 0` 且配置 `buffer_cfg.buffer_size`。框架内部创建一个 `io_process` 执行线程，独立完成底层外部接口操作并把数据缓存到数据总线。用户调用 `acquire_read` 时实际从数据总线中读取，与底层外部接口解耦。这种模式适合”读固定字节数”或”生产消费速率差异大”的场景，例如解码器需要稳定的字节流而网络下载存在突发。

    esp_gmf_io_cfg_t cfg = {
        .thread = {
            .stack = 4 * 1024,
            .prio  = 5,
            .core  = 0,
        },
        .buffer_cfg = {
            .io_size     = 4096,   /* 每次底层 IO 读取大小 */
            .buffer_size = 16 * 1024,
            .read_filter = NULL,
        },
        .enable_speed_monitor = true,
    };

### URL 评分策略

`esp_gmf_io_t` 的 `get_score` 用于获取匹配度，便于从注册池中的多个外部接口里找到最匹配的外部接口。注册池函数 `esp_gmf_pool_get_io_tag_by_url` 遍历所有已注册外部接口的 `get_score`，返回评分最高者。三档评分定义：

评分 | 值 | 含义
--- | --- | ---
`ESP_GMF_IO_SCORE_NONE` | 0 | 外部接口不支持该 URL
`ESP_GMF_IO_SCORE_STANDARD` | 50 | 协议头匹配，例如 `http://` 由 HTTP 外部接口处理
`ESP_GMF_IO_SCORE_PERFECT` | 100 | 协议加扩展名都匹配，或专用 IO 高优先级匹配

自定义外部接口实现 `get_score` 时可以返回任意中间值，便于在多个候选外部接口中区分优先级。

### 无缝衔接与重置

`esp_gmf_io_reload()` 用一个新 URI 重新开启已有外部接口，不销毁底层连接。主要面向 HLS 切片这类”同主机连续下载多个分片”的场景，复用 HTTP 连接以避免反复握手的开销。重新加载内部对异步外部接口做了三件事：清 `data_bus` 的 EOF 标志、清 abort 标志、调用外部接口的 `reload` 回调重新打开新 URI。`reload` 必须在前一次读取完成后调用。

`esp_gmf_io_reset()` 做更全面的清理：把位置和文件大小清零、调用外部接口的 `reset` 回调、重置执行线程并重新加载外部接口 process job。常用于处理链 reset 之后对外部接口做配套清理。

### done / abort 控制

IO 层对 done 与 abort 的控制接口与数据总线一一对应，但在异步模式下还会额外管理 IO 执行线程的 hold 状态。

- `esp_gmf_io_done()` 标记 EOF：abort 异步外部接口的数据总线并把执行线程 hold 住，下游 `acquire` 会获取带 `is_done` 的数据载体。调用方在切换到下一个数据源前必须调用 `esp_gmf_io_clear_done()` 释放被 hold 的执行线程，否则后续外部接口不会推进。

- `esp_gmf_io_abort()` 立即中止当前操作：数据总线 abort、执行线程 hold，所有 `acquire` / `release` 返回 `ESP_GMF_IO_ABORT`。配套的 `esp_gmf_io_clear_abort()` 恢复正常工作。

播放列表切换曲目的典型流程：

    /* 当前曲目播放完毕 */
    esp_gmf_io_done(io_handle);

    /* 等待处理链处理完剩余数据载体 */
    ...

    /* 切换到下一首 */
    esp_gmf_io_set_uri(io_handle, next_uri);
    esp_gmf_io_clear_done(io_handle);
    /* 处理链继续运行，无需重建 */

### 自定义数据载体处理

`esp_gmf_io_buffer_cfg_t` 的 `read_filter` 回调允许在外部接口读到原始数据后、写入数据总线之前插入自定义处理。常见用途包括解密、字节序转换、协议解封装。回调签名：

    esp_gmf_err_t (*read_filter)(esp_gmf_io_handle_t obj,
                                  void *payload,
                                  uint32_t wanted_size,
                                  int block_ticks);

读到的数据载体在回调中可以原地修改 `buf` 与 `valid_size`。

### 速度监控

把 `esp_gmf_io_cfg_t` 的 `enable_speed_monitor` 置 true 后，框架会维护当前与平均传输速度（Kbps），通过 `esp_gmf_io_get_speed_stats()` 取出 `esp_gmf_io_speed_stats_t`。运行中也可以用 `esp_gmf_io_enable_speed_monitor()` 动态开关。常用于网络状况监测与传输速率自适应。

## 字节缓存（cache）

块型数据端口一次 acquire 返回一整块数据，而解码器这类处理单元常常需要”从数据流中精确读 N 个字节”。`esp_gmf_cache` 模块提供字节级缓存能力：

    esp_gmf_cache_handle_t cache;
    esp_gmf_cache_new(1024, &cache);

    /* 每次 acquire 到一块 block 数据载体后，提交给 cache */
    esp_gmf_cache_load(cache, in_load->buf, in_load->valid_size);

    /* 然后按任意字节数读 */
    int read;
    esp_gmf_cache_acquire(cache, 7, out_buf, &read);
    esp_gmf_cache_release(cache, 7);

字节缓存内部维护一个可扩展的滑动缓冲区。处理单元可以连续把多块数据载体中的字节加载到字节缓存中，再按需要读取任意长度的数据；即使一次读取跨越两块数据载体的边界，字节缓存也会从内部缓冲区中连续返回。典型使用场景是音频解码器解析协议头或帧头。

## API 参考

本篇涉及的头文件：

- `esp_gmf_payload.h`：数据载体结构与生命周期

- `esp_gmf_port.h`：数据端口的配置与访问 API

- `esp_gmf_cache.h`：字节缓存

- `esp_gmf_io.h`：外部接口对象的公共接口

### Header File

- gmf_core/include/esp_gmf_payload.h

### Functions

esp_gmf_err_t esp_gmf_payload_new(esp_gmf_payload_t **instance)

  Create a new payload instance without buffer.

  参数:

    instance – [out] Pointer to store the newly created payload instance

  返回:

    - ESP_GMF_ERR_OK On success

    - ESP_GMF_ERR_MEMORY_LACK Not enough memory to create the payload instance

    - ESP_GMF_ERR_INVALID_ARG Invalid argument provided

esp_gmf_err_t esp_gmf_payload_new_with_len(uint32_t buf_length, esp_gmf_payload_t **instance)

  Create a new payload instance and buffer by specified buffer length.

  参数:

    - buf_length – [in] Length of the payload buffer

    - instance – [out] Pointer to store the newly created payload instance

  返回:

    - ESP_GMF_ERR_OK On success

    - ESP_GMF_ERR_MEMORY_LACK Not enough memory to create the payload instance

    - ESP_GMF_ERR_INVALID_ARG Invalid argument provided

esp_gmf_err_t esp_gmf_payload_copy_data(esp_gmf_payload_t *src, esp_gmf_payload_t *dest)

  Copy data and done flag from one payload instance to another.

  参数:

    - src – [in] Source payload instance

    - dest – [out] Destination payload instance

  返回:

    - ESP_GMF_ERR_OK On success

    - ESP_GMF_ERR_INVALID_ARG Invalid argument provided

esp_gmf_err_t esp_gmf_payload_realloc_buf(esp_gmf_payload_t *instance, uint32_t new_length)

  Reallocate the buffer of a payload instance to the specified length Unlike `realloc`，the original valid data in the buffer was not copied to the new buffer.

  参数:

    - instance – [in] Payload instance to reallocate the buffer for

    - new_length – [in] New length for the payload buffer

  返回:

    - ESP_GMF_ERR_OK On success

    - ESP_GMF_ERR_MEMORY_LACK Not enough memory to reallocate the buffer

    - ESP_GMF_ERR_INVALID_ARG Invalid instance or new_length is zero

esp_gmf_err_t esp_gmf_payload_realloc_aligned_buf(esp_gmf_payload_t *instance, uint8_t align, uint32_t new_length)

  Reallocate the buffer of a payload instance to the specified length with specified byte alignment Behavior same as `esp_gmf_payload_realloc_buf` with an additional alignment request Unlike `realloc`，the original valid data in the buffer was not copied to the new buffer.

  参数:

    - instance – [in] Payload instance to reallocate the buffer for

    - align – [in] Byte alignment for the new payload buffer

    - new_length – [in] New length for the payload buffer

  返回:

    - ESP_GMF_ERR_OK On success

    - ESP_GMF_ERR_MEMORY_LACK Not enough memory to reallocate the buffer

    - ESP_GMF_ERR_INVALID_ARG Invalid instance or new_length is zero

esp_gmf_err_t esp_gmf_payload_realloc_buffer_with_separate_alignment(esp_gmf_payload_t *instance, uint8_t addr_align, uint8_t size_align, uint32_t new_length)

  Reallocate the payload buffer with separate address and length alignment.

  备注

  Unlike `realloc`, the original valid data in the buffer is not copied to the new buffer. `addr_align` 0 substitutes `esp_gmf_oal_get_spiram_cache_align()`; use `1` for natural heap alignment (`calloc`). When `size_align` is greater than `1`, it must be a power of two; the allocated byte length is rounded up to a multiple of `size_align`. Use `0` or `1` for `size_align` to keep `new_length` unchanged.

  参数:

    - instance – [in] Payload instance to reallocate the buffer for

    - addr_align – [in] Byte alignment of the buffer base address

    - size_align – [in] Byte alignment used to round up the requested buffer length

    - new_length – [in] Minimum usable length for the payload buffer

  返回:

    - ESP_GMF_ERR_OK On success

    - ESP_GMF_ERR_MEMORY_LACK Not enough memory to reallocate the buffer

    - ESP_GMF_ERR_INVALID_ARG Invalid instance, new_length is zero, or invalid alignment

esp_gmf_err_t esp_gmf_payload_set_done(esp_gmf_payload_t *instance)

  Set the done flag for a payload instance.

  参数:

    instance – [in] Payload instance to set as done

  返回:

    - ESP_GMF_ERR_OK On success

    - ESP_GMF_ERR_INVALID_ARG Invalid argument provided

esp_gmf_err_t esp_gmf_payload_clean_done(esp_gmf_payload_t *instance)

  Clean the done flag for a payload instance.

  参数:

    instance – [in] Payload instance to clean the done status for

  返回:

    - ESP_GMF_ERR_OK On success

    - ESP_GMF_ERR_INVALID_ARG Invalid argument provided

void esp_gmf_payload_delete(esp_gmf_payload_t *instance)

  Delete a payload instance, if needs_free is set free associated resources.

  参数:

    instance – [in] Payload instance to delete

### Structures

struct esp_gmf_payload_t

  Structure representing a payload in GMF.

  Public Members

  uint8_t *buf

    Pointer to the payload buffer

  size_t buf_length

    Length of the payload buffer

  size_t valid_size

    Size of valid data in the payload buffer

  bool is_done

    Flag indicating if this payload buffer marks the end of the stream

  uint64_t pts

    Presentation time stamp

  uint8_t needs_free

    Flag indicating if the payload buffer needs to be freed by esp_gmf_payload_delete or not

  uint8_t meta_flag

    Meta flag for the payload

### Macros

ESP_GMF_META_FLAG_AUD_RECOVERY_PLC

  The meta flag for the current payload.

  The current frame is recovered through the packet loss concealment (PLC) mechanism

### Header File

- gmf_core/include/esp_gmf_port.h

### Functions

esp_gmf_err_t esp_gmf_port_init(esp_gmf_port_config_t *cfg, esp_gmf_port_handle_t *out_result)

  Initialize a GMF port with the given configuration.

  参数:

    - cfg – [in] Pointer to the configuration structure

    - out_result – [out] Pointer to store the result handle after initialization

  返回:

    - ESP_GMF_ERR_OK On success

    - ESP_GMF_ERR_INVALID_ARG Invalid argument

    - ESP_GMF_ERR_MEMORY_LACK Memory allocate failed

esp_gmf_err_t esp_gmf_port_deinit(esp_gmf_port_handle_t handle)

  Deinitialize a GMF port.

  参数:

    handle – [in] The handle of the port to be deinitialized

  返回:

    - ESP_GMF_ERR_OK On success

    - ESP_GMF_ERR_INVALID_ARG Invalid argument

esp_gmf_err_t esp_gmf_port_set_payload(esp_gmf_port_handle_t handle, esp_gmf_payload_t *load)

  Set the self payload for the specific port.

  参数:

    - handle – [in] The handle of the port

    - load – [in] Pointer to the payload structure

  返回:

    - ESP_GMF_ERR_OK On success

    - ESP_GMF_ERR_INVALID_ARG Invalid argument

esp_gmf_err_t esp_gmf_port_clean_payload_done(esp_gmf_port_handle_t handle)

  Clean the payload done status of a GMF port.

  参数:

    handle – [in] The handle of the port

  返回:

    - ESP_GMF_ERR_OK On success

    - ESP_GMF_ERR_INVALID_ARG Invalid argument

esp_gmf_err_t esp_gmf_port_enable_payload_share(esp_gmf_port_handle_t handle, bool enable)

  Enables or disables shared payload for the specified port.

  参数:

    - handle – [in] The port handle to enable or disable payload sharing on

    - enable – [in] Set to true to enable payload sharing, or false to disable it

  返回:

    - ESP_GMF_ERR_OK On success

    - ESP_GMF_ERR_INVALID_ARG Invalid argument provided

esp_gmf_err_t esp_gmf_port_reset(esp_gmf_port_handle_t handle)

  Reset the port payload and variable of self payload.

  参数:

    handle – [in] The handle of the port

  返回:

    - ESP_GMF_ERR_OK On success

    - ESP_GMF_ERR_INVALID_ARG Invalid argument

esp_gmf_err_t esp_gmf_port_set_wait_ticks(esp_gmf_port_handle_t handle, int wait_ticks_ms)

  Set the wait ticks for the specific port.

  参数:

    - handle – [in] The handle of the port

    - wait_ticks_ms – [in] Number of milliseconds to wait

  返回:

    - ESP_GMF_ERR_OK On success

    - ESP_GMF_ERR_INVALID_ARG Invalid argument

esp_gmf_err_t esp_gmf_port_set_reader(esp_gmf_port_handle_t handle, void *reader)

  Set the esp_gmf_port_acquire_in and esp_gmf_port_release_in caller for the specific port.

  参数:

    - handle – [in] The handle of the port

    - reader – [in] Pointer to the reader

  返回:

    - ESP_GMF_ERR_OK On success

    - ESP_GMF_ERR_INVALID_ARG Invalid argument

esp_gmf_err_t esp_gmf_port_set_writer(esp_gmf_port_handle_t handle, void *writer)

  Set the esp_gmf_port_acquire_out and esp_gmf_port_acquire_out caller for the specific port.

  参数:

    - handle – [in] The handle of the port

    - writer – [in] Pointer to the writer

  返回:

    - ESP_GMF_ERR_OK On success

    - ESP_GMF_ERR_INVALID_ARG Invalid argument

esp_gmf_err_t esp_gmf_port_add_last(esp_gmf_port_handle_t head, esp_gmf_port_handle_t io_inst)

  Add a GMF port to the end of the list.

  参数:

    - head – [in] The head of the port list

    - io_inst – [in] The port instance to be added

  返回:

    - ESP_GMF_ERR_OK On success

    - ESP_GMF_ERR_INVALID_ARG Invalid argument

esp_gmf_err_t esp_gmf_port_del_at(esp_gmf_port_handle_t *head, esp_gmf_port_handle_t io_inst)

  Delete a GMF port from the list.

  参数:

    - head – [inout] A pointer to the head of the port list

    - io_inst – [in] The port instance to be deleted

  返回:

    - ESP_GMF_ERR_OK On success

    - ESP_GMF_ERR_INVALID_ARG Invalid argument

esp_gmf_err_io_t esp_gmf_port_acquire_in(esp_gmf_port_handle_t handle, esp_gmf_payload_t **load, uint32_t wanted_size, int wait_ticks)

  Acquire the expected valid data into the specified payload, regardless of whether the payload is NULL or not If writer of port is valid, the payload from the previous element stored on the port `payload` pointer is fetched If the `*load` pointer is NULL, a new payload will be allocated before calling the acquire operation The actual valid size is stored in `load->valid_size`

  参数:

    - handle – [in] The handle of the port

    - load – [inout] Pointer to store the acquired payload

    - wanted_size – [in] Size of the payload to be acquired

    - wait_ticks – [in] Number of ticks to wait, in milliseconds

  返回:

    - ESP_GMF_IO_OK Operation successful

    - ESP_GMF_IO_FAIL Operation failed or invalid arguments

    - ESP_GMF_IO_ABORT Operation aborted

    - ESP_GMF_IO_TIMEOUT Operation timed out

esp_gmf_err_io_t esp_gmf_port_release_in(esp_gmf_port_handle_t handle, esp_gmf_payload_t *load, int wait_ticks)

  Call the release operation or clean the payload pointer of the port.

  参数:

    - handle – [in] The handle of the port

    - load – [in] Pointer to the payload to be released

    - wait_ticks – [in] Number of ticks to wait

  返回:

    - ESP_GMF_IO_OK Operation successful

    - ESP_GMF_IO_FAIL Operation failed or invalid arguments

    - ESP_GMF_IO_ABORT Operation aborted

    - ESP_GMF_IO_TIMEOUT Operation timed out

esp_gmf_err_io_t esp_gmf_port_acquire_out(esp_gmf_port_handle_t handle, esp_gmf_payload_t **load, uint32_t wanted_size, int wait_ticks)

  Acquire the buffer of the expected size into the specified payload, If the reader of the port is valid, store the provided or allocated payload to the input port of the next element If reader pointer is NULL, prepare a payload if `*load` is invalid before calling the acquire operation The actual valid size is stored in `load->valid_size`

  参数:

    - handle – [in] The handle of the port

    - load – [inout] Pointer to store the acquired payload

    - wanted_size – [in] Size of the payload to be acquired

    - wait_ticks – [in] Number of ticks to wait, in milliseconds

  返回:

    - ESP_GMF_IO_OK Operation successful

    - ESP_GMF_IO_FAIL Operation failed or invalid arguments

    - ESP_GMF_IO_ABORT Operation aborted

    - ESP_GMF_IO_TIMEOUT Operation timed out

esp_gmf_err_io_t esp_gmf_port_release_out(esp_gmf_port_handle_t handle, esp_gmf_payload_t *load, int wait_ticks)

  Call the release operation or clean the payload pointer of the port.

  参数:

    - handle – [in] The handle of the port

    - load – [in] Pointer to the payload to be released

    - wait_ticks – [in] Number of ticks to wait

  返回:

    - ESP_GMF_IO_OK Operation successful

    - ESP_GMF_IO_FAIL Operation failed or invalid arguments

    - ESP_GMF_IO_ABORT Operation aborted

    - ESP_GMF_IO_TIMEOUT Operation timed out

static inline void *NEW_ESP_GMF_PORT(uint8_t dir, uint8_t type, void *acq, void *release, void *del, void *ctx, int length, int ticks_ms)

static inline void *NEW_ESP_GMF_PORT_IN_BYTE(void *acq, void *release, void *del, void *ctx, int length, int ticks_ms)

static inline void *NEW_ESP_GMF_PORT_OUT_BYTE(void *acq, void *release, void *del, void *ctx, int length, int ticks_ms)

static inline void *NEW_ESP_GMF_PORT_IN_BLOCK(void *acq, void *release, void *del, void *ctx, int length, int ticks_ms)

static inline void *NEW_ESP_GMF_PORT_OUT_BLOCK(void *acq, void *release, void *del, void *ctx, int length, int ticks_ms)

### Structures

struct esp_gmf_port_io_ops_t

  Structure defining the I/O operations of a GMF port.

  Public Members

  port_acquire acquire

    Function pointer for acquiring data

  port_release release

    Function pointer for releasing data

  port_free del

    Function pointer for freeing the port

struct esp_gmf_port_attr_t

  Structure defining the attributes of a GMF port.

  Public Members

  uint8_t buf_addr_aligned

    Byte-align the address of the buffer

  uint8_t buf_size_aligned

    Byte-align the length of the buffer

  uint8_t dir

    Port direction

  uint8_t type

    Port type

struct esp_gmf_port_

  Structure representing a GMF port The usage of the port in linked elements is as follows.

  +——&#8212;+ +————&#8212;+ +——-&#8212;+ | In Port +–&#8212;> First Element +-&#8212;> Out Port | +——&#8212;+ +—-&#8212;+—-&#8212;+ +——-&#8212;+ | v +——&#8212;+ +—-&#8212;+—-&#8212;+ +——-&#8212;+ | In Port +–&#8212;> More Element +-&#8212;> Out Port | +——&#8212;+ +—-&#8212;+—-&#8212;+ +——-&#8212;+ | v +——&#8212;+ +—-&#8212;+—-&#8212;+ +——-&#8212;+ | In Port +–&#8212;> Last Element +-&#8212;> Out Port | +——&#8212;+ +————&#8212;+ +——-&#8212;+

  Public Members

  struct esp_gmf_port_ *next

    Pointer to the next port

  void *writer

    Acquire out functions caller with the port

  void *reader

    Acquire in functions caller with the port

  esp_gmf_port_io_ops_t ops

    I/O operations of the port

  esp_gmf_port_attr_t attr

    Port attributes

  int data_length

    Data length of the payload

  void *ctx

    User context for the port

  int wait_ticks

    Timeout for port operations

  esp_gmf_payload_t *payload

    Payload pointer to be set

  uint8_t is_shared

    Payload is shared to the next element port or not, 1 for shared (default), 0 for dedicated

  esp_gmf_payload_t *self_payload

    Self payload of the port

  struct esp_gmf_port_ *ref_port

    Pointer to the reference port

  int8_t ref_count

    Reference count indicating the number of active references

struct esp_gmf_port_config_

  Structure defining the configuration of a GMF port.

  Public Members

  uint8_t dir

    Direction of the port

  uint8_t type

    Type of data handled by the port

  esp_gmf_port_io_ops_t ops

    I/O operations of the port

  void *ctx

    User context associated with the port

  int data_length

    Data length of the port

  int wait_ticks

    Timeout for port operations

### Macros

ESP_GMF_PORT_CHECK(log_tag, ret, ret_value, action, format, ...)

ESP_GMF_PORT_ACQUIRE_IN_CHECK(TAG, ret, ret_value, action)

ESP_GMF_PORT_ACQUIRE_OUT_CHECK(TAG, ret, ret_value, action)

ESP_GMF_PORT_RELEASE_IN_CHECK(TAG, ret, ret_value, action)

ESP_GMF_PORT_RELEASE_OUT_CHECK(TAG, ret, ret_value, action)

ESP_GMF_PORT_DIR_IN

  Definition the direction of a GMF port (input or output)

  Input port

ESP_GMF_PORT_DIR_OUT

  Output port

ESP_GMF_PORT_TYPE_BYTE

  Definition the bit mask for the type of data handled by a GMF port (byte or block)

  - A byte-type port transfers values by copying data byte by byte. Users must allocate memory, which means data transmission involves copying. This type of port allows convenient access to arbitrary byte lengths

  - A block-type port transfers data by passing memory addresses. The memory used by the user is provided by another source, so data transmission does not involve copying. However, accessing arbitrary byte lengths is less flexible and may require data concatenation Bit0 for the byte type of GMF port

ESP_GMF_PORT_TYPE_BLOCK

  Bit1 for the block type of GMF port

### Type Definitions

typedef struct esp_gmf_port_ *esp_gmf_port_handle_t

  Handle to a GMF port.

typedef esp_gmf_err_io_t (*port_acquire)(void *handle, esp_gmf_payload_t *load, uint32_t wanted_size, int wait_ticks)

  Function pointer type for acquiring data from a port.

typedef esp_gmf_err_io_t (*port_release)(void *handle, esp_gmf_payload_t *load, int wait_ticks)

  Function pointer type for releasing data from a port.

typedef void (*port_free)(void *p)

  Function pointer type for freeing a port.

typedef struct esp_gmf_port_ esp_gmf_port_t

  Structure representing a GMF port The usage of the port in linked elements is as follows.

  +——&#8212;+ +————&#8212;+ +——-&#8212;+ | In Port +–&#8212;> First Element +-&#8212;> Out Port | +——&#8212;+ +—-&#8212;+—-&#8212;+ +——-&#8212;+ | v +——&#8212;+ +—-&#8212;+—-&#8212;+ +——-&#8212;+ | In Port +–&#8212;> More Element +-&#8212;> Out Port | +——&#8212;+ +—-&#8212;+—-&#8212;+ +——-&#8212;+ | v +——&#8212;+ +—-&#8212;+—-&#8212;+ +——-&#8212;+ | In Port +–&#8212;> Last Element +-&#8212;> Out Port | +——&#8212;+ +————&#8212;+ +——-&#8212;+

typedef struct esp_gmf_port_config_ esp_gmf_port_config_t

  Structure defining the configuration of a GMF port.

### Header File

- gmf_core/include/esp_gmf_cache.h

### Functions

static inline esp_gmf_err_t esp_gmf_cache_new(uint32_t len, esp_gmf_cache_t **handle)

  Create a new GMF cache instance.

  参数:

    - len – [in] The size of the cache buffer to allocate

    - handle – [out] Pointer to the cache handle to be initialized

  返回:

    - ESP_GMF_ERR_OK Success, cache is initialized

    - ESP_GMF_ERR_INVALID_ARG If `handle` is NULL

    - ESP_GMF_ERR_MEMORY_LACK If memory allocation fails

static inline esp_gmf_err_t esp_gmf_cache_delete(esp_gmf_cache_t *handle)

  Delete a GMF cache instance and free associated memory.

  参数:

    handle – [in] Pointer to the cache handle

  返回:

    - ESP_GMF_ERR_OK Success, cache is deleted

    - ESP_GMF_ERR_INVALID_ARG If `handle` is NULL

static inline esp_gmf_err_t esp_gmf_cache_reset(esp_gmf_cache_t *handle)

  Reset a GMF cache instance to its initial state This function clears all cached data and resets the cache state, but preserves the allocated buffer memory.

  参数:

    handle – [in] Pointer to the cache handle

  返回:

    - ESP_GMF_ERR_OK Success, cache is reset

    - ESP_GMF_ERR_INVALID_ARG If `handle` is NULL

static inline esp_gmf_err_t esp_gmf_cache_ready_for_load(esp_gmf_cache_t *handle, bool *is_ready)

  Check if the cache is ready to load new data If the return `is_ready` is true, `esp_gmf_cache_load` can be called to load a new payload.

  参数:

    - handle – [in] Pointer to the cache handle

    - is_ready – [out] Pointer to a boolean flag indicating whether new data can be loaded

  返回:

    - ESP_GMF_ERR_OK Success, `is_ready` is set

    - ESP_GMF_ERR_INVALID_ARG If `handle` or `is_ready` is NULL

static inline esp_gmf_err_t esp_gmf_cache_load(esp_gmf_cache_t *handle, const esp_gmf_payload_t *load_in)

  Load new payload data into the cache Call `esp_gmf_cache_ready_for_load` before use to check if it is ready to load a new payload.

  参数:

    - handle – [in] Pointer to the cache handle

    - load_in – [in] Pointer to the payload data to be loaded

  返回:

    - ESP_GMF_ERR_OK Success, payload is loaded

    - ESP_GMF_ERR_INVALID_ARG If `handle` or `load_in` is NULL

    - ESP_GMF_ERR_INVALID_STATE If previous data has not been consumed

static inline esp_gmf_err_t esp_gmf_cache_acquire(esp_gmf_cache_t *handle, uint32_t expected_size, esp_gmf_payload_t **load_out)

  Acquire a data chunk of the expected size from the cache.

  备注

  - This function must be used in conjunction with `esp_gmf_cache_release`

  - The `expected_size` should match the internal buffer length

  - If `expected_size` exceeds the current buffer length, the buffer will be reallocated

  参数:

    - handle – [in] Pointer to the cache handle

    - expected_size – [in] The requested data size in bytes

    - load_out – [out] Pointer to store the acquired payload data

  返回:

    - ESP_GMF_ERR_OK Data successfully acquired

    - ESP_GMF_ERR_INVALID_ARG If `handle` or `load_out` is NULL

    - ESP_GMF_ERR_MEMORY_LACK Insufficient memory to allocate a new buffer

    - ESP_GMF_ERR_NOT_ENOUGH Cached data size less than expected size

static inline esp_gmf_err_t esp_gmf_cache_release(esp_gmf_cache_t *handle, esp_gmf_payload_t *load)

  Release the payload data previously acquired with `esp_gmf_cache_acquire`

  备注

  The filled portion of the buffer is cleared only if its size equals the buffer length

  参数:

    - handle – [in] Pointer to the cache handle

    - load – [in] Pointer to the payload data to be released

  返回:

    - ESP_GMF_ERR_OK Payload data successfully released

    - ESP_GMF_ERR_INVALID_ARG If either `handle` or `load` is NULL

static inline esp_gmf_err_t esp_gmf_cache_get_cached_size(esp_gmf_cache_t *handle, int *filled)

  Get the total amount of cached data.

  参数:

    - handle – [in] Pointer to the cache handle

    - filled – [out] Pointer to store the filled data size

  返回:

    - ESP_GMF_ERR_OK Success, `filled` is set

    - ESP_GMF_ERR_INVALID_ARG If `handle` or `filled` is NULL

### Structures

struct esp_gmf_cache_t

  This GMF payload cache module is designed to cache a data block of a specified size. Each call to acquire returns this fixed-size block. If the acquired data is smaller than the expected size, new data must be loaded. When sufficient data is available, release clears the cached block. It is commonly used in scenarios where an element can only process a fixed data size, but the input data length is variable. For example, if an element requires exactly 1350 bytes per processing cycle but receives input of varying lengths, you can create a cache with `esp_gmf_cache_new(1350, out_handle)`, and the element can then fetch data using `esp_gmf_cache_acquire`

  Structure representing a cache for GMF payloads

  Public Members

  uint8_t *buf

    Pointer to the cache buffer

  uint32_t buf_len

    Total allocated size of the cache buffer

  uint32_t buf_filled

    Amount of data currently stored in the buffer

  esp_gmf_payload_t origin_load

    Original payload from which data is copied

  esp_gmf_payload_t load

    Current payload structure for acquiring data

### Header File

- gmf_core/include/esp_gmf_io.h

### Functions

esp_gmf_err_t esp_gmf_io_init(esp_gmf_io_handle_t handle, esp_gmf_io_cfg_t *cfg)

  Initialize a I/O handle with the given configuration If the stack size is greater than 0, a GMF task is created with the process job registered.

  参数:

    - handle – [in] GMF I/O handle to initialize

    - cfg – [in] Pointer to the configuration structure

  返回:

    - ESP_GMF_ERR_OK On success

    - ESP_GMF_ERR_INVALID_ARG Invalid argument

    - ESP_GMF_ERR_MEMORY_LACK Insufficient memory to perform the job registration

    - ESP_GMF_ERR_FAIL Failed to create thread

esp_gmf_err_t esp_gmf_io_deinit(esp_gmf_io_handle_t handle)

  Deinitialize a GMF I/O handle, freeing associated resources.

  参数:

    handle – [in] GMF I/O handle to deinitialize

  返回:

    - ESP_GMF_ERR_OK On success

    - ESP_GMF_ERR_INVALID_ARG Invalid argument

esp_gmf_err_t esp_gmf_io_enable_speed_monitor(esp_gmf_io_handle_t handle, bool enabled)

  Enable or disable speed monitor for an I/O.

  参数:

    - handle – [in] I/O handle

    - enabled – [in] true to enable, false to disable

  返回:

    - ESP_GMF_ERR_OK On success

    - ESP_GMF_ERR_INVALID_ARG Invalid argument

esp_gmf_err_t esp_gmf_io_get_speed_stats(esp_gmf_io_handle_t handle, esp_gmf_io_speed_stats_t *stats)

  Get speed statistics for an I/O.

  参数:

    - handle – [in] I/O handle

    - stats – [out] Pointer to store speed statistics

  返回:

    - ESP_GMF_ERR_OK On success

    - ESP_GMF_ERR_INVALID_ARG Invalid argument

esp_gmf_err_t esp_gmf_io_get_score(esp_gmf_io_handle_t handle, const char *url, int *score)

  Evaluate how well the IO matches a given URL The score ranges from ESP_GMF_IO_SCORE_NONE to ESP_GMF_IO_SCORE_PERFECT:

  - ESP_GMF_IO_SCORE_NONE: No match (The IO does not support this URL).

  - ESP_GMF_IO_SCORE_STANDARD: Standard match (e.g., matching the URL scheme like “http://” or “file://”).

  - ESP_GMF_IO_SCORE_PERFECT: Perfect match (e.g., matching both scheme and file extension, or high priority specialized IO).

  参数:

    - handle – [in] GMF I/O handle

    - url – [in] URL to evaluate

    - score – [out] Pointer to store the calculated score

  返回:

    - ESP_GMF_ERR_OK On success

    - ESP_GMF_ERR_INVALID_ARG Invalid argument

    - ESP_GMF_ERR_NOT_SUPPORT The IO does not support scoring

esp_gmf_err_t esp_gmf_io_open(esp_gmf_io_handle_t handle)

  Open the specific I/O handle, run the thread if it is valid.

  参数:

    handle – [in] GMF I/O handle to open

  返回:

    - ESP_GMF_ERR_OK On success

    - ESP_GMF_ERR_INVALID_ARG Invalid argument

esp_gmf_err_t esp_gmf_io_seek(esp_gmf_io_handle_t handle, uint64_t seek_byte_pos)

  Seek to a specific byte position in the specific I/O handle If the IO thread is invalid, the IO’s seek function is called directly (synchronous). If the IO thread is valid, the seek is deferred to the IO task: the seek position is stored and the data bus is aborted to wake up the task. The IO task will process the seek at the beginning of its next iteration. The caller will block and wait for the IO task to complete the seek operation.

  参数:

    - handle – [in] GMF I/O handle

    - seek_byte_pos – [in] Byte position to seek to

  返回:

    - ESP_GMF_ERR_OK On success

    - ESP_GMF_ERR_INVALID_ARG Invalid argument

    - ESP_GMF_ERR_NOT_SUPPORT Not support

    - Others Indicating failure

esp_gmf_err_t esp_gmf_io_close(esp_gmf_io_handle_t handle)

  Close a GMF I/O handle If the IO task is active, this function will block and wait up to `task_timeout_ms` for the task to finish If both prev_close and thread are valid, they will be called before executing the IO close operation.

  参数:

    handle – [in] GMF I/O handle to close

  返回:

    - ESP_GMF_ERR_OK On success

    - ESP_GMF_ERR_INVALID_ARG Invalid argument

esp_gmf_err_io_t esp_gmf_io_acquire_read(esp_gmf_io_handle_t handle, esp_gmf_payload_t *load, uint32_t wanted_size, int wait_ticks)

  Acquire read access to the specific I/O handle.

  参数:

    - handle – [in] GMF I/O handle

    - load – [out] Pointer to store the acquired payload

    - wanted_size – [in] Desired payload size

    - wait_ticks – [in] Timeout value in ticks, in milliseconds

  返回:

    - ESP_GMF_IO_OK Operation successful (check load->is_done to see if IO is done)

    - ESP_GMF_IO_FAIL Operation failed or invalid arguments

    - ESP_GMF_IO_ABORT Operation aborted

    - ESP_GMF_IO_TIMEOUT Operation timed out

esp_gmf_err_io_t esp_gmf_io_release_read(esp_gmf_io_handle_t handle, esp_gmf_payload_t *load, int wait_ticks)

  Release read access to the specific I/O handle.

  参数:

    - handle – [in] GMF I/O handle

    - load – [in] Pointer to the payload to release

    - wait_ticks – [in] Timeout value in ticks

  返回:

    - ESP_GMF_IO_OK Operation successful (check load->is_done to see if IO is done)

    - ESP_GMF_IO_FAIL Operation failed or invalid arguments

    - ESP_GMF_IO_ABORT Operation aborted

    - ESP_GMF_IO_TIMEOUT Operation timed out

esp_gmf_err_io_t esp_gmf_io_acquire_write(esp_gmf_io_handle_t handle, esp_gmf_payload_t *load, uint32_t wanted_size, int wait_ticks)

  Acquire write access to the specific I/O handle.

  参数:

    - handle – [in] GMF I/O handle

    - load – [out] Pointer to store the acquired payload

    - wanted_size – [in] Desired payload size

    - wait_ticks – [in] Timeout value in ticks, in milliseconds

  返回:

    - ESP_GMF_IO_OK Operation successful (check load->is_done to see if IO is done)

    - ESP_GMF_IO_FAIL Operation failed or invalid arguments

    - ESP_GMF_IO_ABORT Operation aborted

    - ESP_GMF_IO_TIMEOUT Operation timed out

esp_gmf_err_io_t esp_gmf_io_release_write(esp_gmf_io_handle_t handle, esp_gmf_payload_t *load, int wait_ticks)

  Release write access to the specific I/O handle.

  参数:

    - handle – [in] GMF I/O handle

    - load – [in] Pointer to the payload to release

    - wait_ticks – [in] Timeout value in ticks

  返回:

    - ESP_GMF_IO_OK Operation successful (check load->is_done to see if IO is done)

    - ESP_GMF_IO_FAIL Operation failed or invalid arguments

    - ESP_GMF_IO_ABORT Operation aborted

    - ESP_GMF_IO_TIMEOUT Operation timed out

esp_gmf_err_t esp_gmf_io_set_info(esp_gmf_io_handle_t handle, esp_gmf_info_file_t *info)

  Set information for the specific I/O handle.

  参数:

    - handle – [in] GMF I/O handle

    - info – [in] Pointer to the file information structure

  返回:

    - ESP_GMF_ERR_OK On success

    - ESP_GMF_ERR_INVALID_ARG Invalid argument

esp_gmf_err_t esp_gmf_io_get_info(esp_gmf_io_handle_t handle, esp_gmf_info_file_t *info)

  Get information from the specific I/O handle.

  参数:

    - handle – [in] GMF I/O handle

    - info – [out] Pointer to store the file information

  返回:

    - ESP_GMF_ERR_OK On success

    - ESP_GMF_ERR_INVALID_ARG Invalid argument

esp_gmf_err_t esp_gmf_io_set_uri(esp_gmf_io_handle_t handle, const char *uri)

  Set the URI for the specific I/O handle.

  参数:

    - handle – [in] GMF I/O handle

    - uri – [in] Pointer to the URI string

  返回:

    - ESP_GMF_ERR_OK On success

    - ESP_GMF_ERR_INVALID_ARG Invalid argument

    - ESP_GMF_ERR_MEMORY_LACK Memory allocation failed

esp_gmf_err_t esp_gmf_io_get_uri(esp_gmf_io_handle_t handle, char **uri)

  Get the URI from the specific I/O handle.

  参数:

    - handle – [in] GMF I/O handle

    - uri – [out] Pointer to store the URI string

  返回:

    - ESP_GMF_ERR_OK On success

    - ESP_GMF_ERR_INVALID_ARG Invalid argument

esp_gmf_err_t esp_gmf_io_set_pos(esp_gmf_io_handle_t handle, uint64_t byte_pos)

  Set the byte position for the specific I/O handle.

  参数:

    - handle – [in] GMF I/O handle

    - byte_pos – [in] Byte position to set

  返回:

    - ESP_GMF_ERR_OK On success

    - ESP_GMF_ERR_INVALID_ARG Invalid argument

esp_gmf_err_t esp_gmf_io_update_pos(esp_gmf_io_handle_t handle, uint64_t byte_pos)

  Update the byte position for the specific I/O handle.

  参数:

    - handle – [in] GMF I/O handle

    - byte_pos – [in] Byte position to update

  返回:

    - ESP_GMF_ERR_OK On success

    - ESP_GMF_ERR_INVALID_ARG Invalid argument

esp_gmf_err_t esp_gmf_io_get_pos(esp_gmf_io_handle_t handle, uint64_t *byte_pos)

  Get the current byte position from the specific I/O handle.

  参数:

    - handle – [in] GMF I/O handle

    - byte_pos – [out] Pointer to store the current byte position

  返回:

    - ESP_GMF_ERR_OK On success

    - ESP_GMF_ERR_INVALID_ARG Invalid argument

esp_gmf_err_t esp_gmf_io_set_size(esp_gmf_io_handle_t handle, uint64_t total_size)

  Set the total size for the specific I/O handle.

  参数:

    - handle – [in] GMF I/O handle

    - total_size – [in] Total size to set

  返回:

    - ESP_GMF_ERR_OK On success

    - ESP_GMF_ERR_INVALID_ARG Invalid argument

esp_gmf_err_t esp_gmf_io_get_size(esp_gmf_io_handle_t handle, uint64_t *total_size)

  Get the total size from the specific I/O handle.

  参数:

    - handle – [in] GMF I/O handle

    - total_size – [out] Pointer to store the total size

  返回:

    - ESP_GMF_ERR_OK On success

    - ESP_GMF_ERR_INVALID_ARG Invalid argument

esp_gmf_err_t esp_gmf_io_get_db_filled_size(esp_gmf_io_handle_t handle, uint32_t *filled_size)

  Get the filled size in the data bus of the specific I/O handle.

  参数:

    - handle – [in] GMF I/O handle

    - filled_size – [out] Pointer to store the filled size in the data bus

  返回:

    - ESP_GMF_ERR_OK On success

    - ESP_GMF_ERR_INVALID_ARG Invalid argument

    - ESP_GMF_ERR_NOT_SUPPORT Operation not supported, the I/O instance does not have a configured data bus

esp_gmf_err_t esp_gmf_io_get_type(esp_gmf_io_handle_t handle, esp_gmf_io_type_t *type)

  Get the I/O type of the specific I/O handle.

  参数:

    - handle – [in] GMF I/O handle

    - type – [out] Pointer to store the I/O type

  返回:

    - ESP_GMF_ERR_OK On success

    - ESP_GMF_ERR_INVALID_ARG Invalid argument

esp_gmf_err_t esp_gmf_io_reset(esp_gmf_io_handle_t handle)

  Reset IO will do reset the position and size, call the reset function if it is valid, then reset the task and reload IO process job.

  参数:

    handle – [in] GMF I/O handle

  返回:

    - ESP_GMF_ERR_OK On success

    - ESP_GMF_ERR_INVALID_ARG Invalid argument

esp_gmf_err_t esp_gmf_io_reload(esp_gmf_io_handle_t handle, const char *uri)

  Reload Io with a URI. Used primarily for seamless transitions (e.g., Hls segments) Reload is specailly designed to optimized download efficiency This function is used to avoid reconnection which is time-consuming when download sequential urls from same host If the IO has an io_process task, this function will reset the done_write (EOF) flag of data_bus and rerun the task.

  备注

  This function should be called after the current IO operation (e.g., reading the resource) has finished.

  参数:

    - handle – [in] GMF I/O handle

    - uri – [in] Pointer to the URI string

  返回:

    - ESP_GMF_ERR_OK On success

    - ESP_GMF_ERR_INVALID_ARG Invalid argument

    - ESP_GMF_ERR_NOT_SUPPORT Not support

    - Others Indicating failure

esp_gmf_err_t esp_gmf_io_done(esp_gmf_io_handle_t handle)

  Mark an I/O as done, cause the `esp_gmf_io_acquire_*` / `esp_gmf_io_release_*` input parameter(load) to have the is_done flag set If the IO has an io_process task, this function will abort the data_bus and hold the task.

  备注

  Typical usage: when the current data source has been fully consumed (e.g. end of a track in a playlist), call this function to signal downstream consumers that no more data is available. The IO task will be held and stop producing data until `esp_gmf_io_clear_done` is called. Caller MUST call `esp_gmf_io_clear_done` before reusing the IO for the next data source, otherwise the IO task remains permanently held and will not process any further data.

  参数:

    handle – [in] GMF I/O handle

  返回:

    - ESP_GMF_ERR_OK On success

    - ESP_GMF_ERR_INVALID_ARG Invalid argument

esp_gmf_err_t esp_gmf_io_clear_done(esp_gmf_io_handle_t handle)

  Clear the done flag for an I/O, then `esp_gmf_io_acquire_*` / `esp_gmf_io_release_*` will operate normally Reset the position to 0 If the IO has an io_process task, this function will reset the data_bus and release the held task.

  备注

  Typical usage: after `esp_gmf_io_done` has been called and the caller is ready to start a new data source (e.g. switching to the next track), call this function to clear the done state, reset position to 0, and release the held IO task so it can resume producing data. This function should only be called after `esp_gmf_io_done`; calling it without a prior done has no effect.

  参数:

    handle – [in] GMF I/O handle

  返回:

    - ESP_GMF_ERR_OK On success

    - ESP_GMF_ERR_INVALID_ARG Invalid argument

esp_gmf_err_t esp_gmf_io_abort(esp_gmf_io_handle_t handle)

  Mark an I/O as aborted, then `esp_gmf_io_acquire_*` / `esp_gmf_io_release_*` will return ESP_GMF_IO_ABORT If the IO has an io_process task, this function will abort the data_bus and hold the task.

  备注

  Typical usage: when the IO operation needs to be interrupted immediately (e.g. user-initiated stop, network error recovery, or switching to a different URI). All ongoing and subsequent acquire/release calls will return ESP_GMF_IO_ABORT until `esp_gmf_io_clear_abort` is called. The IO task will be held and stop producing/consuming data. Caller MUST call `esp_gmf_io_clear_abort` to restore normal operation, otherwise the IO remains permanently in the aborted state and the task stays held.

  参数:

    handle – [in] GMF I/O handle

  返回:

    - ESP_GMF_ERR_OK On success

    - ESP_GMF_ERR_INVALID_ARG Invalid argument

esp_gmf_err_t esp_gmf_io_clear_abort(esp_gmf_io_handle_t handle)

  Clear the abort flag for an I/O, then `esp_gmf_io_acquire_*` / `esp_gmf_io_release_*` will operate normally If the IO has an io_process task, this function will clear abort on the data_bus and release the held task.

  备注

  Typical usage: after `esp_gmf_io_abort` has been called and the error condition has been resolved (e.g. network reconnected, new URI set), call this function to clear the abort state and release the held IO task so it can resume processing data. This function should only be called after `esp_gmf_io_abort`; calling it without a prior abort has no effect.

  参数:

    handle – [in] GMF I/O handle

  返回:

    - ESP_GMF_ERR_OK On success

    - ESP_GMF_ERR_INVALID_ARG Invalid argument

esp_gmf_err_t esp_gmf_io_set_task_timeout(esp_gmf_io_handle_t handle, int32_t timeout_ms)

  Set the timeout for internal IO task operation.

  参数:

    - handle – [in] GMF I/O handle

    - timeout_ms – [in] Timeout in milliseconds

  返回:

    - ESP_GMF_ERR_OK On success

    - ESP_GMF_ERR_INVALID_ARG Invalid argument

### Structures

struct esp_gmf_io_buffer_cfg_t

  Buffer configuration for GMF I/O.

  Public Members

  size_t io_size

    Each time io size in bytes

  size_t buffer_size

    Buffer size in bytes

  esp_gmf_err_t (*read_filter)(esp_gmf_io_handle_t obj, void *payload, uint32_t wanted_size, int block_ticks)

    Read filter callback function

struct esp_gmf_io_speed_stats_t

  Structure representing I/O speed statistics.

  Public Members

  uint64_t total_bytes

    Total bytes

  uint64_t last_total_bytes

    Last total bytes count for interval calculation

  uint64_t total_time_ms

    Total time in milliseconds

  uint64_t last_total_time_ms

    Last update total time in milliseconds

  uint32_t current_speed_kbps

    Current speed in Kbps

  uint32_t average_speed_kbps

    Average speed in Kbps

struct esp_gmf_io_cfg_t

  Configuration structure for a GMF I/O.

  Public Members

  esp_gmf_task_config_t thread

    Task configuration

  esp_gmf_io_buffer_cfg_t buffer_cfg

    Buffer configuration

  bool enable_speed_monitor

    Enable speed monitor

struct esp_gmf_io_

  Structure representing a GMF I/O.

  Public Members

  struct esp_gmf_obj_ parent

    Parent object

  esp_gmf_err_t (*get_score)(esp_gmf_io_handle_t obj, const char *url, int *score)

    Get score callback function

  esp_gmf_err_t (*open)(esp_gmf_io_handle_t obj)

    Open callback function

  esp_gmf_err_t (*seek)(esp_gmf_io_handle_t obj, uint64_t data)

    Seek callback function

  esp_gmf_err_t (*close)(esp_gmf_io_handle_t obj)

    Close callback function

  esp_gmf_err_t (*reset)(esp_gmf_io_handle_t obj)

    Reset callback function

  esp_gmf_err_t (*reload)(esp_gmf_io_handle_t obj, const char *uri)

    Reload callback function Previous close callback function For some block IO instances, this function can be called before the `close` operation

  esp_gmf_err_io_t (*acquire_read)(esp_gmf_io_handle_t handle, void *payload, uint32_t wanted_size, int block_ticks)

    Acquire read callback function

  esp_gmf_err_io_t (*release_read)(esp_gmf_io_handle_t handle, void *payload, int block_ticks)

    Release read callback function

  esp_gmf_err_io_t (*acquire_write)(esp_gmf_io_handle_t handle, void *payload, uint32_t wanted_size, int block_ticks)

    Acquire write callback function

  esp_gmf_err_io_t (*release_write)(esp_gmf_io_handle_t handle, void *payload, int block_ticks)

    Release write callback function

  esp_gmf_task_handle_t task_hd

    Task handle

  esp_gmf_db_handle_t data_bus

    Data bus handle for buffer

  esp_gmf_data_bus_block_t db_block

    Data bus block for data bus read/write operation

  esp_gmf_io_speed_stats_t *speed_stats

    Speed statistics for this I/O (dynamically allocated when enabled)

  void *evt_group

    Event group for IO control synchronization

  esp_gmf_io_dir_t dir

    I/O direction

  esp_gmf_io_type_t type

    I/O type

  esp_gmf_info_file_t attr

    File attribute

  uint64_t seek_pos

    Pending seek position (ESP_GMF_IO_SEEK_POS_INVALID = no pending seek)

  uint8_t _is_done

    Flag indicating if a done signal has been received

  uint8_t _is_abort

    Flag indicating if an abort signal has been received

  uint8_t _is_hold

    Flag indicating if the IO task should hold itself

  int32_t task_timeout_ms

    Timeout for internal IO task operation (default 1000 ms)

### Macros

ESP_GMF_IO_SCORE_NONE

  No match (The IO does not support this URL)

ESP_GMF_IO_SCORE_STANDARD

  Standard match (e.g., matching the URL scheme)

ESP_GMF_IO_SCORE_PERFECT

  Perfect match (e.g., matching both scheme and extension)

### Type Definitions

typedef void *esp_gmf_io_handle_t

  This GMF I/O abstraction can operate in two modes depending on configuration:

          1) Asynchronous I/O (data_bus + task configured)
          When the I/O is configured with a data bus (buffer configured) and a task (thread stack > 0 in esp_gmf_io_cfg_t), the framework
          creates an internal `io_process` task. That task is responsible for driving the data flow between the actual underlying I/O
          (open/seek/close callbacks) and the data bus. In this mode, user-facing APIs such as `esp_gmf_io_acquire_*` / `esp_gmf_io_release_*`
          interact with the data bus (buffered I/O). The task performs blocking or non-blocking reads/writes against the real I/O device and
          pushes/pulls data through the data bus. This model is suitable when the element needs fixed-size transfers or when decoupling
          the producer/consumer timing is desired.

          2) Synchronous I/O (no data_bus and no task)
          If no data bus and no task are configured, the I/O operates in synchronous mode: calls to `esp_gmf_io_acquire_*` / `esp_gmf_io_release_*`
          invoke the I/O driver's callbacks directly and perform actual I/O in the caller's context. Use this mode when the element can safely
          perform I/O on the caller thread or when buffering is not needed.

  Handle to a GMF I/O

typedef struct esp_gmf_io_ esp_gmf_io_t

  Structure representing a GMF I/O.

### Enumerations

enum esp_gmf_io_dir_t

  Enumeration for the direction of a GMF I/O (none, reader, writer)

  Values:

  enumerator ESP_GMF_IO_DIR_NONE

    No direction

  enumerator ESP_GMF_IO_DIR_READER

    Reader direction

  enumerator ESP_GMF_IO_DIR_WRITER

    Writer direction

enum esp_gmf_io_type_t

  Enumeration for the type of data handled by a GMF I/O (byte or block)

  Values:

  enumerator ESP_GMF_IO_TYPE_BYTE

    Byte type

  enumerator ESP_GMF_IO_TYPE_BLOCK

    Block type

此文档对您有帮助吗？

- 反馈已收到，谢谢！
- 如果您有其他意见，欢迎填写乐鑫文档反馈表。

- 我们重视您的反馈。
- 您可以填写乐鑫文档反馈表告诉我们如何改进该文档。