diff --git a/src/include/private/switch_core_pvt.h b/src/include/private/switch_core_pvt.h index 4852afaa4d..18fe82b6ea 100644 --- a/src/include/private/switch_core_pvt.h +++ b/src/include/private/switch_core_pvt.h @@ -138,6 +138,7 @@ struct switch_core_session { switch_frame_t enc_read_frame; uint8_t raw_read_buf[SWITCH_RECOMMENDED_BUFFER_SIZE]; uint8_t enc_read_buf[SWITCH_RECOMMENDED_BUFFER_SIZE]; + switch_codec_t bug_codec; }; struct switch_media_bug { diff --git a/src/include/switch_core.h b/src/include/switch_core.h index 0fa6dae535..1762b53540 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -1025,6 +1025,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_codec_init(switch_codec_t *codec, int channels, uint32_t flags, const switch_codec_settings_t *codec_settings, switch_memory_pool_t *pool); +SWITCH_DECLARE(switch_status_t) switch_core_codec_copy(switch_codec_t *codec, switch_codec_t *new_codec, switch_memory_pool_t *pool); + /*! \brief Encode data using a codec handle \param codec the codec handle to use diff --git a/src/switch_core_codec.c b/src/switch_core_codec.c index 7015ca85e1..1b97958e60 100644 --- a/src/switch_core_codec.c +++ b/src/switch_core_codec.c @@ -154,6 +154,35 @@ SWITCH_DECLARE(switch_codec_t *) switch_core_session_get_video_write_codec(switc } +SWITCH_DECLARE(switch_status_t) switch_core_codec_copy(switch_codec_t *codec, switch_codec_t *new_codec, switch_memory_pool_t *pool) +{ + switch_status_t status; + + switch_assert(codec != NULL); + switch_assert(new_codec != NULL); + + if (pool) { + new_codec->memory_pool = pool; + } else { + if ((status = switch_core_new_memory_pool(&new_codec->memory_pool)) != SWITCH_STATUS_SUCCESS) { + return status; + } + switch_set_flag(new_codec, SWITCH_CODEC_FLAG_FREE_POOL); + } + + new_codec->codec_interface = codec->codec_interface; + new_codec->implementation = codec->implementation; + new_codec->flags = codec->flags; + + if (codec->fmtp_in) { + new_codec->fmtp_in = switch_core_strdup(new_codec->memory_pool, codec->fmtp_in); + } + + new_codec->implementation->init(new_codec, new_codec->flags, NULL); + + return SWITCH_STATUS_SUCCESS; +} + SWITCH_DECLARE(switch_status_t) switch_core_codec_init(switch_codec_t *codec, char *codec_name, char *fmtp, uint32_t rate, int ms, int channels, uint32_t flags, const switch_codec_settings_t *codec_settings, switch_memory_pool_t *pool) @@ -305,6 +334,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_codec_destroy(switch_codec_t *codec) switch_core_destroy_memory_pool(&codec->memory_pool); } + memset(codec, 0, sizeof(*codec)); + return SWITCH_STATUS_SUCCESS; } diff --git a/src/switch_core_io.c b/src/switch_core_io.c index cb93861ec1..1fb50f50e5 100644 --- a/src/switch_core_io.c +++ b/src/switch_core_io.c @@ -186,7 +186,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi if (read_frame->codec || is_cng) { session->raw_read_frame.datalen = session->raw_read_frame.buflen; - + if (is_cng) { memset(session->raw_read_frame.data, 255, read_frame->codec->implementation->bytes_per_frame); session->raw_read_frame.datalen = read_frame->codec->implementation->bytes_per_frame; @@ -194,7 +194,15 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi read_frame = &session->raw_read_frame; status = SWITCH_STATUS_SUCCESS; } else { - status = switch_core_codec_decode(read_frame->codec, + switch_codec_t *use_codec = read_frame->codec; + if (do_bugs) { + if (!session->bug_codec.implementation) { + switch_core_codec_copy(read_frame->codec, &session->bug_codec, switch_core_session_get_pool(session)); + } + use_codec = &session->bug_codec; + } + + status = switch_core_codec_decode(use_codec, session->read_codec, read_frame->data, read_frame->datalen, diff --git a/src/switch_core_media_bug.c b/src/switch_core_media_bug.c index a509ae750f..35c7be8573 100644 --- a/src/switch_core_media_bug.c +++ b/src/switch_core_media_bug.c @@ -288,6 +288,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_bug_remove_all(switch_core_ses return SWITCH_STATUS_SUCCESS; } + if (session->bug_codec.implementation) { + switch_core_codec_destroy(&session->bug_codec); + } + return SWITCH_STATUS_FALSE; } @@ -342,6 +346,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_bug_remove(switch_core_session switch_thread_rwlock_unlock(session->bug_rwlock); status = switch_core_media_bug_close(&bp); } + + if (!session->bugs && session->bug_codec.implementation) { + switch_core_codec_destroy(&session->bug_codec); + } return status; }