1 /*
2  * pvidchan.cxx
3  *
4  * Video Channel implementation.
5  *
6  * Portable Windows Library
7  *
8  * Copyright (c) 1993-1998 Equivalence Pty. Ltd.
9  *
10  * The contents of this file are subject to the Mozilla Public License
11  * Version 1.0 (the "License"); you may not use this file except in
12  * compliance with the License. You may obtain a copy of the License at
13  * http://www.mozilla.org/MPL/
14  *
15  * Software distributed under the License is distributed on an "AS IS"
16  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
17  * the License for the specific language governing rights and limitations
18  * under the License.
19  *
20  * The Original Code is Portable Windows Library.
21  *
22  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
23  *
24  * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
25  * All Rights Reserved.
26  *
27  * Contributor(s): Derek Smithies (derek@indranet.co.nz)
28  *
29  * $Revision: 24459 $
30  * $Author: shorne $
31  * $Date: 2010-06-06 08:59:59 -0500 (Sun, 06 Jun 2010) $
32  */
33 
34 #ifdef __GNUC__
35 #pragma implementation "video.h"
36 #endif
37 
38 #include <ptlib.h>
39 
40 #if P_VIDEO
41 
42 #include <ptlib/video.h>
43 
PVideoChannel()44 PVideoChannel::PVideoChannel()
45 {
46   mpInput = NULL;
47   mpOutput = NULL;
48 }
49 
50 
PVideoChannel(const PString & device,Directions dir)51 PVideoChannel::PVideoChannel(const PString & device,
52                              Directions dir)
53 {
54   mpInput = NULL;
55   mpOutput = NULL;
56   Open(device, dir);
57 }
58 
~PVideoChannel()59 PVideoChannel::~PVideoChannel()
60 {
61   Close();
62 }
63 
64 
GetDeviceNames(Directions)65 PStringArray PVideoChannel::GetDeviceNames(Directions /*dir*/)
66 {
67   return PString("Video Channel Base");
68 }
69 
70 
GetDefaultDevice(Directions)71 PString PVideoChannel::GetDefaultDevice(Directions /*dir*/)
72 {
73 #if defined(P_FREEBSD) || defined(P_OPENBSD)
74   return "/dev/bktr0";
75 #endif
76 
77 #ifndef DEFAULT_VIDEO
78      return "/dev/video0";
79 #else
80   return DEFAULT_VIDEO;
81 #endif
82 }
83 
84 
Open(const PString & dev,Directions dir)85 PBoolean PVideoChannel::Open(const PString & dev,
86                          Directions dir)
87 {
88   PWaitAndSignal m(accessMutex);
89 
90   Close();
91 
92   deviceName = dev;
93   direction = dir;
94 
95   return PTrue;
96 }
97 
98 
99 
Read(void * buf,PINDEX len)100 PBoolean PVideoChannel::Read(void * buf, PINDEX  len)
101 {
102   PWaitAndSignal m(accessMutex);
103 
104   if (mpInput == NULL)
105     return PFalse;
106 
107   BYTE * dataBuf;
108   PINDEX dataLen;
109   dataBuf = (BYTE *)buf;
110   dataLen = len;
111   return mpInput->GetFrameData(dataBuf, &dataLen);
112 
113   // CHANGED  return PTrue;
114 }
115 
Write(const void * buf,PINDEX len)116 PBoolean PVideoChannel::Write(const void * buf,  //image data to be rendered
117                           PINDEX len )
118 {
119 	return Write(buf, len, 0);
120 }
121 
Write(const void * buf,PINDEX,void * mark)122 PBoolean PVideoChannel::Write(const void * buf, PINDEX /*len*/, void * mark)
123 {
124   PWaitAndSignal m(accessMutex);
125 
126   if (mpOutput == NULL)
127     return PFalse;
128 
129 
130   if (mpInput == NULL) {
131     PTRACE(6,"PVC\t::Write, frame size is "
132               << mpOutput->GetFrameWidth() << "x" << mpOutput->GetFrameHeight() <<
133               " VideoGrabber is unavailable");
134     return mpOutput->SetFrameData(0, 0,
135         mpOutput->GetFrameWidth(), mpOutput->GetFrameHeight(),
136         mpOutput->GetSarWidth(),   mpOutput->GetSarHeight(),
137         (const BYTE *)buf, PTrue,0, mark);
138   }
139 
140   PTRACE(6,"PVC\t::Write, frame size is "
141                << mpInput->GetFrameWidth() << "x" << mpInput->GetFrameHeight() <<
142                " VideoGrabber is source of size");
143   return mpOutput->SetFrameData(0, 0,
144         mpInput->GetFrameWidth(), mpInput->GetFrameHeight(),
145         mpInput->GetSarWidth(),   mpInput->GetSarHeight(),
146            (const BYTE *)buf, PTrue,0, mark);
147 
148 }
149 
Close()150 PBoolean PVideoChannel::Close()
151 {
152   PWaitAndSignal m(accessMutex);
153 
154   CloseVideoReader();
155   CloseVideoPlayer();
156 
157   return PTrue;
158 }
159 
160 /*returns true if either input or output is open */
IsOpen() const161 PBoolean PVideoChannel::IsOpen() const
162 {
163    PWaitAndSignal m(accessMutex);
164 
165    return (mpInput != NULL) || (mpOutput != NULL);
166 }
167 
168 
GetName() const169 PString PVideoChannel::GetName() const
170 {
171   return deviceName;
172 }
173 
AttachVideoPlayer(PVideoOutputDevice * device,PBoolean keepCurrent)174 void PVideoChannel::AttachVideoPlayer(PVideoOutputDevice * device, PBoolean keepCurrent)
175 {
176   PWaitAndSignal m(accessMutex);
177 
178   if (mpOutput && keepCurrent)
179     PAssertAlways("Error: Attempt to add video player while one is already defined");
180 
181   CloseVideoPlayer();
182 
183   mpOutput = device;
184 }
185 
AttachVideoReader(PVideoInputDevice * device,PBoolean keepCurrent)186 void PVideoChannel::AttachVideoReader(PVideoInputDevice * device, PBoolean keepCurrent)
187 {
188   PWaitAndSignal m(accessMutex);
189 
190   if ((mpInput != NULL) && keepCurrent)
191     PAssertAlways("Error: Attempt to add video reader while one is already defined");
192 
193   CloseVideoReader();
194 
195   mpInput = device;
196 }
197 
CloseVideoPlayer()198 void PVideoChannel::CloseVideoPlayer()
199 {
200   PWaitAndSignal m(accessMutex);
201 
202   if (mpOutput != NULL)
203     delete mpOutput;
204 
205   mpOutput = NULL;
206 }
207 
CloseVideoReader()208 void PVideoChannel::CloseVideoReader()
209 {
210   PWaitAndSignal m(accessMutex);
211 
212   if (mpInput != NULL)
213     delete mpInput;
214 
215   mpInput = NULL;
216 }
217 
GetGrabHeight()218 PINDEX  PVideoChannel::GetGrabHeight()
219 {
220    PWaitAndSignal m(accessMutex);
221    if (mpInput != NULL)
222      return mpInput->GetFrameHeight();
223    else
224      return 0;
225 }
226 
227 
GetGrabWidth()228 PINDEX  PVideoChannel::GetGrabWidth()
229 {
230    PWaitAndSignal m(accessMutex);
231 
232    if (mpInput != NULL)
233      return mpInput->GetFrameWidth();
234    else
235      return 0;
236 }
237 
IsGrabberOpen()238 PBoolean PVideoChannel::IsGrabberOpen()
239 {
240   PWaitAndSignal m(accessMutex);
241 
242   if (mpInput != NULL)
243     return mpInput->IsOpen();
244   else
245     return PFalse;
246 }
247 
IsRenderOpen()248 PBoolean PVideoChannel::IsRenderOpen()
249 {
250   PWaitAndSignal m(accessMutex);
251 
252   if (mpOutput != NULL)
253     return mpOutput->IsOpen();
254   else
255     return PFalse;
256 }
257 
DisableDecode()258 PBoolean PVideoChannel::DisableDecode()
259 {
260   if (mpOutput != NULL)
261     return mpOutput->DisableDecode();
262   else
263     return PFalse;
264 }
265 
DisplayRawData(void * videoBuffer)266 PBoolean PVideoChannel::DisplayRawData(void *videoBuffer)
267 {
268   PWaitAndSignal m(accessMutex);
269 
270   if ((mpOutput == NULL) || (mpInput == NULL))
271     return PFalse;
272 
273   PINDEX length=0;
274 
275   int frameWidth  = GetGrabWidth();
276   int frameHeight = GetGrabHeight();
277   PTRACE(6,"Video\t data direct:: camera-->render, size " << frameWidth << "x" << frameHeight );
278 
279   // TODO sar default to 1:1
280   SetRenderFrameSize(frameWidth, frameHeight);
281   Read(videoBuffer, length);
282   Write((const void *)videoBuffer, length);
283 
284   return PTrue;
285 }
286 
SetGrabberFrameSize(int _width,int _height)287 void  PVideoChannel::SetGrabberFrameSize(int _width, int _height)
288 {
289   PTRACE(6, "PVC\t Set Grabber frame size to " << _width << "x" << _height);
290   PWaitAndSignal m(accessMutex);
291 
292   if (mpInput != NULL) {
293     if ((GetGrabWidth() != _width) || (GetGrabHeight() != _height))
294       mpInput->SetFrameSize((unsigned)_width, (unsigned)_height);
295   }
296 }
297 
SetRenderFrameSize(int _width,int _height)298 void  PVideoChannel::SetRenderFrameSize(int _width, int _height)
299 {
300    SetRenderFrameSize(_width, _height, 1, 1);
301 }
302 
SetRenderFrameSize(int _width,int _height,int _sarwidth,int _sarheight)303 void  PVideoChannel::SetRenderFrameSize(int _width, int _height, int _sarwidth,int _sarheight)
304 {
305   PTRACE(6, "PVC\t Set Renderer frame size to " << _width << "x" << _height);
306   PWaitAndSignal m(accessMutex);
307 
308   if (mpOutput != NULL)
309   {
310         mpOutput->SetFrameSize(_width, _height);
311         mpOutput->SetFrameSar(_sarwidth, _sarheight);
312   }
313 }
314 
GetVideoReader()315 PVideoInputDevice *PVideoChannel::GetVideoReader()
316 {
317   return mpInput;
318 }
319 
GetVideoPlayer()320 PVideoOutputDevice *PVideoChannel::GetVideoPlayer()
321 {
322   return mpOutput;
323 }
324 
Redraw(const void * frame)325 PBoolean  PVideoChannel::Redraw(const void * frame)
326 {
327   PTRACE(6,"PVC\t::Redraw a frame");
328   return Write(frame, 0);
329 }
330 
GetRenderWidth()331 PINDEX   PVideoChannel::GetRenderWidth()
332 {
333   PWaitAndSignal m(accessMutex);
334 
335   if (mpOutput != NULL)
336     return mpOutput->GetFrameWidth();
337 
338   return 0;
339 }
340 
GetRenderHeight()341 PINDEX  PVideoChannel::GetRenderHeight()
342 {
343   PWaitAndSignal m(accessMutex);
344 
345  if (mpOutput != NULL)
346   return mpOutput->GetFrameHeight();
347 
348  return 0;
349 }
350 
351 
RestrictAccess()352 void PVideoChannel::RestrictAccess()
353 {
354   accessMutex.Wait();
355 }
356 
EnableAccess()357 void PVideoChannel::EnableAccess()
358 {
359   accessMutex.Signal();
360 }
361 
362 
ToggleVFlipInput()363 PBoolean PVideoChannel::ToggleVFlipInput()
364 {
365   PWaitAndSignal m(accessMutex);
366 
367  if (mpOutput != NULL)
368   return mpInput->SetVFlipState(mpInput->GetVFlipState());
369 
370  return PFalse;
371 }
372 
FlowControl(const void * flowData)373 bool PVideoChannel::FlowControl(const void* flowData)
374 {
375     if(mpInput)
376         return mpInput->FlowControl(flowData);
377     return false;
378 }
379 
380 #endif
381 
382 ///////////////////////////////////////////////////////////////////////////
383 // End of file
384 
385