diff options
author | Alden DSouza <aldend@google.com> | 2021-02-11 17:07:01 -0800 |
---|---|---|
committer | Alden DSouza <aldend@google.com> | 2021-02-11 17:07:01 -0800 |
commit | e44e067612a95dcb2dcdc486e15113a2e8632404 (patch) | |
tree | fe78ddf807ce91a3acaf112e72aa43e9510d09bb | |
parent | df92bafc1c836d861c9e4ca2ca8b4fda1d1229b8 (diff) |
audio: Clean up missing memory free's when opening devices/streams
Signed-off-by: Alden DSouza <aldend@google.com>
Change-Id: Iae726f0818464fc09d809120cbba1eb8b109e031
-rw-r--r-- | audio/audio_hw.c | 132 |
1 files changed, 71 insertions, 61 deletions
diff --git a/audio/audio_hw.c b/audio/audio_hw.c index 4a16ac1..5a0953c 100644 --- a/audio/audio_hw.c +++ b/audio/audio_hw.c @@ -57,6 +57,16 @@ static int adev_get_microphones(const struct audio_hw_device* dev, size_t* mic_count); static size_t out_get_buffer_size(const struct audio_stream* stream); +static bool is_aec_input(const struct alsa_stream_in* in) { + /* If AEC is in the app, only configure based on ECHO_REFERENCE spec. + * If AEC is in the HAL, configure using the given mic stream. */ + bool aec_input = true; +#if !defined(AEC_HAL) + aec_input = (in->source == AUDIO_SOURCE_ECHO_REFERENCE); +#endif + return aec_input; +} + static int get_audio_output_port(audio_devices_t devices) { /* Only HDMI out for now #FIXME */ return PORT_HDMI; @@ -784,19 +794,17 @@ static int adev_open_output_stream(struct audio_hw_device *dev, ALOGV("adev_open_output_stream..."); struct alsa_audio_device *ladev = (struct alsa_audio_device *)dev; - struct alsa_stream_out *out; - struct pcm_params *params; - int ret = 0; - int out_port = get_audio_output_port(devices); - - params = pcm_params_get(CARD_OUT, out_port, PCM_OUT); - if (!params) + struct pcm_params* params = pcm_params_get(CARD_OUT, out_port, PCM_OUT); + if (!params) { return -ENOSYS; + } - out = (struct alsa_stream_out *)calloc(1, sizeof(struct alsa_stream_out)); - if (!out) + struct alsa_stream_out* out = + (struct alsa_stream_out*)calloc(1, sizeof(struct alsa_stream_out)); + if (!out) { return -ENOMEM; + } out->stream.common.get_sample_rate = out_get_sample_rate; out->stream.common.set_sample_rate = out_set_sample_rate; @@ -829,7 +837,7 @@ static int adev_open_output_stream(struct audio_hw_device *dev, config->sample_rate = out->config.rate; config->format = audio_format_from_pcm_format(out->config.format); config->channel_mask = audio_channel_out_mask_from_count(CHANNEL_STEREO); - ret = -EINVAL; + goto error_1; } ALOGI("adev_open_output_stream selects channels=%d rate=%d format=%d, devices=%d", @@ -844,8 +852,6 @@ static int adev_open_output_stream(struct audio_hw_device *dev, config->channel_mask = out_get_channels(&out->stream.common); config->sample_rate = out_get_sample_rate(&out->stream.common); - *stream_out = &out->stream; - out->speaker_eq = NULL; if (out_port == PORT_INTERNAL_SPEAKER) { out_set_eq(out); @@ -854,18 +860,20 @@ static int adev_open_output_stream(struct audio_hw_device *dev, } } - /* TODO The retry mechanism isn't implemented in AudioPolicyManager/AudioFlinger. */ - ret = 0; - - if (ret == 0) { - int aec_ret = init_aec_reference_config(ladev->aec, out); - if (aec_ret) { - ALOGE("AEC: Speaker config init failed!"); - return -EINVAL; - } + int aec_ret = init_aec_reference_config(ladev->aec, out); + if (aec_ret) { + ALOGE("AEC: Speaker config init failed!"); + goto error_2; } - return ret; + *stream_out = &out->stream; + return 0; + +error_2: + fir_release(out->speaker_eq); +error_1: + free(out); + return -EINVAL; } static void adev_close_output_stream(struct audio_hw_device *dev, @@ -982,17 +990,16 @@ static int adev_open_input_stream(struct audio_hw_device* dev, audio_io_handle_t ALOGV("adev_open_input_stream..."); struct alsa_audio_device *ladev = (struct alsa_audio_device *)dev; - struct alsa_stream_in *in; - struct pcm_params *params; - int ret = 0; - params = pcm_params_get(CARD_IN, PORT_BUILTIN_MIC, PCM_IN); - if (!params) + struct pcm_params* params = pcm_params_get(CARD_IN, PORT_BUILTIN_MIC, PCM_IN); + if (!params) { return -ENOSYS; + } - in = (struct alsa_stream_in *)calloc(1, sizeof(struct alsa_stream_in)); - if (!in) + struct alsa_stream_in* in = (struct alsa_stream_in*)calloc(1, sizeof(struct alsa_stream_in)); + if (!in) { return -ENOMEM; + } in->stream.common.get_sample_rate = in_get_sample_rate; in->stream.common.set_sample_rate = in_set_sample_rate; @@ -1025,7 +1032,10 @@ static int adev_open_input_stream(struct audio_hw_device* dev, audio_io_handle_t if (in->config.rate != config->sample_rate || audio_channel_count_from_in_mask(config->channel_mask) != CHANNEL_STEREO || in->config.format != pcm_format_from_audio_format(config->format) ) { - ret = -EINVAL; + config->format = in_get_format(&in->stream.common); + config->channel_mask = in_get_channels(&in->stream.common); + config->sample_rate = in_get_sample_rate(&in->stream.common); + goto error_1; } ALOGI("adev_open_input_stream selects channels=%d rate=%d format=%d source=%d", @@ -1037,46 +1047,37 @@ static int adev_open_input_stream(struct audio_hw_device* dev, audio_io_handle_t in->source = source; in->devices = devices; - config->format = in_get_format(&in->stream.common); - config->channel_mask = in_get_channels(&in->stream.common); - config->sample_rate = in_get_sample_rate(&in->stream.common); - - /* If AEC is in the app, only configure based on ECHO_REFERENCE spec. - * If AEC is in the HAL, configure using the given mic stream. */ - bool aecInput = true; -#if !defined(AEC_HAL) - aecInput = (in->source == AUDIO_SOURCE_ECHO_REFERENCE); -#endif - - if ((ret == 0) && aecInput) { + if (is_aec_input(in)) { int aec_ret = init_aec_mic_config(ladev->aec, in); if (aec_ret) { ALOGE("AEC: Mic config init failed!"); - return -EINVAL; + goto error_1; } } - if (ret) { - free(in); - } else { - *stream_in = &in->stream; - } - #if DEBUG_AEC remove("/data/local/traces/aec_ref.pcm"); remove("/data/local/traces/aec_in.pcm"); remove("/data/local/traces/aec_ref_timestamps.txt"); remove("/data/local/traces/aec_in_timestamps.txt"); #endif - return ret; + + *stream_in = &in->stream; + return 0; + +error_1: + free(in); + return -EINVAL; } static void adev_close_input_stream(struct audio_hw_device *dev, struct audio_stream_in *stream) { ALOGV("adev_close_input_stream..."); - struct alsa_audio_device *adev = (struct alsa_audio_device *)dev; - destroy_aec_mic_config(adev->aec); + struct alsa_stream_in* in = (struct alsa_stream_in*)stream; + if (is_aec_input(in)) { + destroy_aec_mic_config(in->dev->aec); + } free(stream); return; } @@ -1093,6 +1094,8 @@ static int adev_close(hw_device_t *device) struct alsa_audio_device *adev = (struct alsa_audio_device *)device; release_aec(adev->aec); + audio_route_free(adev->audio_route); + mixer_close(adev->mixer); free(device); return 0; } @@ -1100,16 +1103,16 @@ static int adev_close(hw_device_t *device) static int adev_open(const hw_module_t* module, const char* name, hw_device_t** device) { - struct alsa_audio_device *adev; - ALOGV("adev_open: %s", name); - if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) + if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) { return -EINVAL; + } - adev = calloc(1, sizeof(struct alsa_audio_device)); - if (!adev) + struct alsa_audio_device* adev = calloc(1, sizeof(struct alsa_audio_device)); + if (!adev) { return -ENOMEM; + } adev->hw_device.common.tag = HARDWARE_DEVICE_TAG; adev->hw_device.common.version = AUDIO_DEVICE_API_VERSION_2_0; @@ -1137,27 +1140,34 @@ static int adev_open(const hw_module_t* module, const char* name, *device = &adev->hw_device.common; adev->mixer = mixer_open(CARD_OUT); - if (!adev->mixer) { ALOGE("Unable to open the mixer, aborting."); - return -EINVAL; + goto error_1; } adev->audio_route = audio_route_init(CARD_OUT, MIXER_XML_PATH); if (!adev->audio_route) { ALOGE("%s: Failed to init audio route controls, aborting.", __func__); - return -EINVAL; + goto error_2; } pthread_mutex_lock(&adev->lock); if (init_aec(CAPTURE_CODEC_SAMPLING_RATE, NUM_AEC_REFERENCE_CHANNELS, CHANNEL_STEREO, &adev->aec)) { pthread_mutex_unlock(&adev->lock); - return -EINVAL; + goto error_3; } pthread_mutex_unlock(&adev->lock); return 0; + +error_3: + audio_route_free(adev->audio_route); +error_2: + mixer_close(adev->mixer); +error_1: + free(adev); + return -EINVAL; } static struct hw_module_methods_t hal_module_methods = { |