Skip to content

Commit

Permalink
st20/rx: use dynamic ext frame for both converter and non-converter m…
Browse files Browse the repository at this point in the history
…ode (#522)

Simple the usage, for non-converter use raw st20 dynamic ext mode, for
convert, call the ext frame query in the frame ready callback.

Signed-off-by: Frank Du <[email protected]>
  • Loading branch information
frankdjx authored Oct 7, 2023
1 parent b29c752 commit f9e004b
Show file tree
Hide file tree
Showing 7 changed files with 154 additions and 251 deletions.
8 changes: 4 additions & 4 deletions app/sample/ext_frame/rx_st20_pipeline_dyn_ext_frame_sample.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,17 @@ static int rx_st20p_frame_available(void* priv) {
return 0;
}

static int rx_st20p_query_ext_frame(void* priv, struct st20_ext_frame* ext_frame,
static int rx_st20p_query_ext_frame(void* priv, struct st_ext_frame* ext_frame,
struct st20_rx_frame_meta* meta) {
struct rx_st20p_sample_ctx* s = priv;
int i = s->ext_idx;
MTL_MAY_UNUSED(meta);

/* you can check the timestamp from lib by meta->timestamp */

ext_frame->buf_addr = s->ext_frames[i].buf_addr;
ext_frame->buf_iova = s->ext_frames[i].buf_iova;
ext_frame->buf_len = s->ext_frames[i].buf_len;
ext_frame->addr[0] = s->ext_frames[i].buf_addr;
ext_frame->iova[0] = s->ext_frames[i].buf_iova;
ext_frame->size = s->ext_frames[i].buf_len;

/* save your private data here get it from st_frame.opaque */
/* ext_frame->opaque = ?; */
Expand Down
141 changes: 60 additions & 81 deletions doc/external_frame.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,40 @@ static int tx_st20p_frame_done(void* priv, struct st_frame*frame) {
}
```

Others follow the general API flow.

### 2.3 st20p_rx usages

#### 2.3.1 dedicated frames
#### 2.3.1 dynamic frames

in ops, set the flag and set query_ext_frame callback

```c
ops_rx.flags |= ST20P_RX_FLAG_EXT_FRAME;
ops_rx.query_ext_frame = st20p_rx_query_ext_frame;
//...
//implement the callback
static int st20p_rx_query_ext_frame(void* priv, st_ext_frame* ext_frame,
struct st20_rx_frame_meta* meta) {
ctx* s = (ctx*)priv;
uint8_t planes = st_frame_fmt_planes(fmt[i]);

/* fill the ext frame */
for (uint8_t plane = 0; plane < planes; plane++) {
ext_frame.addr[i] = your_addr[i];
ext_frame.iova[i] = your_iova[i]; // must provide IOVA for no convert mode
ext_frame.linesize[i] = your_linesize[i];
}
ext_frame.size = your_frame_size;
ext_frame.opaque = your_frame_handle;

return 0;
}
```
User should maintain the lifetime of frames after st22p_rx_get_frame.
#### 2.3.2 dedicated frames
set the ext_frames array in ops
Expand All @@ -90,57 +121,7 @@ ops_rx.ext_frames = ext_frames;
rx_handle = st20p_rx_create(st, &ops_rx);
```

use as the general API

#### 2.3.2 dynamic frames - convert mode

in ops, set the flag

```c
ops_rx.flags |= ST20P_RX_FLAG_EXT_FRAME;
```

when receiving a frame, get the frame with ext_frame info and put the frame

```c
struct st_ext_frame ext_frame;
uint8_t planes = st_frame_fmt_planes(frame->fmt);
for(int i = 0; i < planes; i++) {
ext_frame.addr[i] = your_addr[i];
ext_frame.linesize[i] = your_linesize[i];
}
ext_frame.size = your_frame_size;
ext_frame.opaque = your_frame_handle;
frame = st20p_rx_get_ext_frame(rx_handle, &ext_frame);
st20p_rx_put_frame(rx_handle, frame); // you can put it right away
use_frame(your_frame_handle);
```
user should maintain the lifetime of frames
#### 2.3.3 dynamic frames - no convert mode
(the same usage as raw video API 3.3.2)
implement and set query_ext_frame callback and set incomplete frame flag
```c
// set the callback in ops
// set the incomplete frame flag
ops_rx.query_ext_frame = st20p_rx_query_ext_frame;
ops_rx.flags |= ST20P_RX_FLAG_RECEIVE_INCOMPLETE_FRAME;
//...
//implement the callback
static int st20p_rx_query_ext_frame(void* priv, st20_ext_frame*ext_frame, struct st20_rx_frame_meta* meta) {
ctx* s = (ctx*)priv;
ext_frame->buf_addr = your_addr[0];
ext_frame->buf_iova = your_iova[0];
ext_frame->buf_len = your_frame_size;
ext_frame->opaque = your_frame_handle;
return 0;
}
```

use as the general API, user should maintain the lifetime of frames
Others follow the general API flow.

### 2.4 st22p_tx usages

Expand Down Expand Up @@ -183,6 +164,8 @@ static int tx_st22p_frame_done(void* priv, struct st_frame*frame) {
}
```

Others follow the general API flow.

### 2.5 st22p_rx usages

#### 2.5.1 dynamic frames
Expand All @@ -201,17 +184,13 @@ static int st22p_rx_query_ext_frame(void* priv, st_ext_frame* ext_frame,

/* fill the ext frame */
for (uint8_t plane = 0; plane < planes; plane++) {
ext_frame->linesize[plane] = st_frame_least_linesize(fmt[i], width[i], plane);
if (plane == 0) {
ext_frame->addr[plane] = xxx;
ext_frame->iova[plane] = xxx;
} else {
ext_frame->addr[plane] = xxx;
ext_frame->iova[plane] = xxx;
}
ext_frame.addr[i] = your_addr[i];
ext_frame.iova[i] = your_iova[i]; // must provide IOVA for no convert mode
ext_frame.linesize[i] = your_linesize[i];
}
ext_frame->size = xxx;
ext_frame->opaque = xxx;
ext_frame.size = your_frame_size;
ext_frame.opaque = your_frame_handle;

return 0;
}
```
Expand Down Expand Up @@ -256,25 +235,7 @@ st20_tx_set_ext_frame(s->handle, idx, &ext_frame);
### 3.3 st20_rx usages
#### 3.3.1 dedicated frames
set the ext_frames array in ops
```c
struct st20_ext_frame ext_frames[fb_cnt];
for (int i = 0; i < fb_cnt;++i) {
ext_frames[i].buf_addr = your_addr;
ext_frames[i].buf_iova = your_iova;
ext_frames[i].buf_len = your_frame_size;
ext_frames[i].opaque = your_frame_handle;
}
ops_rx.ext_frames = ext_frames;
rx_handle = st20_rx_create(st, &ops_rx);
```

use as the general API

#### 3.3.2 dynamic frames
#### 3.3.1 dynamic frames
implement and set query_ext_frame callback and set incomplete frame flag
Expand All @@ -296,3 +257,21 @@ static int rx_query_ext_frame(void* priv, st20_ext_frame*ext_frame, struct st20_
```

use as the general API, user should maintain the lifetime of frames

#### 3.3.2 dedicated frames

set the ext_frames array in ops

```c
struct st20_ext_frame ext_frames[fb_cnt];
for (int i = 0; i < fb_cnt;++i) {
ext_frames[i].buf_addr = your_addr;
ext_frames[i].buf_iova = your_iova;
ext_frames[i].buf_len = your_frame_size;
ext_frames[i].opaque = your_frame_handle;
}
ops_rx.ext_frames = ext_frames;
rx_handle = st20_rx_create(st, &ops_rx);
```

Others follow the general API flow.
33 changes: 8 additions & 25 deletions include/st_pipeline_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ enum st22_quality_mode {
#define ST22P_TX_FLAG_DISABLE_BULK (MTL_BIT32(7))
/**
* Flag bit in flags of struct st22p_tx_ops.
* Lib uses user allocated memory for frames.
* Lib uses user dynamic allocated memory for frames.
* The external frames are provided by calling
* st22p_tx_put_ext_frame.
*/
Expand All @@ -387,7 +387,7 @@ enum st22_quality_mode {
#define ST20P_TX_FLAG_USER_R_MAC (MTL_BIT32(1))
/**
* Flag bit in flags of struct st20p_tx_ops.
* Lib uses user allocated memory for frames.
* Lib uses user dynamic allocated memory for frames.
* The external frames are provided by calling
* st20p_tx_put_ext_frame.
*/
Expand Down Expand Up @@ -455,8 +455,8 @@ enum st22_quality_mode {
#define ST22P_RX_FLAG_SIMULATE_PKT_LOSS (MTL_BIT32(3))
/**
* Flag bit in flags of struct st22p_rx_ops.
* Enable the external frame mode, and user must provide a query callback(query_ext_frame
* in st22p_rx_ops) to let MTL can get the frame when needed.
* Enable the dynamic external frame mode, and user must provide a query
* callback(query_ext_frame in st22p_rx_ops) to let MTL can get the frame when needed.
*/
#define ST22P_RX_FLAG_EXT_FRAME (MTL_BIT32(4))

Expand All @@ -480,9 +480,9 @@ enum st22_quality_mode {
#define ST20P_RX_FLAG_ENABLE_VSYNC (MTL_BIT32(1))
/**
* Flag bit in flags of struct st20p_rx_ops.
* Only used for internal convert mode.
* The external frames are provided by calling
* st20p_rx_get_ext_frame.
* Enable the dynamic external frame mode, and user must provide a query
* callback(query_ext_frame in st20p_rx_ops) to let MTL can get the frame when needed.
* Note to enable ST20P_RX_FLAG_RECEIVE_INCOMPLETE_FRAME also for non-converter mode.
*/
#define ST20P_RX_FLAG_EXT_FRAME (MTL_BIT32(2))
/**
Expand Down Expand Up @@ -855,11 +855,10 @@ struct st20p_rx_ops {
struct st_rx_rtcp_ops* rtcp;
/**
* Optional. Callback when the lib query next external frame's data address.
* Only for non-convert mode with ST20P_RX_FLAG_RECEIVE_INCOMPLETE_FRAME.
* And only non-block method can be used within this callback as it run from lcore
* tasklet routine.
*/
int (*query_ext_frame)(void* priv, struct st20_ext_frame* ext_frame,
int (*query_ext_frame)(void* priv, struct st_ext_frame* ext_frame,
struct st20_rx_frame_meta* meta);
/**
* Optional. event callback, lib will call this when there is some event happened.
Expand Down Expand Up @@ -1550,22 +1549,6 @@ st20p_rx_handle st20p_rx_create(mtl_handle mt, struct st20p_rx_ops* ops);
*/
int st20p_rx_free(st20p_rx_handle handle);

/**
* Get one rx frame from the rx st2110-20 pipeline session with external framebuffer.
* This is only used for internal convert mode, the convert is done in this call.
* Call st20p_rx_put_frame to return the frame to session.
*
* @param handle
* The handle to the rx st2110-20 pipeline session.
* @param ext_frame
* The pointer to the structure describing external framebuffer.
* @return
* - NULL if no available frame in the session.
* - Otherwise, the frame pointer.
*/
struct st_frame* st20p_rx_get_ext_frame(st20p_rx_handle handle,
struct st_ext_frame* ext_frame);

/**
* Get one rx frame from the rx st2110-20 pipeline session.
* Call st20p_rx_put_frame to return the frame to session.
Expand Down
Loading

0 comments on commit f9e004b

Please sign in to comment.