ESP32-CAM:调用 esp_camera_fb_get() 时发生内存泄漏

问题描述 投票:0回答:1

我有一块带有 OV2640 摄像头的 Ai-Thinker ESP32-CAM 板。我正在尝试构建一个项目(细节不相关),其中我需要以一定的帧速率(30fps+)拍照(jpeg)并处理它们。

这里的代码很简单。我正在以一定的延迟拍照 - 然后释放缓冲区。 问题是,当我将相机对准明亮的物体或更改场景并使用

Serial.printf("Free Stack: %u bytes\n", uxTaskGetStackHighWaterMark(NULL));
监视我的堆栈时,我发现存在内存泄漏。如果场景变化太频繁,堆栈在几分钟内就会溢出。 我的问题是我做错了什么导致内存泄漏?我是不是错过了什么?

#include "esp_camera.h"

#define PWDN_GPIO_NUM 32
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 0
#define SIOD_GPIO_NUM 26
#define SIOC_GPIO_NUM 27
#define Y9_GPIO_NUM 35
#define Y8_GPIO_NUM 34
#define Y7_GPIO_NUM 39
#define Y6_GPIO_NUM 36
#define Y5_GPIO_NUM 21
#define Y4_GPIO_NUM 19
#define Y3_GPIO_NUM 18
#define Y2_GPIO_NUM 5
#define VSYNC_GPIO_NUM 25
#define HREF_GPIO_NUM 23
#define PCLK_GPIO_NUM 22

camera_fb_t *frameBuffer = NULL;

void setup() {

  Serial.begin(115200);
  Serial.printf("\r\n");
  Serial.printf("Before camera init:\r\n");
  Serial.printf("Free DRAM: %u bytes\r\n", heap_caps_get_free_size(MALLOC_CAP_8BIT));
  Serial.printf("Free PSRAM: %u bytes\r\n", heap_caps_get_free_size(MALLOC_CAP_SPIRAM));

  initialize_camera();

  Serial.printf("\r\n");
  Serial.printf("After camera init:\r\n");
  Serial.printf("Free DRAM: %u bytes\r\n", heap_caps_get_free_size(MALLOC_CAP_8BIT));
  Serial.printf("Free PSRAM: %u bytes\r\n", heap_caps_get_free_size(MALLOC_CAP_SPIRAM));

  delay(5000);
}

void loop() {
  camera_fb_t *frameBuffer = esp_camera_fb_get();

  if (!frameBuffer) {
    Serial.println("Failed to capture frame");
    delay(100);
    return;
  }

  vTaskDelay(pdMS_TO_TICKS(10));

  if (frameBuffer) {
    esp_camera_fb_return(frameBuffer);
    frameBuffer = NULL;
  }

  vTaskDelay(pdMS_TO_TICKS(20));

  if (!heap_caps_check_integrity(MALLOC_CAP_8BIT, true)) {
    Serial.println("Heap integrity check failed \r\n");
  }

  Serial.printf("Free Stack: %u bytes\n", uxTaskGetStackHighWaterMark(NULL));
  Serial.printf("\r\n");
}



void initialize_camera() {
  camera_config_t config;
  config.ledc_channel = LEDC_CHANNEL_0;
  config.ledc_timer = LEDC_TIMER_0;
  config.pin_d0 = Y2_GPIO_NUM;
  config.pin_d1 = Y3_GPIO_NUM;
  config.pin_d2 = Y4_GPIO_NUM;
  config.pin_d3 = Y5_GPIO_NUM;
  config.pin_d4 = Y6_GPIO_NUM;
  config.pin_d5 = Y7_GPIO_NUM;
  config.pin_d6 = Y8_GPIO_NUM;
  config.pin_d7 = Y9_GPIO_NUM;
  config.pin_xclk = XCLK_GPIO_NUM;
  config.pin_pclk = PCLK_GPIO_NUM;
  config.pin_vsync = VSYNC_GPIO_NUM;
  config.pin_href = HREF_GPIO_NUM;
  config.pin_sscb_sda = SIOD_GPIO_NUM;
  config.pin_sscb_scl = SIOC_GPIO_NUM;
  config.pin_pwdn = PWDN_GPIO_NUM;
  config.pin_reset = RESET_GPIO_NUM;
  config.xclk_freq_hz = 20000000;
  config.frame_size = FRAMESIZE_QQVGA;
  config.pixel_format = PIXFORMAT_JPEG;

  if (psramFound()) {
    Serial.print("Using psram \n\r");

    config.jpeg_quality = 5;
    config.fb_count = 2;
    config.grab_mode = CAMERA_GRAB_LATEST;
    config.fb_location = CAMERA_FB_IN_PSRAM;
  } else {
    Serial.print("Using dram. Exiting \n\r");

    return;
  }

  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK) {
    Serial.printf("Сamera error: 0x%x", err);
    return;
  }

  Serial.print("Camera initialized \n\r");
}
c++ embedded esp32
1个回答
0
投票

有几个技巧可以帮助您解决问题

  1. 将相机时钟设置为 10Mhz
config.xclk_freq_hz = 10000000;

我测试了修复我的 WDT 问题

  1. 将帧 JPEG 质量从 5 降低到 10 甚至 20
config.jpeg_quality = 10;
  1. 增加
    fb_count
    以确保有足够的缓冲区
config.fb_count = 30;
  1. 将循环功能的延迟减少到以下

    1ms

  2. 确保您在 Arduino 中正确配置您的开发板并使用稳定的固件,启用

    PSRAM

  3. 如果上述所有步骤都没有解决您的问题测试

    CameraWebServer
    示例与您的测试条件,以确保这是您的代码问题而不是项目配置或板或其他问题

© www.soinside.com 2019 - 2024. All rights reserved.