JeVois  1.0
JeVois Smart Embedded Machine Vision Toolkit
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 platform, since it does not have a display.
25 #ifndef JEVOIS_PLATFORM
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 // ##############################################################################################################
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));
53 
54  jevois::RawImage img;
55  img.width = m.ow;
56  img.height = m.oh;
57  img.fmt = m.ofmt;
58  img.buf = itsBuffers[i];
59  img.bufindex = i;
60 
61  // Push the RawImage to outside consumers:
62  itsImageQueue.push(img);
63  }
64 
65  LDEBUG("Allocated " << nbufs << " buffers");
66 
67  // Open an openCV window:
68  cv::namedWindow(itsName, CV_WINDOW_AUTOSIZE);
69 }
70 
71 // ##############################################################################################################
73 {
74  // Free all our buffers:
75  for (auto & b : itsBuffers)
76  {
77  if (b.use_count() > 1) LERROR("Ref count non zero when attempting to free VideoBuf");
78 
79  b.reset(); // VideoBuf destructor will do the memory freeing
80  }
81 
82  itsBuffers.clear();
83 
84  // Close opencv window, we need a waitKey() for it to actually close:
85  cv::waitKey(1);
86  cv::destroyWindow(itsName);
87  cv::waitKey(20);
88 }
89 
90 // ##############################################################################################################
92 {
93  // Take this buffer out of our queue and hand it over:
94  img = itsImageQueue.pop();
95  LDEBUG("Empty image " << img.bufindex << " handed over to application code for filling");
96 }
97 
98 // ##############################################################################################################
100 {
101  // OpenCV uses BGR color for display:
102  cv::Mat imgbgr;
103 
104  // Convert the image to openCV and to BGR:
105  switch (img.fmt)
106  {
107  case V4L2_PIX_FMT_YUYV:
108  {
109  cv::Mat imgcv(img.height, img.width, CV_8UC2, img.buf->data());
110  cv::cvtColor(imgcv, imgbgr, CV_YUV2BGR_YUYV);
111  }
112  break;
113 
114  case V4L2_PIX_FMT_GREY:
115  {
116  cv::Mat imgcv(img.height, img.width, CV_8UC1, img.buf->data());
117  cv::cvtColor(imgcv, imgbgr, CV_GRAY2BGR);
118  }
119  break;
120 
121  case V4L2_PIX_FMT_SRGGB8:
122  {
123  cv::Mat imgcv(img.height, img.width, CV_8UC1, img.buf->data());
124  cv::cvtColor(imgcv, imgbgr, CV_BayerBG2BGR);
125  }
126  break;
127 
128  case V4L2_PIX_FMT_RGB565:
129  {
130  cv::Mat imgcv(img.height, img.width, CV_8UC2, img.buf->data());
131  cv::cvtColor(imgcv, imgbgr, CV_BGR5652BGR);
132  }
133  break;
134 
135  default: LFATAL("Unsupported video format");
136  }
137 
138  // Display image:
139  cv::imshow(itsName, imgbgr);
140 
141  // OpenCV needs this to actually update the display. Delay is in millisec:
142  cv::waitKey(1);
143 
144  // Just push the buffer back into our queue. Note: we do not bother clearing the data or checking that the image is
145  // legit, i.e., matches one that was obtained via get():
146  itsImageQueue.push(img);
147  LDEBUG("Empty image " << img.bufindex << " ready for filling in by application code");
148 }
149 
150 // ##############################################################################################################
152 { }
153 
154 // ##############################################################################################################
156 { }
157 
158 // ##############################################################################################################
160 { }
161 
162 #else // JEVOIS_PLATFORM
163 
164 // OpenCV is not compiled with HighGui support by buildroot by default, and anyway we can't use it on the platform since
165 // it has no display, so let's not waste resources linking to it:
166 jevois::VideoDisplay::VideoDisplay(char const * displayname, size_t nbufs) :
167  itsImageQueue(nbufs), itsName(displayname)
168 { LFATAL("VideoDisplay is not supported on JeVois hardware platform"); }
169 
171 { LERROR("VideoDisplay is not supported on JeVois hardware platform"); }
172 
173 void jevois::VideoDisplay::setFormat(jevois::VideoMapping const & JEVOIS_UNUSED_PARAM(m))
174 { LFATAL("VideoDisplay is not supported on JeVois hardware platform"); }
175 
176 void jevois::VideoDisplay::get(jevois::RawImage & JEVOIS_UNUSED_PARAM(img))
177 { LFATAL("VideoDisplay is not supported on JeVois hardware platform"); }
178 
179 void jevois::VideoDisplay::send(jevois::RawImage const & JEVOIS_UNUSED_PARAM(img))
180 { LFATAL("VideoDisplay is not supported on JeVois hardware platform"); }
181 
183 { LFATAL("VideoDisplay is not supported on JeVois hardware platform"); }
184 
186 { LFATAL("VideoDisplay is not supported on JeVois hardware platform"); }
187 
189 { LFATAL("VideoDisplay is not supported on JeVois hardware platform"); }
190 
191 #endif // JEVOIS_PLATFORM
192 
#define LDEBUG(msg)
Convenience macro for users to print out console or syslog messages, DEBUG level. ...
Definition: Log.H:148
virtual ~VideoDisplay()
Virtual destructor for safe inheritance.
Definition: VideoDisplay.C:72
unsigned int osize() const
Return the size in bytes of an output image.
Definition: VideoMapping.C:51
unsigned int height
Image height in pixels.
Definition: RawImage.H:140
void setFormat(VideoMapping const &m) override
Set the video format and frame rate, allocate the buffers.
Definition: VideoDisplay.C:40
void abortStream() override
Abort streaming.
Definition: VideoDisplay.C:155
void streamOff() override
Stop streaming.
Definition: VideoDisplay.C:159
STL namespace.
unsigned int ofmt
output pixel format, or 0 for no output over USB
Definition: VideoMapping.H:43
unsigned int fmt
Pixel format as a V4L2_PIX_FMT_XXX.
Definition: RawImage.H:141
std::shared_ptr< VideoBuf > buf
The pixel data buffer.
Definition: RawImage.H:142
#define LERROR(msg)
Convenience macro for users to print out console or syslog messages, ERROR level. ...
Definition: Log.H:186
A raw image as coming from a V4L2 Camera and/or being sent out to a USB Gadget.
Definition: RawImage.H:110
Simple struct to hold video mapping definitions for the processing Engine.
Definition: VideoMapping.H:41
void streamOn() override
Start streaming.
Definition: VideoDisplay.C:151
unsigned int oh
output height
Definition: VideoMapping.H:45
VideoDisplay(char const *displayname, size_t nbufs=2)
Constructor.
Definition: VideoDisplay.C:31
#define LFATAL(msg)
Convenience macro for users to print out console or syslog messages, FATAL level. ...
Definition: Log.H:205
void send(RawImage const &img) override
Send an image out to display.
Definition: VideoDisplay.C:99
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:91
Base class for video output. Gadget, MovieOutput, VideoDisplay, and VideoOutputNone derive from it...
Definition: VideoOutput.H:27
size_t bufindex
The index of the data buffer in the kernel driver.
Definition: RawImage.H:143
unsigned int ow
output width
Definition: VideoMapping.H:44
unsigned int width
Image width in pixels.
Definition: RawImage.H:139