From cc07ef447ee79c6adf0b8428509bba0f6698480f Mon Sep 17 00:00:00 2001 From: Xiaoxia Date: Thu, 14 Aug 2025 22:23:29 +0800 Subject: [PATCH] =?UTF-8?q?Revert=20"camera=20=E4=BC=98=E5=8C=96=EF=BC=9A?= =?UTF-8?q?=E5=9C=A8=E5=8E=9F=E6=9C=89=E7=9A=84RGB565=E5=A4=84=E7=90=86?= =?UTF-8?q?=E4=B8=8B=EF=BC=8C=E5=AE=B9=E6=98=93=E8=B6=85=E6=97=B6=E6=94=B9?= =?UTF-8?q?=E4=B8=BAJPEG=E6=A0=BC=E5=BC=8F=20(#1029)"=20(#1085)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit d6b141496738992389adc802291551cf294047d1. --- .../compact_wifi_board_s3cam.cc | 4 +- main/boards/bread-compact-wifi-s3cam/config.h | 2 +- main/boards/common/esp32_camera.cc | 104 +++++------------- 3 files changed, 31 insertions(+), 79 deletions(-) diff --git a/main/boards/bread-compact-wifi-s3cam/compact_wifi_board_s3cam.cc b/main/boards/bread-compact-wifi-s3cam/compact_wifi_board_s3cam.cc index 416e1f21..45115408 100644 --- a/main/boards/bread-compact-wifi-s3cam/compact_wifi_board_s3cam.cc +++ b/main/boards/bread-compact-wifi-s3cam/compact_wifi_board_s3cam.cc @@ -158,9 +158,9 @@ private: config.pin_pwdn = CAMERA_PIN_PWDN; config.pin_reset = CAMERA_PIN_RESET; config.xclk_freq_hz = XCLK_FREQ_HZ; - config.pixel_format = PIXFORMAT_JPEG; + config.pixel_format = PIXFORMAT_RGB565; config.frame_size = FRAMESIZE_QVGA; - config.jpeg_quality = 10; + config.jpeg_quality = 12; config.fb_count = 1; config.fb_location = CAMERA_FB_IN_PSRAM; config.grab_mode = CAMERA_GRAB_WHEN_EMPTY; diff --git a/main/boards/bread-compact-wifi-s3cam/config.h b/main/boards/bread-compact-wifi-s3cam/config.h index b0bea05f..857d8c08 100644 --- a/main/boards/bread-compact-wifi-s3cam/config.h +++ b/main/boards/bread-compact-wifi-s3cam/config.h @@ -51,7 +51,7 @@ #define CAMERA_PIN_SIOD GPIO_NUM_4 #define CAMERA_PIN_PWDN GPIO_NUM_NC #define CAMERA_PIN_RESET GPIO_NUM_NC -#define XCLK_FREQ_HZ 50000000 +#define XCLK_FREQ_HZ 20000000 #define DISPLAY_BACKLIGHT_PIN GPIO_NUM_38 diff --git a/main/boards/common/esp32_camera.cc b/main/boards/common/esp32_camera.cc index f3c37f9d..40d02edd 100644 --- a/main/boards/common/esp32_camera.cc +++ b/main/boards/common/esp32_camera.cc @@ -65,7 +65,6 @@ Esp32Camera::Esp32Camera(const camera_config_t& config) { ESP_LOGE(TAG, "Failed to allocate memory for preview image"); return; } - } Esp32Camera::~Esp32Camera() { @@ -116,27 +115,14 @@ bool Esp32Camera::Capture() { // 显示预览图片 auto display = Board::GetInstance().GetDisplay(); if (display != nullptr) { - // 检查摄像头输出格式 - if (fb_->format == PIXFORMAT_JPEG) { - // JPEG格式需要先解码为RGB565 - // 分配足够的缓冲区用于RGB565数据 - bool converted = jpg2rgb565(fb_->buf, fb_->len, preview_image_.data, JPG_SCALE_NONE); - if (converted) { - display->SetPreviewImage(&preview_image_); - } else { - ESP_LOGE(TAG, "Failed to convert JPEG to RGB565 for preview"); - } - } else { - // RGB565等格式需要进行字节交换处理 - auto src = (uint16_t*)fb_->buf; - auto dst = (uint16_t*)preview_image_.data; - size_t pixel_count = fb_->len / 2; - for (size_t i = 0; i < pixel_count; i++) { - // 交换每个16位字内的字节 - dst[i] = __builtin_bswap16(src[i]); - } - display->SetPreviewImage(&preview_image_); + auto src = (uint16_t*)fb_->buf; + auto dst = (uint16_t*)preview_image_.data; + size_t pixel_count = fb_->len / 2; + for (size_t i = 0; i < pixel_count; i++) { + // 交换每个16位字内的字节 + dst[i] = __builtin_bswap16(src[i]); } + display->SetPreviewImage(&preview_image_); } return true; } @@ -202,57 +188,27 @@ std::string Esp32Camera::Explain(const std::string& question) { return "{\"success\": false, \"message\": \"Image explain URL or token is not set\"}"; } - QueueHandle_t jpeg_queue = nullptr; - // If the format is not JPEG, we need to convert it to JPEG first - if (fb_->format != PIXFORMAT_JPEG) { - // 创建局部的 JPEG 队列, 40 entries is about to store 512 * 40 = 20480 bytes of JPEG data - jpeg_queue = xQueueCreate(40, sizeof(JpegChunk)); - if (jpeg_queue == nullptr) { - ESP_LOGE(TAG, "Failed to create JPEG queue"); - return "{\"success\": false, \"message\": \"Failed to create JPEG queue\"}"; - } - - // We spawn a thread to encode the image to JPEG - encoder_thread_ = std::thread([this, jpeg_queue]() { - frame2jpg_cb(fb_, 80, [](void* arg, size_t index, const void* data, size_t len) -> unsigned int { - auto jpeg_queue = (QueueHandle_t)arg; - JpegChunk chunk = { - .data = (uint8_t*)heap_caps_aligned_alloc(16, len, MALLOC_CAP_SPIRAM), - .len = len - }; - if (chunk.data != nullptr) { - memcpy(chunk.data, data, len); - xQueueSend(jpeg_queue, &chunk, portMAX_DELAY); - } - return len; - }, jpeg_queue); - // Add a null chunk to indicate the end of the queue - JpegChunk null_chunk = { .data = nullptr, .len = 0 }; - xQueueSend(jpeg_queue, &null_chunk, portMAX_DELAY); - }); - } else { - // JPEG format, we can send it directly - // To keep the logic consistent, we still use a queue to send the data - jpeg_queue = xQueueCreate(2, sizeof(JpegChunk)); - if (jpeg_queue == nullptr) { - ESP_LOGE(TAG, "Failed to create JPEG queue"); - return "{\"success\": false, \"message\": \"Failed to create JPEG queue\"}"; - } - JpegChunk chunk = { - .data = (uint8_t*)heap_caps_aligned_alloc(16, fb_->len, MALLOC_CAP_SPIRAM), - .len = fb_->len - }; - if (chunk.data != nullptr) { - memcpy(chunk.data, fb_->buf, fb_->len); - xQueueSend(jpeg_queue, &chunk, portMAX_DELAY); - } else { - ESP_LOGE(TAG, "Failed to allocate memory for JPEG chunk"); - } - // Add a null chunk to indicate the end of the queue - JpegChunk null_chunk = { .data = nullptr, .len = 0 }; - xQueueSend(jpeg_queue, &null_chunk, portMAX_DELAY); + // 创建局部的 JPEG 队列, 40 entries is about to store 512 * 40 = 20480 bytes of JPEG data + QueueHandle_t jpeg_queue = xQueueCreate(40, sizeof(JpegChunk)); + if (jpeg_queue == nullptr) { + ESP_LOGE(TAG, "Failed to create JPEG queue"); + return "{\"success\": false, \"message\": \"Failed to create JPEG queue\"}"; } + // We spawn a thread to encode the image to JPEG + encoder_thread_ = std::thread([this, jpeg_queue]() { + frame2jpg_cb(fb_, 80, [](void* arg, size_t index, const void* data, size_t len) -> unsigned int { + auto jpeg_queue = (QueueHandle_t)arg; + JpegChunk chunk = { + .data = (uint8_t*)heap_caps_aligned_alloc(16, len, MALLOC_CAP_SPIRAM), + .len = len + }; + memcpy(chunk.data, data, len); + xQueueSend(jpeg_queue, &chunk, portMAX_DELAY); + return len; + }, jpeg_queue); + }); + auto network = Board::GetInstance().GetNetwork(); auto http = network->CreateHttp(3); // 构造multipart/form-data请求体 @@ -269,9 +225,7 @@ std::string Esp32Camera::Explain(const std::string& question) { if (!http->Open("POST", explain_url_)) { ESP_LOGE(TAG, "Failed to connect to explain URL"); // Clear the queue - if (encoder_thread_.joinable()) { - encoder_thread_.join(); - } + encoder_thread_.join(); JpegChunk chunk; while (xQueueReceive(jpeg_queue, &chunk, portMAX_DELAY) == pdPASS) { if (chunk.data != nullptr) { @@ -319,9 +273,7 @@ std::string Esp32Camera::Explain(const std::string& question) { heap_caps_free(chunk.data); } // Wait for the encoder thread to finish - if (encoder_thread_.joinable()) { - encoder_thread_.join(); - } + encoder_thread_.join(); // 清理队列 vQueueDelete(jpeg_queue);