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