Thank you for your answer. The 4500/960 thing as you say is called at every RTP packet I receive from a publisher.
If I read the code correctly, every incoming rtp packet from a publisher will be republished to all listeners:
packet.data = rtp;
packet.length = len;
packet.is_video = video;
/* Backup the actual timestamp and sequence number set by the publisher, in case switching is involved */
packet.timestamp = ntohl(packet.data->timestamp);
packet.seq_number = ntohs(packet.data->seq_number);
/* Go */
g_slist_foreach(participant->listeners, janus_videoroom_relay_rtp_packet, &packet);
So janus_videoroom_relay_rtp_packet is called with the packet received from a publisher. Then in janus_videoroom_relay_rtp_packet:
/* Make sure there hasn't been a publisher switch by checking the SSRC */ <-- I don't understand this comment as you just testing if the packet is a video packet
if(packet->is_video) {
Then finally, if it's a video packet you call:
janus_rtp_header_update(packet->data, &listener->context, TRUE, 4500);
in rtp.c, the function janus_rtp_header_update check if (video) so:
if(video) {
if(ssrc != context->v_last_ssrc) {
/* Video SSRC changed: update both sequence number and timestamp */
JANUS_LOG(LOG_VERB, "Video SSRC changed, %"SCNu32" --> %"SCNu32"\n",
context->v_last_ssrc, ssrc);
context->v_last_ssrc = ssrc;
context->v_base_ts_prev = context->v_last_ts;
context->v_base_ts = timestamp;
context->v_base_seq_prev = context->v_last_seq;
context->v_base_seq = seq;
}
if(context->v_seq_reset) {
/* Video sequence number was paused for a while: just update that */
context->v_seq_reset = FALSE;
context->v_base_seq_prev = context->v_last_seq;
context->v_base_seq = header->seq_number;
}
/* Compute a coherent timestamp and sequence number */
context->v_last_ts = (timestamp-context->v_base_ts) + context->v_base_ts_prev+step; <---- Here, you adapt the context->v_last_ts with the step that is equal to 4500
context->v_last_seq = (seq-context->v_base_seq)+context->v_base_seq_prev+1;
/* Update the timestamp and sequence number in the RTP packet */
header->timestamp = htonl(context->v_last_ts); <---- And finally set the new timestamp computed with step on the RTP header for the listener
header->seq_number = htons(context->v_last_seq);
So if I understand your code correctly, the rtp header packet is updated for every video and audio packet received from the publisher before sent to each listeners with specific v_base_ts and step added (4500 for video / 960 for audio), tell me if I'm wrong.
If I log the header->timestamp updated for a listener, I see it's called all the time for each video packet. It's why I'm asking about the fixed step (4500/960) used.
I'm using a SDP renegotiation because I'm changing the max bitrate & the resolution via getUserMedia (not only the bitrate). I'm not aware of a request that could change the resolution dynamically like the configure request for target bitrate. A/V out-of-sync seems to occur frequently after some video freezes (slow links).
I started to record some streams to see if the problem is coming from the publisher or from janus. I let you know the result after processing with janus-pp-rec.
Thank you Lorenzo.
Sebastien.