VideoTools
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
gvcapture_test.cpp
Go to the documentation of this file.
1 //
2 // Copyright (C) 2017 Graeme Walker
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 // ===
17 //
18 // gvcapture_test.cpp
19 //
20 
21 #include "gdef.h"
22 #include "gvcapture.h"
23 #include "gvcapture_test.h"
24 #include "gmsg.h"
25 #include "gassert.h"
26 #include <stdexcept>
27 #include <sys/types.h>
28 #include <sys/socket.h>
29 #include <fcntl.h>
30 
31 namespace
32 {
33  int dx_() { return 640 ; }
34  int dy_() { return 480 ; }
35  size_t size( size_t channels ) { return channels * 640U * 480U ; }
36  size_t rowsize( size_t channels ) { return channels * 640U ; }
37 }
38 
39 Gv::CaptureTest::CaptureTest( const std::string & config , ImageGenerator * generator ) :
40  m_generator(generator) ,
41  m_capturing(false) ,
42  m_fd_read(-1) ,
43  m_fd_write(-1) ,
44  m_format(99U) ,
45  m_config(config) ,
46  m_timer(*this,&Gv::CaptureTest::onTimeout,*this)
47 {
48  bool rgb = generator->init() ;
49  if( rgb )
50  {
51  // RGB24
52  m_buffer.reset( new CaptureBuffer(size(3U)) ) ;
53  m_scale = CaptureBufferScale( size(3U) , rowsize(3U) , dx_() , dy_() ) ;
54  m_format = CaptureBufferFormat( 0 , "" , CaptureBufferFormat::rgb ,
55  // offset,x-shift,y-shift,step
56  CaptureBufferComponent( 0 , 0 , 0 , 3 ) ,
57  CaptureBufferComponent( 1 , 0 , 0 , 3 ) ,
58  CaptureBufferComponent( 2 , 0 , 0 , 3 ) ) ;
59  }
60  else
61  {
62  // YUYV (YUV422)
63  m_buffer.reset( new CaptureBuffer(size(2U)) ) ;
64  m_scale = CaptureBufferScale( size(2U) , rowsize(2U) , dx_() , dy_() ) ;
65  m_format = CaptureBufferFormat( 0 , "" , CaptureBufferFormat::yuv ,
66  // offset,x-shift,y-shift,step
67  CaptureBufferComponent( 0 , 0 , 0 , 2 ) ,
68  CaptureBufferComponent( 1 , 1 , 0 , 4 ) ,
69  CaptureBufferComponent( 3 , 1 , 0 , 4 ) ) ;
70  }
71 
72  createSockets() ;
73  start() ;
74 }
75 
77 {
78  delete m_generator ;
79  ::close( m_fd_read ) ;
80  ::close( m_fd_write ) ;
81 }
82 
84 {
85  return dx_() ;
86 }
87 
89 {
90  return dy_() ;
91 }
92 
93 unsigned int Gv::CaptureTest::dx() const
94 {
95  return static_cast<unsigned int>(dx_()) ;
96 }
97 
98 unsigned int Gv::CaptureTest::dy() const
99 {
100  return static_cast<unsigned int>(dy_()) ;
101 }
102 
103 void Gv::CaptureTest::onTimeout()
104 {
105  if( m_capturing )
106  raiseEvent() ;
107 }
108 
109 void Gv::CaptureTest::onException( std::exception & )
110 {
111  throw ;
112 }
113 
114 bool Gv::CaptureTest::createSockets()
115 {
116  int fds[2] ;
117  int rc = ::socketpair( AF_LOCAL , SOCK_DGRAM , 0 , fds ) ;
118  if( rc != 0 ) throw std::runtime_error( "socketpair error" ) ;
119  m_fd_read = fds[0] ;
120  m_fd_write = fds[1] ;
121  ::fcntl( m_fd_read , F_SETFL , ::fcntl(m_fd_read,F_GETFL) | O_NONBLOCK ) ;
122  ::fcntl( m_fd_write , F_SETFL , ::fcntl(m_fd_write,F_GETFL) | O_NONBLOCK ) ;
123  return true ;
124 }
125 
126 void Gv::CaptureTest::raiseEvent()
127 {
128  if( m_fd_write != -1 )
129  G::Msg::send( m_fd_write , "" , 1U , 0 ) ;
130 }
131 
133 {
134  if( !m_capturing )
135  {
136  m_capturing = true ;
137  raiseEvent() ;
138  }
139 }
140 
141 void Gv::CaptureTest::flushEvents()
142 {
143  char c ;
144  ssize_t nread ;
145  while( ( nread = G::Msg::recv( m_fd_read , &c , 1U , 0 ) ) == 1 ) ;
146 }
147 
149 {
150  if( m_capturing )
151  {
152  flushEvents() ;
153  m_capturing = false ;
154  }
155 }
156 
158 {
159  return m_capturing ;
160 }
161 
162 std::string Gv::CaptureTest::info() const
163 {
164  return std::string() ;
165 }
166 
167 void Gv::CaptureTest::readSocket()
168 {
169  char c ;
170  ssize_t nread = G::Msg::recv( m_fd_read , &c , 1U , 0 ) ;
171  if( nread != 1 )
172  throw std::runtime_error( "recv error" ) ;
173  if( m_capturing )
174  m_timer.startTimer( 0 , 30000U ) ; // keep going -- set a maximum frame rate
175 }
176 
178 {
179  return false ;
180 }
181 
182 bool Gv::CaptureTest::read( unsigned char * , size_t )
183 {
184  return false ;
185 }
186 
188 {
189  // do the event handling
190  readSocket() ;
191 
192  // create the image
193  m_buffer->setFormat( m_format , m_scale ) ;
194  m_generator->fillBuffer( *m_buffer.get() , m_scale ) ;
195 
196  // callback op()()
197  callback( *m_buffer.get() ) ;
198 
199  return true ;
200 }
201 
203 {
204  return m_fd_read ;
205 }
206 
207 /// \file gvcapture_test.cpp
triple< unsigned char > rgb(triple< unsigned char > yuv) g__noexcept
A top-level function that calculates rgb from yuv with default implementation options.
virtual bool simple() const override
Override from Capture.
virtual unsigned int dx() const override
Override from Capture.
static ssize_t send(int, const void *, size_t, int, int fd_to_send=-1)
A send() replacement using sendmsg().
Definition: gmsg.cpp:32
A descriptor for a v4l pixel format.
An abstract interface for filling a YUYV capture buffer with a generated image.
virtual void start() override
Override from Capture.
virtual int fd() const override
Override from Capture.
A video-capture buffer class to hold image data, with overloaded constructors for the various V4l i/o...
virtual bool init()=0
Initialisation function. Returns true for rgb, false for yuyv.
A structure holding capture buffer dimensions.
virtual bool read(unsigned char *, size_t) override
Override from Capture.
virtual bool active() const override
Override from Capture.
A callback interface for the Gv::Capture class.
Definition: gvcapture.h:99
virtual void stop() override
Override from Capture.
virtual ~CaptureTest()
Destructor.
CaptureTest(const std::string &config, ImageGenerator *)
Constructor.
A Gv::Capture implementation that serves up dummy frames created by a Gv::ImageGenerator.
virtual std::string info() const override
Override from Capture.
virtual unsigned int dy() const override
Override from Capture.
A descriptor for one colour component in a Gv::CaptureBufferFormat structure.
static ssize_t recv(int, void *, size_t, int, int *fd_received_p=nullptr)
A recv() replacement using recvmsg().
Definition: gmsg.cpp:76