H.264 Codec for ESP32-S3
Loading...
Searching...
No Matches
H264Decoder.h
Go to the documentation of this file.
1#pragma once
2
3/**
4 * @file H264Decoder.h
5 * @brief ESP32-S3 H.264 Decoder with Stream Input Support
6 * @version 1.0
7 * @date 2024-12-19
8 * @author Generated by GitHub Copilot
9 *
10 * Provides H264Decoder class for decoding H.264 video streams on ESP32-S3.
11 * Supports various input sources via Arduino Stream interface and multiple
12 * output formats (I420, RGB565).
13 *
14 * This is a lightweight, header-only helper to decode H.264 streams to raw frames
15 * @author esp_h264 library
16 */
17
18#include <Arduino.h>
19#include <esp_log.h>
20#include <functional>
21#include <vector>
22#include <algorithm>
23
24#include "H264Config.h"
25#include "h264/esp_h264_arduino.h"
26#include "h264/esp_h264_dec.h"
27#include "h264/esp_h264_dec_sw.h"
28#include "h264/esp_h264_dec_param.h"
29#include "h264/esp_h264_types.h"
30
31namespace esp_h264 {
32
33/**
34 * @class H264Decoder
35 * @brief Template class for decoding H.264 streams to raw video frames
36 *
37 * H264Decoder is a lightweight, header-only class that wraps H.264 decoder initialization,
38 * stream processing, and output format conversions (I420 → RGB565/other formats).
39 *
40 * The class is templated on an allocator type to allow customization of memory
41 * allocation strategy (e.g., PSRAM vs regular heap).
42 *
43 * @tparam Alloc Memory allocator type for internal buffers (defaults to PSRAMAllocatorH264)
44 *
45 * @note This class intentionally keeps implementation in the header for easy
46 * integration into Arduino sketches without separate .cpp files
47 * @note The decoder supports constrained baseline H.264 profile
48 * @note Requires ESP32 with sufficient memory for frame buffers
49 *
50 * Example usage:
51 * @code
52 * #include "H264Decoder.h"
53 * #include <WiFiUdp.h>
54 *
55 * WiFiUDP udp;
56 * H264DecoderPSRAM decoder(&udp); // Uses PSRAM allocation (simpler than H264Decoder<>)
57 *
58 * void setup() {
59 * auto cfg = decoder.defaultConfig();
60 * cfg.output_format = ESP_H264_RAW_FMT_RGB565_LE;
61 * cfg.frame_callback = [](const uint8_t* frame, uint32_t w, uint32_t h, esp_h264_raw_format_t fmt) {
62 * // Process decoded frame (e.g., display on TFT)
63 * tft.drawFrame(frame, w, h);
64 * };
65 *
66 * udp.begin(5000);
67 * if (!decoder.begin(cfg)) {
68 * Serial.println("Failed to start decoder");
69 * }
70 * }
71 *
72 * void loop() {
73 * decoder.processStream(); // Reads from UDP and decodes
74 * }
75 * @endcode
76 */
77template <typename Alloc = H264_DEFAULT_ALLOCATOR>
79 public:
80 /** @brief Logging tag for ESP32 log system */
81 static constexpr const char* TAG = "H264Decoder";
82
83 /**
84 * @struct Config
85 * @brief Configuration structure for H.264 decoder and output settings
86 *
87 * Contains all parameters needed to configure the H.264 decoder,
88 * output format conversion, and buffer management.
89 */
90 struct Config {
91 /** @brief Output pixel format after decoding (I420, RGB565, etc.) */
92 esp_h264_raw_format_t output_format = ESP_H264_RAW_FMT_I420;
93
94 /** @brief Input buffer size for H.264 stream data (bytes) */
96
97 /** @brief Output buffer size for decoded frame data (bytes) */
98 size_t output_buffer_size = 640 * 480 * 3 / 2; // Default for VGA I420
99
100 /** @brief Maximum bytes to read per processStream() call (0 = read all available) */
101 size_t max_read_bytes = 1500; // Typical UDP packet size
102
103 /** @brief Optional frame callback for real-time processing */
104 std::function<void(const uint8_t* frame_data, uint32_t width, uint32_t height,
105 esp_h264_raw_format_t format)> frame_callback = nullptr;
106 };
107
108 /**
109 * @brief Create a default configuration with reasonable defaults
110 *
111 * Returns a Config structure populated with default values suitable for
112 * typical H.264 decoding scenarios. Output format defaults to I420.
113 *
114 * @return Config Default configuration structure
115 *
116 * @note Input and output buffer sizes are set for VGA resolution
117 * @note Frame callback is nullptr - set manually for real-time processing
118 */
120 ESP_LOGD(TAG, "defaultConfig");
121 Config cfg;
122 cfg.output_format = ESP_H264_RAW_FMT_I420;
123 cfg.input_buffer_size = 400 * 1024;
124 cfg.output_buffer_size = 640 * 480 * 3 / 2;
125 cfg.max_read_bytes = 1500;
126 cfg.frame_callback = nullptr;
127 return cfg;
128 }
129
130 /**
131 * @brief Constructor with input stream
132 *
133 * Creates a H264Decoder that reads H.264 data from the specified stream.
134 * The stream can be UDP, TCP, Serial, or any other Stream implementation.
135 *
136 * @param input_stream Pointer to Stream object for H.264 input data
137 *
138 * @note The stream must remain valid for the lifetime of the decoder
139 * @note Call begin() to initialize decoder resources
140 */
141 explicit H264Decoder(Stream& input_stream) : input_stream_(&input_stream) {
142 ESP_LOGD(TAG, "H264Decoder(Stream&)");
143 }
144
145 /**
146 * @brief Default constructor (no input stream)
147 *
148 * Creates a H264Decoder without an input stream. Use decode() method
149 * to process H.264 data directly from buffers.
150 *
151 * @note Call begin() to initialize decoder resources
152 * @note Use setInputStream() to assign a stream later if needed
153 */
154 H264Decoder() : input_stream_(nullptr) { ESP_LOGD(TAG, "H264Decoder"); }
155
156 /**
157 * @brief Destructor
158 *
159 * Automatically releases decoder and buffer resources by calling end().
160 *
161 * @note Safe to destroy without calling end() explicitly
162 */
164 ESP_LOGD(TAG, "~H264Decoder");
165 end();
166 }
167
168 /**
169 * @brief Set input stream for H.264 data
170 *
171 * Assigns or changes the input stream used by processStream() method.
172 *
173 * @param input_stream Pointer to Stream object for H.264 input data
174 *
175 * @note The stream must remain valid for the lifetime of the decoder
176 * @note Can be called at any time to change input source
177 */
178 void setInputStream(Stream* input_stream) {
179 ESP_LOGD(TAG, "setInputStream");
180 input_stream_ = input_stream;
181 }
182
183 /**
184 * @brief Initialize H.264 decoder and allocate buffers
185 *
186 * Configures and initializes the H.264 software decoder with specified
187 * output format and allocates internal buffers using the configured allocator.
188 *
189 * @param cfg Configuration structure (passed by value to allow temporary objects)
190 * @return true if initialization succeeded, false on any failure
191 *
192 * @note Decoder is configured for constrained baseline H.264 profile
193 * @note Buffers are allocated using the template allocator (Alloc)
194 * @note On failure, any partially initialized resources are cleaned up
195 */
196 bool begin(Config cfg) {
197 ESP_LOGD(TAG, "begin");
198 cfg_ = cfg;
199 if (!initDecoder()) return false;
200 if (!initBuffers()) return false;
201 return true;
202 }
203
204 /**
205 * @brief Process H.264 data from configured input stream
206 *
207 * Reads available H.264 data from the input stream (if configured) and
208 * processes it through the decoder. Automatically handles NAL unit parsing
209 * and frame assembly.
210 *
211 * @return true if stream processing succeeded, false on error or no stream
212 *
213 * @note Returns false if no input stream is configured
214 * @note Amount of data read per call is limited by Config::max_read_bytes
215 * @note Decoded frames trigger frame_callback if configured
216 * @note Use this method in loop() for continuous stream processing
217 */
219 ESP_LOGD(TAG, "processStream");
220 if (!input_stream_) {
221 ESP_LOGW(TAG, "No input stream configured");
222 return false;
223 }
224
225 int available = input_stream_->available();
226 if (available <= 0) return true; // No data available, but not an error
227
228 size_t bytes_to_read = cfg_.max_read_bytes > 0 ?
229 std::min((size_t)available, cfg_.max_read_bytes) :
230 (size_t)available;
231
232 if (temp_buf_.size() < bytes_to_read) {
233 temp_buf_.resize(bytes_to_read);
234 }
235
236 size_t bytes_read = input_stream_->readBytes(temp_buf_.data(), bytes_to_read);
237 if (bytes_read > 0) {
238 return decode(temp_buf_.data(), bytes_read);
239 }
240
241 return true;
242 }
243
244 /**
245 * @brief Decode H.264 data from buffer
246 *
247 * Processes H.264 encoded data directly from a memory buffer.
248 * Handles NAL unit parsing, decoding, and output frame generation.
249 *
250 * @param h264_data Pointer to H.264 encoded data buffer
251 * @param h264_len Size of H.264 data in bytes
252 * @return true if decoding succeeded, false on error
253 *
254 * @note Input data should contain complete NAL units when possible
255 * @note Decoder handles partial NAL units and reassembly internally
256 * @note Decoded frames trigger frame_callback if configured
257 * @note This method can be used without an input stream
258 */
259 bool decode(const uint8_t* h264_data, size_t h264_len) {
260 ESP_LOGD(TAG, "decode");
261 if (!dec_handle_ || !h264_data || h264_len == 0) return false;
262
263 esp_h264_dec_in_frame_t in_frame{};
264 esp_h264_dec_out_frame_t out_frame{};
265
266 // Copy input data to internal buffer
267 if (input_buf_.size() < h264_len) {
268 input_buf_.resize(h264_len);
269 }
270 memcpy(input_buf_.data(), h264_data, h264_len);
271
272 in_frame.raw_data.buffer = input_buf_.data();
273 in_frame.raw_data.len = h264_len;
274 in_frame.consume = 0;
275
276 while (in_frame.raw_data.len > 0) {
277 out_frame.outbuf = nullptr;
278 out_frame.out_size = 0;
279
280 esp_h264_err_t res = esp_h264_dec_process(dec_handle_, &in_frame, &out_frame);
281
282 if (res != ESP_H264_ERR_OK) {
283 decode_errors_++;
284 ESP_LOGW(TAG, "Decode error: %d", (int)res);
285 return false;
286 }
287
288 if (out_frame.out_size > 0 && out_frame.outbuf) {
289 // Frame decoded successfully
290 frame_ready_ = true;
291 frame_count_++;
292
293 // Get frame dimensions from decoder parameters
295 esp_h264_dec_sw_get_param_hd(dec_handle_, &param_hd);
296 esp_h264_resolution_t resolution;
297 if (esp_h264_dec_get_resolution(param_hd, &resolution) == ESP_H264_ERR_OK) {
298 frame_width_ = resolution.width;
299 frame_height_ = resolution.height;
300 }
301
302 // Process decoded frame
303 if (!processDecodedFrame(out_frame.outbuf, out_frame.out_size)) {
304 return false;
305 }
306 }
307
308 // Update input buffer for next iteration
309 in_frame.raw_data.buffer += in_frame.consume;
310 in_frame.raw_data.len -= in_frame.consume;
311 }
312
313 return true;
314 }
315
316 /**
317 * @brief Check if a decoded frame is available
318 *
319 * @return true if a decoded frame is ready for retrieval, false otherwise
320 *
321 * @note Frame availability is reset after calling getFrame()
322 * @note This method is useful for polling-based frame processing
323 */
324 bool hasFrame() const {
325 ESP_LOGD(TAG, "hasFrame");
326 return frame_ready_;
327 }
328
329 /**
330 * @brief Retrieve decoded frame data
331 *
332 * Copies the most recently decoded frame to the provided buffer.
333 * Frame dimensions and format are returned via reference parameters.
334 *
335 * @param dst Destination buffer for frame data
336 * @param dst_len Size of destination buffer in bytes
337 * @param width Reference to store frame width in pixels
338 * @param height Reference to store frame height in pixels
339 * @return true if frame copied successfully, false on error or no frame
340 *
341 * @note Buffer must be large enough for the frame data
342 * @note Frame availability is reset after successful retrieval
343 * @note Frame format matches Config::output_format setting
344 */
345 bool getFrame(uint8_t* dst, size_t dst_len, uint32_t& width, uint32_t& height) {
346 ESP_LOGD(TAG, "getFrame");
347 if (!frame_ready_ || !dst) return false;
348
349 size_t frame_size = frame_width_ * frame_height_ *
350 ESP_H264_GET_BPP_BY_PIC_TYPE(cfg_.output_format);
351
352 if (dst_len < frame_size) {
353 ESP_LOGE(TAG, "Destination buffer too small: need %u got %u",
354 (unsigned)frame_size, (unsigned)dst_len);
355 return false;
356 }
357
358 memcpy(dst, output_buf_.data(), frame_size);
359 width = frame_width_;
360 height = frame_height_;
361 frame_ready_ = false; // Reset frame availability
362
363 return true;
364 }
365
366 /**
367 * @brief Get total number of successfully decoded frames
368 *
369 * @return Number of frames decoded since begin() was called
370 *
371 * @note Counter is reset when begin() is called
372 * @note Useful for monitoring decoder performance
373 */
374 uint32_t getFrameCount() const {
375 ESP_LOGD(TAG, "getFrameCount");
376 return frame_count_;
377 }
378
379 /**
380 * @brief Get total number of decode errors
381 *
382 * @return Number of decode errors since begin() was called
383 *
384 * @note Counter is reset when begin() is called
385 * @note Useful for monitoring stream quality and decoder health
386 */
387 uint32_t getDecodeErrors() const {
388 ESP_LOGD(TAG, "getDecodeErrors");
389 return decode_errors_;
390 }
391
392 /**
393 * @brief Get current frame dimensions
394 *
395 * @param width Reference to store frame width in pixels
396 * @param height Reference to store frame height in pixels
397 * @return true if valid dimensions available, false if no frame decoded yet
398 *
399 * @note Dimensions are available after the first successful frame decode
400 * @note Dimensions may change if stream resolution changes
401 */
402 bool getFrameDimensions(uint32_t& width, uint32_t& height) const {
403 ESP_LOGD(TAG, "getFrameDimensions");
404 if (frame_count_ == 0 || frame_width_ == 0 || frame_height_ == 0) return false;
405 width = frame_width_;
406 height = frame_height_;
407 return true;
408 }
409
410 /**
411 * @brief Cleanup and release decoder resources
412 *
413 * Deinitializes the H.264 decoder and releases all allocated
414 * resources. Should be called when decoding is complete or when
415 * switching decoder configurations.
416 *
417 * @note Safe to call multiple times
418 * @note Required before calling begin() with different Config
419 * @note Automatically called by destructor
420 */
421 void end() {
422 ESP_LOGD(TAG, "end");
423 if (dec_handle_) {
424 esp_h264_dec_close(dec_handle_);
425 esp_h264_dec_del(dec_handle_);
426 dec_handle_ = nullptr;
427 }
428 if (!input_buf_.empty()) {
429 input_buf_.clear();
430 }
431 if (!output_buf_.empty()) {
432 output_buf_.clear();
433 }
434 if (!temp_buf_.empty()) {
435 temp_buf_.clear();
436 }
437 frame_ready_ = false;
438 frame_count_ = 0;
439 decode_errors_ = 0;
440 frame_width_ = 0;
441 frame_height_ = 0;
442 }
443
444 private:
445 Config cfg_;
446 Stream* input_stream_;
447 esp_h264_dec_handle_t dec_handle_ = nullptr;
448 std::vector<uint8_t, Alloc> input_buf_;
449 std::vector<uint8_t, Alloc> output_buf_;
450 std::vector<uint8_t, Alloc> temp_buf_; // For stream reading
451
452 // Frame state
453 uint32_t frame_width_ = 0;
454 uint32_t frame_height_ = 0;
455 bool frame_ready_ = false;
456
457 // Statistics
458 uint32_t frame_count_ = 0;
459 uint32_t decode_errors_ = 0;
460
461 /**
462 * @brief Initialize H.264 software decoder with Config settings
463 * @return true if decoder creation and opening successful, false on error
464 * @note Creates decoder instance for constrained baseline H.264 profile
465 * @note Uses esp_h264 software decoder (tinyH264)
466 */
467 bool initDecoder() {
468 ESP_LOGD(TAG, "initDecoder");
469 esp_h264_dec_cfg_sw_t dec_cfg{};
470 dec_cfg.pic_type = cfg_.output_format;
471
472 esp_h264_err_t res = esp_h264_dec_sw_new(&dec_cfg, &dec_handle_);
473 if (res != ESP_H264_ERR_OK || !dec_handle_) {
474 ESP_LOGE(TAG, "esp_h264_dec_sw_new failed: %d", (int)res);
475 return false;
476 }
477
478 res = esp_h264_dec_open(dec_handle_);
479 if (res != ESP_H264_ERR_OK) {
480 ESP_LOGE(TAG, "esp_h264_dec_open failed: %d", (int)res);
481 esp_h264_dec_del(dec_handle_);
482 dec_handle_ = nullptr;
483 return false;
484 }
485
486 return true;
487 }
488
489 /**
490 * @brief Allocate input and output buffers using configured allocator
491 * @return true if buffer allocation successful, false on error
492 * @note Allocates buffers based on Config buffer size settings
493 * @note Uses template allocator (Alloc) for memory management
494 */
495 bool initBuffers() {
496 ESP_LOGD(TAG, "initBuffers");
497 try {
498 input_buf_.clear();
499 output_buf_.clear();
500 temp_buf_.clear();
501
502 input_buf_.resize(cfg_.input_buffer_size);
503 output_buf_.resize(cfg_.output_buffer_size);
504 temp_buf_.resize(cfg_.max_read_bytes > 0 ? cfg_.max_read_bytes : 1500);
505 } catch (const std::bad_alloc& e) {
506 ESP_LOGE(TAG, "Failed to allocate buffers: %s", e.what());
507 input_buf_.clear();
508 output_buf_.clear();
509 temp_buf_.clear();
510 return false;
511 }
512 return true;
513 }
514
515 /**
516 * @brief Process decoded frame data and handle format conversion if needed
517 *
518 * @param frame_data Pointer to decoded frame data (I420 format from decoder)
519 * @param frame_size Size of frame data in bytes
520 * @return true if frame processing succeeded, false on error
521 *
522 * @note Handles format conversion from I420 to configured output format
523 * @note Calls user frame_callback if configured
524 * @note Updates internal frame state and buffers
525 */
526 bool processDecodedFrame(const uint8_t* frame_data, uint32_t frame_size) {
527 ESP_LOGD(TAG, "processDecodedFrame");
528 if (!frame_data || frame_size == 0) return false;
529
530 // Calculate required output buffer size
531 size_t required_size = frame_width_ * frame_height_ *
532 ESP_H264_GET_BPP_BY_PIC_TYPE(cfg_.output_format);
533
534 if (output_buf_.size() < required_size) {
535 output_buf_.resize(required_size);
536 }
537
538 // Handle format conversion if needed
539 if (cfg_.output_format == ESP_H264_RAW_FMT_I420) {
540 // Direct copy for I420 output
541 memcpy(output_buf_.data(), frame_data, std::min(frame_size, (uint32_t)output_buf_.size()));
542 } else {
543 // Format conversion needed (e.g., I420 to RGB565)
544 if (!convertFormat(frame_data, frame_size)) {
545 ESP_LOGE(TAG, "Format conversion failed");
546 return false;
547 }
548 }
549
550 // Call user callback if provided
551 if (cfg_.frame_callback) {
552 cfg_.frame_callback(output_buf_.data(), frame_width_, frame_height_, cfg_.output_format);
553 }
554
555 return true;
556 }
557
558 /**
559 * @brief Convert decoded I420 frame to configured output format
560 *
561 * @param i420_data Pointer to I420 frame data from decoder
562 * @param i420_size Size of I420 data in bytes
563 * @return true if conversion succeeded, false on error
564 *
565 * @note Currently supports conversion to RGB565_LE
566 * @note Additional format conversions can be added here
567 * @note Writes converted data to output_buf_
568 */
569 bool convertFormat(const uint8_t* i420_data, uint32_t i420_size) {
570 ESP_LOGD(TAG, "convertFormat");
571 switch (cfg_.output_format) {
573 return convertI420ToRGB565(i420_data, i420_size);
575 // Already handled in processDecodedFrame
576 return true;
577 default:
578 ESP_LOGE(TAG, "Unsupported output format: %d", (int)cfg_.output_format);
579 return false;
580 }
581 }
582
583 /**
584 * @brief Convert I420 frame to RGB565 format
585 *
586 * @param i420_data Pointer to I420 frame data (Y + U + V planes)
587 * @param i420_size Size of I420 data in bytes
588 * @return true if conversion succeeded, false on error
589 *
590 * @note I420 format: Y plane (width×height), U plane (width/2×height/2), V plane (width/2×height/2)
591 * @note RGB565 format: 16-bit RGB (5-6-5 bit allocation)
592 * @note Performs YUV to RGB color space conversion
593 */
594 bool convertI420ToRGB565(const uint8_t* i420_data, uint32_t i420_size) {
595 ESP_LOGD(TAG, "convertI420ToRGB565");
596 if (!i420_data || frame_width_ == 0 || frame_height_ == 0) return false;
597
598 const uint8_t* y_plane = i420_data;
599 const uint8_t* u_plane = y_plane + frame_width_ * frame_height_;
600 const uint8_t* v_plane = u_plane + (frame_width_ / 2) * (frame_height_ / 2);
601
602 uint16_t* rgb565_out = (uint16_t*)output_buf_.data();
603
604 for (uint32_t y = 0; y < frame_height_; y++) {
605 for (uint32_t x = 0; x < frame_width_; x++) {
606 // Get Y, U, V values
607 uint8_t Y = y_plane[y * frame_width_ + x];
608 uint8_t U = u_plane[(y / 2) * (frame_width_ / 2) + (x / 2)];
609 uint8_t V = v_plane[(y / 2) * (frame_width_ / 2) + (x / 2)];
610
611 // YUV to RGB conversion (ITU-R BT.601)
612 int C = Y - 16;
613 int D = U - 128;
614 int E = V - 128;
615
616 int R = (298 * C + 409 * E + 128) >> 8;
617 int G = (298 * C - 100 * D - 208 * E + 128) >> 8;
618 int B = (298 * C + 516 * D + 128) >> 8;
619
620 // Clamp to 0-255
621 R = std::max(0, std::min(255, R));
622 G = std::max(0, std::min(255, G));
623 B = std::max(0, std::min(255, B));
624
625 // Convert to RGB565 (5-6-5 bits)
626 uint16_t rgb565 = ((R & 0xF8) << 8) | ((G & 0xFC) << 3) | ((B & 0xF8) >> 3);
627 rgb565_out[y * frame_width_ + x] = rgb565;
628 }
629 }
630
631 return true;
632 }
633};
634
635/**
636 * @brief Type alias for H264Decoder using default PSRAM allocation
637 *
638 * Provides a simpler way to declare H264Decoder instances without specifying
639 * the allocator template parameter. Uses PSRAMAllocatorH264<uint8_t> by default.
640 *
641 * Example usage:
642 * @code
643 * H264DecoderPSRAM decoder(&udp); // Instead of H264Decoder<PSRAMAllocatorH264<uint8_t>>
644 * @endcode
645 */
646using H264DecoderPSRAM = H264Decoder<PSRAMAllocatorH264<uint8_t>>;
647
648/**
649 * @brief Type alias for H264Decoder using internal RAM allocation
650 *
651 * Provides a simpler way to declare H264Decoder instances that use fast
652 * internal RAM instead of external PSRAM.
653 *
654 * Example usage:
655 * @code
656 * H264DecoderRAM decoder(&udp); // Instead of H264Decoder<RAMAllocatorH264<uint8_t>>
657 * @endcode
658 */
659using H264DecoderRAM = H264Decoder<RAMAllocatorH264<uint8_t>>;
660
661} // namespace esp_h264
662
663#ifdef ARDUINO
664using namespace esp_h264;
665#endif
Template class for decoding H.264 streams to raw video frames.
Definition: H264Decoder.h:78
bool getFrame(uint8_t *dst, size_t dst_len, uint32_t &width, uint32_t &height)
Retrieve decoded frame data.
Definition: H264Decoder.h:345
uint32_t getDecodeErrors() const
Get total number of decode errors.
Definition: H264Decoder.h:387
void setInputStream(Stream *input_stream)
Set input stream for H.264 data.
Definition: H264Decoder.h:178
bool decode(const uint8_t *h264_data, size_t h264_len)
Decode H.264 data from buffer.
Definition: H264Decoder.h:259
H264Decoder(Stream &input_stream)
Constructor with input stream.
Definition: H264Decoder.h:141
bool getFrameDimensions(uint32_t &width, uint32_t &height) const
Get current frame dimensions.
Definition: H264Decoder.h:402
bool hasFrame() const
Check if a decoded frame is available.
Definition: H264Decoder.h:324
H264Decoder()
Default constructor (no input stream)
Definition: H264Decoder.h:154
bool begin(Config cfg)
Initialize H.264 decoder and allocate buffers.
Definition: H264Decoder.h:196
void end()
Cleanup and release decoder resources.
Definition: H264Decoder.h:421
bool processStream()
Process H.264 data from configured input stream.
Definition: H264Decoder.h:218
~H264Decoder()
Destructor.
Definition: H264Decoder.h:163
Config defaultConfig()
Create a default configuration with reasonable defaults.
Definition: H264Decoder.h:119
uint32_t getFrameCount() const
Get total number of successfully decoded frames.
Definition: H264Decoder.h:374
static constexpr const char * TAG
Logging tag for ESP32 log system.
Definition: H264Decoder.h:81
esp_h264_err_t esp_h264_dec_process(esp_h264_dec_handle_t dec, esp_h264_dec_in_frame_t *in_frame, esp_h264_dec_out_frame_t *out_frame)
This function performs decoding of H.264 video frames.
Definition: esp_h264_dec.c:19
esp_h264_err_t esp_h264_dec_del(esp_h264_dec_handle_t dec)
This function is used to delete an H.264 decoder.
Definition: esp_h264_dec.c:34
esp_h264_err_t esp_h264_dec_open(esp_h264_dec_handle_t dec)
This function opens an H.264 decoder in stream.
Definition: esp_h264_dec.c:12
esp_h264_err_t esp_h264_dec_close(esp_h264_dec_handle_t dec)
This function closes the H.264 decoder instance specified by dec
Definition: esp_h264_dec.c:27
struct esp_h264_dec_if * esp_h264_dec_handle_t
H.264 stream decoder handle.
Definition: esp_h264_dec.h:25
esp_h264_err_t esp_h264_dec_get_resolution(esp_h264_dec_param_handle_t handle, esp_h264_resolution_t *out_res)
This function retrieves the resolution of the video decoder specified by the handle parameter The dec...
Definition: esp_h264_dec_param.c:12
struct esp_h264_dec_param_if * esp_h264_dec_param_handle_t
It is a pointer to the H.264 decoding parameters structure.
Definition: esp_h264_dec_param.h:18
esp_h264_err_t esp_h264_dec_sw_new(const esp_h264_dec_cfg_sw_t *cfg, esp_h264_dec_handle_t *out_dec)
This function is used to create a new instance of the esp_h264_dec_t data structure,...
Definition: esp_h264_dec_sw.c:94
esp_h264_err_t esp_h264_dec_sw_get_param_hd(esp_h264_dec_handle_t dec, esp_h264_dec_param_sw_handle_t *out_param)
This function returns a pointer to the software-decoded parameter structure associated with the given...
Definition: esp_h264_dec_sw.c:132
esp_h264_dec_cfg_t esp_h264_dec_cfg_sw_t
Configuration type for software-based H.264 decoder.
Definition: esp_h264_dec_sw.h:25
@ ESP_H264_RAW_FMT_I420
Definition: esp_h264_types.h:61
@ ESP_H264_RAW_FMT_RGB565_LE
Definition: esp_h264_types.h:57
#define ESP_H264_GET_BPP_BY_PIC_TYPE(pic_type)
Get bytes per pixel (BPP) by picture type.
Definition: esp_h264_types.h:247
@ ESP_H264_ERR_OK
Definition: esp_h264_types.h:24
Definition: H264Decoder.h:31
Configuration structure for H.264 decoder and output settings.
Definition: H264Decoder.h:90
esp_h264_raw_format_t output_format
Output pixel format after decoding (I420, RGB565, etc.)
Definition: H264Decoder.h:92
size_t max_read_bytes
Maximum bytes to read per processStream() call (0 = read all available)
Definition: H264Decoder.h:101
size_t output_buffer_size
Output buffer size for decoded frame data (bytes)
Definition: H264Decoder.h:98
std::function< void(const uint8_t *frame_data, uint32_t width, uint32_t height, esp_h264_raw_format_t format)> frame_callback
Optional frame callback for real-time processing.
Definition: H264Decoder.h:105
size_t input_buffer_size
Input buffer size for H.264 stream data (bytes)
Definition: H264Decoder.h:95
esp_h264_raw_format_t pic_type
Definition: esp_h264_dec.h:19
esp_h264_pkt_t raw_data
Definition: esp_h264_types.h:228
uint32_t consume
Definition: esp_h264_types.h:229
uint32_t out_size
Definition: esp_h264_types.h:197
uint8_t * outbuf
Definition: esp_h264_types.h:196
uint8_t * buffer
Definition: esp_h264_types.h:100
uint32_t len
Definition: esp_h264_types.h:101
uint16_t height
Definition: esp_h264_types.h:119
uint16_t width
Definition: esp_h264_types.h:110