OpusDecoder *decoder_object;
uint32_t enc_frame_size;
uint32_t dec_frame_size;
+ uint32_t counter_plc_fec;
};
struct {
return SWITCH_STATUS_GENERR;
}
-
+ context->counter_plc_fec = 0;
}
codec->private_info = context;
if (context) {
if (context->decoder_object) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,"tried PLC or FEC %d times \n",context->counter_plc_fec);
opus_decoder_destroy(context->decoder_object);
context->decoder_object = NULL;
}
unsigned int *flag)
{
struct opus_context *context = codec->private_info;
+ switch_core_session_t *session = codec->session;
+ stfu_instance_t *jb = NULL;
+ stfu_frame_t next_frame;
int samples = 0;
uint32_t frame_size;
uint32_t frame_samples;
+ uint32_t found_frame;
if (!context) {
return SWITCH_STATUS_FALSE;
frame_samples = *decoded_data_len / 2 / codec->implementation->number_of_channels;
frame_size = frame_samples - (frame_samples % (codec->implementation->actual_samples_per_second / 400));
- samples = opus_decode(context->decoder_object, (*flag & SFF_PLC) ? NULL : encoded_data, encoded_data_len, decoded_data, frame_size, !!(*flag & SFF_PLC));
+ /*FEC: shameless rip-off from mod_silk.c . OPUS only supports n+1 FEC , SILK is supposed to work with n+1, n+2*/
+ if (*flag & SFF_PLC) {
+ context->counter_plc_fec;
+ if (session) {
+ jb = switch_core_session_get_jb(session, SWITCH_MEDIA_TYPE_AUDIO);
+ }
+ if (jb && codec->cur_frame) {
+ found_frame = stfu_n_copy_next_frame(jb, (uint32_t)codec->cur_frame->timestamp, codec->cur_frame->seq, 1, &next_frame);
+ if (found_frame) {
+ samples = opus_decode(context->decoder_object, next_frame.data, next_frame.dlen, decoded_data, frame_size, 1); /* opus_decode() does PLC if there's no FEC in the packet*/
+ if (samples < 0 ) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Decoder Error (FEC): %s!\n", opus_strerror(samples));
+ return SWITCH_STATUS_FALSE;
+ } else {
+ *decoded_data_len = samples * 2 * codec->implementation->number_of_channels;
+ return SWITCH_STATUS_SUCCESS;
+ }
+ }
+ }
+ }
+
+ samples = opus_decode(context->decoder_object, (*flag & SFF_PLC) ? NULL : encoded_data, encoded_data_len, decoded_data, frame_size, 0);
if (samples < 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Decoder Error: %s fs:%u plc:%d!\n", opus_strerror(samples), frame_size, !!(*flag & SFF_PLC));