mirror of
https://github.com/78/xiaozhi-esp32.git
synced 2026-02-11 06:33:48 +00:00
Fix: esp32camera pixel byte order and uart-uhci compiling error (#1728)
* Fix: uart-uhci compiling errors * Enhance Esp32Camera functionality by adding optional byte swapping for RGB565 format. Introduce SetSwapBytes method to enable/disable byte order swapping, and update Capture method to utilize an encode buffer for improved memory management and performance during image processing.
This commit is contained in:
@@ -9,6 +9,7 @@ public:
|
||||
virtual bool Capture() = 0;
|
||||
virtual bool SetHMirror(bool enabled) = 0;
|
||||
virtual bool SetVFlip(bool enabled) = 0;
|
||||
virtual bool SetSwapBytes(bool enabled) { return false; } // Optional, default no-op
|
||||
virtual std::string Explain(const std::string& question) = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -41,6 +41,11 @@ Esp32Camera::~Esp32Camera() {
|
||||
esp_camera_fb_return(current_fb_);
|
||||
current_fb_ = nullptr;
|
||||
}
|
||||
if (encode_buf_) {
|
||||
heap_caps_free(encode_buf_);
|
||||
encode_buf_ = nullptr;
|
||||
encode_buf_size_ = 0;
|
||||
}
|
||||
esp_camera_deinit();
|
||||
streaming_on_ = false;
|
||||
}
|
||||
@@ -72,30 +77,46 @@ bool Esp32Camera::Capture() {
|
||||
}
|
||||
}
|
||||
|
||||
// Perform byte swapping for RGB565 format and prepare preview image
|
||||
// Prepare encode buffer for RGB565 format (with optional byte swapping)
|
||||
if (current_fb_->format == PIXFORMAT_RGB565) {
|
||||
size_t pixel_count = current_fb_->width * current_fb_->height;
|
||||
size_t data_size = pixel_count * 2;
|
||||
|
||||
uint8_t *preview_data = (uint8_t *)heap_caps_malloc(data_size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
|
||||
if (preview_data == nullptr) {
|
||||
ESP_LOGE(TAG, "Failed to allocate memory for preview image");
|
||||
return false;
|
||||
// Allocate or reallocate encode buffer if needed
|
||||
if (encode_buf_size_ < data_size) {
|
||||
if (encode_buf_) {
|
||||
heap_caps_free(encode_buf_);
|
||||
}
|
||||
encode_buf_ = (uint8_t *)heap_caps_malloc(data_size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
|
||||
if (encode_buf_ == nullptr) {
|
||||
ESP_LOGE(TAG, "Failed to allocate memory for encode buffer");
|
||||
encode_buf_size_ = 0;
|
||||
return false;
|
||||
}
|
||||
encode_buf_size_ = data_size;
|
||||
}
|
||||
|
||||
// Copy data to encode buffer with optional byte swapping
|
||||
uint16_t *src = (uint16_t *)current_fb_->buf;
|
||||
uint16_t *dst = (uint16_t *)preview_data;
|
||||
for (size_t i = 0; i < pixel_count; i++) {
|
||||
// Copy data from driver buffer to preview buffer with byte swapping
|
||||
dst[i] = __builtin_bswap16(src[i]);
|
||||
uint16_t *dst = (uint16_t *)encode_buf_;
|
||||
if (swap_bytes_enabled_) {
|
||||
for (size_t i = 0; i < pixel_count; i++) {
|
||||
dst[i] = __builtin_bswap16(src[i]);
|
||||
}
|
||||
} else {
|
||||
memcpy(encode_buf_, current_fb_->buf, data_size);
|
||||
}
|
||||
|
||||
// Display preview image
|
||||
auto display = dynamic_cast<LvglDisplay *>(Board::GetInstance().GetDisplay());
|
||||
if (display != nullptr) {
|
||||
display->SetPreviewImage(std::make_unique<LvglAllocatedImage>(preview_data, data_size, current_fb_->width, current_fb_->height, current_fb_->width * 2, LV_COLOR_FORMAT_RGB565));
|
||||
} else {
|
||||
heap_caps_free(preview_data);
|
||||
// Allocate separate buffer for preview display
|
||||
uint8_t *preview_data = (uint8_t *)heap_caps_malloc(data_size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
|
||||
if (preview_data != nullptr) {
|
||||
memcpy(preview_data, encode_buf_, data_size);
|
||||
auto display = dynamic_cast<LvglDisplay *>(Board::GetInstance().GetDisplay());
|
||||
if (display != nullptr) {
|
||||
display->SetPreviewImage(std::make_unique<LvglAllocatedImage>(preview_data, data_size, current_fb_->width, current_fb_->height, current_fb_->width * 2, LV_COLOR_FORMAT_RGB565));
|
||||
} else {
|
||||
heap_caps_free(preview_data);
|
||||
}
|
||||
}
|
||||
} else if (current_fb_->format == PIXFORMAT_JPEG) {
|
||||
// JPEG format preview usually requires decoding, skip preview display for now, just log
|
||||
@@ -126,6 +147,11 @@ bool Esp32Camera::SetVFlip(bool enabled) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Esp32Camera::SetSwapBytes(bool enabled) {
|
||||
swap_bytes_enabled_ = enabled;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string Esp32Camera::Explain(const std::string &question) {
|
||||
if (explain_url_.empty()) {
|
||||
throw std::runtime_error("Image explain URL or token is not set");
|
||||
@@ -172,7 +198,15 @@ std::string Esp32Camera::Explain(const std::string &question) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool ok = image_to_jpeg_cb(current_fb_->buf, current_fb_->len, w, h, enc_fmt, 80,
|
||||
// Use encode buffer for RGB565, otherwise use original frame buffer
|
||||
uint8_t *jpeg_src_buf = current_fb_->buf;
|
||||
size_t jpeg_src_len = current_fb_->len;
|
||||
if (current_fb_->format == PIXFORMAT_RGB565 && encode_buf_ != nullptr) {
|
||||
jpeg_src_buf = encode_buf_;
|
||||
jpeg_src_len = encode_buf_size_;
|
||||
}
|
||||
|
||||
bool ok = image_to_jpeg_cb(jpeg_src_buf, jpeg_src_len, w, h, enc_fmt, 80,
|
||||
[](void* arg, size_t index, const void* data, size_t len) -> size_t {
|
||||
auto jpeg_queue = static_cast<QueueHandle_t>(arg);
|
||||
JpegChunk chunk = {.data = nullptr, .len = len};
|
||||
|
||||
@@ -23,10 +23,13 @@ class Esp32Camera : public Camera
|
||||
{
|
||||
private:
|
||||
bool streaming_on_ = false;
|
||||
bool swap_bytes_enabled_ = true; // Swap pixel byte order for RGB565, enabled by default
|
||||
std::string explain_url_;
|
||||
std::string explain_token_;
|
||||
std::thread encoder_thread_;
|
||||
camera_fb_t *current_fb_ = nullptr;
|
||||
uint8_t *encode_buf_ = nullptr; // Buffer for JPEG encoding (with optional byte swap)
|
||||
size_t encode_buf_size_ = 0;
|
||||
|
||||
public:
|
||||
Esp32Camera(const camera_config_t &config);
|
||||
@@ -36,5 +39,6 @@ public:
|
||||
virtual bool Capture() override;
|
||||
virtual bool SetHMirror(bool enabled) override;
|
||||
virtual bool SetVFlip(bool enabled) override;
|
||||
virtual bool SetSwapBytes(bool enabled) override;
|
||||
virtual std::string Explain(const std::string &question) override;
|
||||
};
|
||||
|
||||
@@ -22,9 +22,9 @@ dependencies:
|
||||
78/esp-wifi-connect: ~3.0.2
|
||||
espressif/esp_audio_effects: ~1.2.1
|
||||
espressif/esp_audio_codec: ~2.4.1
|
||||
78/esp-ml307: ~3.6.2
|
||||
78/esp-ml307: ~3.6.3
|
||||
78/uart-eth-modem:
|
||||
version: ~0.3.0
|
||||
version: ~0.3.1
|
||||
rules:
|
||||
- if: target not in [esp32]
|
||||
78/xiaozhi-fonts: ~1.6.0
|
||||
|
||||
Reference in New Issue
Block a user