@@ -21,7 +21,10 @@ use rustrtc::{
2121 track:: SampleStreamTrack ,
2222 } ,
2323} ;
24- use std:: { sync:: Arc , time:: Duration } ;
24+ use std:: {
25+ sync:: Arc ,
26+ time:: { Duration , Instant } ,
27+ } ;
2528use tokio:: sync:: Mutex ;
2629use tokio_util:: sync:: CancellationToken ;
2730use tracing:: { debug, info} ;
@@ -61,10 +64,11 @@ pub struct RtcTrack {
6164 local_source : Option < Arc < SampleStreamSource > > ,
6265 encoder : TrackCodec ,
6366 ssrc : u32 ,
64- payload_type : Arc < std :: sync :: atomic :: AtomicU8 > ,
67+ payload_type : u8 ,
6568 pub peer_connection : Option < Arc < PeerConnection > > ,
66- next_rtp_timestamp : Arc < std:: sync:: atomic:: AtomicU32 > ,
67- next_rtp_sequence_number : Arc < std:: sync:: atomic:: AtomicU16 > ,
69+ next_rtp_timestamp : u32 ,
70+ next_rtp_sequence_number : u16 ,
71+ last_packet_time : Option < Instant > ,
6872}
6973
7074impl RtcTrack {
@@ -85,10 +89,11 @@ impl RtcTrack {
8589 local_source : None ,
8690 encoder : TrackCodec :: new ( ) ,
8791 ssrc : 0 ,
88- payload_type : Arc :: new ( std :: sync :: atomic :: AtomicU8 :: new ( 0 ) ) ,
92+ payload_type : 0 ,
8993 peer_connection : None ,
90- next_rtp_timestamp : Arc :: new ( std:: sync:: atomic:: AtomicU32 :: new ( 0 ) ) ,
91- next_rtp_sequence_number : Arc :: new ( std:: sync:: atomic:: AtomicU16 :: new ( 0 ) ) ,
94+ next_rtp_timestamp : 0 ,
95+ next_rtp_sequence_number : 0 ,
96+ last_packet_time : None ,
9297 }
9398 }
9499
@@ -164,8 +169,7 @@ impl RtcTrack {
164169 . payload_type
165170 . unwrap_or_else ( || codec. payload_type ( ) ) ;
166171
167- self . payload_type
168- . store ( payload_type, std:: sync:: atomic:: Ordering :: SeqCst ) ;
172+ self . payload_type = payload_type;
169173
170174 let params = RtpCodecParameters {
171175 clock_rate : codec. clock_rate ( ) ,
@@ -181,7 +185,7 @@ impl RtcTrack {
181185 peer_connection. clone ( ) ,
182186 self . track_id . clone ( ) ,
183187 self . processor_chain . clone ( ) ,
184- self . payload_type . clone ( ) ,
188+ self . payload_type ,
185189 ) ;
186190
187191 if self . rtc_config . mode == TransportMode :: Rtp {
@@ -195,7 +199,7 @@ impl RtcTrack {
195199 self . track_id . clone ( ) ,
196200 self . cancel_token . clone ( ) ,
197201 self . processor_chain . clone ( ) ,
198- self . payload_type . clone ( ) ,
202+ self . payload_type ,
199203 ) ;
200204 }
201205 }
@@ -209,7 +213,7 @@ impl RtcTrack {
209213 pc : Arc < PeerConnection > ,
210214 track_id : TrackId ,
211215 processor_chain : ProcessorChain ,
212- default_payload_type : Arc < std :: sync :: atomic :: AtomicU8 > ,
216+ default_payload_type : u8 ,
213217 ) {
214218 let cancel_token = self . cancel_token . clone ( ) ;
215219 let packet_sender = self . packet_sender . clone ( ) ;
@@ -282,7 +286,7 @@ impl RtcTrack {
282286 track_id : TrackId ,
283287 cancel_token : CancellationToken ,
284288 processor_chain : ProcessorChain ,
285- default_payload_type : Arc < std :: sync :: atomic :: AtomicU8 > ,
289+ default_payload_type : u8 ,
286290 ) {
287291 let ( tx, mut rx) =
288292 tokio:: sync:: mpsc:: unbounded_channel :: < rustrtc:: media:: frame:: AudioFrame > ( ) ;
@@ -303,7 +307,7 @@ impl RtcTrack {
303307 & track_id_proc,
304308 & packet_sender_proc,
305309 & mut processor_chain_proc,
306- default_payload_type. clone ( ) ,
310+ default_payload_type,
307311 )
308312 . await ;
309313 }
@@ -335,13 +339,11 @@ impl RtcTrack {
335339 track_id : & TrackId ,
336340 packet_sender : & Arc < Mutex < Option < TrackPacketSender > > > ,
337341 processor_chain : & mut ProcessorChain ,
338- default_payload_type : Arc < std :: sync :: atomic :: AtomicU8 > ,
342+ default_payload_type : u8 ,
339343 ) {
340344 let packet_sender = packet_sender. lock ( ) . await ;
341345 if let Some ( sender) = packet_sender. as_ref ( ) {
342- let payload_type = frame
343- . payload_type
344- . unwrap_or_else ( || default_payload_type. load ( std:: sync:: atomic:: Ordering :: SeqCst ) ) ;
346+ let payload_type = frame. payload_type . unwrap_or ( default_payload_type) ;
345347 let src_codec = match CodecType :: try_from ( payload_type) {
346348 Ok ( c) => c,
347349 Err ( _) => {
@@ -401,8 +403,7 @@ impl RtcTrack {
401403 if let Some ( codec) = codec {
402404 if codec != CodecType :: TelephoneEvent {
403405 info ! ( track_id=%self . track_id, "Negotiated primary audio PT {} ({:?})" , pt, codec) ;
404- self . payload_type
405- . store ( pt, std:: sync:: atomic:: Ordering :: SeqCst ) ;
406+ self . payload_type = pt;
406407 break ;
407408 }
408409 }
@@ -512,22 +513,32 @@ impl Track for RtcTrack {
512513 let ( _, encoded) = self . encoder . encode ( payload_type, packet. clone ( ) ) ;
513514 let target_codec = CodecType :: try_from ( payload_type) ?;
514515 if !encoded. is_empty ( ) {
515- let target_samples =
516- ( samples. len ( ) as u64 * target_codec. samplerate ( ) as u64
517- / packet. sample_rate as u64 ) as u32 ;
518- let sample_count_per_channel =
519- target_samples / self . track_config . channels as u32 ;
520- let rtp_timestamp = self . next_rtp_timestamp . fetch_add (
521- sample_count_per_channel,
522- std:: sync:: atomic:: Ordering :: SeqCst ,
523- ) ;
524- let sequence_number = self
525- . next_rtp_sequence_number
526- . fetch_add ( 1 , std:: sync:: atomic:: Ordering :: SeqCst ) ;
516+ let clock_rate = target_codec. clock_rate ( ) ;
517+
518+ let now = Instant :: now ( ) ;
519+ if let Some ( last_time) = self . last_packet_time {
520+ let elapsed = now. duration_since ( last_time) ;
521+ if elapsed. as_millis ( ) > 50 {
522+ let gap_increment =
523+ ( elapsed. as_millis ( ) as u32 * clock_rate) / 1000 ;
524+ self . next_rtp_timestamp += gap_increment;
525+ }
526+ }
527+
528+ self . last_packet_time = Some ( now) ;
529+
530+ let timestamp_increment = ( samples. len ( ) as u64 * clock_rate as u64
531+ / packet. sample_rate as u64
532+ / self . track_config . channels as u64 )
533+ as u32 ;
534+ let rtp_timestamp = self . next_rtp_timestamp ;
535+ self . next_rtp_timestamp += timestamp_increment;
536+ let sequence_number = self . next_rtp_sequence_number ;
537+ self . next_rtp_sequence_number += 1 ;
527538
528539 let frame = RtcAudioFrame {
529540 data : Bytes :: from ( encoded) ,
530- clock_rate : target_codec . clock_rate ( ) ,
541+ clock_rate,
531542 payload_type : Some ( payload_type) ,
532543 sequence_number : Some ( sequence_number) ,
533544 rtp_timestamp,
@@ -540,28 +551,36 @@ impl Track for RtcTrack {
540551 payload_type,
541552 sequence_number,
542553 } => {
543- let target_sample_rate = match * payload_type {
544- 0 | 8 | 18 => 8000 ,
545- 9 => 16000 ,
554+ let clock_rate = match * payload_type {
555+ 0 | 8 | 9 | 18 => 8000 ,
546556 111 => 48000 ,
547557 _ => packet. sample_rate ,
548558 } ;
549559
550- // Estimate samples if we don't have them
560+ let now = Instant :: now ( ) ;
561+ if let Some ( last_time) = self . last_packet_time {
562+ let elapsed = now. duration_since ( last_time) ;
563+ if elapsed. as_millis ( ) > 50 {
564+ let gap_increment = ( elapsed. as_millis ( ) as u32 * clock_rate) / 1000 ;
565+ self . next_rtp_timestamp += gap_increment;
566+ }
567+ }
568+ self . last_packet_time = Some ( now) ;
569+
551570 let increment = match * payload_type {
552571 0 | 8 | 18 => payload. len ( ) as u32 ,
553- 9 => ( payload. len ( ) * 2 ) as u32 ,
554- 111 => ( target_sample_rate / 50 ) as u32 , // Assume 20ms for Opus if unknown
555- _ => ( target_sample_rate / 50 ) as u32 ,
572+ 9 => payload. len ( ) as u32 ,
573+ 111 => ( clock_rate / 50 ) as u32 ,
574+ _ => ( clock_rate / 50 ) as u32 ,
556575 } ;
557- let rtp_timestamp = self
558- . next_rtp_timestamp
559- . fetch_add ( increment, std :: sync :: atomic :: Ordering :: SeqCst ) ;
576+
577+ let rtp_timestamp = self . next_rtp_timestamp ;
578+ self . next_rtp_timestamp += increment;
560579 let sequence_number = * sequence_number;
561580
562581 let frame = RtcAudioFrame {
563582 data : Bytes :: from ( payload. clone ( ) ) ,
564- clock_rate : target_sample_rate ,
583+ clock_rate,
565584 payload_type : Some ( * payload_type) ,
566585 sequence_number : Some ( sequence_number) ,
567586 rtp_timestamp,
@@ -577,7 +596,7 @@ impl Track for RtcTrack {
577596
578597impl RtcTrack {
579598 fn get_payload_type ( & self ) -> u8 {
580- let pt = self . payload_type . load ( std :: sync :: atomic :: Ordering :: SeqCst ) ;
599+ let pt = self . payload_type ;
581600 if pt != 0 {
582601 return pt;
583602 }
0 commit comments