fix bug in OTA leading to freeze during upgrade if music playback is running during upgrade

wait for free space in flac write callback if none can be aquired.

Signed-off-by: Karl Osterseher <karl_osterseher@gmx.at>
This commit is contained in:
Karl Osterseher
2025-03-02 21:13:35 +01:00
Unverified
parent 4eb01805fe
commit cec14ad15b
7 changed files with 2019 additions and 41 deletions

View File

@@ -10,6 +10,7 @@ menu "ESP32 DSP processor config"
config SNAPCLIENT_MIX_LR_TO_MONO
bool "mix stereo audio to mono"
default false
depends on USE_DSP_PROCESSOR
help
mix stereo audio (left and right channel) to mono and play it on the left AND the right channel

View File

@@ -402,7 +402,7 @@ int dsp_processor_worker(void *p_pcmChnk, const void *p_scSet) {
for (i = 0; i < max; i++) {
int16_t channel0 = (int16_t)((tmp[i] & 0xFFFF0000) >> 16);
int16_t channel1 = (int16_t)(tmp[i] & 0x0000FFFF);
int16_t mixMono = (float)channel0 / 2.0 + (float)channel1 / 2.0;
int16_t mixMono = ((int32_t)channel0 + (int32_t)channel1) / 2;
tmp[i] = ((uint32_t)mixMono << 16) | ((uint32_t)mixMono & 0x0000FFFF);
}

View File

@@ -294,6 +294,9 @@ static int destroy_pcm_queue(QueueHandle_t *queueHandle) {
free_pcm_chunk(chnk);
}
}
else {
ESP_LOGE(TAG, "%s: can't get pcm chunk", __func__);
}
}
// delete the queue
@@ -312,6 +315,9 @@ static int destroy_pcm_queue(QueueHandle_t *queueHandle) {
int deinit_player(void) {
int ret = 0;
// must disable i2s before stopping player task or it will hang
my_i2s_channel_disable(tx_chan);
// stop the task
if (playerTaskHandle == NULL) {
ESP_LOGV(TAG, "no sync task created?");
@@ -319,8 +325,7 @@ int deinit_player(void) {
vTaskDelete(playerTaskHandle);
playerTaskHandle = NULL;
}
my_i2s_channel_disable(tx_chan);
if (tx_chan) {
i2s_del_channel(tx_chan);
tx_chan = NULL;
@@ -330,7 +335,6 @@ int deinit_player(void) {
vSemaphoreDelete(snapcastSettingsMux);
snapcastSettingsMux = NULL;
}
ret = destroy_pcm_queue(&pcmChkQHdl);
if (latencyBufSemaphoreHandle == NULL) {

View File

@@ -88,10 +88,10 @@ static void event_handler(void *arg, esp_event_base_t event_base, int event_id,
esp_wifi_connect();
s_retry_num++;
ESP_LOGI(TAG, "retry to connect to the AP");
ESP_LOGV(TAG, "retry to connect to the AP");
}
ESP_LOGI(TAG, "connect to the AP fail");
ESP_LOGV(TAG, "connect to the AP fail");
}
}

View File

@@ -7,6 +7,7 @@
#include "esp_event.h"
#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
#include "freertos/projdefs.h"
#include "freertos/task.h"
#define FIRMWARE_REV " Rev: 0.1"
@@ -156,6 +157,13 @@ void ota_server_start_my(void) {
uint8_t old_percent_loaded;
ESP_ERROR_CHECK(create_tcp_server());
// We don't want any other thread running during this update.
// SuspendAllThreads();
// KillAllThreads();
// dsp_i2s_task_deinit();
vTaskDelete(t_http_get_task);
deinit_player(); // ensure this is called after http_task was killed
const esp_partition_t *update_partition =
esp_ota_get_next_update_partition(NULL);
@@ -168,14 +176,7 @@ void ota_server_start_my(void) {
esp_log_level_set(
"esp_image",
ESP_LOG_ERROR); // set all components to ERROR level ESP_LOG_NONE
// We don't want any other thread running during this update.
// SuspendAllThreads();
// KillAllThreads();
// dsp_i2s_task_deinit();
vTaskDelete(t_http_get_task);
deinit_player(); // ensure this is called after http_task was killed
int recv_len;
char ota_buff[OTA_BUFF_SIZE] = {0};
bool is_req_body_started = false;
@@ -198,7 +199,7 @@ void ota_server_start_my(void) {
sscanf(content_length_start_p, "%d", &content_length);
ESP_LOGI(TAG, "Detected content length: %d", content_length);
ESP_ERROR_CHECK(
esp_ota_begin(update_partition, OTA_SIZE_UNKNOWN, &ota_handle));
esp_ota_begin(update_partition, content_length, &ota_handle));
const char *header_end = "\r\n\r\n";
char *body_start_p = strstr(ota_buff, header_end) + strlen(header_end);
int body_part_len = recv_len - (body_start_p - ota_buff);
@@ -249,11 +250,7 @@ void ota_server_start_my(void) {
ESP_LOGI(TAG, "!!! OTA Failed !!!");
}
// for (int x = 2; x >= 1; x--)
//{
ESP_LOGI(TAG, "Prepare to restart system..");
vTaskDelay(1000 / portTICK_PERIOD_MS);
//}
ESP_LOGI(TAG, "restart system..");
esp_restart();
}

View File

@@ -350,12 +350,17 @@ static FLAC__StreamDecoderWriteStatus write_callback(
return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
}
pcmChunk.outData =
(uint8_t *)realloc(pcmChunk.outData, pcmChunk.bytes + bytes);
if (!pcmChunk.outData) {
ESP_LOGE(TAG, "%s, failed to allocate PCM chunk payload", __func__);
return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
}
uint8_t * pcmData;
do {
pcmData = (uint8_t *)realloc(pcmChunk.outData, pcmChunk.bytes + bytes);
if (!pcmData) {
ESP_LOGW(TAG, "%s, failed to allocate PCM chunk payload, try again", __func__);
vTaskDelay(pdMS_TO_TICKS(5));
//return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
}
} while(!pcmData);
pcmChunk.outData = pcmData;
for (i = 0; i < frame->header.blocksize; i++) {
// write little endian

File diff suppressed because it is too large Load Diff