📄 vfakeio.cxx
字号:
/*
* vfakeio.cxx
*
* Classes to support streaming video input (grabbing) and output.
*
* Portable Windows Library
*
* Copyright (c) 1993-2000 Equivalence Pty. Ltd.
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Portable Windows Library.
*
* The Initial Developer of the Original Code is Equivalence Pty. Ltd.
*
* Contributor(s): Derek J Smithies (derek@indranet.co.nz)
*
* $Log: vfakeio.cxx,v $
* Revision 1.9 2001/11/28 04:39:25 robertj
* Fixed MSVC warning
*
* Revision 1.8 2001/11/28 00:07:32 dereks
* Locking added to PVideoChannel, allowing reader/writer to be changed mid call
* Enabled adjustment of the video frame rate
* New fictitous image, a blank grey area
*
* Revision 1.7 2001/03/12 03:54:11 dereks
* Make setting frame rate consistent with that for real video device.
*
* Revision 1.6 2001/03/09 00:12:40 robertj
* Fixed incorrect number of channels returned on fake video.
*
* Revision 1.5 2001/03/08 22:56:25 robertj
* Fixed compatibility with new meaning of channelNumber variable, cannot be negative.
*
* Revision 1.4 2001/03/03 05:06:31 robertj
* Major upgrade of video conversion and grabbing classes.
*
* Revision 1.3 2001/03/02 06:52:33 yurik
* Got rid of unknown for WinCE pragma
*
* Revision 1.2 2000/12/19 23:58:14 robertj
* Fixed MSVC compatibility issues.
*
* Revision 1.1 2000/12/19 22:20:26 dereks
* Add video channel classes to connect to the PwLib PVideoInputDevice class.
* Add PFakeVideoInput class to generate test images for video.
*
*
*/
#ifdef __GNUC__
#pragma implementation "vfakeio.h"
#endif
#include <ptlib.h>
#include <ptlib/videoio.h>
#define NUM_PATTERNS 4
///////////////////////////////////////////////////////////////////////////////
// PFakeVideoInputDevice
PFakeVideoInputDevice::PFakeVideoInputDevice()
{
grabCount = 0;
SetFrameRate(10);
}
BOOL PFakeVideoInputDevice::Open(const PString & /*devName*/, BOOL /*startImmediate*/)
{
return TRUE;
}
BOOL PFakeVideoInputDevice::IsOpen()
{
return TRUE;
}
BOOL PFakeVideoInputDevice::Close()
{
return TRUE;
}
BOOL PFakeVideoInputDevice::Start()
{
return TRUE;
}
BOOL PFakeVideoInputDevice::Stop()
{
return TRUE;
}
BOOL PFakeVideoInputDevice::IsCapturing()
{
return IsOpen();
}
PStringList PFakeVideoInputDevice::GetDeviceNames() const
{
PStringList list;
list.AppendString("/dev/vFAKE");
return list;
}
BOOL PFakeVideoInputDevice::SetVideoFormat(VideoFormat newFormat)
{
return PVideoDevice::SetVideoFormat(newFormat);
}
int PFakeVideoInputDevice::GetNumChannels()
{
return NUM_PATTERNS;
}
BOOL PFakeVideoInputDevice::SetChannel(int newChannel)
{
return PVideoDevice::SetChannel(newChannel);
}
BOOL PFakeVideoInputDevice::SetColourFormat(const PString & newFormat)
{
return PVideoDevice::SetColourFormat(newFormat);
}
BOOL PFakeVideoInputDevice::SetFrameRate(unsigned rate)
{
if ( (rate < 1) || ( rate > 50) )
PVideoDevice::SetFrameRate(10);
else
PVideoDevice::SetFrameRate(rate);
return TRUE;
}
BOOL PFakeVideoInputDevice::GetFrameSizeLimits(unsigned & minWidth,
unsigned & minHeight,
unsigned & maxWidth,
unsigned & maxHeight)
{
minWidth = 10;
minHeight = 10;
maxWidth = 1000;
maxHeight = 800;
return TRUE;
}
BOOL PFakeVideoInputDevice::SetFrameSize(unsigned width, unsigned height)
{
if (!PVideoDevice::SetFrameSize(width, height))
return FALSE;
videoFrameSize = CalculateFrameBytes(frameWidth, frameHeight, colourFormat);
return TRUE;
}
PINDEX PFakeVideoInputDevice::GetMaxFrameBytes()
{
return videoFrameSize;
}
void PFakeVideoInputDevice::WaitFinishPreviousFrame()
{
frameTimeError += msBetweenFrames;
PTime now;
PTimeInterval delay = now - previousFrameTime;
frameTimeError -= (int)delay.GetMilliSeconds();
previousFrameTime = now;
if (frameTimeError > 0)
#ifdef P_LINUX
usleep(frameTimeError * 1000);
#else
PThread::Current()->Sleep(frameTimeError);
#endif
}
BOOL PFakeVideoInputDevice::GetFrameData(BYTE * buffer, PINDEX * bytesReturned)
{
WaitFinishPreviousFrame();
GetFrameDataNoDelay(buffer, bytesReturned);
*bytesReturned= videoFrameSize;
return TRUE;
}
BOOL PFakeVideoInputDevice::GetFrameDataNoDelay(BYTE *destFrame, PINDEX * /*bytesReturned*/)
{
grabCount++;
// Make sure are NUM_PATTERNS cases here.
switch(channelNumber){
case 0:
GrabMovingBlocksTestFrame(destFrame);
break;
case 1:
GrabMovingLineTestFrame(destFrame);
break;
case 2:
GrabBouncingBoxes(destFrame);
break;
case 3:
GrabBlankImage(destFrame);
break;
default:
GrabNTSCTestFrame(destFrame);
}
return TRUE;
}
void PFakeVideoInputDevice::FillRect(BYTE * frame, unsigned width, unsigned height,
int xPos, int yPos,
int rectWidth, int rectHeight,
int r, int g, int b)
{
// PTRACE(0,"x,y is"<<xPos<<" "<<yPos<<" and size is "<<rectWidth<<" "<<rectHeight);
//This routine fills a region of the video image with data. It is used as the central
//point because one only has to add other image formats here.
int offset = ( yPos * width) + xPos;
int colourOffset = ( (yPos * width) >> 2) + (xPos >> 1);
int Y = (int)( (0.257 * r) + (0.504 * g) + (0.098 * b) + 16);
int Cb = (int)(-(0.148 * r) - (0.291 * g) + (0.439 * b) + 128);
int Cr = (int)( (0.439 * r) - (0.368 * g) - (0.071 * b) + 128);
unsigned char * Yptr = frame + offset;
unsigned char * CbPtr = frame + (width * height) + colourOffset;
unsigned char * CrPtr = frame + (width * height) + (width * height/4) + colourOffset;
int rr ;
int halfRectWidth = rectWidth >> 1;
int halfWidth = width >> 1;
for (rr = 0; rr < rectHeight;rr+=2) {
memset(Yptr, Y, rectWidth);
Yptr += width;
memset(Yptr, Y, rectWidth);
Yptr += width;
memset(CbPtr, Cb, halfRectWidth);
memset(CrPtr, Cr, halfRectWidth);
CbPtr += halfWidth;
CrPtr += halfWidth;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -