Skip to content

Add: New API draft #1100

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions doc/new_API/List-of-changes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# List of changes in API this draft is trying to present

- Removal of "frame" mode and rtp "mode", modified pipeline mode stays as only API for MTL sessions

- Polymorphic session classes used to reduce code repetition

- Replacing callback with event polling function to notify app about events in lib

- Change of usage pattern for zero copy/external frame mode. A clear separation of two types of
buffer ownership; buffers owned by the library and buffers owned by the application.

- Added stop() start() and shutdown()

> **Note**
> Fields in all structures are dummy, they need to be correctly ported from current API. Also a few functions need to ported.
> This is not a complete API, just a presentation of a few ideas.
58 changes: 58 additions & 0 deletions doc/new_API/buffers-api.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>

// Forward declarations
typedef struct media_lib_session_base media_lib_session_t;
typedef struct media_lib_buffer_base media_lib_buffer_t;

// Base buffer structure
typedef struct media_lib_buffer_base {
void* data;
mtl_iova_t iova;
size_t size;
uint64_t timestamp;
uint32_t flags;
uint32_t buffer_id;
void* _internal;
void* user_data;
} media_lib_buffer_base_t;

// Video buffer structure
typedef struct media_lib_video_buffer {
// Base buffer must be the first member
media_lib_buffer_base_t base;

// Video-specific fields
uint32_t width;
uint32_t height;
uint32_t format;
uint32_t stride;
// Additional video buffer fields
} media_lib_video_buffer_t;

// Audio buffer structure
typedef struct media_lib_audio_buffer {
// Base buffer must be the first member
media_lib_buffer_base_t base;

// Audio-specific fields
uint32_t sample_rate;
uint32_t channels;
uint32_t format;
uint32_t samples_per_frame;
// Additional audio buffer fields
} media_lib_audio_buffer_t;

// Type casting macros for safe type conversion
#define MEDIA_LIB_SESSION_TO_VIDEO(session) \
((media_lib_video_session_t*)(session))

#define MEDIA_LIB_SESSION_TO_AUDIO(session) \
((media_lib_audio_session_t*)(session))

#define MEDIA_LIB_BUFFER_TO_VIDEO(buffer) \
((media_lib_video_buffer_t*)(buffer))

#define MEDIA_LIB_BUFFER_TO_AUDIO(buffer) \
((media_lib_audio_buffer_t*)(buffer))
160 changes: 160 additions & 0 deletions doc/new_API/samples/diagrams.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
```mermaid
sequenceDiagram
participant App as Application
participant Session as Media Library Session

participant Network as Network I/O

Note over App,Network: Library-Owned Receiver Flow (sample-rx-lib-owned.c)

App->>Session: media_lib_video_session_create(instance, &rx_config, &session)
Session->>Session: Allocate memory (for NUM_BUFFERS)
Session->>Network: Setup receiver
Session->>Network: Add buffers to receive queue
Session-->>App: Return session handle

loop Receive and process loop
App->>Session: media_lib_buffer_get(session, &buffer, TIMEOUT_MS)
Session->>Network: Wait for data
Network-->>Session: Data received

Session-->>App: Return buffer pointer

Note over App: Process buffer data

App->>Session: media_lib_buffer_put(session, buffer)

Session->>Network: Add buffer to receive queue
Session-->>App: MEDIA_LIB_SUCCESS

end
App->>Session: media_lib_session_shutdown(session)

App->>Session: media_lib_session_destroy(session)
Session->>Session: Deallocate memory

```

