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 "TinyJPEGDecoder.h" // https://github.com/pschatzmann/TinyJPEG
8
16namespace audio_tools {
17
54 public:
56 decoder_.setCallback(onBlock);
57 decoder_.setUserData(this);
58 decoder_.setSwapBytes(byte_swap);
59 }
62
64
69 bool isValid(const uint8_t *data, size_t len) override {
70 return len >= 2 && data[0] == 0xFF && data[1] == 0xD8;
71 }
72
76 void setOutput(Print &out) override { p_out = &out; }
77 void setOutput(VideoOutput &out) override { p_out_video = &out; }
78
81 void setVideoFormat(VideoFormat format) override {
82 if (format != VideoFormat::RGB565) {
83 LOGW("MJPEGDecoder: unsupported VideoFormat %d - only RGB565",
84 (int)format);
85 return;
86 }
87 }
88
99 void setByteSwap(bool active) {
100 byte_swap = active;
101 decoder_.setSwapBytes(active);
102 }
103 bool byteSwap() const { return byte_swap; }
104
107 VideoInfo videoInfo() override {
108 VideoInfo info;
110 info.width = width_;
111 info.height = height_;
112 return info;
113 }
114
115 bool begin() override { return true; }
116 void end() override {}
117
121 size_t write(const uint8_t *data, size_t len) override {
122 if (pos == 0) start_ms = millis();
123 // prevent memory fragmentation, change size only if more memory is needed
124 if (img_vector.size() < pos + len) {
125 img_vector.resize(pos + len);
126 }
127 memcpy(&img_vector[pos], data, len);
128 pos += len;
129 return len;
130 }
131
140 void flush() override {
141 if (pos == 0) return;
142 if (p_out == nullptr && p_out_video == nullptr) {
143 pos = 0;
144 return;
145 }
146 uint16_t w = 0, h = 0;
147 if (decoder_.getJpgSize(&w, &h, img_vector.data(), pos) != JDR_OK ||
148 w == 0 || h == 0) {
149 LOGE("MJPEGDecoder: could not determine JPEG size");
150 pos = 0;
151 return;
152 }
153 width_ = w;
154 height_ = h;
155 size_t needed = (size_t)width_ * height_ * 2;
156 if (frame_buffer.size() < needed) {
157 frame_buffer.resize(needed);
158 if (frame_buffer.data() == nullptr) {
159 LOGE("MJPEGDecoder: frame buffer allocation failed");
160 pos = 0;
161 return;
162 }
163 }
164 if (decoder_.drawJpg(0, 0, img_vector.data(), pos) == JDR_OK) {
166 }
167 pos = 0;
168 }
169
180 bool isKeyFrame(const uint8_t *data, size_t len) override { return true; }
181
182 protected:
184 size_t pos = 0;
185 uint64_t start_ms = 0;
186 tinyjpeg::TinyJPEGDecoder decoder_;
187 Print *p_out = nullptr;
189 uint16_t width_ = 0;
190 uint16_t height_ = 0;
191 bool byte_swap = true; // see setByteSwap()
192 Vector<uint8_t> frame_buffer; // tightly packed RGB565, 2 bytes/pixel
193
197 static bool onBlock(tinyjpeg::TinyJPEGDecoder &decoder, int16_t x,
198 int16_t y, uint16_t w, uint16_t h, uint16_t *data) {
199 return static_cast<MJPEGDecoder *>(decoder.getUserData())
200 ->writeBlock(x, y, w, h, data);
201 }
202
209 bool writeBlock(int16_t x, int16_t y, uint16_t w, uint16_t h,
210 uint16_t *data) {
211 if (x < 0 || y < 0) return true;
212 uint32_t max_x = width_;
213 uint32_t max_y = height_;
214 if ((uint32_t)x >= max_x || (uint32_t)y >= max_y) return true;
215 uint32_t win_w = std::min((uint32_t)w, max_x - (uint32_t)x);
216 uint32_t win_h = std::min((uint32_t)h, max_y - (uint32_t)y);
217 uint16_t *dst = (uint16_t *)frame_buffer.data();
218 for (uint32_t row = 0; row < win_h; row++) {
219 memcpy(dst + ((uint32_t)y + row) * max_x + (uint32_t)x,
220 data + row * w, win_w * sizeof(uint16_t));
221 }
222 return true;
223 }
224
225 size_t writeToOutput(const uint8_t *data, size_t len) {
226 size_t result = 0;
227 if (p_out != nullptr) result = p_out->write(data, len);
228 if (p_out_video != nullptr) result += p_out_video->write(data, len);
229 return result;
230 }
231};
232
233} // 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 TinyJPEGDecoder (https://github.com/pschatzmann/TinyJPEG,...
Definition CodecJPEG.h:53
uint16_t height_
Definition CodecJPEG.h:190
void flush() override
Definition CodecJPEG.h:140
void setOutput(Print &out) override
Definition CodecJPEG.h:76
VideoInfo videoInfo() override
Definition CodecJPEG.h:107
bool isValid(const uint8_t *data, size_t len) override
Definition CodecJPEG.h:69
static bool onBlock(tinyjpeg::TinyJPEGDecoder &decoder, int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t *data)
Definition CodecJPEG.h:197
bool byteSwap() const
Definition CodecJPEG.h:103
Vector< uint8_t > img_vector
Definition CodecJPEG.h:183
VideoOutput * p_out_video
Definition CodecJPEG.h:188
bool byte_swap
Definition CodecJPEG.h:191
size_t pos
Definition CodecJPEG.h:184
bool writeBlock(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t *data)
Definition CodecJPEG.h:209
void end() override
Releases the decoder's resources.
Definition CodecJPEG.h:116
uint64_t start_ms
Definition CodecJPEG.h:185
size_t write(const uint8_t *data, size_t len) override
Definition CodecJPEG.h:121
size_t writeToOutput(const uint8_t *data, size_t len)
Definition CodecJPEG.h:225
VideoFormat codecFormat() override
Definition CodecJPEG.h:63
MJPEGDecoder(VideoOutput &out)
Definition CodecJPEG.h:61
void setByteSwap(bool active)
Definition CodecJPEG.h:99
Print * p_out
Definition CodecJPEG.h:187
void setVideoFormat(VideoFormat format) override
Definition CodecJPEG.h:81
bool isKeyFrame(const uint8_t *data, size_t len) override
Definition CodecJPEG.h:180
bool begin() override
Initializes the decoder (allocates its picture buffers, etc).
Definition CodecJPEG.h:115
void setOutput(VideoOutput &out) override
Definition CodecJPEG.h:77
MJPEGDecoder()
Definition CodecJPEG.h:55
uint16_t width_
Definition CodecJPEG.h:189
MJPEGDecoder(Print &out)
Definition CodecJPEG.h:60
Vector< uint8_t > frame_buffer
Definition CodecJPEG.h:192
tinyjpeg::TinyJPEGDecoder decoder_
Definition CodecJPEG.h:186
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
Provider of VideoInfo (width/height/fps/format) for whoever needs to size buffers/panel setup against...
Definition VideoOutput.h:92
Abstract class for video playback. This class is used to assemble a complete video frame in memory....
Definition VideoOutput.h:107
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 VideoOutput.h:29
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 VideoOutput.h:49
uint16_t height
Frame height in pixels.
Definition VideoOutput.h:53
uint16_t width
Frame width in pixels.
Definition VideoOutput.h:51
VideoFormat format
Video codec - VideoFormat::UNKNOWN if not (yet) determined.
Definition VideoOutput.h:58