Skip to content

Commit 1bd2056

Browse files
tszumskidesaulov
andauthored
Fix: audio RTP timestamp calculation (#1213)
Potentially fixes #1185 Remove (set and unused) pacing_time_stamp struct member Use TAI instead of epoch to calculate RTP time stamp For code consistency use pkt_time instead of pacing->trs --------- Co-authored-by: desaulov <[email protected]>
1 parent 567bbc0 commit 1bd2056

File tree

2 files changed

+31
-8
lines changed

2 files changed

+31
-8
lines changed

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_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)