FS-8144 readability and code formatting cleanup of mod_opus whiel reviewing PLC/FEC bug and document missing options from opus.conf.xml

This commit is contained in:
Brian West 2015-09-09 12:48:34 -05:00
parent 161ed4deb7
commit 1fd9198c15
3 changed files with 195 additions and 152 deletions

View File

@ -1,7 +1,14 @@
<configuration name="opus.conf"> <configuration name="opus.conf">
<settings> <settings>
<param name="use-vbr" value="1"/> <param name="use-vbr" value="1"/>
<!--<param name="use-dtx" value="1"/>-->
<param name="complexity" value="10"/> <param name="complexity" value="10"/>
<!-- Set the initial packet loss percentage 0-100 -->
<!--<param name="packet-loss-percent" value="10"/>-->
<!-- Support asymmetric sample rates -->
<!--<param name="asymmetric-sample-rates" value="1"/>-->
<!-- Keep FEC Enabled -->
<param name="keep-fec-enabled" value="1"/>
<!-- <!--
maxaveragebitrate: the maximum average codec bitrate (values: 6000 to 510000 in bps) 0 is not considered maxaveragebitrate: the maximum average codec bitrate (values: 6000 to 510000 in bps) 0 is not considered
@ -14,6 +21,8 @@
--> -->
<param name="maxaveragebitrate" value="0"/> <param name="maxaveragebitrate" value="0"/>
<param name="maxplaybackrate" value="0"/> <param name="maxplaybackrate" value="0"/>
<!-- Max capture rate, 8000, 12000, 16000, 24000 and 48000 are valid options -->
<!--<param name="sprop-maxcapturerate" value="0"/>-->
</settings> </settings>
</configuration> </configuration>

View File

@ -1,7 +1,14 @@
<configuration name="opus.conf"> <configuration name="opus.conf">
<settings> <settings>
<param name="use-vbr" value="1"/> <param name="use-vbr" value="1"/>
<!--<param name="use-dtx" value="1"/>-->
<param name="complexity" value="10"/> <param name="complexity" value="10"/>
<!-- Set the initial packet loss percentage 0-100 -->
<!--<param name="packet-loss-percent" value="10"/>-->
<!-- Support asymmetric sample rates -->
<!--<param name="asymmetric-sample-rates" value="1"/>-->
<!-- Keep FEC Enabled -->
<param name="keep-fec-enabled" value="1"/>
<!-- <!--
maxaveragebitrate: the maximum average codec bitrate (values: 6000 to 510000 in bps) 0 is not considered maxaveragebitrate: the maximum average codec bitrate (values: 6000 to 510000 in bps) 0 is not considered
@ -14,6 +21,8 @@
--> -->
<param name="maxaveragebitrate" value="0"/> <param name="maxaveragebitrate" value="0"/>
<param name="maxplaybackrate" value="0"/> <param name="maxplaybackrate" value="0"/>
<!-- Max capture rate, 8000, 12000, 16000, 24000 and 48000 are valid options -->
<!--<param name="sprop-maxcapturerate" value="0"/>-->
</settings> </settings>
</configuration> </configuration>

View File

