Avoid malloc on every Audio Frame

This commit is contained in:
Florian Märkl 2019-08-01 18:45:10 +02:00
commit 01111d62e4
No known key found for this signature in database
GPG key ID: 125BC8A5A6A1E857
3 changed files with 37 additions and 11 deletions

View file

@ -19,6 +19,7 @@
#define CHIAKI_AUDIO_H #define CHIAKI_AUDIO_H
#include <stdint.h> #include <stdint.h>
#include <unistd.h>
#include "common.h" #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_load(ChiakiAudioHeader *audio_header, const uint8_t *buf);
CHIAKI_EXPORT void chiaki_audio_header_save(ChiakiAudioHeader *audio_header, 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 #ifdef __cplusplus
} }
#endif #endif

View file

@ -38,6 +38,8 @@ typedef struct chiaki_audio_receiver_t
ChiakiAudioHeader audio_header; ChiakiAudioHeader audio_header;
ChiakiSeqNum16 frame_index_prev; ChiakiSeqNum16 frame_index_prev;
bool frame_index_startup; // whether frame_index_prev has definitely not wrapped yet bool frame_index_startup; // whether frame_index_prev has definitely not wrapped yet
int16_t *pcm_buf;
size_t pcm_buf_size;
} ChiakiAudioReceiver; } ChiakiAudioReceiver;
CHIAKI_EXPORT ChiakiErrorCode chiaki_audio_receiver_init(ChiakiAudioReceiver *audio_receiver, struct chiaki_session_t *session); CHIAKI_EXPORT ChiakiErrorCode chiaki_audio_receiver_init(ChiakiAudioReceiver *audio_receiver, struct chiaki_session_t *session);

View file

@ -34,6 +34,9 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_audio_receiver_init(ChiakiAudioReceiver *au
audio_receiver->frame_index_prev = 0; audio_receiver->frame_index_prev = 0;
audio_receiver->frame_index_startup = true; 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); ChiakiErrorCode err = chiaki_mutex_init(&audio_receiver->mutex, false);
if(err != CHIAKI_ERR_SUCCESS) if(err != CHIAKI_ERR_SUCCESS)
return err; return err;
@ -46,6 +49,7 @@ CHIAKI_EXPORT void chiaki_audio_receiver_fini(ChiakiAudioReceiver *audio_receive
{ {
opus_decoder_destroy(audio_receiver->opus_decoder); opus_decoder_destroy(audio_receiver->opus_decoder);
chiaki_mutex_fini(&audio_receiver->mutex); 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); audio_receiver->opus_decoder = opus_decoder_create(audio_header->rate, audio_header->channels, &error);
if(error != OPUS_OK) if(error != OPUS_OK)
{
CHIAKI_LOGE(audio_receiver->log, "Audio Receiver failed to initialize opus decoder: %s", opus_strerror(error)); CHIAKI_LOGE(audio_receiver->log, "Audio Receiver failed to initialize opus decoder: %s", opus_strerror(error));
else goto beach;
}
CHIAKI_LOGI(audio_receiver->log, "Audio Receiver initialized opus decoder with the settings above"); 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); 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; audio_receiver->frame_index_prev = frame_index;
// TODO: don't malloc int r = opus_decode(audio_receiver->opus_decoder, buf, (opus_int32)buf_size, audio_receiver->pcm_buf, audio_receiver->audio_header.frame_size, 0);
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);
if(r < 1) if(r < 1)
CHIAKI_LOGE(audio_receiver->log, "Decoding audio frame with opus failed: %s", opus_strerror(r)); CHIAKI_LOGE(audio_receiver->log, "Decoding audio frame with opus failed: %s", opus_strerror(r));
else else
{ audio_receiver->session->audio_frame_cb(audio_receiver->pcm_buf, (size_t)r, audio_receiver->session->audio_frame_cb_user);
audio_receiver->session->audio_frame_cb(pcm, (size_t)r, audio_receiver->session->audio_frame_cb_user);
}
free(pcm);
beach: beach:
chiaki_mutex_unlock(&audio_receiver->mutex); chiaki_mutex_unlock(&audio_receiver->mutex);