mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-04-14 16:15:04 +00:00
Merge pull request #264 in FS/freeswitch from ~DRAGOS_OANCEA/freeswitch-dragos:mod_opus_fec_jb to master
* commit 'bd3589a2fbb56486f3c76548a4197716ebcce8c7': FS-7436: added FEC support for mod_opus
This commit is contained in:
commit
4aaaa485ce
@ -74,6 +74,7 @@ struct opus_context {
|
||||
OpusDecoder *decoder_object;
|
||||
uint32_t enc_frame_size;
|
||||
uint32_t dec_frame_size;
|
||||
uint32_t counter_plc_fec;
|
||||
};
|
||||
|
||||
struct {
|
||||
@ -338,7 +339,7 @@ static switch_status_t switch_opus_init(switch_codec_t *codec, switch_codec_flag
|
||||
|
||||
return SWITCH_STATUS_GENERR;
|
||||
}
|
||||
|
||||
context->counter_plc_fec = 0;
|
||||
}
|
||||
|
||||
codec->private_info = context;
|
||||
@ -352,6 +353,7 @@ static switch_status_t switch_opus_destroy(switch_codec_t *codec)
|
||||
|
||||
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;
|
||||
}
|
||||
@ -400,9 +402,13 @@ static switch_status_t switch_opus_decode(switch_codec_t *codec,
|
||||
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;
|
||||
@ -411,7 +417,28 @@ static switch_status_t switch_opus_decode(switch_codec_t *codec,
|
||||
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));
|
||||
|
Loading…
x
Reference in New Issue
Block a user