arduino-audio-tools
Loading...
Searching...
No Matches
CodecJPEG.h
Go to the documentation of this file.
1#pragma once
2
3#include <algorithm> // std::min
4
7#include "JPEGDecoder.h" // https://github.com/Bodmer/JPEGDecoder
8
16namespace audio_tools {
17
46 public:
47 MJPEGDecoder() = default;
50
54 void setOutput(Print &out) { p_out = &out; }
55 void setOutput(VideoOutput &out) { p_out_video = &out; }
56
59 void setVideoFormat(VideoFormat format) override {
60 if (format != VideoFormat::RGB565) {
61 LOGW("MJPEGDecoder: unsupported VideoFormat %d - only RGB565",
62 (int)format);
63 return;
64 }
65 }
66
69 VideoInfo videoInfo() override {
70 VideoInfo info;
72 info.width = width_;
73 info.height = height_;
74 return info;
75 }
76
77 bool begin() override { return true; }
78 void end() override {}
79
83 size_t write(const uint8_t *data, size_t len) override {
84 if (pos == 0) start_ms = millis();
85 // prevent memory fragmentation, change size only if more memory is needed
86 if (img_vector.size() < pos + len) {
87 img_vector.resize(pos + len);
88 }
89 memcpy(&img_vector[pos], data, len);
90 pos += len;
91 return len;
92 }
93
97 void flush() override {
98 if (pos == 0) return;
99 if (p_out == nullptr && p_out_video == nullptr) {
100 pos = 0;
101 return;
102 }
103 jpeg_decoder.decodeArray((const uint8_t *)&img_vector[0], pos);
104 width_ = jpeg_decoder.width;
105 height_ = jpeg_decoder.height;
107 size_t needed = (size_t)width_ * height_ * 2;
108 if (needed > 0 && frame_buffer.size() >= needed) {
110 }
111 pos = 0;
112 }
113
114 protected:
116 size_t pos = 0;
117 uint64_t start_ms = 0;
118 JPEGDecoder jpeg_decoder;
119 Print *p_out = nullptr;
121 uint16_t width_ = 0;
122 uint16_t height_ = 0;
123 Vector<uint8_t> frame_buffer; // tightly packed RGB565, 2 bytes/pixel
124
131 uint16_t mcu_w = jpeg_decoder.MCUWidth;
132 uint16_t mcu_h = jpeg_decoder.MCUHeight;
133 uint32_t max_x = jpeg_decoder.width;
134 uint32_t max_y = jpeg_decoder.height;
135 size_t needed = (size_t)max_x * max_y * 2;
136 if (frame_buffer.size() < needed) {
137 frame_buffer.resize(needed);
138 if (frame_buffer.data() == nullptr) {
139 LOGE("MJPEGDecoder: frame buffer allocation failed");
140 return;
141 }
142 }
143 uint16_t *dst = (uint16_t *)frame_buffer.data();
144 while (jpeg_decoder.read()) {
145 uint16_t *src = jpeg_decoder.pImage;
146 uint32_t mcu_x = jpeg_decoder.MCUx * mcu_w;
147 uint32_t mcu_y = jpeg_decoder.MCUy * mcu_h;
148 uint32_t win_w = std::min((uint32_t)mcu_w, max_x - mcu_x);
149 uint32_t win_h = std::min((uint32_t)mcu_h, max_y - mcu_y);
150 for (uint32_t row = 0; row < win_h; row++) {
151 memcpy(dst + (mcu_y + row) * max_x + mcu_x, src + row * mcu_w,
152 win_w * sizeof(uint16_t));
153 }
154 }
155 }
156
157 size_t writeToOutput(const uint8_t *data, size_t len) {
158 size_t result = 0;
159 if (p_out != nullptr) result = p_out->write(data, len);
160 if (p_out_video != nullptr) result += p_out_video->write(data, len);
161 return result;
162 }
163};
164
165} // namespace audio_tools
#define LOGW(...)
Definition AudioLoggerIDF.h:29
#define LOGE(...)
Definition AudioLoggerIDF.h:30
Definition Arduino.h:56
virtual size_t write(const uint8_t *data, size_t len)
Definition Arduino.h:120
Motion-JPEG video decoder: wraps JPEGDecoder (https://github.com/Bodmer/JPEGDecoder) as a VideoDecode...
Definition CodecJPEG.h:45
uint16_t height_
Definition CodecJPEG.h:122
void flush() override
Definition CodecJPEG.h:97
VideoInfo videoInfo() override
Definition CodecJPEG.h:69
Vector< uint8_t > img_vector
Definition CodecJPEG.h:115
VideoOutput * p_out_video
Definition CodecJPEG.h:120
size_t pos
Definition CodecJPEG.h:116
void decodeToFrameBuffer()
Definition CodecJPEG.h:130
void end() override
Releases the decoder's resources.
Definition CodecJPEG.h:78
uint64_t start_ms
Definition CodecJPEG.h:117
size_t write(const uint8_t *data, size_t len) override
Definition CodecJPEG.h:83
size_t writeToOutput(const uint8_t *data, size_t len)
Definition CodecJPEG.h:157
MJPEGDecoder(VideoOutput &out)
Definition CodecJPEG.h:49
void setOutput(VideoOutput &out)
Definition CodecJPEG.h:55
JPEGDecoder jpeg_decoder
Definition CodecJPEG.h:118
Print * p_out
Definition CodecJPEG.h:119
void setVideoFormat(VideoFormat format) override
Definition CodecJPEG.h:59
bool begin() override
Initializes the decoder (allocates its picture buffers, etc).
Definition CodecJPEG.h:77
void setOutput(Print &out)
Definition CodecJPEG.h:54
uint16_t width_
Definition CodecJPEG.h:121
MJPEGDecoder(Print &out)
Definition CodecJPEG.h:48
Vector< uint8_t > frame_buffer
Definition CodecJPEG.h:123
Vector implementation which provides the most important methods as defined by std::vector....
Definition Vector.h:21
bool resize(size_t newSize, T value)
Definition Vector.h:266
T * data()
Definition Vector.h:316
int size()
Definition Vector.h:178
Common interface for video decoders (e.g. H264Decoder, H264DecoderESP32S3 - CodecH264....
Definition CodecVideo.h:18
Definition Video.h:176
Abstract class for video playback. This class is used to assemble a complete video frame in memory....
Definition Video.h:192
virtual size_t write(const uint8_t *data, size_t len)=0
VideoFormat
Video codec/pixel-format identifier, shared by two unrelated uses: the (single) video stream of a con...
Definition Video.h:43
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition LMSEchoCancellationStream.h:6
uint32_t millis()
Returns the milliseconds since the start.
Definition Arduino.h:260
Basic video information (width/height/codec/frame size), analogous to AudioInfo - common to both Demu...
Definition Video.h:102
uint16_t height
Frame height in pixels.
Definition Video.h:106
uint16_t width
Frame width in pixels.
Definition Video.h:104
VideoFormat format
Video codec - VideoFormat::UNKNOWN if not (yet) determined.
Definition Video.h:111