Data Flow

[中文]

This document describes how data flows between elements, covering payload fields and ownership, the port acquire-release protocol, how IO connects at the head and tail of a pipeline, and the byte cache.

For element lifecycle, port attributes, capability description, and runtime methods, see GMF Elements. For pipeline orchestration, task scheduling, lifecycle, and control interfaces, see GMF Pipeline and Task Scheduling. For the four data bus implementations and their selection, see Data Bus. For the overall architecture and object relationships, see GMF-Core Overview.

Payload and Port

Each element exposes only two data interfaces externally: an input port and an output port. Data is passed between ports as esp_gmf_payload_t; elements are not responsible for buffer allocation or cross-thread synchronization, and only need to read and write data following an acquire-release protocol.

The complete data flow in a single process call is shown below, using a Decoder -> Resample pipeline as an example.

        sequenceDiagram
    participant T as Task
    participant E as resample
    participant IP as in_port
    participant OP as out_port
    participant D as Downstream

    T->>+E: process()
    E->>+IP: acquire_in(size)
    IP-->>-E: input payload in
    E->>+OP: acquire_out(size)
    OP-->>-E: output payload out
    Note over E: Process input and generate output
    E->>OP: release_out(out)
    OP->>D: Submit output payload
    E->>IP: release_in(in)
    E-->>-T: ok
    

The sequence above contains two rules. First, the payload returned by acquire_in remains owned by the current element until release_in is called; the port maintains the validity of this data via reference counting or the underlying implementation, so the element does not need to handle cross-thread synchronization itself. Second, release_out submits the output payload. For block-type ports, the submission typically does not copy data, but hands the payload to the downstream input port or the underlying data queue, so one piece of data can traverse the entire pipeline without intermediate copies.

acquire-release is the fundamental protocol of the GMF-Core data path. The following sections detail the payload and port.

Payload

Fields

esp_gmf_payload_t is defined in esp_gmf_payload.h with the following fields.

Field

Type

Meaning

buf

uint8_t*

Pointer to the data buffer

buf_length

size_t

Total buffer length

valid_size

size_t

Length of valid data in the buffer

is_done

bool

End-of-stream flag; set to 1 for the last data block, triggers the pipeline to enter FINISHED

pts

uint64_t

Presentation timestamp, used for audio/video synchronization

needs_free

uint8_t

1-bit field indicating whether buf should be automatically freed when the payload is destroyed

meta_flag

uint8_t

7-bit field; currently defines ESP_GMF_META_FLAG_AUD_RECOVERY_PLC to mark audio frames recovered via packet loss concealment

Lifecycle and Ownership

In element code, a payload appears as an esp_gmf_payload_t * pointer. Ownership belongs to the current element during acquire-release; after release, it is returned to port and data bus management. Three rules apply when using payloads:

  • Do not free manually: Payloads acquired from a port are managed by the port; elements can only read and write buf content and must not call esp_gmf_payload_delete.

  • valid_size is set by the writer: After acquiring an output payload, the element writes data and fills valid_size with the actual number of bytes written; downstream uses this to determine how much valid data there is.

  • acquire and release must be paired: Even if an error occurs during processing, release must still be called; otherwise the port enters a leaked state and subsequent calls will exhaust the buffers.

In the less common scenario where an element allocates its own payload (typically a source IO element), it can explicitly create one with esp_gmf_payload_new() or esp_gmf_payload_new_with_len() and release it with esp_gmf_payload_delete() when no longer referenced. For PSRAM cache alignment, use esp_gmf_payload_realloc_aligned_buf().

is_done and pts

is_done is the signal for the pipeline to naturally transition from RUNNING to FINISHED. When an IO element reads to the end of the file, it sets is_done to 1 and sends it with the payload; downstream elements process the end-marked payload in turn and trigger close level by level.

pts is the presentation timestamp, typically filled by the source element. Intermediate elements update it as needed or pass it through directly. Elements near the playback end use it for audio/video synchronization.

Port

Direction and Type

Each port is defined by two attributes.

Direction: ESP_GMF_PORT_DIR_IN indicates an input port (reads payloads from upstream); ESP_GMF_PORT_DIR_OUT indicates an output port (writes payloads to downstream). Each element has one input port and one output port.

