Skip to content

Commit

Permalink
refactoring, increased bitrate, reduced buffers
Browse files Browse the repository at this point in the history
  • Loading branch information
mdevaev committed Jan 18, 2025
1 parent 10595a1 commit a94ff66
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 20 deletions.
30 changes: 16 additions & 14 deletions janus/src/acap.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include "uslibs/ring.h"
#include "uslibs/threading.h"

#include "rtp.h"
#include "logging.h"


Expand All @@ -49,24 +50,23 @@
// - https://github.com/xiph/opus/blob/7b05f44/src/opus_demo.c#L368
// #define _HZ_TO_FRAMES(_hz) (6 * (_hz) / 50) // 120ms
#define _HZ_TO_FRAMES(_hz) ((_hz) / 50) // 20ms
#define _HZ_TO_BUF16(_hz) (_HZ_TO_FRAMES(_hz) * 2) // One stereo frame = (16bit L) + (16bit R)
#define _HZ_TO_BUF16(_hz) (_HZ_TO_FRAMES(_hz) * US_RTP_OPUS_CH) // ... * 2: One stereo frame = (16bit L) + (16bit R)
#define _HZ_TO_BUF8(_hz) (_HZ_TO_BUF16(_hz) * sizeof(s16))

#define _MIN_PCM_HZ 8000
#define _MAX_PCM_HZ 192000
#define _MAX_BUF16 _HZ_TO_BUF16(_MAX_PCM_HZ)
#define _MAX_BUF8 _HZ_TO_BUF8(_MAX_PCM_HZ)
#define _ENCODER_INPUT_HZ 48000


typedef struct {
s16 data[_MAX_BUF16];
} _pcm_buffer_s;

typedef struct {
u8 data[_MAX_BUF8]; // Worst case
u8 data[US_RTP_PAYLOAD_SIZE];
uz used;
u64 pts;
u64 pts;
} _enc_buffer_s;


