Skip to content
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
49 changes: 16 additions & 33 deletions lib/src/st2110/st_tx_ancillary_session.c
Original file line number Diff line number Diff line change
Expand Up @@ -278,14 +278,6 @@ static int tx_ancillary_session_init_pacing(struct st_tx_ancillary_session_impl*
return 0;
}

static int tx_ancillary_session_init_pacing_epoch(
struct mtl_main_impl* impl, struct st_tx_ancillary_session_impl* s) {
uint64_t ptp_time = mt_get_ptp_time(impl, MTL_PORT_P);
struct st_tx_ancillary_session_pacing* pacing = &s->pacing;
pacing->cur_epochs = ptp_time / pacing->frame_time;
return 0;
}

static inline uint64_t tx_ancillary_pacing_time(
struct st_tx_ancillary_session_pacing* pacing, uint64_t epochs) {
return nextafter(epochs * pacing->frame_time, INFINITY);
Expand Down Expand Up @@ -344,7 +336,13 @@ static inline uint64_t tx_ancillary_calc_epoch(struct st_tx_ancillary_session_im
uint64_t cur_tai, uint64_t required_tai) {
struct st_tx_ancillary_session_pacing* pacing = &s->pacing;
uint64_t current_epoch = cur_tai / pacing->frame_time;
uint64_t next_free_epoch = pacing->cur_epochs + 1;
/*
* cur_epochs is 0 before the first frame (zero-initialized struct).
* Real PTP-derived epochs are ~10^11, so 0 is a safe "uninitialized" sentinel.
* On first call, start from current_epoch to avoid a false epoch_drop.
*/
uint64_t next_free_epoch =
likely(pacing->cur_epochs) ? pacing->cur_epochs + 1 : current_epoch;
uint64_t epoch = next_free_epoch;

if (required_tai) {
Expand All @@ -365,14 +363,16 @@ static inline uint64_t tx_ancillary_calc_epoch(struct st_tx_ancillary_session_im
} else {
dbg("%s(%d), frame is late, current_epoch %" PRIu64 " next_free_epoch %" PRIu64 "\n",
__func__, s->idx, current_epoch, next_free_epoch);
ST_SESSION_STAT_ADD(s, port_user_stats.common, stat_epoch_drop,
(current_epoch - next_free_epoch));

if (s->ops.notify_frame_late) {
s->ops.notify_frame_late(s->ops.priv, current_epoch - next_free_epoch);
if (!required_tai) {
ST_SESSION_STAT_ADD(s, port_user_stats.common, stat_epoch_drop,
(current_epoch - next_free_epoch));
if (s->ops.notify_frame_late) {
s->ops.notify_frame_late(s->ops.priv, current_epoch - next_free_epoch);
}
epoch = current_epoch;
}

epoch = current_epoch;
/* when required_tai is set, keep user-derived epoch — scheduler jitter
* does not mean the user dropped epochs */
}

return epoch;
Expand Down Expand Up @@ -448,22 +448,6 @@ static int tx_ancillary_session_init(struct st_tx_ancillary_sessions_mgr* mgr,
return 0;
}

static int tx_ancillary_sessions_tasklet_start(void* priv) {
struct st_tx_ancillary_sessions_mgr* mgr = priv;
struct mtl_main_impl* impl = mgr->parent;
struct st_tx_ancillary_session_impl* s;

for (int sidx = 0; sidx < mgr->max_idx; sidx++) {
s = tx_ancillary_session_get(mgr, sidx);
if (!s) continue;

tx_ancillary_session_init_pacing_epoch(impl, s);
tx_ancillary_session_put(mgr, sidx);
}

return 0;
}

static int tx_ancillary_session_update_redundant(struct st_tx_ancillary_session_impl* s,
struct rte_mbuf* pkt_r) {
struct mt_udp_hdr* hdr = rte_pktmbuf_mtod(pkt_r, struct mt_udp_hdr*);
Expand Down Expand Up @@ -1918,7 +1902,6 @@ static int tx_ancillary_sessions_mgr_init(struct mtl_main_impl* impl,
memset(&ops, 0x0, sizeof(ops));
ops.priv = mgr;
ops.name = "tx_ancillary_sessions_mgr";
ops.start = tx_ancillary_sessions_tasklet_start;
ops.handler = tx_ancillary_sessions_tasklet_handler;

mgr->tasklet = mtl_sch_register_tasklet(sch, &ops);
Expand Down
41 changes: 13 additions & 28 deletions lib/src/st2110/st_tx_audio_session.c
Original file line number Diff line number Diff line change
Expand Up @@ -219,14 +219,6 @@ static int tx_audio_session_init_pacing(struct st_tx_audio_session_impl* s) {
return 0;
}

static int tx_audio_session_init_pacing_epoch(struct mtl_main_impl* impl,
struct st_tx_audio_session_impl* s) {
uint64_t ptp_time = mt_get_ptp_time(impl, MTL_PORT_P);
struct st_tx_audio_session_pacing* pacing = &s->pacing;
pacing->cur_epochs = ptp_time / pacing->trs;
return 0;
}

static inline double tx_audio_pacing_time(struct st_tx_audio_session_pacing* pacing,
uint64_t epochs) {
return epochs * pacing->trs;
Expand Down Expand Up @@ -268,7 +260,7 @@ static int tx_audio_session_sync_pacing(struct mtl_main_impl* impl,
long double pkt_time = pacing->trs;
/* always use MTL_PORT_P for ptp now */
uint64_t ptp_time = mt_get_ptp_time(impl, MTL_PORT_P);
uint64_t next_epochs = pacing->cur_epochs + 1;
uint64_t next_epochs;
uint64_t epochs;
double to_epoch;
uint64_t ptp_epochs;
Expand All @@ -286,6 +278,13 @@ static int tx_audio_session_sync_pacing(struct mtl_main_impl* impl,
epochs = ptp_time / pkt_time;
}

/*
* cur_epochs is 0 before the first frame (zero-initialized struct).
* Real PTP-derived epochs are ~10^11, so 0 is a safe "uninitialized" sentinel.
* On first call, start from ptp-derived epoch to avoid a false epoch_drop.
*/
next_epochs = likely(pacing->cur_epochs) ? pacing->cur_epochs + 1 : epochs;

dbg("%s(%d), epochs %" PRIu64 " %" PRIu64 "\n", __func__, s->idx, epochs,
pacing->cur_epochs);
if (epochs <= pacing->cur_epochs) {
Expand Down Expand Up @@ -325,8 +324,11 @@ static int tx_audio_session_sync_pacing(struct mtl_main_impl* impl,
}

if (epochs > next_epochs) {
ST_SESSION_STAT_ADD(s, port_user_stats.common, stat_epoch_drop,
(epochs - next_epochs));
/* skip drop accounting when user controls pacing — epoch jumps are intentional */
if (!required_tai) {
ST_SESSION_STAT_ADD(s, port_user_stats.common, stat_epoch_drop,
(epochs - next_epochs));
}
}

if (epochs < next_epochs) {
Expand Down Expand Up @@ -395,22 +397,6 @@ static int tx_audio_session_init(struct st_tx_audio_sessions_mgr* mgr,
return 0;
}

static int tx_audio_sessions_tasklet_start(void* priv) {
struct st_tx_audio_sessions_mgr* mgr = priv;
struct mtl_main_impl* impl = mgr->parent;
struct st_tx_audio_session_impl* s;

for (int sidx = 0; sidx < mgr->max_idx; sidx++) {
s = tx_audio_session_get(mgr, sidx);
if (!s) continue;

tx_audio_session_init_pacing_epoch(impl, s);
tx_audio_session_put(mgr, sidx);
}

return 0;
}

static int tx_audio_session_update_redundant(struct st_tx_audio_session_impl* s,
struct rte_mbuf* pkt_r) {
struct mt_udp_hdr* hdr = rte_pktmbuf_mtod(pkt_r, struct mt_udp_hdr*);
Expand Down Expand Up @@ -2433,7 +2419,6 @@ static int tx_audio_sessions_mgr_init(struct mtl_main_impl* impl,
memset(&ops, 0x0, sizeof(ops));
ops.priv = mgr;
ops.name = "tx_audio_sessions";
ops.start = tx_audio_sessions_tasklet_start;
ops.handler = tx_audio_sessions_tasklet;

mgr->tasklet = mtl_sch_register_tasklet(sch, &ops);
Expand Down
37 changes: 10 additions & 27 deletions lib/src/st2110/st_tx_fastmetadata_session.c
Original file line number Diff line number Diff line change
Expand Up @@ -215,14 +215,6 @@ static int tx_fastmetadata_session_init_pacing(
return 0;
}

static int tx_fastmetadata_session_init_pacing_epoch(
struct mtl_main_impl* impl, struct st_tx_fastmetadata_session_impl* s) {
uint64_t ptp_time = mt_get_ptp_time(impl, MTL_PORT_P);
struct st_tx_fastmetadata_session_pacing* pacing = &s->pacing;
pacing->cur_epochs = ptp_time / pacing->frame_time;
return 0;
}

static inline double tx_fastmetadata_pacing_time(
struct st_tx_fastmetadata_session_pacing* pacing, uint64_t epochs) {
return epochs * pacing->frame_time;
Expand Down Expand Up @@ -264,7 +256,7 @@ static int tx_fastmetadata_session_sync_pacing(struct mtl_main_impl* impl,
double frame_time = pacing->frame_time;
/* always use MTL_PORT_P for ptp now */
uint64_t ptp_time = mt_get_ptp_time(impl, MTL_PORT_P);
uint64_t next_epochs = pacing->cur_epochs + 1;
uint64_t next_epochs;
uint64_t epochs;
double to_epoch;
bool interlaced = s->ops.interlaced;
Expand All @@ -281,6 +273,13 @@ static int tx_fastmetadata_session_sync_pacing(struct mtl_main_impl* impl,
epochs = ptp_time / frame_time;
}

/*
* cur_epochs is 0 before the first frame (zero-initialized struct).
* Real PTP-derived epochs are ~10^11, so 0 is a safe "uninitialized" sentinel.
* On first call, start from ptp-derived epoch to avoid a false epoch_drop.
*/
next_epochs = likely(pacing->cur_epochs) ? pacing->cur_epochs + 1 : epochs;

dbg("%s(%d), epochs %" PRIu64 " %" PRIu64 "\n", __func__, s->idx, epochs,
pacing->cur_epochs);
if (epochs <= pacing->cur_epochs) {
Expand All @@ -306,7 +305,8 @@ static int tx_fastmetadata_session_sync_pacing(struct mtl_main_impl* impl,
to_epoch = 0; /* send asap */
}

if (epochs > next_epochs) s->stat_epoch_drop += (epochs - next_epochs);
/* skip drop accounting when user controls pacing — epoch jumps are intentional */
if (epochs > next_epochs && !required_tai) s->stat_epoch_drop += (epochs - next_epochs);
if (epochs < next_epochs) {
ST_SESSION_STAT_ADD(s, port_user_stats.common, stat_epoch_onward,
(next_epochs - epochs));
Expand Down Expand Up @@ -355,22 +355,6 @@ static int tx_fastmetadata_session_init(struct st_tx_fastmetadata_sessions_mgr*
return 0;
}

static int tx_fastmetadata_sessions_tasklet_start(void* priv) {
struct st_tx_fastmetadata_sessions_mgr* mgr = priv;
struct mtl_main_impl* impl = mgr->parent;
struct st_tx_fastmetadata_session_impl* s;

for (int sidx = 0; sidx < mgr->max_idx; sidx++) {
s = tx_fastmetadata_session_get(mgr, sidx);
if (!s) continue;

tx_fastmetadata_session_init_pacing_epoch(impl, s);
tx_fastmetadata_session_put(mgr, sidx);
}

return 0;
}

static int tx_fastmetadata_session_update_redundant(
struct st_tx_fastmetadata_session_impl* s, struct rte_mbuf* pkt_r) {
struct mt_udp_hdr* hdr = rte_pktmbuf_mtod(pkt_r, struct mt_udp_hdr*);
Expand Down Expand Up @@ -1678,7 +1662,6 @@ static int tx_fastmetadata_sessions_mgr_init(
memset(&ops, 0x0, sizeof(ops));
ops.priv = mgr;
ops.name = "tx_fastmetadata_sessions_mgr";
ops.start = tx_fastmetadata_sessions_tasklet_start;
ops.handler = tx_fastmetadata_sessions_tasklet_handler;

mgr->tasklet = mtl_sch_register_tasklet(sch, &ops);
Expand Down
35 changes: 16 additions & 19 deletions lib/src/st2110/st_tx_video_session.c
Original file line number Diff line number Diff line change
Expand Up @@ -604,14 +604,6 @@ static int tv_init_pacing(struct mtl_main_impl* impl,
return 0;
}

static int tv_init_pacing_epoch(struct mtl_main_impl* impl,
struct st_tx_video_session_impl* s) {
uint64_t ptp_time = mt_get_ptp_time(impl, MTL_PORT_P);
struct st_tx_video_pacing* pacing = &s->pacing;
pacing->cur_epochs = ptp_time / pacing->frame_time;
return 0;
}

static void validate_user_timestamp(struct st_tx_video_session_impl* s,
uint64_t requested_frame_count,
uint64_t current_frame_count) {
Expand All @@ -633,7 +625,13 @@ static inline uint64_t calc_frame_count_since_epoch(struct st_tx_video_session_i
uint64_t cur_tai,
uint64_t required_tai) {
uint64_t frame_count_tai = cur_tai / s->pacing.frame_time;
uint64_t next_free_frame_slot = s->pacing.cur_epochs + 1;
/*
* cur_epochs is 0 before the first frame (zero-initialized struct).
* Real PTP-derived epochs are ~10^11, so 0 is a safe "uninitialized" sentinel.
* On first call, start from frame_count_tai to avoid a false epoch_drop.
*/
uint64_t next_free_frame_slot =
likely(s->pacing.cur_epochs) ? s->pacing.cur_epochs + 1 : frame_count_tai;
uint64_t frame_count;

if (required_tai) {
Expand Down Expand Up @@ -661,14 +659,16 @@ static inline uint64_t calc_frame_count_since_epoch(struct st_tx_video_session_i
dbg("%s(%d), frame is late, frame_count_tai %" PRIu64 " next_free_frame_slot %" PRIu64
"\n",
__func__, s->idx, frame_count_tai, next_free_frame_slot);
ST_SESSION_STAT_ADD(s, port_user_stats.common, stat_epoch_drop,
(frame_count_tai - next_free_frame_slot));

if (s->ops.notify_frame_late) {
s->ops.notify_frame_late(s->ops.priv, frame_count_tai - next_free_frame_slot);
if (!required_tai) {
ST_SESSION_STAT_ADD(s, port_user_stats.common, stat_epoch_drop,
(frame_count_tai - next_free_frame_slot));
if (s->ops.notify_frame_late) {
s->ops.notify_frame_late(s->ops.priv, frame_count_tai - next_free_frame_slot);
}
frame_count = frame_count_tai;
}

frame_count = frame_count_tai;
/* when required_tai is set, keep user-derived frame_count — scheduler jitter
* does not mean the user dropped epochs */
}

return frame_count;
Expand Down Expand Up @@ -1746,8 +1746,6 @@ static int tv_tasklet_start(void* priv) {
for (int i = 0; i < s->ops.num_port; i++) {
s->last_burst_succ_time_tsc[i] = mt_get_tsc(impl);
}
/* calculate the pacing epoch */
tv_init_pacing_epoch(impl, s);
tx_video_session_put(mgr, sidx);
}

Expand Down Expand Up @@ -3359,7 +3357,6 @@ static int tv_attach(struct mtl_main_impl* impl, struct st_tx_video_sessions_mgr
s->last_burst_succ_time_tsc[i] = mt_get_tsc(impl);
}

tv_init_pacing_epoch(impl, s);
s->active = true;

info("%s(%d), len %d(%d) total %d each line %d type %d flags 0x%x, %s\n", __func__, idx,
Expand Down
Loading
Loading