arduino-audio-tools
Loading...
Searching...
No Matches
OutputOpenCV.h
Go to the documentation of this file.
1#pragma once
2
4#include <opencv2/core/core.hpp>
5#include <opencv2/highgui/highgui.hpp>
6#include <opencv2/imgproc/imgproc.hpp>
7
8namespace audio_tools {
9
23class OutputOpenCV : public VideoOutput {
24public:
25 OutputOpenCV() = default;
26
28 void setVideoFormat(VideoFormat format) { video_format = format; }
29
33 void setSize(uint16_t width, uint16_t height) {
34 this->width = width;
35 this->height = height;
36 }
37
46 void setVideoInfoSource(VideoInfoSource &source) override { p_info = &source; }
47
48 size_t write(const uint8_t *data, size_t len) override {
49 auto start = millis();
51 if (p_info != nullptr) {
52 VideoInfo info = p_info->videoInfo();
53 if (info.width > 0 && info.height > 0) {
54 width = info.width;
55 height = info.height;
56 }
57 }
59 displayRaw(data, len);
60 return len;
61 }
62 // Accumulates jpeg bytes for the frame currently being assembled
63 if (pos == 0) start = millis();
64 // prevent memory fragmentation, change size only if more memory is needed
65 if (img_vector.size() < pos + len) {
66 img_vector.resize(pos + len);
67 }
68 memcpy(&img_vector[pos], data, len);
69 pos += len;
71 return len;
72 }
73
78 void flush() override {
79 if (pos == 0) return;
81 pos = 0;
82 }
83
84 uint32_t getWriteTimeMs() const override { return write_time_ms; }
85
86protected:
89 uint16_t width = 0;
90 uint16_t height = 0;
91 bool create_window = true;
92 std::vector<uint8_t> img_vector;
93 const char *window = "Movie";
94 size_t pos = 0;
95 uint64_t start = 0;
96 uint32_t write_time_ms = 0;
97 std::vector<uint8_t> swap_buffer; // see displayRaw()'s RGB565 case
98
99 void ensureWindow() {
100 if (create_window) {
101 create_window = false;
102 // create image window named "My Image"
103 cv::namedWindow(window);
104 }
105 }
106
107 void displayJpeg() {
108 cv::Mat data(1, pos, CV_8UC1, (void *)&img_vector[0]);
109 // cv::InputArray input_array(img_vector);
110 cv::Mat mat = cv::imdecode(data, 0);
111 cv::imshow(window, mat);
112 // cv::pollKey();
113 cv::waitKey(1);
114 }
115
120 void displayRaw(const uint8_t *data, size_t len) {
121 if (width == 0 || height == 0) {
122 LOGE("OutputOpenCV: setSize() was not called");
123 return;
124 }
125 cv::Mat bgr;
126 switch (video_format) {
127 case VideoFormat::RGB565: {
128 // Every RGB565 producer here (H264Decoder, MPGDecoder,
129 // MJPEGDecoder) packs each pixel into a native uint16
130 // ((r<<8)|(g<<3)|(b>>3)) - little-endian in memory on a desktop
131 // x86/ARM build - but cv::COLOR_BGR5652BGR expects it
132 // byte-swapped, the same transmission order real SPI TFT panels
133 // need (see e.g. MPGDecoder::setByteSwap()/MJPEGDecoder's own).
134 // Swapped into a scratch buffer since 'data' isn't ours to
135 // modify in place.
136 size_t needed = (size_t)width * height * 2;
137 if (swap_buffer.size() < needed) swap_buffer.resize(needed);
138 const uint16_t *src = (const uint16_t *)data;
139 uint16_t *dst = (uint16_t *)swap_buffer.data();
140 size_t n = (size_t)width * height;
141 for (size_t i = 0; i < n; i++) {
142 uint16_t v = src[i];
143 dst[i] = (uint16_t)((v << 8) | (v >> 8));
144 }
145 cv::Mat raw(height, width, CV_8UC2, (void *)swap_buffer.data());
146 cv::cvtColor(raw, bgr, cv::COLOR_BGR5652BGR);
147 break;
148 }
150 case VideoFormat::RGB666: {
151 // RGB666's low 2 bits/channel are unused (left-justified in each
152 // byte, see VideoFormat) - same 3-bytes/pixel memory layout as
153 // RGB888 otherwise, so displays fine at slightly reduced precision
154 cv::Mat raw(height, width, CV_8UC3, (void *)data);
155 cv::cvtColor(raw, bgr, cv::COLOR_RGB2BGR);
156 break;
157 }
158 case VideoFormat::YUV422: {
159 cv::Mat raw(height, width, CV_8UC2, (void *)data);
160 cv::cvtColor(raw, bgr, cv::COLOR_YUV2BGR_YUYV);
161 break;
162 }
163 case VideoFormat::I420: {
164 cv::Mat raw(height + height / 2, width, CV_8UC1, (void *)data);
165 cv::cvtColor(raw, bgr, cv::COLOR_YUV2BGR_I420);
166 break;
167 }
168 default:
169 LOGE("OutputOpenCV: unsupported VideoFormat %d", (int)video_format);
170 return;
171 }
172 cv::imshow(window, bgr);
173 cv::waitKey(1);
174 }
175};
176
177} // namespace audio_tools
#define LOGE(...)
Definition AudioLoggerIDF.h:30
Display a video frame with OpenCV, to be used on the desktop - VideoFormat::MJPEG (the default) expec...
Definition OutputOpenCV.h:23
bool create_window
Definition OutputOpenCV.h:91
void flush() override
Definition OutputOpenCV.h:78
uint32_t write_time_ms
Definition OutputOpenCV.h:96
void ensureWindow()
Definition OutputOpenCV.h:99
VideoInfoSource * p_info
Definition OutputOpenCV.h:87
const char * window
Definition OutputOpenCV.h:93
size_t pos
Definition OutputOpenCV.h:94
void displayJpeg()
Definition OutputOpenCV.h:107
void setSize(uint16_t width, uint16_t height)
Definition OutputOpenCV.h:33
uint64_t start
Definition OutputOpenCV.h:95
size_t write(const uint8_t *data, size_t len) override
Definition OutputOpenCV.h:48
VideoFormat video_format
Definition OutputOpenCV.h:88
uint16_t height
Definition OutputOpenCV.h:90
std::vector< uint8_t > img_vector
Definition OutputOpenCV.h:92
void setVideoFormat(VideoFormat format)
Selects the format of the data passed to write() - see class comment.
Definition OutputOpenCV.h:28
uint16_t width
Definition OutputOpenCV.h:89
void displayRaw(const uint8_t *data, size_t len)
Definition OutputOpenCV.h:120
void setVideoInfoSource(VideoInfoSource &source) override
Definition OutputOpenCV.h:46
uint32_t getWriteTimeMs() const override
Optional: returns the time (ms) spent in the last write() call.
Definition OutputOpenCV.h:84
std::vector< uint8_t > swap_buffer
Definition OutputOpenCV.h:97
Provider of VideoInfo (width/height/fps/format) for whoever needs to size buffers/panel setup against...
Definition VideoOutput.h:92
virtual VideoInfo videoInfo()=0
Abstract class for video playback. This class is used to assemble a complete video frame in memory....
Definition VideoOutput.h:107
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