```mermaid
sequenceDiagram
participant App as Application
participant Session as Media Library Session
participant Network as Network I/O

Note over App,Network: Library-Owned Transmitter Flow (sample-tx-lib-owned.c)

App->>Session: media_lib_video_session_create(instance, &tx_config, &session)
Session->>Session: Allocate memory (for NUM_BUFFERS)
Session->>Network: Setup transmitter
Session-->>App: Return session handle


loop Acquire, fill, and transmit loop
App->>Session: media_lib_buffer_get(session, &buffer, TIMEOUT_MS)
Session->>Session: Wait for available buffer
Session-->>App: Return available buffer

Note over App: Fill buffer with media data

App->>Session: media_lib_buffer_put(session, buffer)
Session->>Network: Start transmission
Session-->>App: MEDIA_LIB_SUCCESS
Network-->>Session: Transmission complete
Session->>Session: Mark buffer as available

end

App->>Session:media_lib_buffers_flush(session)
App->>Session: media_lib_session_shutdown(session)
App->>Session: media_lib_session_destroy(session)
Session->>Session: Deallocate memory

```

```mermaid
sequenceDiagram
participant App as Application
participant Session as Media Library Session
participant DMA as DMA Memory Manager
participant Events as Event Queue
participant Network as Network I/O

Note over App,Events: App-Owned Receiver Flow (sample-rx-app-owned.c)

App->>Session: media_lib_video_session_create(instance, &rx_config, &session)
Session->>Network: Setup receiver
Session-->>App: Return session handle

App->>App: Allocate memory (for NUM_BUFFERS)
App->>Session: media_lib_mem_register(session, memory, size, &dma_mem)
Session->>DMA: Register memory for DMA
DMA-->>Session: DMA handle
Session-->>App: Return DMA handle

loop Buffer setup loop
App->>App: Create app_buffer_t for each buffer segment
App->>Session: media_lib_buffer_post(session, data, size, app_buffer)
Session->>Network: Add buffer to receive queue
end

loop Poll and process loop
App->>Session: media_lib_event_poll(session, &event, TIMEOUT_MS)
Session->>Events: Check for events

alt Data received
Network->>Session: Data received in posted buffer
Session->>Events: Add BUFFER_RECEIVED event
Events-->>Session: Return event
Session-->>App: Return event with app_buffer context

Note over App: Process buffer data

App->>Session: media_lib_buffer_post(session, buf->data, buf->size, buf)
Session->>Network: Repost buffer for next receive
end
end

Note over App: Cleanup (not shown in sample)
App->>Session: media_lib_mem_unregister(session, dma_mem)
App->>Session: media_lib_session_shutdown(session)
App->>Session: media_lib_session_destroy(session)

```

```mermaid
sequenceDiagram
participant ProducerThread as Producer Thread
participant PollerThread as Poller Thread
participant BufferQueue as Buffer Queue
participant Session as Media Library Session
participant DMA as DMA Memory Manager
participant Events as Event Queue
participant Network as Network I/O

Note over ProducerThread,Events: App-Owned Transmitter Flow (sample-tx-app-owned.c)

Note over ProducerThread,PollerThread: Main thread setup (not shown)

Note over Session,DMA: Memory registration occurs in main thread

loop Producer Thread Loop
ProducerThread->>BufferQueue: dequeue() - Get free buffer
BufferQueue-->>ProducerThread: Return app_buffer_t
Note over ProducerThread: Fill buffer with data
ProducerThread->>Session: media_lib_buffer_post(session, buf->data, buf->size, buf)
Session->>Network: Queue buffer for transmission
end

loop Poller Thread Loop
PollerThread->>Session: media_lib_event_poll(session, &event, TIMEOUT_MS)
Session->>Events: Check for events
alt Transmission complete
Events-->>Session: Return BUFFER_TRANSMITTED event
Session-->>PollerThread: Return event with app_buffer context
PollerThread->>BufferQueue: enqueue(buffer) - Return to free queue
end
end

Note over ProducerThread,PollerThread: Cleanup (not reached in sample)

```
108 changes: 108 additions & 0 deletions doc/new_API/samples/sample-rx-app-owned.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "media-lib-api.h"

#define TIMEOUT_MS 1000
#define NUM_BUFFERS 4
#define BUFFER_SIZE 1024

