mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-02-07 22:03:50 +00:00
FS-7601 #resolve
This commit is contained in:
parent
6209d91f9c
commit
5c5b53a453
@ -1601,7 +1601,8 @@ typedef enum {
|
|||||||
SWITCH_CODEC_FLAG_FREE_POOL = (1 << 5),
|
SWITCH_CODEC_FLAG_FREE_POOL = (1 << 5),
|
||||||
SWITCH_CODEC_FLAG_AAL2 = (1 << 6),
|
SWITCH_CODEC_FLAG_AAL2 = (1 << 6),
|
||||||
SWITCH_CODEC_FLAG_PASSTHROUGH = (1 << 7),
|
SWITCH_CODEC_FLAG_PASSTHROUGH = (1 << 7),
|
||||||
SWITCH_CODEC_FLAG_READY = (1 << 8)
|
SWITCH_CODEC_FLAG_READY = (1 << 8),
|
||||||
|
SWITCH_CODEC_FLAG_HAS_PLC = (1 << 15)
|
||||||
} switch_codec_flag_enum_t;
|
} switch_codec_flag_enum_t;
|
||||||
typedef uint32_t switch_codec_flag_t;
|
typedef uint32_t switch_codec_flag_t;
|
||||||
|
|
||||||
|
@ -328,6 +328,7 @@ static switch_status_t switch_opus_init(switch_codec_t *codec, switch_codec_flag
|
|||||||
context->decoder_object = opus_decoder_create(codec->implementation->actual_samples_per_second,
|
context->decoder_object = opus_decoder_create(codec->implementation->actual_samples_per_second,
|
||||||
codec->implementation->number_of_channels, &err);
|
codec->implementation->number_of_channels, &err);
|
||||||
|
|
||||||
|
switch_set_flag(codec, SWITCH_CODEC_FLAG_HAS_PLC);
|
||||||
|
|
||||||
if (err != OPUS_OK) {
|
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_LOG, SWITCH_LOG_ERROR, "Cannot create decoder: %s\n", opus_strerror(err));
|
||||||
@ -417,20 +418,23 @@ static switch_status_t switch_opus_decode(switch_codec_t *codec,
|
|||||||
frame_samples = *decoded_data_len / 2 / codec->implementation->number_of_channels;
|
frame_samples = *decoded_data_len / 2 / codec->implementation->number_of_channels;
|
||||||
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));
|
||||||
|
|
||||||
/*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) {
|
if (*flag & SFF_PLC) {
|
||||||
context->counter_plc_fec++;
|
|
||||||
if (session) {
|
if (session) {
|
||||||
jb = switch_core_session_get_jb(session, SWITCH_MEDIA_TYPE_AUDIO);
|
jb = switch_core_session_get_jb(session, SWITCH_MEDIA_TYPE_AUDIO);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (jb && codec->cur_frame) {
|
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);
|
found_frame = stfu_n_copy_next_frame(jb, (uint32_t)codec->cur_frame->timestamp, codec->cur_frame->seq, 1, &next_frame);
|
||||||
|
|
||||||
if (found_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*/
|
samples = opus_decode(context->decoder_object, next_frame.data, next_frame.dlen, decoded_data, frame_size, 1);
|
||||||
|
|
||||||
if (samples < 0 ) {
|
if (samples < 0 ) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Decoder Error (FEC): %s!\n", opus_strerror(samples));
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Decoder Error (FEC): %s!\n", opus_strerror(samples));
|
||||||
return SWITCH_STATUS_FALSE;
|
|
||||||
} else {
|
} else {
|
||||||
|
context->counter_plc_fec++;
|
||||||
|
*flag &= ~SFF_PLC;
|
||||||
*decoded_data_len = samples * 2 * codec->implementation->number_of_channels;
|
*decoded_data_len = samples * 2 * codec->implementation->number_of_channels;
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -438,13 +442,19 @@ static switch_status_t switch_opus_decode(switch_codec_t *codec,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* opus_decode() does PLC if there's no FEC in the packet*/
|
||||||
samples = opus_decode(context->decoder_object, (*flag & SFF_PLC) ? NULL : encoded_data, encoded_data_len, decoded_data, frame_size, 0);
|
samples = opus_decode(context->decoder_object, (*flag & SFF_PLC) ? NULL : encoded_data, encoded_data_len, decoded_data, frame_size, 0);
|
||||||
|
|
||||||
|
if (*flag & SFF_PLC) {
|
||||||
|
context->counter_plc_fec++;
|
||||||
|
*flag &= ~SFF_PLC;
|
||||||
|
}
|
||||||
|
|
||||||
if (samples < 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));
|
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));
|
||||||
return SWITCH_STATUS_GENERR;
|
return SWITCH_STATUS_GENERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
*decoded_data_len = samples * 2 * codec->implementation->number_of_channels;
|
*decoded_data_len = samples * 2 * codec->implementation->number_of_channels;
|
||||||
|
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
@ -204,6 +204,9 @@ static switch_status_t switch_silk_init(switch_codec_t *codec,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (decoding) {
|
if (decoding) {
|
||||||
|
|
||||||
|
switch_set_flag(codec, SWITCH_CODEC_FLAG_HAS_PLC);
|
||||||
|
|
||||||
if (SKP_Silk_SDK_Get_Decoder_Size(&decSizeBytes)) {
|
if (SKP_Silk_SDK_Get_Decoder_Size(&decSizeBytes)) {
|
||||||
return SWITCH_STATUS_FALSE;
|
return SWITCH_STATUS_FALSE;
|
||||||
}
|
}
|
||||||
@ -335,14 +338,19 @@ static switch_status_t switch_silk_decode(switch_codec_t *codec,
|
|||||||
*decoded_data_len = 0;
|
*decoded_data_len = 0;
|
||||||
|
|
||||||
if (lost_flag) {
|
if (lost_flag) {
|
||||||
|
*flag &= ~SFF_PLC;
|
||||||
|
|
||||||
if (session) {
|
if (session) {
|
||||||
jb = switch_core_session_get_jb(session, SWITCH_MEDIA_TYPE_AUDIO);
|
jb = switch_core_session_get_jb(session, SWITCH_MEDIA_TYPE_AUDIO);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (jb && codec->cur_frame) {
|
if (jb && codec->cur_frame) {
|
||||||
for (i = 1; i <= MAX_LBRR_DELAY; i++) {
|
for (i = 1; i <= MAX_LBRR_DELAY; i++) {
|
||||||
found_frame = stfu_n_copy_next_frame(jb, (uint32_t)codec->cur_frame->timestamp, codec->cur_frame->seq, (uint16_t)i, &next_frame);
|
found_frame = stfu_n_copy_next_frame(jb, (uint32_t)codec->cur_frame->timestamp, codec->cur_frame->seq, (uint16_t)i, &next_frame);
|
||||||
|
|
||||||
if (found_frame) {
|
if (found_frame) {
|
||||||
SKP_Silk_SDK_search_for_LBRR(next_frame.data, (const int)next_frame.dlen, i, (SKP_uint8*) &recbuff, &reclen);
|
SKP_Silk_SDK_search_for_LBRR(next_frame.data, (const int)next_frame.dlen, i, (SKP_uint8*) &recbuff, &reclen);
|
||||||
|
|
||||||
if (reclen) {
|
if (reclen) {
|
||||||
encoded_data = &recbuff;
|
encoded_data = &recbuff;
|
||||||
encoded_data_len = reclen;
|
encoded_data_len = reclen;
|
||||||
|
@ -467,7 +467,13 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
|
|||||||
if (!do_bugs) goto done;
|
if (!do_bugs) goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (switch_test_flag(read_frame, SFF_PLC)) {
|
if (!switch_test_flag(read_frame->codec, SWITCH_CODEC_FLAG_HAS_PLC) &&
|
||||||
|
(switch_channel_test_flag(session->channel, CF_JITTERBUFFER_PLC) ||
|
||||||
|
switch_channel_test_flag(session->channel, CF_CNG_PLC)) && !session->plc) {
|
||||||
|
session->plc = plc_init(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!switch_test_flag(read_frame->codec, SWITCH_CODEC_FLAG_HAS_PLC) && session->plc && switch_test_flag(read_frame, SFF_PLC)) {
|
||||||
session->raw_read_frame.datalen = read_frame->codec->implementation->decoded_bytes_per_packet;
|
session->raw_read_frame.datalen = read_frame->codec->implementation->decoded_bytes_per_packet;
|
||||||
session->raw_read_frame.samples = session->raw_read_frame.datalen / sizeof(int16_t) / session->read_impl.number_of_channels;
|
session->raw_read_frame.samples = session->raw_read_frame.datalen / sizeof(int16_t) / session->read_impl.number_of_channels;
|
||||||
session->raw_read_frame.channels = session->read_impl.number_of_channels;
|
session->raw_read_frame.channels = session->read_impl.number_of_channels;
|
||||||
@ -479,7 +485,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
|
|||||||
if (!switch_core_codec_ready(codec)) {
|
if (!switch_core_codec_ready(codec)) {
|
||||||
codec = read_frame->codec;
|
codec = read_frame->codec;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch_thread_rwlock_rdlock(session->bug_rwlock);
|
switch_thread_rwlock_rdlock(session->bug_rwlock);
|
||||||
codec->cur_frame = read_frame;
|
codec->cur_frame = read_frame;
|
||||||
session->read_codec->cur_frame = read_frame;
|
session->read_codec->cur_frame = read_frame;
|
||||||
@ -497,11 +503,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (status == SWITCH_STATUS_SUCCESS && session->read_impl.number_of_channels == 1) {
|
if (status == SWITCH_STATUS_SUCCESS && session->read_impl.number_of_channels == 1) {
|
||||||
if ((switch_channel_test_flag(session->channel, CF_JITTERBUFFER_PLC) || switch_channel_test_flag(session->channel, CF_CNG_PLC))
|
|
||||||
&& !session->plc) {
|
|
||||||
session->plc = plc_init(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (session->plc) {
|
if (session->plc) {
|
||||||
if (switch_test_flag(read_frame, SFF_PLC)) {
|
if (switch_test_flag(read_frame, SFF_PLC)) {
|
||||||
plc_fillin(session->plc, session->raw_read_frame.data, session->raw_read_frame.datalen / 2);
|
plc_fillin(session->plc, session->raw_read_frame.data, session->raw_read_frame.datalen / 2);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user