janus: ssrc per client

This commit is contained in:
Maxim Devaev
2026-05-31 07:11:44 +03:00
parent 9fe42b038a
commit 4dc0f73e1b
7 changed files with 55 additions and 41 deletions

View File

@@ -55,6 +55,9 @@ us_janus_client_s *us_janus_client_init(janus_callbacks *gw, janus_plugin_sessio
US_CALLOC(client, 1);
client->gw = gw;
client->session = session;
client->video_ssrc = us_get_ssrc();
client->audio_ssrc = us_get_ssrc();
atomic_init(&client->transmit, false);
atomic_init(&client->transmit_acap, false);
atomic_init(&client->transmit_aplay, false);
@@ -181,6 +184,8 @@ static void *_video_or_acap_thread(void *v_client, bool video) {
atomic_load(&client->transmit)
&& (video || atomic_load(&client->transmit_acap))
) {
us_rtp_write_ssrc(&rtp, (rtp.video ? client->video_ssrc : client->audio_ssrc));
janus_plugin_rtp packet = {
.video = rtp.video,
.buffer = (char*)rtp.datagram,

View File

@@ -37,6 +37,9 @@
typedef struct {
janus_callbacks *gw;
janus_plugin_session *session;
u32 video_ssrc;
u32 audio_ssrc;
atomic_bool transmit;
atomic_bool transmit_acap;
atomic_bool transmit_aplay;

View File

@@ -641,14 +641,22 @@ static struct janus_plugin_result *_plugin_handle_message(
}
{
_LOCK_ALL;
US_LIST_ITERATE(_g_clients, client, {
if (client->session == session) {
char *const sdp = us_sdp_create(
_g_rtpv,
(with_acap ? _g_rtpa : NULL),
client->video_ssrc,
client->audio_ssrc,
with_acap,
with_aplay);
json_t *const offer_jsep = json_pack("{ssss}", "type", "offer", "sdp", sdp);
PUSH_STATUS("started", NULL, offer_jsep);
json_decref(offer_jsep);
free(sdp);
break;
}
});
_UNLOCK_ALL;
}
{

View File

@@ -44,9 +44,11 @@ void us_rtp_destroy(us_rtp_s *rtp) {
void us_rtp_assign(us_rtp_s *rtp, uint payload, bool video) {
rtp->payload = payload;
rtp->video = video;
rtp->ssrc = us_triple_u32(us_get_now_monotonic_u64());
}
#define WRITE_BE_U32(x_offset, x_value) \
*((u32*)(rtp->datagram + x_offset)) = __builtin_bswap32(x_value)
void us_rtp_write_header(us_rtp_s *rtp, u32 pts, bool last_header) {
u32 word0 = 0x80000000;
if (last_header) {
@@ -56,10 +58,13 @@ void us_rtp_write_header(us_rtp_s *rtp, u32 pts, bool last_header) {
word0 |= rtp->seq;
++rtp->seq;
# define WRITE_BE_U32(x_offset, x_value) \
*((u32*)(rtp->datagram + x_offset)) = __builtin_bswap32(x_value)
WRITE_BE_U32(0, word0);
WRITE_BE_U32(4, pts);
WRITE_BE_U32(8, rtp->ssrc);
# undef WRITE_BE_U32
WRITE_BE_U32(8, 0); // SSRC should be written separately for each client
}
void us_rtp_write_ssrc(us_rtp_s *rtp, u32 ssrc) {
WRITE_BE_U32(8, ssrc);
}
#undef WRITE_BE_U32

View File

@@ -23,6 +23,7 @@
#pragma once
#include "uslibs/types.h"
#include "uslibs/tools.h"
// Max RTP size for WebRTC is 1200 bytes:
@@ -47,7 +48,6 @@
typedef struct {
uint payload;
bool video;
u32 ssrc;
u16 seq;
u8 datagram[US_RTP_TOTAL_SIZE];
@@ -62,8 +62,13 @@ typedef struct {
typedef void (*us_rtp_callback_f)(const us_rtp_s *rtp);
static inline u32 us_get_ssrc(void) {
return us_triple_u32(us_get_now_monotonic_u64());
}
us_rtp_s *us_rtp_init(void);
void us_rtp_destroy(us_rtp_s *rtp);
void us_rtp_assign(us_rtp_s *rtp, uint payload, bool video);
void us_rtp_write_header(us_rtp_s *rtp, u32 pts, bool last_header);
void us_rtp_write_ssrc(us_rtp_s *rtp, u32 ssrc);

View File

@@ -34,12 +34,12 @@
#include "rtpa.h"
char *us_sdp_create(us_rtpv_s *rtpv, us_rtpa_s *rtpa, bool mic) {
char *us_sdp_create(u32 video_ssrc, u32 audio_ssrc, bool acap, bool aplay) {
char *video_sdp;
{
// https://tools.ietf.org/html/rfc6184
// https://github.com/meetecho/janus-gateway/issues/2443
const uint pl = rtpv->rtp->payload;
const uint pl = US_RTP_H264_PAYLOAD;
US_ASPRINTF(
video_sdp,
"m=video 1 RTP/SAVPF %u" RN
@@ -58,31 +58,20 @@ char *us_sdp_create(us_rtpv_s *rtpv, us_rtpa_s *rtpa, bool mic) {
"a=extmap:3/sendonly http://www.webrtc.org/experiments/rtp-hdrext/abs-capture-time" RN
"a=sendonly" RN,
pl, pl, pl, pl, pl, pl, pl,
rtpv->rtp->ssrc);
video_ssrc);
}
char *audio_sdp;
if (rtpa == NULL) {
audio_sdp = us_strdup("");
} else {
if (acap || aplay) {
const uint pl = US_RTP_OPUS_PAYLOAD;
if (rtpa != NULL || mic) {
uint pl;
u32 ssrc;
if (rtpa != NULL) {
pl = rtpa->rtp->payload;
ssrc = rtpa->rtp->ssrc;
} else {
pl = US_RTP_OPUS_PAYLOAD;
ssrc = us_triple_u32(us_get_now_monotonic_u64());
}
char *dir = "sendrecv";
if (rtpa == NULL) {
dir = "recvonly";
} else if (!mic) {
char *dir = "";
if (acap && aplay) {
dir = "sendrecv";
} else if (acap && !aplay) {
dir = "sendonly";
} else if (!acap && aplay) {
dir = "recvonly";
}
US_ASPRINTF(
@@ -98,8 +87,10 @@ char *us_sdp_create(us_rtpv_s *rtpv, us_rtpa_s *rtpa, bool mic) {
pl, pl,
US_RTP_OPUS_HZ, US_RTP_OPUS_CH,
pl,
ssrc,
audio_ssrc,
dir);
} else {
audio_sdp = us_strdup("");
}
char *sdp;

View File

@@ -24,8 +24,5 @@
#include "uslibs/types.h"
#include "rtpv.h"
#include "rtpa.h"
char *us_sdp_create(us_rtpv_s *rtpv, us_rtpa_s *rtpa, bool mic);
char *us_sdp_create(u32 video_ssrc, u32 audio_ssrc, bool acap, bool aplay);