@ -34,7 +34,6 @@
#include "switch.h" #include "switch.h"
#include "opus.h" #include "opus.h"
SWITCH_MODULE_LOAD_FUNCTION(mod_opus_load); SWITCH_MODULE_LOAD_FUNCTION(mod_opus_load);
SWITCH_MODULE_DEFINITION(mod_opus, mod_opus_load, NULL, NULL); SWITCH_MODULE_DEFINITION(mod_opus, mod_opus_load, NULL, NULL);
@ -134,7 +133,6 @@ static switch_status_t switch_opus_fmtp_parse(const char *fmtp, switch_codec_fmt
data++; data++;
} }
if ((arg = strchr(data, '='))) { if ((arg = strchr(data, '='))) {
*arg++ = '\0'; *arg++ = '\0';
@ -327,7 +325,6 @@ static switch_status_t switch_opus_init(switch_codec_t *codec, switch_codec_flag
context->enc_frame_size = codec->implementation->actual_samples_per_second * (codec->implementation->microseconds_per_packet / 1000) / 1000; context->enc_frame_size = codec->implementation->actual_samples_per_second * (codec->implementation->microseconds_per_packet / 1000) / 1000;
memset(&codec_fmtp, '\0', sizeof(struct switch_codec_fmtp)); memset(&codec_fmtp, '\0', sizeof(struct switch_codec_fmtp));
codec_fmtp.private_info = &opus_codec_settings; codec_fmtp.private_info = &opus_codec_settings;
switch_opus_fmtp_parse(codec->fmtp_in, &codec_fmtp); switch_opus_fmtp_parse(codec->fmtp_in, &codec_fmtp);
@ -339,17 +336,22 @@ static switch_status_t switch_opus_init(switch_codec_t *codec, switch_codec_flag
context->codec_settings = opus_codec_settings; context->codec_settings = opus_codec_settings;
/* Verify if the local or remote configuration are lowering maxaveragebitrate and/or maxplaybackrate */ /* Verify if the local or remote configuration are lowering maxaveragebitrate and/or maxplaybackrate */
if ( opus_prefs.maxaveragebitrate && (opus_prefs.maxaveragebitrate < opus_codec_settings_remote.maxaveragebitrate || !opus_codec_settings_remote.maxaveragebitrate) ) { if (opus_prefs.maxaveragebitrate &&
(opus_prefs.maxaveragebitrate < opus_codec_settings_remote.maxaveragebitrate || !opus_codec_settings_remote.maxaveragebitrate)) {
opus_codec_settings.maxaveragebitrate = opus_prefs.maxaveragebitrate; opus_codec_settings.maxaveragebitrate = opus_prefs.maxaveragebitrate;
} else { } else {
opus_codec_settings.maxaveragebitrate = opus_codec_settings_remote.maxaveragebitrate; opus_codec_settings.maxaveragebitrate = opus_codec_settings_remote.maxaveragebitrate;
} }
if ( opus_prefs.maxplaybackrate && (opus_prefs.maxplaybackrate < opus_codec_settings_remote.maxplaybackrate || !opus_codec_settings_remote.maxplaybackrate) ) {
if (opus_prefs.maxplaybackrate &&
(opus_prefs.maxplaybackrate < opus_codec_settings_remote.maxplaybackrate || !opus_codec_settings_remote.maxplaybackrate)) {
opus_codec_settings.maxplaybackrate = opus_prefs.maxplaybackrate; opus_codec_settings.maxplaybackrate = opus_prefs.maxplaybackrate;
} else { } else {
opus_codec_settings.maxplaybackrate=opus_codec_settings_remote.maxplaybackrate; opus_codec_settings.maxplaybackrate=opus_codec_settings_remote.maxplaybackrate;
} }
if ( opus_prefs.sprop_maxcapturerate && (opus_prefs.sprop_maxcapturerate < opus_codec_settings_remote.sprop_maxcapturerate || !opus_codec_settings_remote.sprop_maxcapturerate) ) {
if (opus_prefs.sprop_maxcapturerate &&
(opus_prefs.sprop_maxcapturerate < opus_codec_settings_remote.sprop_maxcapturerate || !opus_codec_settings_remote.sprop_maxcapturerate)) {
opus_codec_settings.sprop_maxcapturerate = opus_prefs.sprop_maxcapturerate; opus_codec_settings.sprop_maxcapturerate = opus_prefs.sprop_maxcapturerate;
} else { } else {
opus_codec_settings.sprop_maxcapturerate = opus_codec_settings_remote.sprop_maxcapturerate; opus_codec_settings.sprop_maxcapturerate = opus_codec_settings_remote.sprop_maxcapturerate;
@ -398,7 +400,6 @@ static switch_status_t switch_opus_init(switch_codec_t *codec, switch_codec_flag
return SWITCH_STATUS_GENERR; return SWITCH_STATUS_GENERR;
} }
/* Setting documented in "RTP Payload Format for Opus Speech and Audio Codec" draft-spittka-payload-rtp-opus-03 */ /* Setting documented in "RTP Payload Format for Opus Speech and Audio Codec" draft-spittka-payload-rtp-opus-03 */
if (opus_codec_settings.maxaveragebitrate) { /* Remote codec settings found in SDP "fmtp", we accept to tune the Encoder */ if (opus_codec_settings.maxaveragebitrate) { /* Remote codec settings found in SDP "fmtp", we accept to tune the Encoder */
opus_encoder_ctl(context->encoder_object, OPUS_SET_BITRATE(opus_codec_settings.maxaveragebitrate)); opus_encoder_ctl(context->encoder_object, OPUS_SET_BITRATE(opus_codec_settings.maxaveragebitrate));
@ -438,6 +439,7 @@ static switch_status_t switch_opus_init(switch_codec_t *codec, switch_codec_flag
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder: CBR mode enabled\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder: CBR mode enabled\n");
opus_encoder_ctl(context->encoder_object, OPUS_SET_VBR(0)); opus_encoder_ctl(context->encoder_object, OPUS_SET_VBR(0));
} }
if (complexity) { if (complexity) {
opus_encoder_ctl(context->encoder_object, OPUS_SET_COMPLEXITY(complexity)); opus_encoder_ctl(context->encoder_object, OPUS_SET_COMPLEXITY(complexity));
} }
@ -542,7 +544,10 @@ static switch_status_t switch_opus_encode(switch_codec_t *codec,
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} }
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Encoder Error: %s Decoded Datalen %u Codec NumberChans %u Len %u DecodedDate %p EncodedData %p ContextEncoderObject %p!\n", opus_strerror(bytes),decoded_data_len,codec->implementation->number_of_channels,len,(void *) decoded_data,(void *) encoded_data,(void *) context->encoder_object); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
"Encoder Error: %s Decoded Datalen %u Codec NumberChans %u Len %u DecodedDate %p EncodedData %p ContextEncoderObject %p!\n",
opus_strerror(bytes),decoded_data_len,codec->implementation->number_of_channels,len,(void *) decoded_data,
(void *) encoded_data,(void *) context->encoder_object);
return SWITCH_STATUS_GENERR; return SWITCH_STATUS_GENERR;
} }
@ -570,6 +575,7 @@ static switch_status_t switch_opus_decode(switch_codec_t *codec,
if (*flag & SFF_PLC) { if (*flag & SFF_PLC) {
plc = 1; plc = 1;
encoded_data = NULL; encoded_data = NULL;
opus_decoder_ctl(context->decoder_object, OPUS_GET_LAST_PACKET_DURATION(&frame_size)); opus_decoder_ctl(context->decoder_object, OPUS_GET_LAST_PACKET_DURATION(&frame_size));
if (!frame_size) { if (!frame_size) {
frame_size = frame_samples - (frame_samples % (codec->implementation->actual_samples_per_second / 400)); frame_size = frame_samples - (frame_samples % (codec->implementation->actual_samples_per_second / 400));
@ -623,13 +629,15 @@ static switch_status_t switch_opus_encode_repacketize(switch_codec_t *codec,
if (!context) { if (!context) {
switch_goto_status(SWITCH_STATUS_FALSE, end); switch_goto_status(SWITCH_STATUS_FALSE, end);
} }
opus_repacketizer_init(rp); opus_repacketizer_init(rp);
for (i = 0; i < nb_frames; i++) { for (i = 0; i < nb_frames; i++) {
dec_ptr_buf = (int16_t *)decoded_data + i * (decoded_data_len / 2 / nb_frames); dec_ptr_buf = (int16_t *)decoded_data + i * (decoded_data_len / 2 / nb_frames);
bytes = opus_encode(context->encoder_object, (opus_int16 *) dec_ptr_buf, context->enc_frame_size / nb_frames, enc_ptr_buf, len); bytes = opus_encode(context->encoder_object, (opus_int16 *) dec_ptr_buf, context->enc_frame_size / nb_frames, enc_ptr_buf, len);
if (bytes < 0) { if (bytes < 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Encoder Error: %s Decoded Datalen %u Codec NumberChans %u" \ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Encoder Error: %s Decoded Datalen %u Codec NumberChans %u" \
"Len %u DecodedDate %p EncodedData %p ContextEncoderObject %p enc_frame_size: %d\n",opus_strerror(bytes),decoded_data_len,codec->implementation->number_of_channels,len, "Len %u DecodedDate %p EncodedData %p ContextEncoderObject %p enc_frame_size: %d\n",
opus_strerror(bytes), decoded_data_len, codec->implementation->number_of_channels, len,
(void *) decoded_data, (void *) encoded_data, (void *) context->encoder_object, context->enc_frame_size); (void *) decoded_data, (void *) encoded_data, (void *) context->encoder_object, context->enc_frame_size);
switch_goto_status(SWITCH_STATUS_GENERR, end); switch_goto_status(SWITCH_STATUS_GENERR, end);
} }
@ -651,10 +659,12 @@ static switch_status_t switch_opus_encode_repacketize(switch_codec_t *codec,
} }
ret = opus_repacketizer_out(rp, encoded_data, total_len+opus_repacketizer_get_nb_frames(rp)); ret = opus_repacketizer_out(rp, encoded_data, total_len+opus_repacketizer_get_nb_frames(rp));
if (globals.debug) { if (globals.debug) {
int samplerate = context->enc_frame_size * 1000 / (codec->implementation->microseconds_per_packet / 1000); int samplerate = context->enc_frame_size * 1000 / (codec->implementation->microseconds_per_packet / 1000);
switch_opus_info(encoded_data, ret, samplerate, "encode_repacketize"); switch_opus_info(encoded_data, ret, samplerate, "encode_repacketize");
} }
if (ret <= 0) { if (ret <= 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Opus encoder: error while repacketizing (out) : %s !\n", opus_strerror(ret)); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Opus encoder: error while repacketizing (out) : %s !\n", opus_strerror(ret));
switch_goto_status(SWITCH_STATUS_GENERR, end); switch_goto_status(SWITCH_STATUS_GENERR, end);
@ -666,6 +676,7 @@ end:
if (rp) { if (rp) {
opus_repacketizer_destroy(rp); opus_repacketizer_destroy(rp);
} }
return status; return status;
} }
@ -736,10 +747,13 @@ static switch_status_t switch_opus_keep_fec_enabled(switch_codec_t *codec)
opus_encoder_ctl(context->encoder_object, OPUS_GET_BITRATE(&current_bitrate)); opus_encoder_ctl(context->encoder_object, OPUS_GET_BITRATE(&current_bitrate));
opus_encoder_ctl(context->encoder_object, OPUS_GET_PACKET_LOSS_PERC(&current_loss)); opus_encoder_ctl(context->encoder_object, OPUS_GET_PACKET_LOSS_PERC(&current_loss));
if (current_loss == 0) { if (current_loss == 0) {
opus_encoder_ctl(context->encoder_object, OPUS_SET_BITRATE(opus_prefs.maxaveragebitrate)); opus_encoder_ctl(context->encoder_object, OPUS_SET_BITRATE(opus_prefs.maxaveragebitrate));
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} }
if (fs == 8000) { if (fs == 8000) {
LBRR_rate_thres_bps = 12000; /*LBRR_NB_MIN_RATE_BPS*/ LBRR_rate_thres_bps = 12000; /*LBRR_NB_MIN_RATE_BPS*/
} else if (fs == 12000) { } else if (fs == 12000) {
@ -753,25 +767,32 @@ static switch_status_t switch_opus_keep_fec_enabled(switch_codec_t *codec)
a32 = LBRR_rate_thres_bps * (125 -(((current_loss) < (25)) ? (current_loss) : (25))); a32 = LBRR_rate_thres_bps * (125 -(((current_loss) < (25)) ? (current_loss) : (25)));
b32 = ((opus_int32)((0.01) * ((opus_int64)1 << (16)) + 0.5)); b32 = ((opus_int32)((0.01) * ((opus_int64)1 << (16)) + 0.5));
LBRR_threshold_bitrate = (a32 >> 16) * (opus_int32)((opus_int16)b32) + (((a32 & 0x0000FFFF) * (opus_int32)((opus_int16)b32)) >> 16); LBRR_threshold_bitrate = (a32 >> 16) * (opus_int32)((opus_int16)b32) + (((a32 & 0x0000FFFF) * (opus_int32)((opus_int16)b32)) >> 16);
if ((!real_target_bitrate || !LBRR_threshold_bitrate)) { if ((!real_target_bitrate || !LBRR_threshold_bitrate)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Opus encoder: error while controlling FEC params\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Opus encoder: error while controlling FEC params\n");
return SWITCH_STATUS_FALSE; return SWITCH_STATUS_FALSE;
} }
/* Is there any FEC at the current bitrate and requested packet loss ? /* Is there any FEC at the current bitrate and requested packet loss ?
* If yes, then keep the current bitrate. If not, modify bitrate to keep FEC on. */ * If yes, then keep the current bitrate. If not, modify bitrate to keep FEC on. */
if (real_target_bitrate > LBRR_threshold_bitrate) { if (real_target_bitrate > LBRR_threshold_bitrate) {
/*FEC is already enabled, do nothing*/ /*FEC is already enabled, do nothing*/
if (globals.debug) if (globals.debug) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder: FEC is enabled\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder: FEC is enabled\n");
}
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} else { } else {
while (real_target_bitrate <= LBRR_threshold_bitrate) { while (real_target_bitrate <= LBRR_threshold_bitrate) {
current_bitrate += step; current_bitrate += step;
real_target_bitrate = (uint32_t)(8 * (current_bitrate * context->enc_frame_size / ( fs * 8 ) - 1) * frame_rate); real_target_bitrate = (uint32_t)(8 * (current_bitrate * context->enc_frame_size / ( fs * 8 ) - 1) * frame_rate);
} }
opus_encoder_ctl(context->encoder_object,OPUS_SET_BITRATE(current_bitrate)); opus_encoder_ctl(context->encoder_object,OPUS_SET_BITRATE(current_bitrate));
if (globals.debug)
if (globals.debug) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder: increased bitrate to [%d] to keep FEC enabled\n", current_bitrate); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder: increased bitrate to [%d] to keep FEC enabled\n", current_bitrate);
}
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} }
} }
@ -800,9 +821,16 @@ static switch_status_t switch_opus_control(switch_codec_t *codec,
if (plpct != context->old_plpct) { if (plpct != context->old_plpct) {
opus_encoder_ctl(context->encoder_object, OPUS_SET_PACKET_LOSS_PERC(plpct)); opus_encoder_ctl(context->encoder_object, OPUS_SET_PACKET_LOSS_PERC(plpct));
if (opus_prefs.keep_fec)
if (opus_prefs.keep_fec) {
switch_opus_keep_fec_enabled(codec); switch_opus_keep_fec_enabled(codec);
} }
if (globals.debug) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus Adjusting packet loss percent from %d%% to %d%%!\n",
context->old_plpct, plpct);
}
}
context->old_plpct = plpct; context->old_plpct = plpct;
} }
break; break;
@ -867,9 +895,11 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_opus_load)
if (opus_prefs.maxaveragebitrate) { if (opus_prefs.maxaveragebitrate) {
settings.maxaveragebitrate = opus_prefs.maxaveragebitrate; settings.maxaveragebitrate = opus_prefs.maxaveragebitrate;
} }
if (opus_prefs.maxplaybackrate) { if (opus_prefs.maxplaybackrate) {
settings.maxplaybackrate = opus_prefs.maxplaybackrate; settings.maxplaybackrate = opus_prefs.maxplaybackrate;
} }
if (opus_prefs.sprop_maxcapturerate) { if (opus_prefs.sprop_maxcapturerate) {
settings.sprop_maxcapturerate = opus_prefs.sprop_maxcapturerate; settings.sprop_maxcapturerate = opus_prefs.sprop_maxcapturerate;
} }
@ -928,7 +958,6 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_opus_load)
bytes *= 2; bytes *= 2;
samples *= 2; samples *= 2;
mss *= 2; mss *= 2;
} }
@ -1033,11 +1062,9 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_opus_load)
} }
bytes *= 2; bytes *= 2;
samples *= 2; samples *= 2;
mss *= 2; mss *= 2;
} }
/* indicate that the module should continue to be loaded */ /* indicate that the module should continue to be loaded */
@ -1045,8 +1072,6 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_opus_load)
} }
/* For Emacs: /* For Emacs:
* Local Variables: * Local Variables:
* mode:c * mode:c