From 01111d62e4197409aa11534e3ebe34e3f67c4847 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=A4rkl?= Date: Thu, 1 Aug 2019 18:45:10 +0200 Subject: [PATCH] Avoid malloc on every Audio Frame --- lib/include/chiaki/audio.h | 6 +++++ lib/include/chiaki/audioreceiver.h | 2 ++ lib/src/audioreceiver.c | 40 ++++++++++++++++++++++-------- 3 files changed, 37 insertions(+), 11 deletions(-) diff --git a/lib/include/chiaki/audio.h b/lib/include/chiaki/audio.h index 071f77a..e03778f 100644 --- a/lib/include/chiaki/audio.h +++ b/lib/include/chiaki/audio.h @@ -19,6 +19,7 @@ #define CHIAKI_AUDIO_H #include +#include #include "common.h" @@ -40,6 +41,11 @@ typedef struct chiaki_audio_header_t CHIAKI_EXPORT void chiaki_audio_header_load(ChiakiAudioHeader *audio_header, const uint8_t *buf); CHIAKI_EXPORT void chiaki_audio_header_save(ChiakiAudioHeader *audio_header, uint8_t *buf); +static inline size_t chiaki_audio_header_frame_buf_size(ChiakiAudioHeader *audio_header) +{ + return audio_header->frame_size * audio_header->channels * sizeof(int16_t); +} + #ifdef __cplusplus } #endif diff --git a/lib/include/chiaki/audioreceiver.h b/lib/include/chiaki/audioreceiver.h index aac96ef..43c3ef3 100644 --- a/lib/include/chiaki/audioreceiver.h +++ b/lib/include/chiaki/audioreceiver.h @@ -38,6 +38,8 @@ typedef struct chiaki_audio_receiver_t ChiakiAudioHeader audio_header; ChiakiSeqNum16 frame_index_prev; bool frame_index_startup; // whether frame_index_prev has definitely not wrapped yet + int16_t *pcm_buf; + size_t pcm_buf_size; } ChiakiAudioReceiver; CHIAKI_EXPORT ChiakiErrorCode chiaki_audio_receiver_init(ChiakiAudioReceiver *audio_receiver, struct chiaki_session_t *session); diff --git a/lib/src/audioreceiver.c b/lib/src/audioreceiver.c index 7e58a6e..4a5ec99 100644 --- a/lib/src/audioreceiver.c +++ b/lib/src/audioreceiver.c @@ -34,6 +34,9 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_audio_receiver_init(ChiakiAudioReceiver *au audio_receiver->frame_index_prev = 0; audio_receiver->frame_index_startup = true; + audio_receiver->pcm_buf = NULL; + audio_receiver->pcm_buf_size = 0; + ChiakiErrorCode err = chiaki_mutex_init(&audio_receiver->mutex, false); if(err != CHIAKI_ERR_SUCCESS) return err; @@ -46,6 +49,7 @@ CHIAKI_EXPORT void chiaki_audio_receiver_fini(ChiakiAudioReceiver *audio_receive { opus_decoder_destroy(audio_receiver->opus_decoder); chiaki_mutex_fini(&audio_receiver->mutex); + free(audio_receiver->pcm_buf); } @@ -67,10 +71,31 @@ CHIAKI_EXPORT void chiaki_audio_receiver_stream_info(ChiakiAudioReceiver *audio_ audio_receiver->opus_decoder = opus_decoder_create(audio_header->rate, audio_header->channels, &error); if(error != OPUS_OK) + { CHIAKI_LOGE(audio_receiver->log, "Audio Receiver failed to initialize opus decoder: %s", opus_strerror(error)); - else - CHIAKI_LOGI(audio_receiver->log, "Audio Receiver initialized opus decoder with the settings above"); + goto beach; + } + CHIAKI_LOGI(audio_receiver->log, "Audio Receiver initialized opus decoder with the settings above"); + + size_t pcm_buf_size_required = chiaki_audio_header_frame_buf_size(audio_header); + int16_t *pcm_buf_old = audio_receiver->pcm_buf; + if(!audio_receiver->pcm_buf || audio_receiver->pcm_buf_size != pcm_buf_size_required) + audio_receiver->pcm_buf = realloc(audio_receiver->pcm_buf, pcm_buf_size_required); + + if(!audio_receiver->pcm_buf) + { + free(pcm_buf_old); + CHIAKI_LOGE(audio_receiver->log, "Audio Receiver failed to alloc pcm buffer"); + opus_decoder_destroy(audio_receiver->opus_decoder); + audio_receiver->opus_decoder = NULL; + audio_receiver->pcm_buf_size = 0; + goto beach; + } + + audio_receiver->pcm_buf_size = pcm_buf_size_required; + +beach: chiaki_mutex_unlock(&audio_receiver->mutex); } @@ -145,18 +170,11 @@ static void chiaki_audio_receiver_frame(ChiakiAudioReceiver *audio_receiver, Chi audio_receiver->frame_index_prev = frame_index; - // TODO: don't malloc - opus_int16 *pcm = malloc(audio_receiver->audio_header.frame_size * audio_receiver->audio_header.channels * sizeof(opus_int16)); - - int r = opus_decode(audio_receiver->opus_decoder, buf, (opus_int32)buf_size, pcm, audio_receiver->audio_header.frame_size, 0); + int r = opus_decode(audio_receiver->opus_decoder, buf, (opus_int32)buf_size, audio_receiver->pcm_buf, audio_receiver->audio_header.frame_size, 0); if(r < 1) CHIAKI_LOGE(audio_receiver->log, "Decoding audio frame with opus failed: %s", opus_strerror(r)); else - { - audio_receiver->session->audio_frame_cb(pcm, (size_t)r, audio_receiver->session->audio_frame_cb_user); - } - - free(pcm); + audio_receiver->session->audio_frame_cb(audio_receiver->pcm_buf, (size_t)r, audio_receiver->session->audio_frame_cb_user); beach: chiaki_mutex_unlock(&audio_receiver->mutex);