Type: Byte type and block type, corresponding to two data exchange strategies.

  • ESP_GMF_PORT_TYPE_BYTE (byte type) allows the element to read and write any number of bytes; the framework handles internal copying and splicing as needed. Suitable for scenarios requiring precise fixed-length access, such as a decoder parsing protocol headers.

  • ESP_GMF_PORT_TYPE_BLOCK (block type) accesses one entire block at a time, without copying; only buffer addresses are passed between ports. Suitable for processing an entire video frame or bulk PCM, with higher performance but lower configurability.

acquire-release Protocol

A port exposes four APIs used in pairs to form the acquire-release access protocol. The complete signature of acquire_in as an example:

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

The four parameters:

  • handle is the input port handle.

  • load is an output parameter; after the call returns, *load points to a payload ready for reading.

  • wanted_size is the data length the element wants to obtain. For source IOs or ports bound to a data bus, the underlying implementation prepares data according to this value; for payloads already submitted to the input port by an upstream element, the port returns the current payload directly, and the actual valid length is based on (*load)->valid_size.

  • wait_ticks is the wait timeout in system ticks. ESP_GMF_MAX_DELAY means wait indefinitely; 0 means return immediately.

The return type is esp_gmf_err_io_t:

Return Code

Value

Meaning

ESP_GMF_IO_OK

>= 0

Success; the value indicates the actual number of bytes read

ESP_GMF_IO_FAIL

-1

Operation failed

ESP_GMF_IO_TIMEOUT

-2

Wait timed out

ESP_GMF_IO_ABORT

-3

Actively aborted by esp_gmf_db_abort or a task stop

Template for element code handling return values:

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;
}
/* Use in_load->buf, in_load->valid_size */

The four APIs work in pairs:

  • Read side: acquire_in gets a readable payload; the element consumes it and calls release_in to return it.

  • Write side: acquire_out gets a writable payload; the element fills it and calls release_out to submit it.

The typical call order in process is: acquire_in first to get the input, then acquire_out to prepare the output buffer, after processing call release_out to submit to downstream, and finally release_in to return the input. Acquiring the output before processing allows waiting in advance if downstream is blocked, avoiding discovering an unavailable output port only after processing is complete.

acquire and release must be paired, even if an error occurs during processing. The framework provides several helper macros to simplify error paths:

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

These macros consolidate the return value check and error branch into a single line.

Shared Buffer Management

GMF provides two mechanisms to reduce memory usage and avoid unnecessary data copies.

Reference Counting

For bypass or in-place processing elements, the same payload can be passed directly to downstream elements or user applications. Each additional consumer increments the port’s ref_count; the corresponding release_in / release_out decrements it. When the count reaches zero, the port invokes the underlying release callback to reclaim the buffer. Sharing is controlled by the port’s is_shared flag, which can be enabled or disabled via esp_gmf_port_enable_payload_share() (shared by default).

        flowchart LR
    Source --> Bypass
    Bypass --> User
    Bypass --> Downstream["Downstream Element"]
    

The same data is shared throughout this flow without extra copies.

Buffer Reuse (AB Buffer)

For elements that produce new output data, the framework reuses payload buffers across elements via is_shared. For a pipeline A B C:

A → B → C
  • A outputs Buffer A.

  • B uses Buffer A as input and writes to Buffer B.

  • After B completes, Buffer A can be reclaimed and reallocated.

  • C uses Buffer B as input; its output can reuse the freed Buffer A.

As data flows through the pipeline, Buffer A and Buffer B alternate in reuse. Even with many elements in the chain, two working buffers are typically sufficient, significantly reducing memory consumption.

At initialization, elements declare constraints on their input and output ports, such as port type, alignment requirements, and recommended data size per acquire. Port attributes are part of the element configuration; for the complete description, see GMF Elements.

The data queue corresponding to a port is managed by the data bus. GMF-Core provides four data buses (ringbuffer / fifo / block / pbuf); a port binds to one of them at creation time, and the interface seen by element code is completely identical. For the trade-offs between the four implementations and flow control interfaces, see Data Bus.

