Skip to content

Commit c93485c

Browse files
Merge branch 'main' into pstaszczuk/smoke-tests
2 parents 6505fab + b581962 commit c93485c

File tree

4 files changed

+84
-34
lines changed

4 files changed

+84
-34
lines changed

app/sample/ext_frame/rx_st20_pipeline_dyn_ext_frame_sample.c

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -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);

lib/src/st2110/st_header.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -747,8 +747,6 @@ struct st_tx_audio_session_pacing {
747747
uint64_t cur_epochs; /* epoch of current pkt */
748748
/* timestamp for rtp header */
749749
uint32_t rtp_time_stamp;
750-
/* timestamp for pacing */
751-
uint32_t pacing_time_stamp;
752750
uint64_t cur_epoch_time;
753751
/* in ns, tsc time cursor for packet pacing */
754752
uint64_t tsc_time_cursor;

lib/src/st2110/st_rx_video_session.c

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1525,13 +1525,15 @@ static int rv_handle_frame_pkt(struct st_rx_video_session_impl* s, struct rte_mb
15251525
/* find the target slot by tmstamp */
15261526
bool exist_ts = false;
15271527
struct st_rx_video_slot_impl* slot = rv_slot_by_tmstamp(s, tmstamp, NULL, &exist_ts);
1528-
if (!slot || !slot->frame) {
1529-
if (exist_ts) {
1530-
s->stat_pkts_redundant_dropped++;
1531-
slot->pkts_recv_per_port[s_port]++;
1532-
} else {
1533-
s->stat_pkts_no_slot++;
1534-
}
1528+
/* Based on rv_slot_by_tmstamp - exist_ts is only true when slot is found */
1529+
if (exist_ts && !slot->frame) {
1530+
s->stat_pkts_redundant_dropped++;
1531+
slot->pkts_recv_per_port[s_port]++;
1532+
return 0;
1533+
}
1534+
1535+
if ((!slot || !slot->frame) && !exist_ts) {
1536+
s->stat_pkts_no_slot++;
15351537
return -EIO;
15361538
}
15371539

@@ -1941,13 +1943,15 @@ static int rv_handle_st22_pkt(struct st_rx_video_session_impl* s, struct rte_mbu
19411943
/* find the target slot by tmstamp */
19421944
bool exist_ts = false;
19431945
struct st_rx_video_slot_impl* slot = rv_slot_by_tmstamp(s, tmstamp, NULL, &exist_ts);
1944-
if (!slot || !slot->frame) {
1945-
if (exist_ts) {
1946-
s->stat_pkts_redundant_dropped++;
1947-
slot->pkts_recv_per_port[s_port]++;
1948-
} else {
1949-
s->stat_pkts_no_slot++;
1950-
}
1946+
/* Based on rv_slot_by_tmstamp - exist_ts is only true when slot is found */
1947+
if (exist_ts && !slot->frame) {
1948+
s->stat_pkts_redundant_dropped++;
1949+
slot->pkts_recv_per_port[s_port]++;
1950+
return 0;
1951+
}
1952+
1953+
if ((!slot || !slot->frame) && !exist_ts) {
1954+
s->stat_pkts_no_slot++;
19511955
return -EIO;
19521956
}
19531957
uint8_t* bitmap = slot->frame_bitmap;
@@ -2111,13 +2115,15 @@ static int rv_handle_hdr_split_pkt(struct st_rx_video_session_impl* s,
21112115
/* find the target slot by tmstamp */
21122116
bool exist_ts = false;
21132117
struct st_rx_video_slot_impl* slot = rv_slot_by_tmstamp(s, tmstamp, payload, &exist_ts);
2114-
if (!slot || !slot->frame) {
2115-
if (exist_ts) {
2116-
s->stat_pkts_redundant_dropped++;
2117-
slot->pkts_recv_per_port[s_port]++;
2118-
} else {
2119-
s->stat_pkts_no_slot++;
2120-
}
2118+
/* Based on rv_slot_by_tmstamp - exist_ts is only true when slot is found */
2119+
if (exist_ts && !slot->frame) {
2120+
s->stat_pkts_redundant_dropped++;
2121+
slot->pkts_recv_per_port[s_port]++;
2122+
return 0;
2123+
}
2124+
2125+
if ((!slot || !slot->frame) && !exist_ts) {
2126+
s->stat_pkts_no_slot++;
21212127
return -EIO;
21222128
}
21232129
uint8_t* bitmap = slot->frame_bitmap;

lib/src/st2110/st_tx_audio_session.c

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ static int tx_audio_session_sync_pacing(struct mtl_main_impl* impl,
264264
struct st_tx_audio_session_impl* s, bool sync,
265265
uint64_t required_tai) {
266266
struct st_tx_audio_session_pacing* pacing = &s->pacing;
267-
double pkt_time = pacing->trs;
267+
long double pkt_time = pacing->trs;
268268
/* always use MTL_PORT_P for ptp now */
269269
uint64_t ptp_time = mt_get_ptp_time(impl, MTL_PORT_P);
270270
uint64_t next_epochs = pacing->cur_epochs + 1;
@@ -302,7 +302,18 @@ static int tx_audio_session_sync_pacing(struct mtl_main_impl* impl,
302302
}
303303
}
304304

305-
to_epoch = tx_audio_pacing_time(pacing, epochs) - ptp_time;
305+
if (required_tai) {
306+
to_epoch = (double)required_tai - ptp_time;
307+
if (to_epoch > NS_PER_S) {
308+
dbg("%s(%d), required tai %" PRIu64 " ptp_epochs %" PRIu64 " epochs %" PRIu64 "\n",
309+
__func__, s->idx, required_tai, ptp_epochs, epochs);
310+
s->stat_error_user_timestamp++;
311+
to_epoch = NS_PER_S; // do our best to slow down
312+
}
313+
} else {
314+
to_epoch = tx_audio_pacing_time(pacing, epochs) - ptp_time;
315+
}
316+
306317
if (to_epoch < 0) {
307318
/* time bigger than the assigned epoch time */
308319
s->stat_epoch_mismatch++;
@@ -313,13 +324,27 @@ static int tx_audio_session_sync_pacing(struct mtl_main_impl* impl,
313324
if (epochs < next_epochs) s->stat_epoch_onward += (next_epochs - epochs);
314325

315326
pacing->cur_epochs = epochs;
316-
pacing->cur_epoch_time = tx_audio_pacing_time(pacing, epochs);
317-
pacing->pacing_time_stamp = tx_audio_pacing_time_stamp(pacing, epochs);
318-
pacing->rtp_time_stamp = pacing->pacing_time_stamp;
327+
328+
if (required_tai) {
329+
pacing->cur_epoch_time = required_tai + pkt_time; // prepare next packet
330+
/*
331+
* Cast [double] to intermediate [uint64_t] to extract 32 least significant bits.
332+
* If calculated time stored in [double] is larger than max uint32_t,
333+
* then result of direct cast to [uint32_t] results in max uint32_t which is not
334+
* what we want. "& 0xffffffff" is used to extract 32 least significant bits
335+
* without compiler trying to optimize-out intermediate cast.
336+
*/
337+
pacing->rtp_time_stamp =
338+
((uint64_t)((required_tai / pkt_time) * pacing->pkt_time_sampling) & 0xffffffff);
339+
} else {
340+
pacing->cur_epoch_time = tx_audio_pacing_time(pacing, epochs);
341+
pacing->rtp_time_stamp = tx_audio_pacing_time_stamp(pacing, epochs);
342+
}
343+
319344
if (s->ops.rtp_timestamp_delta_us) {
320345
double rtp_timestamp_delta_us = s->ops.rtp_timestamp_delta_us;
321346
int32_t rtp_timestamp_delta =
322-
(rtp_timestamp_delta_us * NS_PER_US) * pacing->pkt_time_sampling / pacing->trs;
347+
(rtp_timestamp_delta_us * NS_PER_US) * pacing->pkt_time_sampling / pkt_time;
323348
pacing->rtp_time_stamp += rtp_timestamp_delta;
324349
}
325350
pacing->tsc_time_cursor = (double)mt_get_tsc(impl) + to_epoch;

0 commit comments

Comments
 (0)