mirror of
https://github.com/pikvm/ustreamer.git
synced 2026-07-17 17:21:55 +00:00
janus: ssrc per client
This commit is contained in:
@@ -55,6 +55,9 @@ us_janus_client_s *us_janus_client_init(janus_callbacks *gw, janus_plugin_sessio
|
|||||||
US_CALLOC(client, 1);
|
US_CALLOC(client, 1);
|
||||||
client->gw = gw;
|
client->gw = gw;
|
||||||
client->session = session;
|
client->session = session;
|
||||||
|
client->video_ssrc = us_get_ssrc();
|
||||||
|
client->audio_ssrc = us_get_ssrc();
|
||||||
|
|
||||||
atomic_init(&client->transmit, false);
|
atomic_init(&client->transmit, false);
|
||||||
atomic_init(&client->transmit_acap, false);
|
atomic_init(&client->transmit_acap, false);
|
||||||
atomic_init(&client->transmit_aplay, 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)
|
atomic_load(&client->transmit)
|
||||||
&& (video || atomic_load(&client->transmit_acap))
|
&& (video || atomic_load(&client->transmit_acap))
|
||||||
) {
|
) {
|
||||||
|
us_rtp_write_ssrc(&rtp, (rtp.video ? client->video_ssrc : client->audio_ssrc));
|
||||||
|
|
||||||
janus_plugin_rtp packet = {
|
janus_plugin_rtp packet = {
|
||||||
.video = rtp.video,
|
.video = rtp.video,
|
||||||
.buffer = (char*)rtp.datagram,
|
.buffer = (char*)rtp.datagram,
|
||||||
|
|||||||
@@ -37,6 +37,9 @@
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
janus_callbacks *gw;
|
janus_callbacks *gw;
|
||||||
janus_plugin_session *session;
|
janus_plugin_session *session;
|
||||||
|
u32 video_ssrc;
|
||||||
|
u32 audio_ssrc;
|
||||||
|
|
||||||
atomic_bool transmit;
|
atomic_bool transmit;
|
||||||
atomic_bool transmit_acap;
|
atomic_bool transmit_acap;
|
||||||
atomic_bool transmit_aplay;
|
atomic_bool transmit_aplay;
|
||||||
|
|||||||
@@ -641,14 +641,22 @@ static struct janus_plugin_result *_plugin_handle_message(
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
char *const sdp = us_sdp_create(
|
_LOCK_ALL;
|
||||||
_g_rtpv,
|
US_LIST_ITERATE(_g_clients, client, {
|
||||||
(with_acap ? _g_rtpa : NULL),
|
if (client->session == session) {
|
||||||
with_aplay);
|
char *const sdp = us_sdp_create(
|
||||||
json_t *const offer_jsep = json_pack("{ssss}", "type", "offer", "sdp", sdp);
|
client->video_ssrc,
|
||||||
PUSH_STATUS("started", NULL, offer_jsep);
|
client->audio_ssrc,
|
||||||
json_decref(offer_jsep);
|
with_acap,
|
||||||
free(sdp);
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -44,9 +44,11 @@ void us_rtp_destroy(us_rtp_s *rtp) {
|
|||||||
void us_rtp_assign(us_rtp_s *rtp, uint payload, bool video) {
|
void us_rtp_assign(us_rtp_s *rtp, uint payload, bool video) {
|
||||||
rtp->payload = payload;
|
rtp->payload = payload;
|
||||||
rtp->video = video;
|
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) {
|
void us_rtp_write_header(us_rtp_s *rtp, u32 pts, bool last_header) {
|
||||||
u32 word0 = 0x80000000;
|
u32 word0 = 0x80000000;
|
||||||
if (last_header) {
|
if (last_header) {
|
||||||
@@ -56,10 +58,13 @@ void us_rtp_write_header(us_rtp_s *rtp, u32 pts, bool last_header) {
|
|||||||
word0 |= rtp->seq;
|
word0 |= rtp->seq;
|
||||||
++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(0, word0);
|
||||||
WRITE_BE_U32(4, pts);
|
WRITE_BE_U32(4, pts);
|
||||||
WRITE_BE_U32(8, rtp->ssrc);
|
WRITE_BE_U32(8, 0); // SSRC should be written separately for each client
|
||||||
# undef WRITE_BE_U32
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void us_rtp_write_ssrc(us_rtp_s *rtp, u32 ssrc) {
|
||||||
|
WRITE_BE_U32(8, ssrc);
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef WRITE_BE_U32
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "uslibs/types.h"
|
#include "uslibs/types.h"
|
||||||
|
#include "uslibs/tools.h"
|
||||||
|
|
||||||
|
|
||||||
// Max RTP size for WebRTC is 1200 bytes:
|
// Max RTP size for WebRTC is 1200 bytes:
|
||||||
@@ -47,7 +48,6 @@
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
uint payload;
|
uint payload;
|
||||||
bool video;
|
bool video;
|
||||||
u32 ssrc;
|
|
||||||
|
|
||||||
u16 seq;
|
u16 seq;
|
||||||
u8 datagram[US_RTP_TOTAL_SIZE];
|
u8 datagram[US_RTP_TOTAL_SIZE];
|
||||||
@@ -62,8 +62,13 @@ typedef struct {
|
|||||||
typedef void (*us_rtp_callback_f)(const us_rtp_s *rtp);
|
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);
|
us_rtp_s *us_rtp_init(void);
|
||||||
void us_rtp_destroy(us_rtp_s *rtp);
|
void us_rtp_destroy(us_rtp_s *rtp);
|
||||||
|
|
||||||
void us_rtp_assign(us_rtp_s *rtp, uint payload, bool video);
|
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_header(us_rtp_s *rtp, u32 pts, bool last_header);
|
||||||
|
void us_rtp_write_ssrc(us_rtp_s *rtp, u32 ssrc);
|
||||||
|
|||||||
@@ -34,12 +34,12 @@
|
|||||||
#include "rtpa.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) {
|
||||||
char *video_sdp;
|
char *video_sdp;
|
||||||
{
|
{
|
||||||
// https://tools.ietf.org/html/rfc6184
|
// https://tools.ietf.org/html/rfc6184
|
||||||
// https://github.com/meetecho/janus-gateway/issues/2443
|
// https://github.com/meetecho/janus-gateway/issues/2443
|
||||||
const uint pl = rtpv->rtp->payload;
|
const uint pl = US_RTP_H264_PAYLOAD;
|
||||||
US_ASPRINTF(
|
US_ASPRINTF(
|
||||||
video_sdp,
|
video_sdp,
|
||||||
"m=video 1 RTP/SAVPF %u" RN
|
"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=extmap:3/sendonly http://www.webrtc.org/experiments/rtp-hdrext/abs-capture-time" RN
|
||||||
"a=sendonly" RN,
|
"a=sendonly" RN,
|
||||||
pl, pl, pl, pl, pl, pl, pl,
|
pl, pl, pl, pl, pl, pl, pl,
|
||||||
rtpv->rtp->ssrc);
|
video_ssrc);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *audio_sdp;
|
char *audio_sdp;
|
||||||
if (rtpa == NULL) {
|
if (acap || aplay) {
|
||||||
audio_sdp = us_strdup("");
|
const uint pl = US_RTP_OPUS_PAYLOAD;
|
||||||
} else {
|
|
||||||
|
|
||||||
|
char *dir = "";
|
||||||
if (rtpa != NULL || mic) {
|
if (acap && aplay) {
|
||||||
uint pl;
|
dir = "sendrecv";
|
||||||
u32 ssrc;
|
} else if (acap && !aplay) {
|
||||||
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) {
|
|
||||||
dir = "sendonly";
|
dir = "sendonly";
|
||||||
|
} else if (!acap && aplay) {
|
||||||
|
dir = "recvonly";
|
||||||
}
|
}
|
||||||
|
|
||||||
US_ASPRINTF(
|
US_ASPRINTF(
|
||||||
@@ -98,8 +87,10 @@ char *us_sdp_create(us_rtpv_s *rtpv, us_rtpa_s *rtpa, bool mic) {
|
|||||||
pl, pl,
|
pl, pl,
|
||||||
US_RTP_OPUS_HZ, US_RTP_OPUS_CH,
|
US_RTP_OPUS_HZ, US_RTP_OPUS_CH,
|
||||||
pl,
|
pl,
|
||||||
ssrc,
|
audio_ssrc,
|
||||||
dir);
|
dir);
|
||||||
|
} else {
|
||||||
|
audio_sdp = us_strdup("");
|
||||||
}
|
}
|
||||||
|
|
||||||
char *sdp;
|
char *sdp;
|
||||||
|
|||||||
@@ -24,8 +24,5 @@
|
|||||||
|
|
||||||
#include "uslibs/types.h"
|
#include "uslibs/types.h"
|
||||||
|
|
||||||
#include "rtpv.h"
|
|
||||||
#include "rtpa.h"
|
|
||||||
|
|
||||||
|
char *us_sdp_create(u32 video_ssrc, u32 audio_ssrc, bool acap, bool aplay);
|
||||||
char *us_sdp_create(us_rtpv_s *rtpv, us_rtpa_s *rtpa, bool mic);
|
|
||||||
|
|||||||
Reference in New Issue
Block a user