@@ -18,9 +18,8 @@ static inline double pacing_time(struct st_tx_video_pacing* pacing, uint64_t epo
18
18
return epochs * pacing -> frame_time ;
19
19
}
20
20
21
- static inline double pacing_first_pkt_time (struct st_tx_video_pacing * pacing ,
22
- uint64_t epochs ) {
23
- return pacing_time (pacing , epochs ) + pacing -> tr_offset - (pacing -> vrx * pacing -> trs );
21
+ static inline double pacing_first_pkt_time (struct st_tx_video_pacing * pacing ) {
22
+ return pacing -> tr_offset - (pacing -> vrx * pacing -> trs );
24
23
}
25
24
26
25
/* pacing start time(warmup pkt if has warmup stage) of the frame */
@@ -33,25 +32,26 @@ static inline double pacing_start_time(struct st_tx_video_pacing* pacing,
33
32
/* time stamp on the first pkt video pkt(not the warmup) */
34
33
static inline uint32_t pacing_time_stamp (struct st_tx_video_session_impl * s ,
35
34
struct st_tx_video_pacing * pacing ,
36
- uint64_t epochs ) {
35
+ uint64_t epochs , uint64_t tai ) {
37
36
uint64_t tmstamp64 ;
38
- double time ;
39
- if (s -> ops .flags & ST20_TX_FLAG_RTP_TIMESTAMP_EPOCH ) {
40
- /* the start of epoch */
41
- time = pacing_first_pkt_time (pacing , epochs );
42
- } else if (s -> ops .flags & ST20_TX_FLAG_RTP_TIMESTAMP_FIRST_PKT ) {
37
+ long double frame_time = pacing -> frame_time ;
38
+ double time = pacing_time (pacing , epochs );
39
+
40
+ if (s -> ops .flags & ST20_TX_FLAG_USER_TIMESTAMP ) {
41
+ time = tai ;
42
+ } else if (s -> ops .flags & ST20_TX_FLAG_RTP_TIMESTAMP_EPOCH ) {
43
+ time += pacing_first_pkt_time (pacing );
44
+ } else { // if (s->ops.flags & ST20_TX_FLAG_RTP_TIMESTAMP_FIRST_PKT) {
43
45
/* the start of first pkt */
44
- time = pacing_first_pkt_time (pacing , epochs );
45
- if (pacing -> warm_pkts ) time -= 3 * pacing -> trs ; /* deviation for VRX */
46
- } else if (s -> ops .rtp_timestamp_delta_us ) {
47
- int32_t rtp_timestamp_delta_us = s -> ops .rtp_timestamp_delta_us ;
48
- time = pacing_time (pacing , epochs ) + (rtp_timestamp_delta_us * NS_PER_US );
49
- } else {
50
- /* default to the start of first pkt */
51
- time = pacing_first_pkt_time (pacing , epochs );
46
+ time += pacing_first_pkt_time (pacing );
52
47
if (pacing -> warm_pkts ) time -= 3 * pacing -> trs ; /* deviation for VRX */
53
48
}
54
- tmstamp64 = (time / pacing -> frame_time ) * pacing -> frame_time_sampling ;
49
+
50
+ if (s -> ops .rtp_timestamp_delta_us ) {
51
+ time += (s -> ops .rtp_timestamp_delta_us * NS_PER_US );
52
+ }
53
+
54
+ tmstamp64 = (time / frame_time ) * pacing -> frame_time_sampling ;
55
55
uint32_t tmstamp32 = tmstamp64 ;
56
56
57
57
return tmstamp32 ;
@@ -600,10 +600,12 @@ static int tv_sync_pacing(struct mtl_main_impl* impl, struct st_tx_video_session
600
600
int idx = s -> idx ;
601
601
struct st_tx_video_pacing * pacing = & s -> pacing ;
602
602
double frame_time = pacing -> frame_time ;
603
+ double to_epoch ;
603
604
/* always use MTL_PORT_P for ptp now */
604
605
uint64_t ptp_time = mt_get_ptp_time (impl , MTL_PORT_P );
605
606
uint64_t next_epochs = pacing -> cur_epochs + 1 ;
606
607
uint64_t epochs ;
608
+ uint64_t ptp_epochs ;
607
609
bool interlaced = s -> ops .interlaced ;
608
610
609
611
if (required_tai ) {
@@ -638,7 +640,22 @@ static int tv_sync_pacing(struct mtl_main_impl* impl, struct st_tx_video_session
638
640
639
641
/* epoch resolved */
640
642
double start_time_ptp = pacing_start_time (pacing , epochs );
641
- double to_epoch = start_time_ptp - ptp_time ;
643
+ if (required_tai ) {
644
+ to_epoch = (double )required_tai - ptp_time ;
645
+ if (to_epoch > NS_PER_S ) {
646
+ dbg ("%s(%d), required tai %" PRIu64 " ptp_epochs %" PRIu64 " epochs %" PRIu64 "\n" ,
647
+ __func__ , s -> idx , required_tai , ptp_epochs , epochs );
648
+ s -> stat_error_user_timestamp ++ ;
649
+ to_epoch = NS_PER_S ; // do our best to slow down
650
+ }
651
+ if (to_epoch < 0 ) {
652
+ /* time bigger than the assigned epoch time */
653
+ to_epoch = 0 ; /* send asap */
654
+ }
655
+ } else {
656
+ to_epoch = start_time_ptp - ptp_time ;
657
+ }
658
+
642
659
if (to_epoch < 0 ) {
643
660
/* time larger than the next assigned epoch time */
644
661
dbg ("%s(%d), to_epoch %f, ptp epochs %" PRIu64 " cur_epochs %" PRIu64
@@ -665,8 +682,13 @@ static int tv_sync_pacing(struct mtl_main_impl* impl, struct st_tx_video_session
665
682
}
666
683
if (epochs < next_epochs ) s -> stat_epoch_onward += (next_epochs - epochs );
667
684
pacing -> cur_epochs = epochs ;
668
- pacing -> cur_epoch_time = pacing_time (pacing , epochs );
669
- pacing -> rtp_time_stamp = pacing_time_stamp (s , pacing , epochs );
685
+ if (s -> ops .flags & ST20_TX_FLAG_USER_TIMESTAMP ){
686
+ pacing -> cur_epoch_time = required_tai ;
687
+ }else {
688
+ pacing -> cur_epoch_time = pacing_time (pacing , epochs );
689
+ }
690
+
691
+ pacing -> rtp_time_stamp = pacing_time_stamp (s , pacing , epochs , required_tai );
670
692
dbg ("%s(%d), old time_cursor %fms\n" , __func__ , idx ,
671
693
pacing -> tsc_time_cursor / 1000 / 1000 );
672
694
pacing -> tsc_time_cursor = (double )mt_get_tsc (impl ) + to_epoch ;
0 commit comments