External IO

An external IO (esp_gmf_io_t) is a special element at the head and tail of a pipeline, handling reading and writing of external data sources such as files, networks, and codecs. In addition to the basic open / acquire / release / close, asynchronous mode is supported: an io_process task writes data to an internal data bus while the caller reads from the buffer, smoothing rate fluctuations such as HTTP downloads; transfer rates are available via esp_gmf_io_speed_stats_t as instantaneous and average Kbps. Advanced control interfaces for switching data sources, interruption recovery, and similar scenarios are also provided.

Synchronous and Asynchronous Modes

An IO is configured at creation via esp_gmf_io_cfg_t to select its operating mode.

Synchronous mode: thread.stack = 0 and no buffer_cfg configured. esp_gmf_io_acquire_read executes the underlying IO operation (such as fread) directly in the calling thread context. Advantages are low latency and small memory footprint; the disadvantage is that the caller must tolerate potentially long blocking from IO operations (such as network reads).

Asynchronous mode: thread.stack > 0 and buffer_cfg.buffer_size configured. The framework internally creates an io_process task that independently performs the underlying IO operation and caches data to the data bus. When the user calls acquire_read, it actually reads from the data bus, decoupled from the underlying IO. This mode is suitable for “reading a fixed number of bytes” or “large production/consumption rate differences,” such as when a decoder needs a stable byte stream but network download is bursty.

esp_gmf_io_cfg_t cfg = {
    .thread = {
        .stack = 4 * 1024,
        .prio  = 5,
        .core  = 0,
    },
    .buffer_cfg = {
        .io_size     = 4096,   /* Size of each underlying IO read */
        .buffer_size = 16 * 1024,
        .read_filter = NULL,
    },
    .enable_speed_monitor = true,
};

URL Scoring Strategy

The get_score of esp_gmf_io_t is used to obtain the match score, enabling the pool to find the best-matching IO among multiple registered IOs. The pool function esp_gmf_pool_get_io_tag_by_url iterates all registered IOs’ get_score and returns the one with the highest score. Three scoring levels:

Score

Value

Meaning

ESP_GMF_IO_SCORE_NONE

0

IO does not support this URL

ESP_GMF_IO_SCORE_STANDARD

50

Protocol prefix matches, e.g., http:// is handled by the HTTP IO

ESP_GMF_IO_SCORE_PERFECT

100

Both protocol and file extension match, or a specialized IO with high-priority matching

Custom IOs implementing get_score can return any intermediate value to distinguish priority among multiple candidate IOs.

Seamless Reload and Reset

esp_gmf_io_reload() reopens an existing IO with a new URI without destroying the underlying connection. Primarily for scenarios like HLS segments where “multiple segments are downloaded continuously from the same host,” reusing the HTTP connection to avoid repeated handshake overhead. Internally, the reload clears the data_bus EOF flag, clears the abort flag, and calls the IO’s reload callback to reopen the new URI. reload must be called after the previous read has completed.

esp_gmf_io_reset() performs a more comprehensive cleanup: clears position and file size to zero, calls the IO’s reset callback, resets the task, and reloads the IO process job. Commonly used for corresponding IO cleanup after a pipeline reset.

Done / Abort Control

The IO layer’s done and abort control interfaces correspond one-to-one with the data bus, but in asynchronous mode they also additionally manage the IO task’s hold state.

  • esp_gmf_io_done() marks EOF: aborts the asynchronous IO’s data bus and holds the task; downstream acquire will get a payload with is_done set. The caller must call esp_gmf_io_clear_done() to release the held task before switching to the next data source, otherwise the subsequent IO will not advance.

  • esp_gmf_io_abort() immediately aborts the current operation: data bus abort, task hold; all acquire / release return ESP_GMF_IO_ABORT. The paired esp_gmf_io_clear_abort() restores normal operation.

Typical flow for switching tracks in a playlist:

/* Current track finished */
esp_gmf_io_done(io_handle);

/* Wait for the pipeline to finish processing remaining payloads */
...