// Application-defined simple buffer structure.
typedef struct {
uint8_t* data; // Pointer to the buffer data.
size_t size; // Size of the buffer.
int id; // Buffer identifier.
} app_buffer_t;

int main(void) {
// Assume instance is created by the library initialization routine.
mtl_handle* instance = /* ... */ NULL;
media_lib_video_session_config_t rx_config = {0};
media_lib_session_t* session = NULL;
uint8_t* registered_memory = NULL;
mtl_dma_mem_handle* dma_mem = NULL;
app_buffer_t* buffers[NUM_BUFFERS];
media_lib_event_t event;
int err;

// Configure a receiver session in user-owned (zero-copy) mode.
rx_config.base.type = MEDIA_LIB_SESSION_RECEIVER;
rx_config.base.ownership = MEDIA_LIB_BUFFER_USER_OWNED;
rx_config.base.buffer_size = BUFFER_SIZE;
rx_config.base.num_buffers = NUM_BUFFERS;
rx_config.base.address = "192.168.1.100";
rx_config.base.port = 1234;
rx_config.base.timeout_ms = TIMEOUT_MS;
rx_config.width = 640;
rx_config.height = 480;
rx_config.framerate = 30;
rx_config.format = 0; // e.g., V_FMT_YUV420P

err = media_lib_video_session_create(instance, &rx_config, &session);
if (err != MEDIA_LIB_SUCCESS) {
printf("Failed to create receiver session\n");
return -1;
}

// Allocate a contiguous block of memory for all buffers.
registered_memory = malloc(NUM_BUFFERS * BUFFER_SIZE);
if (!registered_memory) {
printf("Failed to allocate memory\n");
return -1;
}
err = media_lib_mem_register(session, registered_memory, NUM_BUFFERS * BUFFER_SIZE, &dma_mem);
if (err != MEDIA_LIB_SUCCESS) {
printf("Failed to register memory\n");
free(registered_memory);
return -1;
}

// Create an array of application-defined buffers.
for (int i = 0; i < NUM_BUFFERS; i++) {
buffers[i] = malloc(sizeof(app_buffer_t));
if (!buffers[i]) {
printf("Failed to allocate app_buffer_t for buffer %d\n", i);
// Cleanup omitted for brevity.
return -1;
}
buffers[i]->data = registered_memory + i * BUFFER_SIZE;
buffers[i]->size = BUFFER_SIZE;
buffers[i]->id = i;
// Post the buffer to the library.
// The app_buffer_t pointer is passed as the context.
err = media_lib_buffer_post(session, buffers[i]->data, buffers[i]->size, (void*)buffers[i]);
if (err != MEDIA_LIB_SUCCESS) {
printf("Failed to post rx buffer %d\n", i);
}
}

// Polling loop: process received buffers and repost them.
while (1) {
err = media_lib_event_poll(session, &event, TIMEOUT_MS);
if (err == MEDIA_LIB_SUCCESS) {
if (event.type == MEDIA_LIB_EVENT_BUFFER_RECEIVED) {
// event.ctx is the application context.
app_buffer_t* buf = (app_buffer_t*)event.ctx;
printf("Received buffer id %d, size %ld\n", buf->id, buf->size);
// Process the data in buf->data as needed...

// After processing, repost the buffer back to the library.
err = media_lib_buffer_post(session, buf->data, buf->size, (void*)buf);
if (err != MEDIA_LIB_SUCCESS) {
printf("Failed to repost rx buffer for id %d\n", buf->id);
}
}
}
}

// Cleanup (never reached in this sample).
media_lib_mem_unregister(session, dma_mem);
media_lib_session_shutdown(session);
media_lib_session_destroy(session);
free(registered_memory);
for (int i = 0; i < NUM_BUFFERS; i++) {
free(buffers[i]);
}
return 0;
}
Loading
Loading