@@ -42,13 +42,23 @@ static int rx_st20p_query_ext_frame(void* priv, struct st_ext_frame* ext_frame,
4242 struct rx_st20p_sample_ctx * s = priv ;
4343 int i = s -> ext_idx ;
4444 MTL_MAY_UNUSED (meta );
45-
4645 /* you can check the timestamp from lib by meta->timestamp */
4746
4847 ext_frame -> addr [0 ] = s -> ext_frames [i ].buf_addr ;
4948 ext_frame -> iova [0 ] = s -> ext_frames [i ].buf_iova ;
5049 ext_frame -> size = s -> ext_frames [i ].buf_len ;
5150
51+ uint8_t * addr = ext_frame -> addr [0 ];
52+ uint8_t planes = st_frame_fmt_planes (meta -> fmt );
53+ for (int plane = 0 ; plane < planes ; plane ++ ) {
54+ if (plane > 0 )
55+ ext_frame -> iova [plane ] =
56+ ext_frame -> iova [plane - 1 ] + ext_frame -> linesize [plane - 1 ] * meta -> height ;
57+ ext_frame -> linesize [plane ] = st_frame_least_linesize (meta -> fmt , meta -> width , plane );
58+ ext_frame -> addr [plane ] = addr ;
59+ addr += ext_frame -> linesize [plane ] * meta -> height ;
60+ }
61+
5262 /* save your private data here get it from st_frame.opaque */
5363 /* ext_frame->opaque = ?; */
5464
@@ -150,6 +160,15 @@ int main(int argc, char** argv) {
150160 ret = rx_sample_parse_args (& ctx , argc , argv );
151161 if (ret < 0 ) return ret ;
152162
163+ bool is_output_yuv420 = ctx .output_fmt == ST_FRAME_FMT_YUV420CUSTOM8 ||
164+ ctx .output_fmt == ST_FRAME_FMT_YUV420PLANAR8 ;
165+ if (ctx .ext_frame && is_output_yuv420 ) {
166+ warn (
167+ "%s: external frame mode does not support yuv420 output format, use other format "
168+ "e.g. yuv422\n" ,
169+ __func__ );
170+ }
171+
153172 /* enable auto start/stop */
154173 ctx .param .flags |= MTL_FLAG_DEV_AUTO_START_STOP ;
155174 ctx .st = mtl_init (& ctx .param );
@@ -199,12 +218,13 @@ int main(int argc, char** argv) {
199218 ops_rx .framebuff_cnt = app [i ]-> fb_cnt ;
200219 ops_rx .notify_frame_available = rx_st20p_frame_available ;
201220
202- if (equal ) {
203- /* no convert, use ext frame for example */
221+ if (equal || ctx . ext_frame ) {
222+ /* pre-allocate ext frames */
204223 app [i ]-> ext_frames =
205224 (struct st20_ext_frame * )malloc (sizeof (* app [i ]-> ext_frames ) * app [i ]-> fb_cnt );
206- size_t framebuff_size =
207- st20_frame_size (ops_rx .transport_fmt , ops_rx .width , ops_rx .height );
225+ size_t framebuff_size = st_frame_size (ops_rx .output_fmt , ops_rx .width ,
226+ ops_rx .height , ops_rx .interlaced );
227+
208228 size_t fb_size = framebuff_size * app [i ]-> fb_cnt ;
209229 /* alloc enough memory to hold framebuffers and map to iova */
210230 mtl_dma_mem_handle dma_mem = mtl_dma_mem_alloc (ctx .st , fb_size );
@@ -225,6 +245,7 @@ int main(int argc, char** argv) {
225245 /* use dynamic external frames */
226246 ops_rx .query_ext_frame = rx_st20p_query_ext_frame ;
227247 ops_rx .flags |= ST20P_RX_FLAG_RECEIVE_INCOMPLETE_FRAME ;
248+ ops_rx .flags |= ST20P_RX_FLAG_EXT_FRAME ;
228249 }
229250
230251 st20p_rx_handle rx_handle = st20p_rx_create (ctx .st , & ops_rx );
0 commit comments