/* Switch to the next track */
esp_gmf_io_set_uri(io_handle, next_uri);
esp_gmf_io_clear_done(io_handle);
/* Pipeline continues running without rebuilding */

Custom Payload Processing

The read_filter callback in esp_gmf_io_buffer_cfg_t allows inserting custom processing after the IO reads raw data and before it is written to the data bus. Common uses include decryption, byte-order conversion, and protocol de-encapsulation. Callback signature:

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

The payload’s buf and valid_size can be modified in-place within the callback.

Speed Monitoring

After setting enable_speed_monitor to true in esp_gmf_io_cfg_t, the framework maintains current and average transfer speeds (Kbps), which can be retrieved via esp_gmf_io_get_speed_stats() as esp_gmf_io_speed_stats_t. The monitor can also be dynamically toggled at runtime with esp_gmf_io_enable_speed_monitor(). Commonly used for network condition monitoring and adaptive transfer rate.

Byte Cache

A block-type port returns an entire block per acquire, but elements such as decoders often need to “read exactly N bytes from the data stream.” The esp_gmf_cache module provides byte-level caching:

esp_gmf_cache_handle_t cache;
esp_gmf_cache_new(1024, &cache);

/* After each block payload is acquired, load it into cache */
esp_gmf_cache_load(cache, in_load->buf, in_load->valid_size);

/* Then read by any number of bytes */
int read;
esp_gmf_cache_acquire(cache, 7, out_buf, &read);
esp_gmf_cache_release(cache, 7);

The byte cache internally maintains an expandable sliding buffer. An element can continuously load bytes from multiple payloads into the cache, then read data of any desired length; even if a single read spans the boundary of two payloads, the cache returns the data continuously from its internal buffer. A typical use case is audio decoders parsing protocol or frame headers.

API Reference

Core header files covered in this document:

  • esp_gmf_payload.h: Payload structure and lifecycle

  • esp_gmf_port.h: Port configuration and access APIs

  • esp_gmf_cache.h: Byte cache

  • esp_gmf_io.h: Public interfaces for IO objects

Header File

Functions

esp_gmf_err_t esp_gmf_payload_new(esp_gmf_payload_t **instance)

Create a new payload instance without buffer.

Parameters:

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

Returns:

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

Parameters:
  • buf_length[in] Length of the payload buffer

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

Returns:

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

Parameters:
  • src[in] Source payload instance

  • dest[out] Destination payload instance

Returns:

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

Parameters:
  • instance[in] Payload instance to reallocate the buffer for

  • new_length[in] New length for the payload buffer

Returns:

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

Parameters:
  • 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

Returns:

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

Note

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.

Parameters:
  • 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

Returns:

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

Parameters:

instance[in] Payload instance to set as done

Returns:

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

Parameters:

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

Returns:

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

Parameters:

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

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.

Parameters:
  • cfg[in] Pointer to the configuration structure

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

Returns:

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

Parameters:

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

Returns:

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

Parameters:
  • handle[in] The handle of the port

  • load[in] Pointer to the payload structure

Returns:

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

Parameters:

handle[in] The handle of the port

Returns:

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

Parameters:
  • 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

Returns:

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

Parameters:

handle[in] The handle of the port

Returns:

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

Parameters:
  • handle[in] The handle of the port

  • wait_ticks_ms[in] Number of milliseconds to wait

Returns:

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

Parameters:
  • handle[in] The handle of the port

  • reader[in] Pointer to the reader

Returns:

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

Parameters:
  • handle[in] The handle of the port

  • writer[in] Pointer to the writer

Returns:

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

Parameters:
  • head[in] The head of the port list

  • io_inst[in] The port instance to be added

Returns:

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

Parameters:
  • head[inout] A pointer to the head of the port list

  • io_inst[in] The port instance to be deleted

Returns:

  • 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

Parameters:
  • 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

Returns:

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

Parameters:
  • handle[in] The handle of the port

  • load[in] Pointer to the payload to be released

  • wait_ticks[in] Number of ticks to wait

Returns:

  • 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

Parameters:
  • 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

Returns:

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

Parameters:
  • handle[in] The handle of the port

  • load[in] Pointer to the payload to be released

  • wait_ticks[in] Number of ticks to wait

