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