Expand Down Expand Up @@ -117,7 +117,7 @@ us_acap_s *us_acap_init(const char *name, uint pcm_hz) {

SET_PARAM("Can't initialize PCM params", snd_pcm_hw_params_any);
SET_PARAM("Can't set PCM access type", snd_pcm_hw_params_set_access, SND_PCM_ACCESS_RW_INTERLEAVED);
SET_PARAM("Can't set PCM channels numbre", snd_pcm_hw_params_set_channels, 2);
SET_PARAM("Can't set PCM channels number", snd_pcm_hw_params_set_channels, US_RTP_OPUS_CH);
SET_PARAM("Can't set PCM sampling format", snd_pcm_hw_params_set_format, SND_PCM_FORMAT_S16_LE);
SET_PARAM("Can't set PCM sampling rate", snd_pcm_hw_params_set_rate_near, &acap->pcm_hz, 0);
if (acap->pcm_hz < _MIN_PCM_HZ || acap->pcm_hz > _MAX_PCM_HZ) {
Expand All @@ -132,8 +132,8 @@ us_acap_s *us_acap_init(const char *name, uint pcm_hz) {
# undef SET_PARAM
}

if (acap->pcm_hz != _ENCODER_INPUT_HZ) {
acap->res = speex_resampler_init(2, acap->pcm_hz, _ENCODER_INPUT_HZ, SPEEX_RESAMPLER_QUALITY_DESKTOP, &err);
if (acap->pcm_hz != US_RTP_OPUS_HZ) {
acap->res = speex_resampler_init(US_RTP_OPUS_CH, acap->pcm_hz, US_RTP_OPUS_HZ, SPEEX_RESAMPLER_QUALITY_DESKTOP, &err);
if (err < 0) {
acap->res = NULL;
_JLOG_PERROR_RES(err, "acap", "Can't create resampler");
Expand All @@ -143,9 +143,11 @@ us_acap_s *us_acap_init(const char *name, uint pcm_hz) {

{
// OPUS_APPLICATION_VOIP, OPUS_APPLICATION_RESTRICTED_LOWDELAY
acap->enc = opus_encoder_create(_ENCODER_INPUT_HZ, 2, OPUS_APPLICATION_AUDIO, &err);
acap->enc = opus_encoder_create(US_RTP_OPUS_HZ, US_RTP_OPUS_CH, OPUS_APPLICATION_AUDIO, &err);
assert(err == 0);
assert(!opus_encoder_ctl(acap->enc, OPUS_SET_BITRATE(48000)));
// https://github.com/meetecho/janus-gateway/blob/3cdd6ff/src/plugins/janus_audiobridge.c#L2272
// https://datatracker.ietf.org/doc/html/rfc7587#section-3.1.1
assert(!opus_encoder_ctl(acap->enc, OPUS_SET_BITRATE(128000)));
assert(!opus_encoder_ctl(acap->enc, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND)));
assert(!opus_encoder_ctl(acap->enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC)));
// OPUS_SET_INBAND_FEC(1), OPUS_SET_PACKET_LOSS_PERC(10): see rtpa.c
Expand Down Expand Up @@ -258,13 +260,13 @@ static void *_encoder_thread(void *v_acap) {

s16 *in_ptr;
if (acap->res != NULL) {
assert(acap->pcm_hz != _ENCODER_INPUT_HZ);
assert(acap->pcm_hz != US_RTP_OPUS_HZ);
u32 in_count = acap->pcm_frames;
u32 out_count = _HZ_TO_FRAMES(_ENCODER_INPUT_HZ);
u32 out_count = _HZ_TO_FRAMES(US_RTP_OPUS_HZ);
speex_resampler_process_interleaved_int(acap->res, in->data, &in_count, in_res, &out_count);
in_ptr = in_res;
} else {
assert(acap->pcm_hz == _ENCODER_INPUT_HZ);
assert(acap->pcm_hz == US_RTP_OPUS_HZ);
in_ptr = in->data;
}

Expand All @@ -276,14 +278,14 @@ static void *_encoder_thread(void *v_acap) {
}
_enc_buffer_s *const out = acap->enc_ring->items[out_ri];

const int size = opus_encode(acap->enc, in_ptr, _HZ_TO_FRAMES(_ENCODER_INPUT_HZ), out->data, US_ARRAY_LEN(out->data));
const int size = opus_encode(acap->enc, in_ptr, _HZ_TO_FRAMES(US_RTP_OPUS_HZ), out->data, US_ARRAY_LEN(out->data));
us_ring_consumer_release(acap->pcm_ring, in_ri);

if (size >= 0) {
out->used = size;
out->pts = acap->pts;
// https://datatracker.ietf.org/doc/html/rfc7587#section-4.2
acap->pts += _HZ_TO_FRAMES(_ENCODER_INPUT_HZ);
acap->pts += _HZ_TO_FRAMES(US_RTP_OPUS_HZ);
} else {
_JLOG_PERROR_OPUS(size, "acap", "Fatal: Can't encode PCM frame to OPUS");
}
Expand Down
8 changes: 6 additions & 2 deletions janus/src/rtp.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,13 @@
// https://stackoverflow.com/questions/47635545/why-webrtc-chose-rtp-max-packet-size-to-1200-bytes
#define US_RTP_DATAGRAM_SIZE 1200
#define US_RTP_HEADER_SIZE 12
#define US_RTP_PAYLOAD_SIZE (US_RTP_DATAGRAM_SIZE - US_RTP_HEADER_SIZE)

#define US_RTP_VIDEO_PAYLOAD 96
#define US_RTP_AUDIO_PAYLOAD 111
#define US_RTP_H264_PAYLOAD 96
#define US_RTP_OPUS_PAYLOAD 111

#define US_RTP_OPUS_HZ 48000
#define US_RTP_OPUS_CH 2


typedef struct {
Expand Down
8 changes: 5 additions & 3 deletions janus/src/rtpa.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ us_rtpa_s *us_rtpa_init(us_rtp_callback_f callback) {
us_rtpa_s *rtpa;
US_CALLOC(rtpa, 1);
rtpa->rtp = us_rtp_init();
us_rtp_assign(rtpa->rtp, US_RTP_AUDIO_PAYLOAD, false);
us_rtp_assign(rtpa->rtp, US_RTP_OPUS_PAYLOAD, false);
rtpa->callback = callback;
return rtpa;
}
Expand All @@ -49,14 +49,16 @@ char *us_rtpa_make_sdp(us_rtpa_s *rtpa, bool mic) {
US_ASPRINTF(sdp,
"m=audio 1 RTP/SAVPF %u" RN
"c=IN IP4 0.0.0.0" RN
"a=rtpmap:%u OPUS/48000/2" RN
"a=rtpmap:%u OPUS/%u/%u" RN
"a=fmtp:%u sprop-stereo=1" RN // useinbandfec=1
"a=rtcp-fb:%u nack" RN
"a=rtcp-fb:%u nack pli" RN
"a=rtcp-fb:%u goog-remb" RN
"a=ssrc:%" PRIu32 " cname:ustreamer" RN
"a=%s" RN,
pl, pl, pl, pl, pl, pl,
pl, pl,
US_RTP_OPUS_HZ, US_RTP_OPUS_CH,
pl, pl, pl, pl,
rtpa->rtp->ssrc,
(mic ? "sendrecv" : "sendonly")
);
Expand Down
2 changes: 1 addition & 1 deletion janus/src/rtpv.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ us_rtpv_s *us_rtpv_init(us_rtp_callback_f callback) {
us_rtpv_s *rtpv;
US_CALLOC(rtpv, 1);
rtpv->rtp = us_rtp_init();
us_rtp_assign(rtpv->rtp, US_RTP_VIDEO_PAYLOAD, true);
us_rtp_assign(rtpv->rtp, US_RTP_H264_PAYLOAD, true);
rtpv->callback = callback;
return rtpv;
}
Expand Down

0 comments on commit a94ff66

Please sign in to comment.