Returns:

  • 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

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.

Parameters:
  • len[in] The size of the cache buffer to allocate

  • handle[out] Pointer to the cache handle to be initialized

Returns:

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

Parameters:

handle[in] Pointer to the cache handle

Returns:

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

Parameters:

handle[in] Pointer to the cache handle

Returns:

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

Parameters:
  • handle[in] Pointer to the cache handle

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

Returns:

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

Parameters:
  • handle[in] Pointer to the cache handle

  • load_in[in] Pointer to the payload data to be loaded

Returns:

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

Note

  • 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

Parameters:
  • 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

Returns:

  • 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

Note

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

Parameters:
  • handle[in] Pointer to the cache handle

  • load[in] Pointer to the payload data to be released

Returns:

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

Parameters:
  • handle[in] Pointer to the cache handle

  • filled[out] Pointer to store the filled data size

Returns:

  • 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

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.

Parameters:
  • handle[in] GMF I/O handle to initialize

  • cfg[in] Pointer to the configuration structure

Returns:

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

Parameters:

handle[in] GMF I/O handle to deinitialize

Returns:

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

Parameters:
  • handle[in] I/O handle

  • enabled[in] true to enable, false to disable

Returns:

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

Parameters:
  • handle[in] I/O handle

  • stats[out] Pointer to store speed statistics

Returns:

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

Parameters:
  • handle[in] GMF I/O handle

  • url[in] URL to evaluate

  • score[out] Pointer to store the calculated score

Returns:

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

Parameters:

handle[in] GMF I/O handle to open

Returns:

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

Parameters:
  • handle[in] GMF I/O handle

  • seek_byte_pos[in] Byte position to seek to

Returns:

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

Parameters:

handle[in] GMF I/O handle to close

Returns:

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

Parameters:
  • 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

Returns:

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

Parameters:
  • handle[in] GMF I/O handle

  • load[in] Pointer to the payload to release

  • wait_ticks[in] Timeout value in ticks

Returns:

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

Parameters:
  • 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

Returns:

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

Parameters:
  • handle[in] GMF I/O handle

  • load[in] Pointer to the payload to release

  • wait_ticks[in] Timeout value in ticks

Returns:

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

Parameters:
  • handle[in] GMF I/O handle

  • info[in] Pointer to the file information structure

Returns:

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

Parameters:
  • handle[in] GMF I/O handle

  • info[out] Pointer to store the file information

Returns:

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

Parameters:
  • handle[in] GMF I/O handle

  • uri[in] Pointer to the URI string

Returns:

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

Parameters:
  • handle[in] GMF I/O handle

  • uri[out] Pointer to store the URI string

Returns:

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

Parameters:
  • handle[in] GMF I/O handle

  • byte_pos[in] Byte position to set

Returns:

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

Parameters:
  • handle[in] GMF I/O handle

  • byte_pos[in] Byte position to update

Returns:

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

Parameters:
  • handle[in] GMF I/O handle

  • byte_pos[out] Pointer to store the current byte position

Returns:

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

Parameters:
  • handle[in] GMF I/O handle

  • total_size[in] Total size to set

Returns:

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

Parameters:
  • handle[in] GMF I/O handle

  • total_size[out] Pointer to store the total size

Returns:

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

Parameters:
  • handle[in] GMF I/O handle

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

Returns:

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

Parameters:
  • handle[in] GMF I/O handle

  • type[out] Pointer to store the I/O type

Returns:

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

Parameters:

handle[in] GMF I/O handle

Returns:

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

Note

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

Parameters:
  • handle[in] GMF I/O handle

  • uri[in] Pointer to the URI string

Returns:

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

Note

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.

Parameters:

handle[in] GMF I/O handle

Returns:

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

Note

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.

Parameters:

handle[in] GMF I/O handle

Returns:

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

Note

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.

Parameters:

handle[in] GMF I/O handle

Returns:

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

Note

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.

Parameters:

handle[in] GMF I/O handle

Returns:

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

Parameters:
  • handle[in] GMF I/O handle

  • timeout_ms[in] Timeout in milliseconds

Returns:

  • 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


Was this page helpful?