PTLib  Version 2.18.8
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
wxWinVidDev.h
Go to the documentation of this file.
1 /*
2  * wxWinVidDev.h
3  *
4  * Classes to support video output via wxWindows
5  *
6  * Copyright (c) 2017 Equivalence Pty. Ltd.
7  *
8  * The contents of this file are subject to the Mozilla Public License
9  * Version 1.0 (the "License"); you may not use this file except in
10  * compliance with the License. You may obtain a copy of the License at
11  * http://www.mozilla.org/MPL/
12  *
13  * Software distributed under the License is distributed on an "AS IS"
14  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
15  * the License for the specific language governing rights and limitations
16  * under the License.
17  *
18  * The Original Code is Portable Tools Library.
19  *
20  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
21  *
22  * Note, is expected the application include this header in precisely
23  * one source file compiled.
24  */
25 
26 #include <ptlib/videoio.h>
27 #include <wx/rawbmp.h>
28 
29 
30 #ifndef P_WXWINDOWS_IMPLEMENTATION_ONLY
31 
32 #define P_WXWINDOWS_DRIVER_NAME "wxWindows"
33 #define P_WXWINDOWS_DEVICE_NAME "wxWindows"
34 #define P_WXWINDOWS_DEVICE_CLASS PVideoOutputDevice_##wxWindows
35 
36 
39 class P_WXWINDOWS_DEVICE_CLASS : public PVideoOutputDeviceRGB, public wxFrame
40 {
42  public:
46 
49 
52  virtual PStringArray GetDeviceNames() const;
54 
57  virtual PBoolean Open(
58  const PString & deviceName,
59  PBoolean /*startImmediate*/ = true
60  );
61 
64  virtual PBoolean Close();
65 
68  virtual PBoolean Stop();
69 
71  virtual PBoolean IsOpen();
72 
83  virtual PBoolean SetColourFormat(
84  const PString & colourFormat
85  );
86 
95  virtual PBoolean SetFrameSize(
96  unsigned width,
97  unsigned height
98  );
99 
102  virtual PBoolean FrameComplete();
103 
104  protected:
105  void InternalOpen();
106  void InternalClose();
107  void InternalFrameComplete();
108 
109  void OnClose(wxCloseEvent &);
110  void OnPaint(wxPaintEvent &);
111 
112  enum { e_Closing, e_Closed, e_Open, e_Opening } m_state; // Note order important
113  wxBitmap m_bitmap;
114 
117 };
118 
119 #endif // P_WXWINDOWS_IMPLEMENTATION_ONLY
120 
121 #ifndef P_WXWINDOWS_DECLARATION_ONLY
122 
124 
125 BEGIN_EVENT_TABLE(P_WXWINDOWS_DEVICE_CLASS, wxFrame)
126  EVT_CLOSE(P_WXWINDOWS_DEVICE_CLASS::OnClose)
127  EVT_PAINT(P_WXWINDOWS_DEVICE_CLASS::OnPaint)
128 END_EVENT_TABLE()
129 
131  virtual bool ValidateDeviceName(const PString & deviceName, P_INT_PTR /*userData*/) const
132  {
133  return deviceName.NumCompare(GetServiceName()) == PObject::EqualTo;
134  }
135 );
136 
137 
139  : m_state(e_Closed)
140 #ifdef _WIN32
141  , m_bitmap(m_frameWidth, m_frameHeight, 24)
142 #else
143  , m_bitmap(m_frameWidth, m_frameHeight, 32)
144 #endif
145 {
146  wxNativePixelData bmdata(m_bitmap);
147  m_nativeVerticalFlip = bmdata.GetRowStride() < 0;
148 }
149 
150 
152 {
153  Close();
154 }
155 
156 
158 {
159  return GetOutputDeviceNames();
160 }
161 
162 
164 {
166 }
167 
168 
169 PBoolean P_WXWINDOWS_DEVICE_CLASS::Open(const PString & deviceName, PBoolean /*startImmediate*/)
170 {
171  m_state = e_Opening;
172  m_deviceName = deviceName;
173  if (wxThread::IsMain())
174  InternalOpen();
175  else {
176  PTRACE(4, P_WXWINDOWS_DEVICE_NAME, "Opening asynchronously " << *this);
178  }
179 
180  return m_state >= e_Open;
181 }
182 
183 
185 {
186  PWaitAndSignal lock(m_mutex);
187 
189  m_state = Create(NULL, 0,
190  PwxString(ParseDeviceNameTokenString("TITLE", "Video Output")),
191  wxPoint(ParseDeviceNameTokenInt("X", -1),
192  ParseDeviceNameTokenInt("Y", -1)),
193  wxSize(GetFrameWidth(), GetFrameHeight())) ? e_Open : e_Closed;
194  PTRACE(m_state != e_Open ? 2 : 4, P_WXWINDOWS_DEVICE_NAME, "Open " << (m_state == e_Open ? "successful" : "failed") << " on " << *this);
195  }
196 }
197 
198 
200 {
201  if (!IsOpen())
202  return false;
203 
204  m_state = e_Closing;
205  if (wxThread::IsMain())
206  InternalClose();
207  else {
208  PTRACE(4, P_WXWINDOWS_DEVICE_NAME, "Closing asynchronously " << *this);
210  }
211 
212  return true;
213 }
214 
215 
217 {
218  PTRACE(4, P_WXWINDOWS_DEVICE_NAME, "Closing " << *this);
219  PWaitAndSignal lock(m_mutex);
220  wxFrame::Close(true);
221 }
222 
223 
224 void P_WXWINDOWS_DEVICE_CLASS::OnClose(wxCloseEvent & evt)
225 {
226  PWaitAndSignal lock(m_mutex);
227 
228  if (m_state == e_Closed)
229  return;
230 
231  if (evt.CanVeto())
232  evt.Veto();
233  else {
234  Destroy();
235  m_state = e_Closed;
236  PTRACE(4, P_WXWINDOWS_DEVICE_NAME, "Closed " << *this);
237  }
238 }
239 
240 
242 {
243  return Close();
244 }
245 
246 
248 {
249  return m_state >= e_Open;
250 }
251 
252 
254 {
255  PWaitAndSignal lock(m_mutex);
256  return (colourFormat *= psprintf("BGR%u", m_bitmap.GetDepth()))
258 }
259 
260 
261 PBoolean P_WXWINDOWS_DEVICE_CLASS::SetFrameSize(unsigned width, unsigned height)
262 {
263  PWaitAndSignal lock(m_mutex);
264 
265  if (width == m_frameWidth && height == m_frameHeight)
266  return true;
267 
268  if (!PVideoOutputDeviceRGB::SetFrameSize(width, height))
269  return false;
270 
271  if (IsOpen()) {
272  if (!m_bitmap.Create(m_frameWidth, m_frameHeight, m_bitmap.GetDepth())) {
273  PTRACE(1, P_WXWINDOWS_DEVICE_NAME, "Cannot copy frame, wxBitmap create failed on " << *this);
274  return false;
275  }
276 
277  PTRACE(4, P_WXWINDOWS_DEVICE_NAME, "Resized wxBitmap to " << m_frameWidth << 'x' << m_frameHeight << " on " << *this);
278  }
279 
280  return true;
281 }
282 
283 
285 {
286  PWaitAndSignal lock(m_mutex);
287 
288  if (!IsOpen())
289  return false;
290 
291  wxNativePixelData bmdata(m_bitmap);
292  wxNativePixelData::Iterator it = bmdata.GetPixels();
293  if (!it.IsOk()) {
294  PTRACE(1, P_WXWINDOWS_DEVICE_NAME, "Cannot copy frame, wxBitmap invalid on " << *this);
295  return false;
296  }
297 
298  if (bmdata.GetRowStride() < 0)
299  it.Offset(bmdata, 0, m_frameHeight - 1);
300  memcpy((BYTE *)&it.Data(), m_frameStore.GetPointer(), m_frameStore.GetSize());
301 
303  return true;
304 }
305 
306 
308 {
309  PWaitAndSignal lock(m_mutex);
310 
311  if (IsOpen()) {
312  wxSize sz = GetClientSize();
313  if (sz.GetWidth() != m_bitmap.GetWidth() || sz.GetHeight() != m_bitmap.GetHeight()) {
314  PTRACE(4, P_WXWINDOWS_DEVICE_NAME, "Resized window to " << m_bitmap.GetWidth() << 'x' << m_bitmap.GetHeight() << " on " << *this);
315  SetClientSize(m_bitmap.GetWidth(), m_bitmap.GetHeight());
316  }
317  Show(true);
318  Refresh(false);
319  }
320 }
321 
322 
324 {
325  PWaitAndSignal lock(m_mutex);
326 
327  if (IsOpen() && PAssert(m_bitmap.IsOk(), PLogicError)) {
328  wxPaintDC pDC(this);
329  wxMemoryDC bmDC;
330  bmDC.SelectObject(m_bitmap);
331  if (pDC.Blit(0, 0, m_bitmap.GetWidth(), m_bitmap.GetHeight(), &bmDC, 0, 0))
332  PTRACE(5, P_WXWINDOWS_DEVICE_NAME, "Updated screen on " << *this);
333  else
334  PTRACE(1, P_WXWINDOWS_DEVICE_NAME, "Cannot update screen, Blit failed on " << *this);
335  }
336 }
337 
338 
339 #endif // P_WXWINDOWS_DECLARATION_ONLY
340 
341 // End Of File ///////////////////////////////////////////////////////////////
static PStringArray GetOutputDeviceNames()
Definition: wxWinVidDev.h:163
unsigned m_frameWidth
Definition: videoio.h:266
This class defines a class to bridge WX Widgets strings to PTLib strings.
Definition: wxstring.h:34
This class waits for the semaphore on construction and automatically signals the semaphore on destruc...
Definition: psync.h:115
wxDECLARE_DYNAMIC_CLASS(P_WXWINDOWS_DEVICE_CLASS)
Definition: object.h:2253
void OnClose(wxCloseEvent &)
Definition: wxWinVidDev.h:224
Definition: wxWinVidDev.h:112
virtual PStringArray GetDeviceNames() const
Get a list of all of the devices available.
Definition: wxWinVidDev.h:157
#define P_WXWINDOWS_DEVICE_NAME
Definition: wxWinVidDev.h:33
int ParseDeviceNameTokenInt(const char *token, int defaultValue)
virtual unsigned GetFrameHeight() const
Get the height of the frame being used.
virtual PBoolean FrameComplete()
Set a section of the output frame buffer.
Definition: wxWinVidDev.h:284
void InternalOpen()
Definition: wxWinVidDev.h:184
~P_WXWINDOWS_DEVICE_CLASS()
Destroy the device, make sure it is closed.
Definition: wxWinVidDev.h:151
PString ParseDeviceNameTokenString(const char *token, const char *defaultValue)
virtual PBoolean SetColourFormat(const PString &colourFormat)
Set the colour format to be used.
This is an array collection class of PString objects.
Definition: pstring.h:2365
void InternalFrameComplete()
Definition: wxWinVidDev.h:307
virtual PBoolean IsOpen()
Indicate if this video rendering class is open.
Definition: wxWinVidDev.h:247
PCaselessString m_deviceName
Definition: videoio.h:684
#define PTRACE(...)
Output trace.
Definition: object.h:1039
unsigned m_frameHeight
Definition: videoio.h:267
virtual PBoolean Close()
Synonymous with the destructor.
Definition: wxWinVidDev.h:199
Display data to the wxWindows window.
Definition: wxWinVidDev.h:39
void InternalClose()
Definition: wxWinVidDev.h:216
Definition: wxWinVidDev.h:112
virtual PINDEX GetSize() const
Get the current size of the container.
bool PBoolean
Definition: object.h:174
virtual PBoolean Open(const PString &deviceName, PBoolean=true)
Open the device given the device name.
Definition: wxWinVidDev.h:169
intptr_t P_INT_PTR
Definition: object.h:2646
The character string class.
Definition: pstring.h:108
virtual PBoolean SetFrameSize(unsigned width, unsigned height)
Set the frame size to be used.
T * GetPointer(PINDEX minSize=0)
Get a pointer to the internal array and assure that it is of at least the specified size...
Definition: array.h:366
virtual PBoolean SetFrameSize(unsigned width, unsigned height)
Set the frame size to be used.
Definition: wxWinVidDev.h:261
virtual PBoolean Stop()
Stop the video device I/O display.
Definition: wxWinVidDev.h:241
This class defines a video output device for RGB in a frame store.
Definition: videoio.h:879
virtual PBoolean SetColourFormat(const PString &colourFormat)
Set the colour format to be used.
Definition: wxWinVidDev.h:253
PCREATE_VIDOUTPUT_PLUGIN_EX(wxWindows, virtual bool ValidateDeviceName(const PString &deviceName, P_INT_PTR) const {return deviceName.NumCompare(GetServiceName())==PObject::EqualTo;})
Definition: wxWinVidDev.h:112
bool m_nativeVerticalFlip
Definition: videoio.h:689
PBYTEArray m_frameStore
Definition: videoio.h:692
virtual unsigned GetFrameWidth() const
Get the width of the frame being used.
wxBitmap m_bitmap
Definition: wxWinVidDev.h:113
#define PAssert(b, msg)
This macro is used to assert that a condition must be true.
Definition: object.h:400
P_WXWINDOWS_DEVICE_CLASS()
Constructor.
Definition: wxWinVidDev.h:138
wxIMPLEMENT_DYNAMIC_CLASS(P_WXWINDOWS_DEVICE_CLASS, wxFrame)
void OnPaint(wxPaintEvent &)
Definition: wxWinVidDev.h:323
PString psprintf(const char *fmt,...)
The same as the standard C snprintf(fmt, 1000, ...), but returns a PString instead of a const char *...
enum P_WXWINDOWS_DEVICE_CLASS::@43 m_state
A logic error occurred.
Definition: object.h:370
Definition: wxWinVidDev.h:112