dec_stats_t decoder_stats;
enc_stats_t encoder_stats;
codec_control_state_t control_state;
+ switch_bool_t recreate_decoder;
};
struct {
return SWITCH_STATUS_FALSE ;
}
-static switch_status_t switch_opus_info(void * encoded_data, uint32_t len, uint32_t samples_per_second, char *print_text)
+static switch_status_t switch_opus_info(switch_core_session_t *session, void * encoded_data, uint32_t len, uint32_t samples_per_second, char *print_text)
{
int nb_samples, nb_opus_frames, nb_channels;
int audiobandwidth;
if (!encoded_data) {
/* print stuff, even if encoded_data is NULL. eg: "PLC correction" */
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s", print_text);
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s", print_text);
return SWITCH_STATUS_FALSE;
}
audiobandwidth = opus_packet_get_bandwidth(encoded_data);
if (!switch_opus_show_audio_bandwidth(audiobandwidth,audiobandwidth_str)) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s: OPUS_INVALID_PACKET !\n", print_text);
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s: OPUS_INVALID_PACKET !\n", print_text);
}
if ((nb_opus_frames = opus_packet_parse(encoded_data, len, NULL, frame_data, frame_sizes, NULL)) <= 0 ) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s: OPUS_INVALID_PACKET ! frames: %d\n", print_text, nb_opus_frames);
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s: OPUS_INVALID_PACKET ! frames: %d\n", print_text, nb_opus_frames);
return SWITCH_STATUS_FALSE;
}
nb_channels = opus_packet_get_nb_channels(payload);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s: opus_frames [%d] samples [%d] audio bandwidth [%s] bytes [%d] FEC[%s] channels[%d]\n",
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s: opus_frames [%d] samples [%d] audio bandwidth [%s] bytes [%d] FEC[%s] channels[%d]\n",
print_text, nb_opus_frames, nb_samples, audiobandwidth_str, len, has_fec ? "yes" : "no", nb_channels);
return SWITCH_STATUS_SUCCESS;
switch_codec_fmtp_t codec_fmtp, codec_fmtp_only_remote = { 0 };
opus_codec_settings_t opus_codec_settings = { 0 };
opus_codec_settings_t opus_codec_settings_remote = { 0 };
+ switch_core_session_t *session = codec->session;
if (!(encoding || decoding) || (!(context = switch_core_alloc(codec->memory_pool, sizeof(*context))))) {
return SWITCH_STATUS_FALSE;
if (settings && settings->maxplaybackrate < enc_samplerate && settings->maxplaybackrate) {
enc_samplerate = settings->maxplaybackrate; /*R1*/
context->enc_frame_size = enc_samplerate * (codec->implementation->microseconds_per_packet / 1000) / 1000;
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder will be created at sample rate %d hz\n",enc_samplerate);
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Opus encoder will be created at sample rate %d hz\n",enc_samplerate);
} else {
enc_samplerate = codec->implementation->actual_samples_per_second;
}
codec->implementation->number_of_channels == 1 ? OPUS_APPLICATION_VOIP : OPUS_APPLICATION_AUDIO, &err);
if (err != OPUS_OK) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot create encoder: %s\n", opus_strerror(err));
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot create encoder: %s\n", opus_strerror(err));
return SWITCH_STATUS_GENERR;
}
/* https://tools.ietf.org/html/rfc7587 */
if (opus_codec_settings.maxaveragebitrate) {
opus_encoder_ctl(context->encoder_object, OPUS_SET_BITRATE(opus_codec_settings.maxaveragebitrate));
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder: set bitrate based on maxaveragebitrate value found in SDP or local config [%dbps]\n", opus_codec_settings.maxaveragebitrate);
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Opus encoder: set bitrate based on maxaveragebitrate value found in SDP or local config [%dbps]\n", opus_codec_settings.maxaveragebitrate);
} else {
opus_encoder_ctl(context->encoder_object, OPUS_SET_BANDWIDTH(OPUS_AUTO));
opus_encoder_ctl(context->encoder_object, OPUS_SET_BITRATE(bitrate_bps)); /* OPUS_AUTO */
opus_encoder_ctl(context->encoder_object, OPUS_GET_BITRATE(&bitrate_bps)); /* return average bps for this audio bandwidth */
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder: set bitrate to local settings [%dbps]\n", bitrate_bps);
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Opus encoder: set bitrate to local settings [%dbps]\n", bitrate_bps);
}
/* Another fmtp setting from https://tools.ietf.org/html/rfc7587 - "RTP Payload Format for the Opus Speech and Audio Codec" */
if (opus_codec_settings.maxplaybackrate) {
if (!switch_opus_show_audio_bandwidth(audiobandwidth,audiobandwidth_str)) {
snprintf(audiobandwidth_str, sizeof(audiobandwidth_str), "%s", "OPUS_AUTO");
}
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder: set audio bandwidth to [%s] based on maxplaybackrate value found in SDP or local config [%dHz]\n",audiobandwidth_str,opus_codec_settings.maxplaybackrate);
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Opus encoder: set audio bandwidth to [%s] based on maxplaybackrate value found in SDP or local config [%dHz]\n",audiobandwidth_str,opus_codec_settings.maxplaybackrate);
}
if (use_vbr) {
/* VBR is default*/
opus_encoder_ctl(context->encoder_object, OPUS_SET_VBR(use_vbr));
} else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder: CBR mode enabled\n");
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Opus encoder: CBR mode enabled\n");
opus_encoder_ctl(context->encoder_object, OPUS_SET_VBR(0));
}
if (settings && dec_samplerate > settings->sprop_maxcapturerate && settings->sprop_maxcapturerate) {
dec_samplerate = settings->sprop_maxcapturerate; /* R2 */
context->dec_frame_size = dec_samplerate*(codec->implementation->microseconds_per_packet / 1000) / 1000;
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus decoder will be created at sample rate %d hz\n",dec_samplerate);
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Opus decoder will be created at sample rate %d hz\n",dec_samplerate);
} else {
dec_samplerate = codec->implementation->actual_samples_per_second;
}
switch_set_flag(codec, SWITCH_CODEC_FLAG_HAS_PLC);
if (err != OPUS_OK) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot create decoder: %s\n", opus_strerror(err));
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot create decoder: %s\n", opus_strerror(err));
if (context->encoder_object) {
opus_encoder_destroy(context->encoder_object);
if (globals.debug || context->debug > 1) {
int samplerate = context->enc_frame_size * 1000 / (codec->implementation->microseconds_per_packet / 1000);
- switch_opus_info(encoded_data, bytes, samplerate, "encode");
+ switch_opus_info(codec->session, encoded_data, bytes, samplerate, "encode");
}
if (bytes > 0) {
return SWITCH_STATUS_SUCCESS;
}
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), 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);
int32_t frame_size = 0, last_frame_size = 0;
uint32_t frame_samples;
uint8_t buf[SWITCH_RTP_MAX_BUF_LEN];
+ switch_core_session_t *session = codec->session;
if (!context) {
return SWITCH_STATUS_FALSE;
frame_size = frame_samples - (frame_samples % (codec->implementation->actual_samples_per_second / 400));
if (*flag & SFF_PLC) {
- switch_core_session_t *session = codec->session;
switch_jb_t *jb = NULL;
plc = 1;
frame.buflen = sizeof(buf);
if (globals.debug || context->debug) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Missing %s %u Checking JB\n", seq ? "SEQ" : "TS", seq ? seq : ts);
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Missing %s %u Checking JB\n", seq ? "SEQ" : "TS", seq ? seq : ts);
}
if (switch_jb_peek_frame(jb, ts, seq, 1, &frame) == SWITCH_STATUS_SUCCESS) {
if (globals.debug || context->debug) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Lookahead frame found: %u:%u\n",
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Lookahead frame found: %u:%u\n",
frame.timestamp, frame.seq);
}
if (globals.debug || context->debug) {
if (fec) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "FEC info available in packet with SEQ: %d LEN: %d\n",
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "FEC info available in packet with SEQ: %d LEN: %d\n",
frame.seq, frame.datalen);
} else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "NO FEC info in this packet with SEQ: %d LEN: %d\n",
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "NO FEC info in this packet with SEQ: %d LEN: %d\n",
frame.seq, frame.datalen);
}
}
if (globals.debug || context->debug) {
if (opus_prefs.use_jb_lookahead || context->use_jb_lookahead) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "MISSING FRAME: %s\n", fec ? "Look-ahead FEC" : "PLC");
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "MISSING FRAME: %s\n", fec ? "Look-ahead FEC" : "PLC");
} else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "MISSING FRAME: OPUS_PLC\n");
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "MISSING FRAME: OPUS_PLC\n");
}
}
if (globals.debug || context->debug > 1) {
int samplerate = context->dec_frame_size * 1000 / (codec->implementation->microseconds_per_packet / 1000);
- switch_opus_info(encoded_data, encoded_data_len,
+ switch_opus_info(codec->session, encoded_data, encoded_data_len,
samplerate ? samplerate : codec->implementation->actual_samples_per_second,
!encoded_data ? "PLC correction" : fec ? "FEC correction" : "decode");
}
samples = opus_decode(context->decoder_object, encoded_data, encoded_data_len, decoded_data, frame_size, fec);
if (samples < 0) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Decoder Error: %s fs:%u plc:%s!\n",
- opus_strerror(samples), frame_size, plc ? "true" : "false");
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Decoder Error: %s fs:%u plc:%s!\n",
+ opus_strerror(samples), frame_size, plc ? "true" : "false");
return SWITCH_STATUS_NOOP;
}
}
frame_size = (decoded_data_len / 2) / nb_frames;
if((frame_size * nb_frames) != context->enc_frame_size) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,"Encoder Error: Decoded Datalen %u Number of frames: %u Encoder frame size: %u\n",decoded_data_len,nb_frames,context->enc_frame_size);
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_ERROR,"Encoder Error: Decoded Datalen %u Number of frames: %u Encoder frame size: %u\n",decoded_data_len,nb_frames,context->enc_frame_size);
switch_goto_status(SWITCH_STATUS_GENERR, end);
}
opus_repacketizer_init(rp);
bytes = opus_encode(context->encoder_object, (opus_int16 *) dec_ptr_buf, frame_size, enc_ptr_buf, len);
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_SESSION_LOG(codec->session), 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,
(void *) decoded_data, (void *) encoded_data, (void *) context->encoder_object, context->enc_frame_size);
/* enc_ptr_buf : Opus API manual: "The application must ensure this pointer remains valid until the next call to opus_repacketizer_init() or opus_repacketizer_destroy()." */
ret = opus_repacketizer_cat(rp, enc_ptr_buf, bytes);
if (ret != OPUS_OK) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Opus encoder: error while repacketizing (cat) : %s !\n",opus_strerror(ret));
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_ERROR, "Opus encoder: error while repacketizing (cat) : %s !\n",opus_strerror(ret));
switch_goto_status(SWITCH_STATUS_GENERR, end);
}
enc_ptr_buf += bytes;
}
/* this will never happen, unless there is a huge and unsupported number of frames */
if (total_len + opus_repacketizer_get_nb_frames(rp) > len / 2) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Opus encoder: error while repacketizing: not enough buffer space\n");
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_ERROR, "Opus encoder: error while repacketizing: not enough buffer space\n");
switch_goto_status(SWITCH_STATUS_GENERR, end);
}
ret = opus_repacketizer_out(rp, encoded_data, total_len+opus_repacketizer_get_nb_frames(rp));
if (globals.debug || context->debug) {
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(codec->session, encoded_data, ret, samplerate, "encode_repacketize");
}
if (ret <= 0) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Opus encoder: error while repacketizing (out) : %s ! packed nb_frames: %d\n", opus_strerror(ret), opus_repacketizer_get_nb_frames(rp));
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_ERROR, "Opus encoder: error while repacketizing (out) : %s ! packed nb_frames: %d\n", opus_strerror(ret), opus_repacketizer_get_nb_frames(rp));
switch_goto_status(SWITCH_STATUS_GENERR, end);
}
if (want_fec) {
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) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Opus encoder: error while controlling FEC params\n");
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_ERROR, "Opus encoder: error while controlling FEC params\n");
return SWITCH_STATUS_FALSE;
}
if (real_target_bitrate > LBRR_threshold_bitrate) {
/*FEC is already enabled, do nothing*/
if (globals.debug || context->debug) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder: FEC is enabled\n");
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_DEBUG, "Opus encoder: FEC is enabled\n");
}
return SWITCH_STATUS_SUCCESS;
} else {
opus_encoder_ctl(context->encoder_object,OPUS_SET_BITRATE(current_bitrate));
if (globals.debug || context->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_SESSION_LOG(codec->session), SWITCH_LOG_DEBUG, "Opus encoder: increased bitrate to [%d] to keep FEC enabled\n", current_bitrate);
}
return SWITCH_STATUS_SUCCESS;
}
if (globals.debug || context->debug) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder: Adjusting packet loss percent from %d%% to %d%%!\n",
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_DEBUG, "Opus encoder: Adjusting packet loss percent from %d%% to %d%%!\n",
context->old_plpct, plpct);
}
}
float steps = (float)((float)(range / 100) / base_step);
int br_step = (int)(round(steps) * base_step) * plpct;
if (globals.debug || context->debug) {
- switch_log_printf(SWITCH_CHANNEL_LOG,
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session),
SWITCH_LOG_DEBUG, "Opus encoder: bitrate increase/decrease step now is: %d bps, range:%d\n", br_step, range);
}
context->control_state.increase_step = context->control_state.decrease_step = br_step;
opus_prefs.keep_fec = 1; /* enable back FEC if it was disabled by SCC_AUDIO_ADJUST_BITRATE, we have enough network bandwidth now */
}
if (globals.debug || context->debug) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder: Adjusting bitrate to %d (increase)\n", current_bitrate+br_step);
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_DEBUG, "Opus encoder: Adjusting bitrate to %d (increase)\n", current_bitrate+br_step);
}
}
} else if (!strcasecmp(cmd, "decrease")) {
}
opus_encoder_ctl(context->encoder_object, OPUS_SET_BITRATE(current_bitrate-br_step));
if (globals.debug || context->debug) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder: Adjusting bitrate to %d (decrease)\n", current_bitrate-br_step);
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_DEBUG, "Opus encoder: Adjusting bitrate to %d (decrease)\n", current_bitrate-br_step);
}
}
} else if (!strcasecmp(cmd, "default")) {
opus_prefs.keep_fec = 1; /* enable back FEC, we have enough network bandwidth now */
}
if (globals.debug || context->debug) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder: Adjusting bitrate to %d (configured maxaveragebitrate)\n", opus_prefs.maxaveragebitrate);
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_DEBUG, "Opus encoder: Adjusting bitrate to %d (configured maxaveragebitrate)\n", opus_prefs.maxaveragebitrate);
}
} else {
/* set Opus minimum bitrate */
opus_prefs.keep_fec = 0; /* do not enforce FEC anymore, we're low on network bandwidth */
}
if (globals.debug || context->debug) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder: Adjusting bitrate to %d (minimum)\n", SWITCH_OPUS_MIN_BITRATE);
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_DEBUG, "Opus encoder: Adjusting bitrate to %d (minimum)\n", SWITCH_OPUS_MIN_BITRATE);
}
}
}