38
38
#include "uslibs/ring.h"
39
39
#include "uslibs/threading.h"
40
40
41
+ #include "rtp.h"
41
42
#include "logging.h"
42
43
43
44
49
50
// - https://github.com/xiph/opus/blob/7b05f44/src/opus_demo.c#L368
50
51
// #define _HZ_TO_FRAMES(_hz) (6 * (_hz) / 50) // 120ms
51
52
#define _HZ_TO_FRAMES (_hz ) ((_hz) / 50) // 20ms
52
- #define _HZ_TO_BUF16 (_hz ) (_HZ_TO_FRAMES(_hz) * 2 ) // One stereo frame = (16bit L) + (16bit R)
53
+ #define _HZ_TO_BUF16 (_hz ) (_HZ_TO_FRAMES(_hz) * US_RTP_OPUS_CH ) // ... * 2: One stereo frame = (16bit L) + (16bit R)
53
54
#define _HZ_TO_BUF8 (_hz ) (_HZ_TO_BUF16(_hz) * sizeof(s16))
54
55
55
56
#define _MIN_PCM_HZ 8000
56
57
#define _MAX_PCM_HZ 192000
57
58
#define _MAX_BUF16 _HZ_TO_BUF16(_MAX_PCM_HZ)
58
59
#define _MAX_BUF8 _HZ_TO_BUF8(_MAX_PCM_HZ)
59
- #define _ENCODER_INPUT_HZ 48000
60
60
61
61
62
62
typedef struct {
63
63
s16 data [_MAX_BUF16 ];
64
64
} _pcm_buffer_s ;
65
65
66
66
typedef struct {
67
- u8 data [_MAX_BUF8 ]; // Worst case
67
+ u8 data [US_RTP_PAYLOAD_SIZE ];
68
68
uz used ;
69
- u64 pts ;
69
+ u64 pts ;
70
70
} _enc_buffer_s ;
71
71
72
72
@@ -117,7 +117,7 @@ us_acap_s *us_acap_init(const char *name, uint pcm_hz) {
117
117
118
118
SET_PARAM ("Can't initialize PCM params" , snd_pcm_hw_params_any );
119
119
SET_PARAM ("Can't set PCM access type" , snd_pcm_hw_params_set_access , SND_PCM_ACCESS_RW_INTERLEAVED );
120
- SET_PARAM ("Can't set PCM channels numbre " , snd_pcm_hw_params_set_channels , 2 );
120
+ SET_PARAM ("Can't set PCM channels number " , snd_pcm_hw_params_set_channels , US_RTP_OPUS_CH );
121
121
SET_PARAM ("Can't set PCM sampling format" , snd_pcm_hw_params_set_format , SND_PCM_FORMAT_S16_LE );
122
122
SET_PARAM ("Can't set PCM sampling rate" , snd_pcm_hw_params_set_rate_near , & acap -> pcm_hz , 0 );
123
123
if (acap -> pcm_hz < _MIN_PCM_HZ || acap -> pcm_hz > _MAX_PCM_HZ ) {
@@ -132,8 +132,8 @@ us_acap_s *us_acap_init(const char *name, uint pcm_hz) {
132
132
# undef SET_PARAM
133
133
}
134
134
135
- if (acap -> pcm_hz != _ENCODER_INPUT_HZ ) {
136
- acap -> res = speex_resampler_init (2 , acap -> pcm_hz , _ENCODER_INPUT_HZ , SPEEX_RESAMPLER_QUALITY_DESKTOP , & err );
135
+ if (acap -> pcm_hz != US_RTP_OPUS_HZ ) {
136
+ acap -> res = speex_resampler_init (US_RTP_OPUS_CH , acap -> pcm_hz , US_RTP_OPUS_HZ , SPEEX_RESAMPLER_QUALITY_DESKTOP , & err );
137
137
if (err < 0 ) {
138
138
acap -> res = NULL ;
139
139
_JLOG_PERROR_RES (err , "acap" , "Can't create resampler" );
@@ -143,9 +143,11 @@ us_acap_s *us_acap_init(const char *name, uint pcm_hz) {
143
143
144
144
{
145
145
// OPUS_APPLICATION_VOIP, OPUS_APPLICATION_RESTRICTED_LOWDELAY
146
- acap -> enc = opus_encoder_create (_ENCODER_INPUT_HZ , 2 , OPUS_APPLICATION_AUDIO , & err );
146
+ acap -> enc = opus_encoder_create (US_RTP_OPUS_HZ , US_RTP_OPUS_CH , OPUS_APPLICATION_AUDIO , & err );
147
147
assert (err == 0 );
148
- assert (!opus_encoder_ctl (acap -> enc , OPUS_SET_BITRATE (48000 )));
148
+ // https://github.com/meetecho/janus-gateway/blob/3cdd6ff/src/plugins/janus_audiobridge.c#L2272
149
+ // https://datatracker.ietf.org/doc/html/rfc7587#section-3.1.1
150
+ assert (!opus_encoder_ctl (acap -> enc , OPUS_SET_BITRATE (128000 )));
149
151
assert (!opus_encoder_ctl (acap -> enc , OPUS_SET_MAX_BANDWIDTH (OPUS_BANDWIDTH_FULLBAND )));
150
152
assert (!opus_encoder_ctl (acap -> enc , OPUS_SET_SIGNAL (OPUS_SIGNAL_MUSIC )));
151
153
// OPUS_SET_INBAND_FEC(1), OPUS_SET_PACKET_LOSS_PERC(10): see rtpa.c
@@ -258,13 +260,13 @@ static void *_encoder_thread(void *v_acap) {
258
260
259
261
s16 * in_ptr ;
260
262
if (acap -> res != NULL ) {
261
- assert (acap -> pcm_hz != _ENCODER_INPUT_HZ );
263
+ assert (acap -> pcm_hz != US_RTP_OPUS_HZ );
262
264
u32 in_count = acap -> pcm_frames ;
263
- u32 out_count = _HZ_TO_FRAMES (_ENCODER_INPUT_HZ );
265
+ u32 out_count = _HZ_TO_FRAMES (US_RTP_OPUS_HZ );
264
266
speex_resampler_process_interleaved_int (acap -> res , in -> data , & in_count , in_res , & out_count );
265
267
in_ptr = in_res ;
266
268
} else {
267
- assert (acap -> pcm_hz == _ENCODER_INPUT_HZ );
269
+ assert (acap -> pcm_hz == US_RTP_OPUS_HZ );
268
270
in_ptr = in -> data ;
269
271
}
270
272
@@ -276,14 +278,14 @@ static void *_encoder_thread(void *v_acap) {
276
278
}
277
279
_enc_buffer_s * const out = acap -> enc_ring -> items [out_ri ];
278
280
279
- const int size = opus_encode (acap -> enc , in_ptr , _HZ_TO_FRAMES (_ENCODER_INPUT_HZ ), out -> data , US_ARRAY_LEN (out -> data ));
281
+ const int size = opus_encode (acap -> enc , in_ptr , _HZ_TO_FRAMES (US_RTP_OPUS_HZ ), out -> data , US_ARRAY_LEN (out -> data ));
280
282
us_ring_consumer_release (acap -> pcm_ring , in_ri );
281
283
282
284
if (size >= 0 ) {
283
285
out -> used = size ;
284
286
out -> pts = acap -> pts ;
285
287
// https://datatracker.ietf.org/doc/html/rfc7587#section-4.2
286
- acap -> pts += _HZ_TO_FRAMES (_ENCODER_INPUT_HZ );
288
+ acap -> pts += _HZ_TO_FRAMES (US_RTP_OPUS_HZ );
287
289
} else {
288
290
_JLOG_PERROR_OPUS (size , "acap" , "Fatal: Can't encode PCM frame to OPUS" );
289
291
}
0 commit comments