1
0
mirror of https://github.com/esphome/esphome.git synced 2025-10-06 11:53:45 +01:00

Introduce base Camera class to support alternative camera implementations (#9285)

Co-authored-by: J. Nick Koston <nick@koston.org>
Co-authored-by: J. Nick Koston <nick+github@koston.org>
This commit is contained in:
DT-art1
2025-07-07 05:45:00 +02:00
committed by GitHub
parent bdd52dbaa4
commit e49b89a051
27 changed files with 254 additions and 132 deletions

View File

@@ -7,7 +7,7 @@
#include <freertos/queue.h>
#include "esphome/core/automation.h"
#include "esphome/core/component.h"
#include "esphome/core/entity_base.h"
#include "esphome/components/camera/camera.h"
#include "esphome/core/helpers.h"
#ifdef USE_I2C
@@ -19,9 +19,6 @@ namespace esp32_camera {
class ESP32Camera;
/* ---------------- enum classes ---------------- */
enum CameraRequester { IDLE, API_REQUESTER, WEB_REQUESTER };
enum ESP32CameraFrameSize {
ESP32_CAMERA_SIZE_160X120, // QQVGA
ESP32_CAMERA_SIZE_176X144, // QCIF
@@ -77,13 +74,13 @@ enum ESP32SpecialEffect {
};
/* ---------------- CameraImage class ---------------- */
class CameraImage {
class ESP32CameraImage : public camera::CameraImage {
public:
CameraImage(camera_fb_t *buffer, uint8_t requester);
ESP32CameraImage(camera_fb_t *buffer, uint8_t requester);
camera_fb_t *get_raw_buffer();
uint8_t *get_data_buffer();
size_t get_data_length();
bool was_requested_by(CameraRequester requester) const;
uint8_t *get_data_buffer() override;
size_t get_data_length() override;
bool was_requested_by(camera::CameraRequester requester) const override;
protected:
camera_fb_t *buffer_;
@@ -96,21 +93,21 @@ struct CameraImageData {
};
/* ---------------- CameraImageReader class ---------------- */
class CameraImageReader {
class ESP32CameraImageReader : public camera::CameraImageReader {
public:
void set_image(std::shared_ptr<CameraImage> image);
size_t available() const;
uint8_t *peek_data_buffer();
void consume_data(size_t consumed);
void return_image();
void set_image(std::shared_ptr<camera::CameraImage> image) override;
size_t available() const override;
uint8_t *peek_data_buffer() override;
void consume_data(size_t consumed) override;
void return_image() override;
protected:
std::shared_ptr<CameraImage> image_;
std::shared_ptr<ESP32CameraImage> image_;
size_t offset_{0};
};
/* ---------------- ESP32Camera class ---------------- */
class ESP32Camera : public EntityBase, public Component {
class ESP32Camera : public camera::Camera {
public:
ESP32Camera();
@@ -162,14 +159,15 @@ class ESP32Camera : public EntityBase, public Component {
void dump_config() override;
float get_setup_priority() const override;
/* public API (specific) */
void start_stream(CameraRequester requester);
void stop_stream(CameraRequester requester);
void request_image(CameraRequester requester);
void start_stream(camera::CameraRequester requester) override;
void stop_stream(camera::CameraRequester requester) override;
void request_image(camera::CameraRequester requester) override;
void update_camera_parameters();
void add_image_callback(std::function<void(std::shared_ptr<CameraImage>)> &&callback);
void add_image_callback(std::function<void(std::shared_ptr<camera::CameraImage>)> &&callback) override;
void add_stream_start_callback(std::function<void()> &&callback);
void add_stream_stop_callback(std::function<void()> &&callback);
camera::CameraImageReader *create_image_reader() override;
protected:
/* internal methods */
@@ -206,12 +204,12 @@ class ESP32Camera : public EntityBase, public Component {
uint32_t idle_update_interval_{15000};
esp_err_t init_error_{ESP_OK};
std::shared_ptr<CameraImage> current_image_;
std::shared_ptr<ESP32CameraImage> current_image_;
uint8_t single_requesters_{0};
uint8_t stream_requesters_{0};
QueueHandle_t framebuffer_get_queue_;
QueueHandle_t framebuffer_return_queue_;
CallbackManager<void(std::shared_ptr<CameraImage>)> new_image_callback_{};
CallbackManager<void(std::shared_ptr<camera::CameraImage>)> new_image_callback_{};
CallbackManager<void()> stream_start_callback_{};
CallbackManager<void()> stream_stop_callback_{};
@@ -222,13 +220,10 @@ class ESP32Camera : public EntityBase, public Component {
#endif // USE_I2C
};
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
extern ESP32Camera *global_esp32_camera;
class ESP32CameraImageTrigger : public Trigger<CameraImageData> {
public:
explicit ESP32CameraImageTrigger(ESP32Camera *parent) {
parent->add_image_callback([this](const std::shared_ptr<esp32_camera::CameraImage> &image) {
parent->add_image_callback([this](const std::shared_ptr<camera::CameraImage> &image) {
CameraImageData camera_image_data{};
camera_image_data.length = image->get_data_length();
camera_image_data.data = image->get_data_buffer();