JeVois  1.20
JeVois Smart Embedded Machine Vision Toolkit
Share this page:
VideoDisplay.C
Go to the documentation of this file.
1 // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2 //
3 // JeVois Smart Embedded Machine Vision Toolkit - Copyright (C) 2016 by Laurent Itti, the University of Southern
4 // California (USC), and iLab at USC. See http://iLab.usc.edu and http://jevois.org for information about this project.
5 //
6 // This file is part of the JeVois Smart Embedded Machine Vision Toolkit. This program is free software; you can
7 // redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software
8 // Foundation, version 2. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9 // without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
10 // License for more details. You should have received a copy of the GNU General Public License along with this program;
11 // if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
12 //
13 // Contact information: Laurent Itti - 3641 Watt Way, HNB-07A - Los Angeles, CA 90089-2520 - USA.
14 // Tel: +1 213 740 3527 - itti@pollux.usc.edu - http://iLab.usc.edu - http://jevois.org
15 // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
16 /*! \file */
17 
19 #include <jevois/Debug/Log.H>
20 #include <jevois/Util/Utils.H>
21 
22 #include <linux/videodev2.h>
23 
24 // Do not compile any highgui-dependent code on the JeVois-A33 platform, since it does not have a display.
25 #ifndef JEVOIS_PLATFORM_A33
26 #include <opencv2/core/core.hpp>
27 #include <opencv2/highgui/highgui.hpp>
28 #include <opencv2/imgproc/imgproc.hpp>
29 
30 // ##############################################################################################################
31 jevois::VideoDisplay::VideoDisplay(char const * displayname, size_t nbufs) :
32  jevois::VideoOutput(), itsImageQueue(std::max(size_t(2), nbufs)), itsName(displayname)
33 {
34  // Open an openCV window:
35  cv::namedWindow(itsName, cv::WINDOW_AUTOSIZE); // autosize keeps the original size
36  //cv::namedWindow(itsName, cv::WINDOW_NORMAL | cv::WINDOW_KEEPRATIO); // normal can be resized
37 }
38 
39 // ##############################################################################################################
40 void jevois::VideoDisplay::setFormat(jevois::VideoMapping const & m)
41 {
42  // Nuke any old buffers:
43  itsBuffers.clear();
44  itsImageQueue.clear();
45  size_t const nbufs = itsImageQueue.size();
46 
47  // Allocate the buffers and make them all immediately available as RawImage:
48  unsigned int imsize = m.osize();
49 
50  for (size_t i = 0; i < nbufs; ++i)
51  {
52  itsBuffers.push_back(std::make_shared<jevois::VideoBuf>(-1, imsize, 0, -1));
53 
54  jevois::RawImage img;
55  img.width = m.ow;
56  img.height = m.oh;
57  img.fmt = m.ofmt;
58  img.fps = m.ofps;
59  img.buf = itsBuffers[i];
60  img.bufindex = i;
61 
62  // Push the RawImage to outside consumers:
63  itsImageQueue.push(img);
64  }
65 
66  LDEBUG("Allocated " << nbufs << " buffers");
67 
68  // Open an openCV window:
69  cv::namedWindow(itsName, cv::WINDOW_AUTOSIZE);
70 }
71 
72 // ##############################################################################################################
74 {
75  // Free all our buffers:
76  for (auto & b : itsBuffers)
77  {
78  if (b.use_count() > 1) LERROR("Ref count non zero when attempting to free VideoBuf");
79 
80  b.reset(); // VideoBuf destructor will do the memory freeing
81  }
82 
83  itsBuffers.clear();
84 
85  // Close opencv window, we need a waitKey() for it to actually close:
86  cv::waitKey(1);
87  cv::destroyWindow(itsName);
88  cv::waitKey(20);
89 }
90 
91 // ##############################################################################################################
93 {
94  // Take this buffer out of our queue and hand it over:
95  img = itsImageQueue.pop();
96  LDEBUG("Empty image " << img.bufindex << " handed over to application code for filling");
97 }
98 
99 // ##############################################################################################################
101 {
102  // OpenCV uses BGR color for display:
103  cv::Mat imgbgr;
104 
105  // Convert the image to openCV and to BGR:
106  switch (img.fmt)
107  {
108  case V4L2_PIX_FMT_YUYV:
109  {
110  cv::Mat imgcv(img.height, img.width, CV_8UC2, img.buf->data());
111  cv::cvtColor(imgcv, imgbgr, cv::COLOR_YUV2BGR_YUYV);
112  }
113  break;
114 
115  case V4L2_PIX_FMT_GREY:
116  {
117  cv::Mat imgcv(img.height, img.width, CV_8UC1, img.buf->data());
118  cv::cvtColor(imgcv, imgbgr, cv::COLOR_GRAY2BGR);
119  }
120  break;
121 
122  case V4L2_PIX_FMT_SRGGB8:
123  {
124  cv::Mat imgcv(img.height, img.width, CV_8UC1, img.buf->data());
125  cv::cvtColor(imgcv, imgbgr, cv::COLOR_BayerBG2BGR);
126  }
127  break;
128 
129  case V4L2_PIX_FMT_RGB565:
130  {
131  cv::Mat imgcv(img.height, img.width, CV_8UC2, img.buf->data());
132  cv::cvtColor(imgcv, imgbgr, cv::COLOR_BGR5652BGR);
133  }
134  break;
135 
136  default: LFATAL("Unsupported video format");
137  }
138 
139  // Display image:
140  cv::imshow(itsName, imgbgr);
141 
142  // OpenCV needs this to actually update the display. Delay is in millisec:
143  cv::waitKey(1);
144 
145  // Just push the buffer back into our queue. Note: we do not bother clearing the data or checking that the image is
146  // legit, i.e., matches one that was obtained via get():
147  itsImageQueue.push(img);
148  LDEBUG("Empty image " << img.bufindex << " ready for filling in by application code");
149 }
150 
151 // ##############################################################################################################
153 { }
154 
155 // ##############################################################################################################
157 { }
158 
159 // ##############################################################################################################
161 { }
162 
163 #else // JEVOIS_PLATFORM_A33
164 
165 // OpenCV is not compiled with HighGui support by buildroot by default, and anyway we can't use it on the platform since
166 // it has no display, so let's not waste resources linking to it:
167 jevois::VideoDisplay::VideoDisplay(char const * displayname, size_t nbufs) :
168  itsImageQueue(nbufs), itsName(displayname)
169 { LFATAL("VideoDisplay is not supported on JeVois hardware platform"); }
170 
172 { LERROR("VideoDisplay is not supported on JeVois hardware platform"); }
173 
174 void jevois::VideoDisplay::setFormat(jevois::VideoMapping const & JEVOIS_UNUSED_PARAM(m))
175 { LFATAL("VideoDisplay is not supported on JeVois hardware platform"); }
176 
177 void jevois::VideoDisplay::get(jevois::RawImage & JEVOIS_UNUSED_PARAM(img))
178 { LFATAL("VideoDisplay is not supported on JeVois hardware platform"); }
179 
180 void jevois::VideoDisplay::send(jevois::RawImage const & JEVOIS_UNUSED_PARAM(img))
181 { LFATAL("VideoDisplay is not supported on JeVois hardware platform"); }
182 
184 { LFATAL("VideoDisplay is not supported on JeVois hardware platform"); }
185 
187 { LFATAL("VideoDisplay is not supported on JeVois hardware platform"); }
188 
190 { LFATAL("VideoDisplay is not supported on JeVois hardware platform"); }
191 
192 #endif // JEVOIS_PLATFORM_A33
193 
LDEBUG
#define LDEBUG(msg)
Convenience macro for users to print out console or syslog messages, DEBUG level.
Definition: Log.H:173
jevois::VideoDisplay::streamOn
void streamOn() override
Start streaming.
Definition: VideoDisplay.C:183
jevois::RawImage
A raw image as coming from a V4L2 Camera and/or being sent out to a USB Gadget.
Definition: RawImage.H:110
jevois::RawImage::bufindex
size_t bufindex
The index of the data buffer in the kernel driver.
Definition: RawImage.H:150
jevois::RawImage::fps
float fps
Programmed frames/s as given by current video mapping, may not be actual.
Definition: RawImage.H:148
LERROR
#define LERROR(msg)
Convenience macro for users to print out console or syslog messages, ERROR level.
Definition: Log.H:211
jevois::VideoDisplay::setFormat
void setFormat(VideoMapping const &m) override
Set the video format and frame rate, allocate the buffers.
Definition: VideoDisplay.C:174
jevois::VideoDisplay::send
void send(RawImage const &img) override
Send an image out to display.
Definition: VideoDisplay.C:180
jevois::RawImage::width
unsigned int width
Image width in pixels.
Definition: RawImage.H:145
jevois::VideoDisplay::get
void get(RawImage &img) override
Get a pre-allocated image so that we can fill the pixel data and later send out using send()
Definition: VideoDisplay.C:177
jevois
Definition: Concepts.dox:1
Log.H
LFATAL
#define LFATAL(msg)
Convenience macro for users to print out console or syslog messages, FATAL level.
jevois::VideoDisplay::~VideoDisplay
virtual ~VideoDisplay()
Virtual destructor for safe inheritance.
Definition: VideoDisplay.C:171
jevois::RawImage::height
unsigned int height
Image height in pixels.
Definition: RawImage.H:146
jevois::RawImage::fmt
unsigned int fmt
Pixel format as a V4L2_PIX_FMT_XXX.
Definition: RawImage.H:147
Utils.H
jevois::RawImage::buf
std::shared_ptr< VideoBuf > buf
The pixel data buffer.
Definition: RawImage.H:149
jevois::VideoDisplay::VideoDisplay
VideoDisplay(char const *displayname, size_t nbufs=2)
Constructor.
Definition: VideoDisplay.C:167
jevois::VideoDisplay::abortStream
void abortStream() override
Abort streaming.
Definition: VideoDisplay.C:186
VideoDisplay.H
jevois::VideoDisplay::streamOff
void streamOff() override
Stop streaming.
Definition: VideoDisplay.C:189