ESPHome 2026.6.0-dev
Loading...
Searching...
No Matches
esp32_camera.cpp
Go to the documentation of this file.
1#ifdef USE_ESP32
2
3#include "esp32_camera.h"
5#include "esphome/core/hal.h"
6#include "esphome/core/log.h"
7
8#include <freertos/task.h>
9
11
12static const char *const TAG = "esp32_camera";
13static constexpr size_t FRAMEBUFFER_TASK_STACK_SIZE = 1792;
14#if ESPHOME_LOG_LEVEL < ESPHOME_LOG_LEVEL_VERBOSE
15static constexpr uint32_t FRAME_LOG_INTERVAL_MS = 60000;
16#endif
17
18static const char *frame_size_to_str(framesize_t size) {
19 switch (size) {
20 case FRAMESIZE_QQVGA:
21 return "160x120 (QQVGA)";
22 case FRAMESIZE_QCIF:
23 return "176x155 (QCIF)";
24 case FRAMESIZE_HQVGA:
25 return "240x176 (HQVGA)";
26 case FRAMESIZE_QVGA:
27 return "320x240 (QVGA)";
28 case FRAMESIZE_CIF:
29 return "400x296 (CIF)";
30 case FRAMESIZE_VGA:
31 return "640x480 (VGA)";
32 case FRAMESIZE_SVGA:
33 return "800x600 (SVGA)";
34 case FRAMESIZE_XGA:
35 return "1024x768 (XGA)";
36 case FRAMESIZE_SXGA:
37 return "1280x1024 (SXGA)";
38 case FRAMESIZE_UXGA:
39 return "1600x1200 (UXGA)";
40 case FRAMESIZE_FHD:
41 return "1920x1080 (FHD)";
42 case FRAMESIZE_P_HD:
43 return "720x1280 (P_HD)";
44 case FRAMESIZE_P_3MP:
45 return "864x1536 (P_3MP)";
46 case FRAMESIZE_QXGA:
47 return "2048x1536 (QXGA)";
48 case FRAMESIZE_QHD:
49 return "2560x1440 (QHD)";
50 case FRAMESIZE_WQXGA:
51 return "2560x1600 (WQXGA)";
52 case FRAMESIZE_P_FHD:
53 return "1080x1920 (P_FHD)";
54 case FRAMESIZE_QSXGA:
55 return "2560x1920 (QSXGA)";
56 default:
57 return "UNKNOWN";
58 }
59}
60
61static const char *pixel_format_to_str(pixformat_t format) {
62 switch (format) {
63 case PIXFORMAT_RGB565:
64 return "RGB565";
65 case PIXFORMAT_YUV422:
66 return "YUV422";
67 case PIXFORMAT_YUV420:
68 return "YUV420";
69 case PIXFORMAT_GRAYSCALE:
70 return "GRAYSCALE";
71 case PIXFORMAT_JPEG:
72 return "JPEG";
73 case PIXFORMAT_RGB888:
74 return "RGB888";
75 case PIXFORMAT_RAW:
76 return "RAW";
77 case PIXFORMAT_RGB444:
78 return "RGB444";
79 case PIXFORMAT_RGB555:
80 return "RGB555";
81 default:
82 return "UNKNOWN";
83 }
84}
85
86/* ---------------- public API (derivated) ---------------- */
88#ifdef USE_I2C
89 if (this->i2c_bus_ != nullptr) {
90 this->config_.sccb_i2c_port = this->i2c_bus_->get_port();
91 }
92#endif
93
94 /* initialize time to now */
95 this->last_update_ = millis();
96
97 /* initialize camera */
98 esp_err_t err = esp_camera_init(&this->config_);
99 if (err != ESP_OK) {
100 ESP_LOGE(TAG, "esp_camera_init failed: %s", esp_err_to_name(err));
101 this->init_error_ = err;
102 this->mark_failed();
103 return;
104 }
105
106 /* initialize camera parameters */
108
109 /* initialize RTOS */
110 this->framebuffer_get_queue_ = xQueueCreate(1, sizeof(camera_fb_t *));
111 this->framebuffer_return_queue_ = xQueueCreate(1, sizeof(camera_fb_t *));
112 xTaskCreatePinnedToCore(&ESP32Camera::framebuffer_task,
113 "framebuffer_task", // name
114 FRAMEBUFFER_TASK_STACK_SIZE, // stack size
115 this, // task pv params
116 1, // priority
117 nullptr, // handle
118 1 // core
119 );
120}
121
123 auto conf = this->config_;
124 ESP_LOGCONFIG(TAG,
125 "ESP32 Camera:\n"
126 " Name: %s\n"
127 " Internal: %s\n"
128 " Data Pins: D0:%d D1:%d D2:%d D3:%d D4:%d D5:%d D6:%d D7:%d\n"
129 " VSYNC Pin: %d\n"
130 " HREF Pin: %d\n"
131 " Pixel Clock Pin: %d\n"
132 " External Clock: Pin:%d Frequency:%u\n"
133 " I2C Pins: SDA:%d SCL:%d\n"
134 " Reset Pin: %d",
135 this->name_.c_str(), YESNO(this->is_internal()), conf.pin_d0, conf.pin_d1, conf.pin_d2, conf.pin_d3,
136 conf.pin_d4, conf.pin_d5, conf.pin_d6, conf.pin_d7, conf.pin_vsync, conf.pin_href, conf.pin_pclk,
137 conf.pin_xclk, conf.xclk_freq_hz, conf.pin_sccb_sda, conf.pin_sccb_scl, conf.pin_reset);
138
139 ESP_LOGCONFIG(TAG, " Resolution: %s", frame_size_to_str(this->config_.frame_size));
140 ESP_LOGCONFIG(TAG, " Pixel Format: %s", pixel_format_to_str(this->config_.pixel_format));
141
142 if (this->is_failed()) {
143 ESP_LOGE(TAG, " Setup Failed: %s", esp_err_to_name(this->init_error_));
144 return;
145 }
146
147 sensor_t *s = esp_camera_sensor_get();
148 if (s == nullptr) {
149 ESP_LOGE(TAG, " Camera sensor not available");
150 return;
151 }
152 auto st = s->status;
153 ESP_LOGCONFIG(TAG,
154 " JPEG Quality: %u\n"
155 " Framebuffer Count: %u\n"
156 " Framebuffer Location: %s\n"
157 " Contrast: %d\n"
158 " Brightness: %d\n"
159 " Saturation: %d\n"
160 " Vertical Flip: %s\n"
161 " Horizontal Mirror: %s\n"
162 " Special Effect: %u\n"
163 " White Balance Mode: %u",
164 st.quality, conf.fb_count, this->config_.fb_location == CAMERA_FB_IN_PSRAM ? "PSRAM" : "DRAM",
165 st.contrast, st.brightness, st.saturation, ONOFF(st.vflip), ONOFF(st.hmirror), st.special_effect,
166 st.wb_mode);
167 // ESP_LOGCONFIG(TAG, " Auto White Balance: %u", st.awb);
168 // ESP_LOGCONFIG(TAG, " Auto White Balance Gain: %u", st.awb_gain);
169 ESP_LOGCONFIG(TAG,
170 " Auto Exposure Control: %u\n"
171 " Auto Exposure Control 2: %u\n"
172 " Auto Exposure Level: %d\n"
173 " Auto Exposure Value: %u\n"
174 " AGC: %u\n"
175 " AGC Gain: %u\n"
176 " Gain Ceiling: %u",
177 st.aec, st.aec2, st.ae_level, st.aec_value, st.agc, st.agc_gain, st.gainceiling);
178 // ESP_LOGCONFIG(TAG, " BPC: %u", st.bpc);
179 // ESP_LOGCONFIG(TAG, " WPC: %u", st.wpc);
180 // ESP_LOGCONFIG(TAG, " RAW_GMA: %u", st.raw_gma);
181 // ESP_LOGCONFIG(TAG, " Lens Correction: %u", st.lenc);
182 // ESP_LOGCONFIG(TAG, " DCW: %u", st.dcw);
183 ESP_LOGCONFIG(TAG, " Test Pattern: %s", YESNO(st.colorbar));
184}
185
187 // Fast path: skip all work when truly idle
188 // (no current image, no pending requests, and not time for idle request yet)
190 if (!this->current_image_ && !this->has_requested_image_()) {
191 // Only check idle interval when we're otherwise idle
192 if (this->idle_update_interval_ != 0 && now - this->last_idle_request_ > this->idle_update_interval_) {
193 this->last_idle_request_ = now;
195 } else {
196 return;
197 }
198 }
199
200 // check if we can return the image
201 if (this->can_return_image_()) {
202 // return image
203#ifdef USE_ESP32_CAMERA_JPEG_CONVERSION
204 if (this->config_.pixel_format != PIXFORMAT_JPEG && this->config_.jpeg_quality > 0) {
205 // for non-JPEG format, we need to free the data and raw buffer
206 auto *jpg_buf = this->current_image_->get_data_buffer();
207 free(jpg_buf); // NOLINT(cppcoreguidelines-no-malloc)
208 auto *fb = this->current_image_->get_raw_buffer();
209 this->fb_allocator_.deallocate(fb, 1);
210 } else
211#endif
212 {
213 auto *fb = this->current_image_->get_raw_buffer();
214 xQueueSend(this->framebuffer_return_queue_, &fb, portMAX_DELAY);
215 }
216 this->current_image_.reset();
217 }
218
219 // Check if we should fetch a new image
220 if (!this->has_requested_image_())
221 return;
222 if (this->current_image_.use_count() > 1) {
223 // image is still in use
224 return;
225 }
227 return;
228
229 // request new image
230 camera_fb_t *fb;
231 if (xQueueReceive(this->framebuffer_get_queue_, &fb, 0L) != pdTRUE) {
232 // no frame ready
233 ESP_LOGVV(TAG, "No frame ready");
234 return;
235 }
236
237 if (fb == nullptr) {
238 ESP_LOGW(TAG, "Got invalid frame from camera!");
239 xQueueSend(this->framebuffer_return_queue_, &fb, portMAX_DELAY);
240 return;
241 }
242
243#ifdef USE_ESP32_CAMERA_JPEG_CONVERSION
244 if (this->config_.pixel_format != PIXFORMAT_JPEG && this->config_.jpeg_quality > 0) {
245 // for non-JPEG format, we need to convert the frame to JPEG
246 uint8_t *jpg_buf;
247 size_t jpg_buf_len;
248 size_t width = fb->width;
249 size_t height = fb->height;
250 struct timeval timestamp = fb->timestamp;
251 bool ok = frame2jpg(fb, 100 - this->config_.jpeg_quality, &jpg_buf, &jpg_buf_len);
252 // return the original frame buffer to the queue
253 xQueueSend(this->framebuffer_return_queue_, &fb, portMAX_DELAY);
254 if (!ok) {
255 ESP_LOGE(TAG, "Failed to convert frame to JPEG!");
256 return;
257 }
258 // create a new camera_fb_t for the JPEG data
259 fb = this->fb_allocator_.allocate(1);
260 if (fb == nullptr) {
261 ESP_LOGE(TAG, "Failed to allocate memory for camera frame buffer!");
262 free(jpg_buf); // NOLINT(cppcoreguidelines-no-malloc)
263 return;
264 }
265 memset(fb, 0, sizeof(camera_fb_t));
266 fb->buf = jpg_buf;
267 fb->len = jpg_buf_len;
268 fb->width = width;
269 fb->height = height;
270 fb->format = PIXFORMAT_JPEG;
271 fb->timestamp = timestamp;
272 }
273#endif
274 this->current_image_ = std::make_shared<ESP32CameraImage>(fb, this->single_requesters_ | this->stream_requesters_);
275
276#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE
277 ESP_LOGV(TAG, "Got Image: len=%u", fb->len);
278#else
279 // Initialize log time on first frame to ensure accurate interval measurement
280 if (this->frame_count_ == 0) {
281 this->last_log_time_ = now;
282 }
283 this->frame_count_++;
284 if (now - this->last_log_time_ >= FRAME_LOG_INTERVAL_MS) {
285 ESP_LOGD(TAG, "Received %u images in last %us", this->frame_count_, FRAME_LOG_INTERVAL_MS / 1000);
286 this->last_log_time_ = now;
287 this->frame_count_ = 0;
288 }
289#endif
290 for (auto *listener : this->listeners_) {
291 listener->on_camera_image(this->current_image_);
292 }
293 this->last_update_ = now;
294 this->single_requesters_ = 0;
295}
296
297/* ---------------- constructors ---------------- */
299 this->config_.pin_pwdn = -1;
300 this->config_.pin_reset = -1;
301 this->config_.pin_xclk = -1;
302 this->config_.ledc_timer = LEDC_TIMER_0;
303 this->config_.ledc_channel = LEDC_CHANNEL_0;
304 this->config_.pixel_format = PIXFORMAT_JPEG;
305 this->config_.frame_size = FRAMESIZE_VGA; // 640x480
306 this->config_.jpeg_quality = 10;
307 this->config_.fb_count = 1;
308 this->config_.grab_mode = CAMERA_GRAB_WHEN_EMPTY;
309 this->config_.fb_location = CAMERA_FB_IN_PSRAM;
310}
311
312/* ---------------- setters ---------------- */
313/* set pin assignment */
314void ESP32Camera::set_data_pins(std::array<uint8_t, 8> pins) {
315 this->config_.pin_d0 = pins[0];
316 this->config_.pin_d1 = pins[1];
317 this->config_.pin_d2 = pins[2];
318 this->config_.pin_d3 = pins[3];
319 this->config_.pin_d4 = pins[4];
320 this->config_.pin_d5 = pins[5];
321 this->config_.pin_d6 = pins[6];
322 this->config_.pin_d7 = pins[7];
323}
324void ESP32Camera::set_vsync_pin(uint8_t pin) { this->config_.pin_vsync = pin; }
325void ESP32Camera::set_href_pin(uint8_t pin) { this->config_.pin_href = pin; }
326void ESP32Camera::set_pixel_clock_pin(uint8_t pin) { this->config_.pin_pclk = pin; }
328 this->config_.pin_xclk = pin;
329 this->config_.xclk_freq_hz = frequency;
330}
331void ESP32Camera::set_i2c_pins(uint8_t sda, uint8_t scl) {
332 this->config_.pin_sccb_sda = sda;
333 this->config_.pin_sccb_scl = scl;
334}
335#ifdef USE_I2C
337 this->i2c_bus_ = i2c_bus;
338 this->config_.pin_sccb_sda = -1;
339 this->config_.pin_sccb_scl = -1;
340}
341#endif // USE_I2C
342void ESP32Camera::set_reset_pin(uint8_t pin) { this->config_.pin_reset = pin; }
343void ESP32Camera::set_power_down_pin(uint8_t pin) { this->config_.pin_pwdn = pin; }
344
345/* set image parameters */
347 switch (size) {
349 this->config_.frame_size = FRAMESIZE_QQVGA;
350 break;
352 this->config_.frame_size = FRAMESIZE_QCIF;
353 break;
355 this->config_.frame_size = FRAMESIZE_HQVGA;
356 break;
358 this->config_.frame_size = FRAMESIZE_QVGA;
359 break;
361 this->config_.frame_size = FRAMESIZE_CIF;
362 break;
364 this->config_.frame_size = FRAMESIZE_VGA;
365 break;
367 this->config_.frame_size = FRAMESIZE_SVGA;
368 break;
370 this->config_.frame_size = FRAMESIZE_XGA;
371 break;
373 this->config_.frame_size = FRAMESIZE_SXGA;
374 break;
376 this->config_.frame_size = FRAMESIZE_UXGA;
377 break;
379 this->config_.frame_size = FRAMESIZE_FHD;
380 break;
382 this->config_.frame_size = FRAMESIZE_P_HD;
383 break;
385 this->config_.frame_size = FRAMESIZE_P_3MP;
386 break;
388 this->config_.frame_size = FRAMESIZE_QXGA;
389 break;
391 this->config_.frame_size = FRAMESIZE_QHD;
392 break;
394 this->config_.frame_size = FRAMESIZE_WQXGA;
395 break;
397 this->config_.frame_size = FRAMESIZE_P_FHD;
398 break;
400 this->config_.frame_size = FRAMESIZE_QSXGA;
401 break;
402 }
403}
405 switch (format) {
407 this->config_.pixel_format = PIXFORMAT_RGB565;
408 break;
410 this->config_.pixel_format = PIXFORMAT_YUV422;
411 break;
413 this->config_.pixel_format = PIXFORMAT_YUV420;
414 break;
416 this->config_.pixel_format = PIXFORMAT_GRAYSCALE;
417 break;
419 this->config_.pixel_format = PIXFORMAT_JPEG;
420 break;
422 this->config_.pixel_format = PIXFORMAT_RGB888;
423 break;
425 this->config_.pixel_format = PIXFORMAT_RAW;
426 break;
428 this->config_.pixel_format = PIXFORMAT_RGB444;
429 break;
431 this->config_.pixel_format = PIXFORMAT_RGB555;
432 break;
433 }
434}
435void ESP32Camera::set_jpeg_quality(uint8_t quality) { this->config_.jpeg_quality = quality; }
436void ESP32Camera::set_vertical_flip(bool vertical_flip) { this->vertical_flip_ = vertical_flip; }
437void ESP32Camera::set_horizontal_mirror(bool horizontal_mirror) { this->horizontal_mirror_ = horizontal_mirror; }
438void ESP32Camera::set_contrast(int contrast) { this->contrast_ = contrast; }
439void ESP32Camera::set_brightness(int brightness) { this->brightness_ = brightness; }
440void ESP32Camera::set_saturation(int saturation) { this->saturation_ = saturation; }
442/* set exposure parameters */
444void ESP32Camera::set_aec2(bool aec2) { this->aec2_ = aec2; }
445void ESP32Camera::set_ae_level(int ae_level) { this->ae_level_ = ae_level; }
446void ESP32Camera::set_aec_value(uint32_t aec_value) { this->aec_value_ = aec_value; }
447/* set gains parameters */
449void ESP32Camera::set_agc_value(uint8_t agc_value) { this->agc_value_ = agc_value; }
451/* set white balance */
453/* set test mode */
454void ESP32Camera::set_test_pattern(bool test_pattern) { this->test_pattern_ = test_pattern; }
455/* set fps */
457 this->max_update_interval_ = max_update_interval;
458}
460 this->idle_update_interval_ = idle_update_interval;
461}
462/* set frame buffer parameters */
463void ESP32Camera::set_frame_buffer_mode(camera_grab_mode_t mode) { this->config_.grab_mode = mode; }
465 this->config_.fb_count = fb_count;
466 this->set_frame_buffer_mode(fb_count > 1 ? CAMERA_GRAB_LATEST : CAMERA_GRAB_WHEN_EMPTY);
467}
468void ESP32Camera::set_frame_buffer_location(camera_fb_location_t fb_location) {
469 this->config_.fb_location = fb_location;
470}
471
472/* ---------------- public API (specific) ---------------- */
474 for (auto *listener : this->listeners_) {
475 listener->on_stream_start();
476 }
477 this->stream_requesters_ |= (1U << requester);
478}
480 for (auto *listener : this->listeners_) {
481 listener->on_stream_stop();
482 }
483 this->stream_requesters_ &= ~(1U << requester);
484}
485void ESP32Camera::request_image(camera::CameraRequester requester) { this->single_requesters_ |= (1U << requester); }
488 sensor_t *s = esp_camera_sensor_get();
489 if (s == nullptr) {
490 return;
491 }
492 /* update image */
493 s->set_vflip(s, this->vertical_flip_);
494 s->set_hmirror(s, this->horizontal_mirror_);
495 s->set_contrast(s, this->contrast_);
496 s->set_brightness(s, this->brightness_);
497 s->set_saturation(s, this->saturation_);
498 s->set_special_effect(s, (int) this->special_effect_); // 0 to 6
499 /* update exposure */
500 s->set_exposure_ctrl(s, (bool) this->aec_mode_);
501 s->set_aec2(s, this->aec2_); // 0 = disable , 1 = enable
502 s->set_ae_level(s, this->ae_level_); // -2 to 2
503 s->set_aec_value(s, this->aec_value_); // 0 to 1200
504 /* update gains */
505 s->set_gain_ctrl(s, (bool) this->agc_mode_);
506 s->set_agc_gain(s, (int) this->agc_value_); // 0 to 30
507 s->set_gainceiling(s, (gainceiling_t) this->agc_gain_ceiling_);
508 /* update white balance mode */
509 s->set_wb_mode(s, (int) this->wb_mode_); // 0 to 4
510 /* update test pattern */
511 s->set_colorbar(s, this->test_pattern_);
512}
513
514/* ---------------- Internal methods ---------------- */
516bool ESP32Camera::can_return_image_() const { return this->current_image_.use_count() == 1; }
518 ESP32Camera *that = (ESP32Camera *) pv;
519 while (true) {
520 camera_fb_t *framebuffer = esp_camera_fb_get();
521 xQueueSend(that->framebuffer_get_queue_, &framebuffer, portMAX_DELAY);
522 // Only wake the main loop if there's a pending request to consume the frame
523 if (that->has_requested_image_()) {
525 }
526 // return is no-op for config with 1 fb
527 xQueueReceive(that->framebuffer_return_queue_, &framebuffer, portMAX_DELAY);
528 esp_camera_fb_return(framebuffer);
529 }
530}
531
532/* ---------------- ESP32CameraImageReader class ----------- */
533void ESP32CameraImageReader::set_image(std::shared_ptr<camera::CameraImage> image) {
534 this->image_ = std::static_pointer_cast<ESP32CameraImage>(image);
535 this->offset_ = 0;
536}
538 if (!this->image_)
539 return 0;
540
541 return this->image_->get_data_length() - this->offset_;
542}
544void ESP32CameraImageReader::consume_data(size_t consumed) { this->offset_ += consumed; }
545uint8_t *ESP32CameraImageReader::peek_data_buffer() { return this->image_->get_data_buffer() + this->offset_; }
546
547/* ---------------- ESP32CameraImage class ----------- */
548ESP32CameraImage::ESP32CameraImage(camera_fb_t *buffer, uint8_t requesters)
549 : buffer_(buffer), requesters_(requesters) {}
550
551camera_fb_t *ESP32CameraImage::get_raw_buffer() { return this->buffer_; }
552uint8_t *ESP32CameraImage::get_data_buffer() { return this->buffer_->buf; }
553size_t ESP32CameraImage::get_data_length() { return this->buffer_->len; }
555 return (this->requesters_ & (1 << requester)) != 0;
556}
557
558} // namespace esphome::esp32_camera
559
560#endif
BedjetMode mode
BedJet operating mode.
uint16_le_t frequency
Definition bl0942.h:6
void wake_loop_threadsafe()
Wake the main event loop from another thread or callback.
uint32_t IRAM_ATTR HOT get_loop_component_start_time() const
Get the cached time in milliseconds from when the current component started its loop execution.
void mark_failed()
Mark this component as failed.
bool is_failed() const
Definition component.h:272
bool is_internal() const
void deallocate(T *p, size_t n)
Definition helpers.h:2110
T * allocate(size_t n)
Definition helpers.h:2080
constexpr const char * c_str() const
Definition string_ref.h:73
Abstract image reader base class.
Definition camera.h:70
void set_i2c_pins(uint8_t sda, uint8_t scl)
void set_agc_value(uint8_t agc_value)
void set_test_pattern(bool test_pattern)
void set_jpeg_quality(uint8_t quality)
void set_wb_mode(ESP32WhiteBalanceMode mode)
ESP32AgcGainCeiling agc_gain_ceiling_
void set_vertical_flip(bool vertical_flip)
void set_aec_value(uint32_t aec_value)
void set_special_effect(ESP32SpecialEffect effect)
void set_aec_mode(ESP32GainControlMode mode)
void set_data_pins(std::array< uint8_t, 8 > pins)
void stop_stream(camera::CameraRequester requester) override
std::vector< camera::CameraListener * > listeners_
void set_i2c_id(i2c::InternalI2CBus *i2c_bus)
void set_pixel_format(ESP32CameraPixelFormat format)
void set_frame_size(ESP32CameraFrameSize size)
void set_external_clock(uint8_t pin, uint32_t frequency)
void set_max_update_interval(uint32_t max_update_interval)
std::shared_ptr< ESP32CameraImage > current_image_
std::atomic< uint8_t > single_requesters_
void set_horizontal_mirror(bool horizontal_mirror)
camera::CameraImageReader * create_image_reader() override
void set_frame_buffer_count(uint8_t fb_count)
void set_agc_gain_ceiling(ESP32AgcGainCeiling gain_ceiling)
void set_agc_mode(ESP32GainControlMode mode)
void set_frame_buffer_location(camera_fb_location_t fb_location)
void set_frame_buffer_mode(camera_grab_mode_t mode)
void set_idle_update_interval(uint32_t idle_update_interval)
void start_stream(camera::CameraRequester requester) override
void request_image(camera::CameraRequester requester) override
std::atomic< uint8_t > stream_requesters_
static void framebuffer_task(void *pv)
RAMAllocator< camera_fb_t > fb_allocator_
bool was_requested_by(camera::CameraRequester requester) const override
ESP32CameraImage(camera_fb_t *buffer, uint8_t requester)
void set_image(std::shared_ptr< camera::CameraImage > image) override
std::shared_ptr< ESP32CameraImage > image_
void consume_data(size_t consumed) override
virtual int get_port() const =0
Returns the I2C port number.
CameraRequester
Different sources for filtering.
Definition camera.h:15
const char int const __FlashStringHelper * format
Definition log.h:74
uint16_t size
Definition helpers.cpp:25
uint32_t IRAM_ATTR HOT millis()
Definition hal.cpp:28
Application App
Global storage of Application pointer - only one Application can exist.
static void uint32_t
uint16_t timestamp
Definition tt21100.cpp:2