mirror of
https://github.com/esphome/esphome.git
synced 2026-06-01 09:25:09 +08:00
[mixer] Fix memory leak in mixer task on stop/start cycles (#15185)
This commit is contained in:
committed by
Jesse Hills
parent
dc634b8c7b
commit
514c0c8331
@@ -597,6 +597,7 @@ void MixerSpeaker::audio_mixer_task(void *params) {
|
|||||||
|
|
||||||
xEventGroupSetBits(this_mixer->event_group_, MIXER_TASK_STATE_STARTING);
|
xEventGroupSetBits(this_mixer->event_group_, MIXER_TASK_STATE_STARTING);
|
||||||
|
|
||||||
|
{ // Ensure C++ objects fall out of scope to ensure proper cleanup before stopping the task
|
||||||
std::unique_ptr<audio::AudioSinkTransferBuffer> output_transfer_buffer = audio::AudioSinkTransferBuffer::create(
|
std::unique_ptr<audio::AudioSinkTransferBuffer> output_transfer_buffer = audio::AudioSinkTransferBuffer::create(
|
||||||
this_mixer->audio_stream_info_.value().ms_to_bytes(TRANSFER_BUFFER_DURATION_MS));
|
this_mixer->audio_stream_info_.value().ms_to_bytes(TRANSFER_BUFFER_DURATION_MS));
|
||||||
|
|
||||||
@@ -671,8 +672,8 @@ void MixerSpeaker::audio_mixer_task(void *params) {
|
|||||||
const uint32_t frames_available_in_buffer =
|
const uint32_t frames_available_in_buffer =
|
||||||
active_stream_info.bytes_to_frames(transfer_buffers_with_data[0]->available());
|
active_stream_info.bytes_to_frames(transfer_buffers_with_data[0]->available());
|
||||||
frames_to_mix = std::min(frames_to_mix, frames_available_in_buffer);
|
frames_to_mix = std::min(frames_to_mix, frames_available_in_buffer);
|
||||||
copy_frames(reinterpret_cast<int16_t *>(transfer_buffers_with_data[0]->get_buffer_start()), active_stream_info,
|
copy_frames(reinterpret_cast<int16_t *>(transfer_buffers_with_data[0]->get_buffer_start()),
|
||||||
reinterpret_cast<int16_t *>(output_transfer_buffer->get_buffer_end()),
|
active_stream_info, reinterpret_cast<int16_t *>(output_transfer_buffer->get_buffer_end()),
|
||||||
this_mixer->audio_stream_info_.value(), frames_to_mix);
|
this_mixer->audio_stream_info_.value(), frames_to_mix);
|
||||||
|
|
||||||
// Set playback delay for newly contributing source
|
// Set playback delay for newly contributing source
|
||||||
@@ -712,8 +713,8 @@ void MixerSpeaker::audio_mixer_task(void *params) {
|
|||||||
} else {
|
} else {
|
||||||
// Determine how many frames to mix
|
// Determine how many frames to mix
|
||||||
for (size_t i = 0; i < transfer_buffers_with_data.size(); ++i) {
|
for (size_t i = 0; i < transfer_buffers_with_data.size(); ++i) {
|
||||||
const uint32_t frames_available_in_buffer =
|
const uint32_t frames_available_in_buffer = speakers_with_data[i]->get_audio_stream_info().bytes_to_frames(
|
||||||
speakers_with_data[i]->get_audio_stream_info().bytes_to_frames(transfer_buffers_with_data[i]->available());
|
transfer_buffers_with_data[i]->available());
|
||||||
frames_to_mix = std::min(frames_to_mix, frames_available_in_buffer);
|
frames_to_mix = std::min(frames_to_mix, frames_available_in_buffer);
|
||||||
}
|
}
|
||||||
int16_t *primary_buffer = reinterpret_cast<int16_t *>(transfer_buffers_with_data[0]->get_buffer_start());
|
int16_t *primary_buffer = reinterpret_cast<int16_t *>(transfer_buffers_with_data[0]->get_buffer_start());
|
||||||
@@ -758,12 +759,11 @@ void MixerSpeaker::audio_mixer_task(void *params) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
xEventGroupSetBits(this_mixer->event_group_, MIXER_TASK_STATE_STOPPING);
|
xEventGroupSetBits(this_mixer->event_group_, MIXER_TASK_STATE_STOPPING);
|
||||||
|
}
|
||||||
|
|
||||||
// Reset pipeline frame count since the task is stopping
|
// Reset pipeline frame count since the task is stopping
|
||||||
this_mixer->frames_in_pipeline_.store(0, std::memory_order_release);
|
this_mixer->frames_in_pipeline_.store(0, std::memory_order_release);
|
||||||
|
|
||||||
output_transfer_buffer.reset();
|
|
||||||
|
|
||||||
xEventGroupSetBits(this_mixer->event_group_, MIXER_TASK_STATE_STOPPED);
|
xEventGroupSetBits(this_mixer->event_group_, MIXER_TASK_STATE_STOPPED);
|
||||||
|
|
||||||
vTaskSuspend(nullptr); // Suspend this task indefinitely until the loop method deletes it
|
vTaskSuspend(nullptr); // Suspend this task indefinitely until the loop method deletes it
|
||||||
|
|||||||
Reference in New Issue
Block a user