4 * Classes to support streaming video input (grabbing) and output.
6 * Portable Windows Library
8 * Copyright (c) 1993-2000 Equivalence Pty. Ltd.
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/
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
20 * The Original Code is Portable Windows Library.
22 * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
24 * Contributor(s): Derek J Smithies (derek@indranet.co.nz)
27 * Revision 1.29 2004/03/17 22:24:29 rjongbloed
30 * Revision 1.28 2004/03/16 10:10:47 csoutheren
31 * Proper fix that does not generate warnings
33 * Revision 1.27 2004/03/16 08:27:14 csoutheren
34 * Removed illegal characters
36 * Revision 1.26 2003/12/14 10:01:02 rjongbloed
37 * Resolved issue with name space conflict os static and virtual forms of GetDeviceNames() function.
39 * Revision 1.25 2003/11/19 09:29:45 csoutheren
40 * Added super hack to avoid problems with multiple plugins in a single file
42 * Revision 1.24 2003/11/19 04:29:46 csoutheren
43 * Changed to support video output plugins
45 * Revision 1.23 2003/08/12 22:04:18 dereksmithies
46 * Add fix from Philippe Massicotte to fix segfaults on large images. Thanks!
48 * Revision 1.22 2003/06/14 03:28:50 rjongbloed
49 * Further MSVC warning fix up
51 * Revision 1.21 2003/06/14 02:59:34 rjongbloed
54 * Revision 1.20 2003/06/11 22:17:54 dereksmithies
55 * Add fake video device which display text, on --videoinput 5
57 * Revision 1.19 2003/06/10 03:45:11 dereksmithies
58 * Change so box on left moves all the way down left side of image.
60 * Revision 1.18 2003/06/10 00:36:57 dereksmithies
61 * Formatting changes. Remove rounding errors.
63 * Revision 1.17 2003/06/03 04:21:49 dereksmithies
64 * Add PTRACE statement, and tidy up format of one if statement.
66 * Revision 1.16 2003/03/17 07:46:49 robertj
67 * Migrated vflip member variable and functions into PVideoDevice class.
69 * Revision 1.15 2002/09/23 07:17:24 robertj
70 * Changes to allow winsock2 to be included.
72 * Revision 1.14 2002/01/28 21:22:10 dereks
73 * Fix the method for returning the device name.
75 * Revision 1.13 2002/01/17 03:47:27 dereks
76 * Fix latest addition to the fake images gallery.
78 * Revision 1.12 2002/01/16 08:02:06 robertj
79 * MSVC compatibilty changes
81 * Revision 1.11 2002/01/16 03:49:23 dereks
84 * Revision 1.10 2002/01/04 04:11:45 dereks
85 * Add video flip code from Walter Whitlock, which flips code at the grabber.
87 * Revision 1.9 2001/11/28 04:39:25 robertj
90 * Revision 1.8 2001/11/28 00:07:32 dereks
91 * Locking added to PVideoChannel, allowing reader/writer to be changed mid call
92 * Enabled adjustment of the video frame rate
93 * New fictitous image, a blank grey area
95 * Revision 1.7 2001/03/12 03:54:11 dereks
96 * Make setting frame rate consistent with that for real video device.
98 * Revision 1.6 2001/03/09 00:12:40 robertj
99 * Fixed incorrect number of channels returned on fake video.
101 * Revision 1.5 2001/03/08 22:56:25 robertj
102 * Fixed compatibility with new meaning of channelNumber variable, cannot be negative.
104 * Revision 1.4 2001/03/03 05:06:31 robertj
105 * Major upgrade of video conversion and grabbing classes.
107 * Revision 1.3 2001/03/02 06:52:33 yurik
108 * Got rid of unknown for WinCE pragma
110 * Revision 1.2 2000/12/19 23:58:14 robertj
111 * Fixed MSVC compatibility issues.
113 * Revision 1.1 2000/12/19 22:20:26 dereks
114 * Add video channel classes to connect to the PwLib PVideoInputDevice class.
115 * Add PFakeVideoInput class to generate test images for video.
120 #pragma implementation "vfakeio.h"
123 #define P_FORCE_STATIC_PLUGIN
126 #include <ptlib/videoio.h>
129 #define NUM_PATTERNS 6
132 #define MAX_L_HEIGHT 11
136 char *line
[MAX_L_HEIGHT
];
137 } OneVFakeLetterData
;
141 * The fonts for these letters were written by Sverre H. Huseby, and have been included
142 * in vfakeio by Derek Smithies.
144 static OneVFakeLetterData vFakeLetterData
[] = {
761 { '\xc6', { " ** ***",
1260 /** This class defines a video input device that
1261 generates fictitous image data.
1263 class PVideoInputDevice_FakeVideo
: public PVideoInputDevice
1265 PCLASSINFO(PVideoInputDevice_FakeVideo
, PVideoInputDevice
);
1267 /** Create a new (fake) video input device.
1269 PVideoInputDevice_FakeVideo();
1272 /**Open the device given the device name.
1275 const PString
& deviceName
, /// Device name to open
1276 BOOL startImmediate
= TRUE
/// Immediately start device
1279 /**Determine of the device is currently open.
1283 /**Close the device.
1287 /**Start the video device I/O.
1291 /**Stop the video device I/O capture.
1295 /**Determine if the video device I/O capture is in progress.
1299 /**Get a list of all of the drivers available.
1301 static PStringList
GetInputDeviceNames();
1303 virtual PStringList
GetDeviceNames() const
1304 { return GetInputDeviceNames(); }
1306 /**Get the maximum frame size in bytes.
1308 Note a particular device may be able to provide variable length
1309 frames (eg motion JPEG) so will be the maximum size of all frames.
1311 virtual PINDEX
GetMaxFrameBytes();
1313 BOOL
GetFrame(PBYTEArray
& frame
);
1318 There will be a delay in returning, as specified by frame rate.
1320 virtual BOOL
GetFrameData(
1321 BYTE
* buffer
, /// Buffer to receive frame
1322 PINDEX
* bytesReturned
= NULL
/// Optional bytes returned.
1327 Do not delay according to the current frame rate.
1329 virtual BOOL
GetFrameDataNoDelay(
1330 BYTE
* buffer
, /// Buffer to receive frame
1331 PINDEX
* bytesReturned
= NULL
/// OPtional bytes returned.
1335 /**A test image that contains area of low and high resolution.
1336 The picture changes every second*/
1337 void GrabMovingBlocksTestFrame(BYTE
*resFrame
);
1339 /**a test image consisting of a horizontal line moving down the image,
1340 with a constantly varying background. */
1341 void GrabMovingLineTestFrame(BYTE
*resFrame
);
1343 /**Generate a constant image, which contains the colours for
1344 a NTSC test frame.*/
1345 void GrabNTSCTestFrame(BYTE
*resFrame
);
1347 /**Generate three bouncing boxes, which bounce from a different height
1349 void GrabBouncingBoxes(BYTE
*resFrame
);
1351 /**Generate a static image, containing a constant field of grey.
1353 void GrabBlankImage(BYTE
*resFrame
);
1355 /**Generate the original form of the moving blocks test frame.
1357 void GrabOriginalMovingBlocksFrame(BYTE
*resFrame
);
1359 /**Generate a textual output on the fake video image
1361 void GrabTextVideoFrame(BYTE
*resFrame
);
1363 /**Get the stucture holding required letter for GetTextVideoFrame()
1365 OneVFakeLetterData
*FindLetter(char ascii
);
1367 /** Fills a region of the image with a constant colour.
1369 void FillRect(BYTE
* frame
, unsigned width
, unsigned height
,
1371 int rectWidth
, int rectHeight
,
1372 int r
, int g
, int b
);
1374 /** Given a preset interval of n milliseconds, this function
1375 returns n msecs after the previous frame capture was initiated.
1377 virtual void WaitFinishPreviousFrame();
1379 /**Set the video format to be used.
1381 Default behaviour sets the value of the videoFormat variable and then
1382 returns the IsOpen() status.
1384 virtual BOOL
SetVideoFormat(
1385 VideoFormat videoFormat
/// New video format
1388 /**Get the number of video channels available on the device.
1390 Default behaviour returns 1.
1392 virtual int GetNumChannels() ;
1394 /**Set the video channel to be used on the device.
1396 Default behaviour sets the value of the channelNumber variable and then
1397 returns the IsOpen() status.
1399 virtual BOOL
SetChannel(
1400 int channelNumber
/// New channel number for device.
1403 /**Set the colour format to be used.
1405 Default behaviour sets the value of the colourFormat variable and then
1406 returns the IsOpen() status.
1408 virtual BOOL
SetColourFormat(
1409 const PString
& colourFormat
// New colour format for device.
1412 /**Set the video frame rate to be used on the device.
1414 Default behaviour sets the value of the frameRate variable and then
1415 return the IsOpen() status.
1417 virtual BOOL
SetFrameRate(
1418 unsigned rate
/// Frames per second
1421 /**Get the minimum & maximum size of a frame on the device.
1423 Default behaviour returns the value 1 to UINT_MAX for both and returns
1426 virtual BOOL
GetFrameSizeLimits(
1427 unsigned & minWidth
, /// Variable to receive minimum width
1428 unsigned & minHeight
, /// Variable to receive minimum height
1429 unsigned & maxWidth
, /// Variable to receive maximum width
1430 unsigned & maxHeight
/// Variable to receive maximum height
1433 /**Set the frame size to be used.
1435 Default behaviour sets the frameWidth and frameHeight variables and
1436 returns the IsOpen() status.
1438 virtual BOOL
SetFrameSize(
1439 unsigned width
, /// New width of frame
1440 unsigned height
/// New height of frame
1443 void ClearMapping() { return ; }
1445 /**Try all known video formats & see which ones are accepted by the video driver
1447 virtual BOOL
TestAllFormats()
1451 PINDEX videoFrameSize
;
1454 PString textLine
[MAX_L_HEIGHT
];
1457 PCREATE_VIDINPUT_PLUGIN(FakeVideo
, PVideoInputDevice_FakeVideo
);
1459 ///////////////////////////////////////////////////////////////////////////////
1460 // PVideoInputDevice_FakeVideo
1463 PVideoInputDevice_FakeVideo::PVideoInputDevice_FakeVideo()
1472 BOOL
PVideoInputDevice_FakeVideo::Open(const PString
& /*devName*/, BOOL
/*startImmediate*/)
1478 BOOL
PVideoInputDevice_FakeVideo::IsOpen()
1484 BOOL
PVideoInputDevice_FakeVideo::Close()
1490 BOOL
PVideoInputDevice_FakeVideo::Start()
1496 BOOL
PVideoInputDevice_FakeVideo::Stop()
1502 BOOL
PVideoInputDevice_FakeVideo::IsCapturing()
1508 PStringList
PVideoInputDevice_FakeVideo::GetInputDeviceNames()
1512 list
.AppendString("fake");
1518 BOOL
PVideoInputDevice_FakeVideo::SetVideoFormat(VideoFormat newFormat
)
1520 return PVideoDevice::SetVideoFormat(newFormat
);
1524 int PVideoInputDevice_FakeVideo::GetNumChannels()
1526 return NUM_PATTERNS
;
1530 BOOL
PVideoInputDevice_FakeVideo::SetChannel(int newChannel
)
1532 return PVideoDevice::SetChannel(newChannel
);
1536 BOOL
PVideoInputDevice_FakeVideo::SetColourFormat(const PString
& newFormat
)
1538 return PVideoDevice::SetColourFormat(newFormat
);
1542 BOOL
PVideoInputDevice_FakeVideo::SetFrameRate(unsigned rate
)
1544 if ((rate
< 1) || (rate
> 50))
1545 PVideoDevice::SetFrameRate(10);
1547 PVideoDevice::SetFrameRate(rate
);
1553 BOOL
PVideoInputDevice_FakeVideo::GetFrameSizeLimits(unsigned & minWidth
,
1554 unsigned & minHeight
,
1555 unsigned & maxWidth
,
1556 unsigned & maxHeight
)
1567 BOOL
PVideoInputDevice_FakeVideo::SetFrameSize(unsigned width
, unsigned height
)
1569 if (!PVideoDevice::SetFrameSize(width
, height
))
1572 videoFrameSize
= CalculateFrameBytes(frameWidth
, frameHeight
, colourFormat
);
1578 PINDEX
PVideoInputDevice_FakeVideo::GetMaxFrameBytes()
1580 return videoFrameSize
;
1583 void PVideoInputDevice_FakeVideo::WaitFinishPreviousFrame()
1585 frameTimeError
+= msBetweenFrames
;
1588 PTimeInterval delay
= now
- previousFrameTime
;
1589 frameTimeError
-= (int)delay
.GetMilliSeconds();
1590 previousFrameTime
= now
;
1592 if (frameTimeError
> 0) {
1593 PTRACE(6, "FakeVideo\t Sleep for " << frameTimeError
<< " milli seconds");
1595 usleep(frameTimeError
* 1000);
1597 PThread::Current()->Sleep(frameTimeError
);
1602 BOOL
PVideoInputDevice_FakeVideo::GetFrame(PBYTEArray
& frame
)
1605 if (!GetFrameData(frame
.GetPointer(GetMaxFrameBytes()), &returned
))
1608 frame
.SetSize(returned
);
1613 BOOL
PVideoInputDevice_FakeVideo::GetFrameData(BYTE
* buffer
, PINDEX
* bytesReturned
)
1615 WaitFinishPreviousFrame();
1617 GetFrameDataNoDelay(buffer
, bytesReturned
);
1619 *bytesReturned
= videoFrameSize
;
1625 BOOL
PVideoInputDevice_FakeVideo::GetFrameDataNoDelay(BYTE
*destFrame
, PINDEX
* /*bytesReturned*/)
1629 // Make sure are NUM_PATTERNS cases here.
1630 switch(channelNumber
){
1632 GrabMovingBlocksTestFrame(destFrame
);
1635 GrabMovingLineTestFrame(destFrame
);
1638 GrabBouncingBoxes(destFrame
);
1641 GrabBlankImage(destFrame
);
1644 GrabOriginalMovingBlocksFrame(destFrame
);
1647 GrabTextVideoFrame(destFrame
);
1650 GrabNTSCTestFrame(destFrame
);
1657 void PVideoInputDevice_FakeVideo::FillRect(BYTE
* frame
, unsigned width
, unsigned height
,
1658 int xPos
, int initialYPos
,
1659 int rectWidth
, int rectHeight
,
1660 int r
, int g
, int b
)
1662 // PTRACE(0,"x,y is"<<xPos<<" "<<yPos<<" and size is "<<rectWidth<<" "<<rectHeight);
1663 //This routine fills a region of the video image with data. It is used as the central
1664 //point because one only has to add other image formats here.
1667 yPos
= height
- ( initialYPos
+ rectHeight
);
1668 yPos
= ( yPos
>> 2 ) * 4;
1673 int offset
= ( yPos
* width
) + xPos
;
1674 int colourOffset
= ( (yPos
* width
) >> 2) + (xPos
>> 1);
1676 int Y
= (int)( (0.257 * r
) + (0.504 * g
) + (0.098 * b
) + 16);
1677 int Cb
= (int)(-(0.148 * r
) - (0.291 * g
) + (0.439 * b
) + 128);
1678 int Cr
= (int)( (0.439 * r
) - (0.368 * g
) - (0.071 * b
) + 128);
1680 unsigned char * Yptr
= frame
+ offset
;
1681 unsigned char * CbPtr
= frame
+ (width
* height
) + colourOffset
;
1682 unsigned char * CrPtr
= frame
+ (width
* height
) + (width
* height
/4) + colourOffset
;
1685 int halfRectWidth
= rectWidth
>> 1;
1686 int halfWidth
= width
>> 1;
1688 for (rr
= 0; rr
< rectHeight
;rr
+=2) {
1689 memset(Yptr
, Y
, rectWidth
);
1691 memset(Yptr
, Y
, rectWidth
);
1694 memset(CbPtr
, Cb
, halfRectWidth
);
1695 memset(CrPtr
, Cr
, halfRectWidth
);
1702 void PVideoInputDevice_FakeVideo::GrabBouncingBoxes(BYTE
*resFrame
)
1705 unsigned height
= 0;
1706 GetFrameSize(width
, height
);
1710 FillRect(resFrame
, width
, height
,
1711 0, 0, //Position x,y
1712 width
, height
, //Fill the whole frame with the colour.
1713 200,200,200); //a light grey colour.
1715 double t
= (grabCount
%50) -25 ;
1716 double h
= t
*t
*height
*0.85/625;
1718 yBox
= (yBox
>>1) * 2; //yBox is even.
1720 int boxHeight
= (int)(height
*0.1);
1721 boxHeight
= (boxHeight
>>1) * 2;
1722 int boxWidth
= (int)(width
*0.1);
1723 boxWidth
= (boxWidth
>>1) * 2;
1725 FillRect(resFrame
, width
, height
,
1727 boxWidth
, boxHeight
,
1728 255, 0, 0); // Red Box.
1730 t
= (grabCount
%40) -20 ;
1731 h
= t
*t
*height
*0.85/400 ;
1733 yBox
= (yBox
>>1) * 2; //yBox is even.
1735 FillRect(resFrame
, width
, height
,
1738 0, 255, 0); // Green
1740 t
= (grabCount
%100) -50 ;
1741 h
= t
*t
*height
*0.85/2500;
1743 yBox
= (yBox
>>1) * 2; //yBox is even.
1745 FillRect(resFrame
, width
, height
,
1746 (width
>>1) + (width
>>2),yBox
,
1753 void PVideoInputDevice_FakeVideo::GrabNTSCTestFrame(BYTE
*resFrame
)
1756 // A static image is generated, consisting of a series of coloured block.
1757 // Sample NTSC test frame is found at http://www.displaymate.com/patterns.html
1759 static int row1
[7][3] = {
1760 { 204, 204, 204 }, // 80% grey
1761 { 255, 255, 0 }, // yellow
1762 { 0, 255, 255 }, // cyan
1763 { 0, 255, 0 }, // green
1764 { 255, 0, 255 }, // magenta
1765 { 255, 0, 0 }, // red
1766 { 0, 0, 255 }, // blue
1769 static int row2
[7][3] = {
1770 { 0, 0, 255 }, // blue
1771 { 19, 19, 19 }, // black
1772 { 255, 0, 255 }, // magenta
1773 { 19, 19, 19 }, // black
1774 { 0, 255, 255 }, // cyan
1775 { 19, 19, 19 }, // black
1776 { 204, 204, 204 }, // grey
1779 static int row3a
[4][3] = {
1781 { 255, 255, 255 }, // white
1782 { 58, 0, 126 }, // +Q
1783 { 19, 19, 19 }, // black
1786 static int row3b
[3][3] = {
1788 { 19, 19, 19 }, // 7.5
1789 { 38, 38, 38 }, // 11.5
1792 static int row3c
[3] = { 19, 19, 19 };
1796 GetFrameSize(width
,height
);
1798 int row1Height
= (int)(0.66 * height
);
1799 int row2Height
= (int)((0.75 * height
) - row1Height
);
1800 row1Height
= (row1Height
>>1)*2; //Require that height is even.
1801 row2Height
= (row2Height
>>1)*2;
1802 int row3Height
= height
- row1Height
- row2Height
;
1808 columns
[i
]= i
*width
/7;
1809 columns
[i
]= (columns
[i
]>>1)*2; // require that columns[i] is even.
1815 for (i
= 0; i
< 6; i
++)
1816 FillRect(resFrame
, width
, height
,
1817 columns
[i
], 0, //Position x,y
1818 columns
[i
+1]-columns
[i
], row1Height
, //Size (width*height)
1819 row1
[i
][0], row1
[i
][1], row1
[i
][2]); // rgb
1824 for (i
= 0; i
< 7; i
++)
1825 FillRect(resFrame
, width
, height
,
1826 columns
[i
], row1Height
,
1827 columns
[i
+1]-columns
[i
], row2Height
,
1828 row2
[i
][0], row2
[i
][1], row2
[i
][2]);
1833 for (i
=0; i
<4; i
++) {
1834 columnBot
[i
]= i
*columns
[5]/4;
1835 columnBot
[i
] = 2 * (columnBot
[i
]>>1);
1837 columnBot
[4]= columns
[5];
1839 for (i
= 0; i
< 4; i
++)
1840 FillRect(resFrame
, width
, height
,
1841 columnBot
[i
],row1Height
+ row2Height
,
1842 columnBot
[i
+1]-columnBot
[i
], row3Height
,
1843 row3a
[i
][0], row3a
[i
][1], row3a
[i
][2]);
1845 for (i
=0; i
<3; i
++) {
1846 columnBot
[i
] = columns
[4]+(i
*width
)/(7*3);
1847 columnBot
[i
] = 2 * (columnBot
[i
]>>1); //Force even.
1849 columnBot
[3]= columns
[5];
1851 for (i
= 0; i
< 3; i
++)
1852 FillRect(resFrame
, width
, height
,
1853 columnBot
[i
], row1Height
+ row2Height
,
1854 columnBot
[i
+1] - columnBot
[i
], row3Height
,
1855 row3b
[i
][0], row3b
[i
][1], row3b
[i
][2]);
1857 FillRect(resFrame
, width
, height
,
1858 columns
[6], row1Height
+ row2Height
,
1859 columns
[7] - columns
[6], row3Height
,
1860 row3c
[0], row3c
[1], row3c
[2]);
1866 void PVideoInputDevice_FakeVideo::GrabMovingBlocksTestFrame(BYTE
* resFrame
)
1869 /*Brightness is set to alter, left to right.
1870 Colour component alters top to bottom.
1872 Image contains lots of high and low resolution areas.
1874 unsigned width
, height
, wi
,hi
, colourIndex
,colNo
, boxSize
;
1876 #define COL(b,x,y) ((b+x+y)%7)
1878 static int background
[7][3] = {
1879 { 254, 254, 254 }, // white
1880 { 255, 255, 0 }, // yellow
1881 { 0, 255, 255 }, // cyan
1882 { 0, 255, 0 }, // green
1883 { 255, 0, 255 }, // magenta
1884 { 255, 0, 0 }, // red
1885 { 0, 0, 255 }, // blue
1888 width
= 0; //Stops compiler warning about unitialized variables.
1890 GetFrameSize(width
, height
);
1895 offset
= (width
>> 3) & 0xffe;
1897 for(wi
= 0; wi
< 8; wi
++)
1898 columns
[wi
] = wi
* offset
;
1901 offset
= (height
>> 3) & 0xffe;
1902 for(hi
= 0; hi
< 9; hi
++)
1903 heights
[hi
] = hi
* offset
;
1904 heights
[8] = height
;
1907 colourIndex
= time(NULL
);//time in seconds since last epoch.
1908 // Provides a difference if run on two ohphone sessions.
1909 colNo
= (colourIndex
/ 10) % 7; //Every 10 seconds, coloured background blocks move.
1911 for(hi
= 0; hi
< 8; hi
++) //Fill the background in.
1912 for(wi
= 0 ; wi
< 8; wi
++) {
1913 FillRect(resFrame
, width
, height
, //frame details.
1914 columns
[wi
], heights
[hi
], //X,Y Pos.
1915 columns
[wi
+ 1] - columns
[wi
], heights
[hi
+ 1] - heights
[hi
],
1916 background
[COL(colNo
, wi
, hi
)][0], background
[COL(colNo
, wi
, hi
)][1], background
[COL(colNo
, wi
, hi
)][2]);
1919 //Draw a black box rapidly moving down the left of the window.
1920 boxSize
= height
/ 10;
1921 hi
= ((3 * colourIndex
) % (height
-boxSize
)) & 0xffe; //Make certain hi is even.
1922 FillRect(resFrame
, width
, height
, 10, hi
, boxSize
, boxSize
, 0, 0, 0); //Black Box.
1924 //Draw four parallel black lines, which move up the middle of the window.
1925 colourIndex
= colourIndex
/ 3; //Every three seconds, lines move.
1927 for(wi
= 0; wi
< 2; wi
++)
1928 columns
[wi
]= (((wi
+ 1) * width
) / 3) & 0xffe;// Force columns to be even.
1930 hi
= colourIndex
% ((height
- 16) / 2);
1931 hi
= (height
- 16) - (hi
* 2); //hi is even, Lines move in opp. direction to box.
1934 for(yi
= 0; yi
< 4; yi
++)
1935 FillRect(resFrame
, width
, height
,
1936 columns
[0], hi
+(yi
* 4),
1937 columns
[1] - columns
[0], 2, 0, 0, 0);
1941 void PVideoInputDevice_FakeVideo::GrabMovingLineTestFrame(BYTE
*resFrame
)
1944 // Faster image generation. Same every times system runs.
1945 // Colours cycle through. Have a vertical lines style of pattern.
1946 // There is a horizontal bar which moves down the screen .
1947 unsigned width
,height
;
1951 width
=0; //Stops compiler warning about unitialized variables.
1954 GetFrameSize(width
,height
);
1961 FillRect(resFrame
, width
, height
, 0, 0,width
, height
, r
, g
, b
);
1963 int hi
= (v
% (height
-2) >> 1) *2;
1965 FillRect(resFrame
, width
, height
, 0, hi
, width
, 2, 0, 0, 0);
1968 void PVideoInputDevice_FakeVideo::GrabBlankImage(BYTE
*resFrame
)
1972 GetFrameSize(width
,height
);
1976 FillRect(resFrame
, width
, height
,
1977 0, 0, //Position x,y
1978 width
, height
, //Fill the whole frame with the colour.
1979 200,200,200); //a light grey colour.
1982 void PVideoInputDevice_FakeVideo::GrabOriginalMovingBlocksFrame(BYTE
*frame
)
1990 int wi
,hi
,colourIndex
,colourNumber
;
1991 int framesize
= width
*height
;
1993 static int gCount
=0;
1996 colourIndex
= gCount
/10;
1997 colourNumber
= (colourIndex
/10)%7; //Every 10 seconds, coloured background blocks move.
1999 for(hi
=0; hi
<height
; hi
++) //slow moving group of lines going upwards.
2000 for(wi
=0; wi
<width
; wi
++)
2001 if ( (wi
>width
/3)&&(wi
<width
*2/3)&&
2002 ( ((gCount
+hi
)%height
)<16)&&
2004 frame
[(hi
*width
)+wi
] = 16;
2006 frame
[(hi
*width
)+wi
] = (BYTE
)(((colourNumber
+((wi
*7)/width
))%7)*35+26);
2008 for(hi
=1; hi
<=height
; hi
++) //fast moving block going downwards.
2009 for(wi
=width
/9; wi
<(2*width
/9); wi
++)
2010 if( (( (gCount
*4)+hi
)%height
)<20)
2011 frame
[((height
-hi
)*width
)+wi
] = 16;
2013 int halfWidth
= width
/2;
2014 int halfHeight
= height
/2;
2015 for(hi
=1; hi
<halfHeight
; hi
++)
2016 for(wi
=0; wi
<halfWidth
; wi
++)
2017 frame
[framesize
+(hi
*halfWidth
)+wi
] = (BYTE
)(((((hi
*7)/halfHeight
)+colourNumber
)%7)*35+26);
2020 void PVideoInputDevice_FakeVideo::GrabTextVideoFrame(BYTE
*resFrame
)
2024 unsigned height
= 0;
2025 GetFrameSize(width
, height
);
2026 static PTime startTime
;
2029 FillRect(resFrame
, width
, height
,
2030 0, 0, //Position x,y
2031 width
, height
, //Fill the whole frame with the colour.
2032 200, 200, 200); //a light grey colour.
2035 if (textLine
[0].GetLength() < 2) {
2036 PStringStream message
;
2037 message
<< PProcess::Current().GetUserName() << " on " <<
2038 PProcess::Current().GetOSName() << ":" <<
2039 PProcess::Current().GetOSHardware();
2040 PINDEX nChars
= message
.GetLength();
2041 OneVFakeLetterData
*ld
;
2043 for (j
= 0; j
< MAX_L_HEIGHT
; j
++)
2046 for (i
= 0; i
< (nChars
+ 2); i
++){
2048 ld
= FindLetter(' ');
2050 ld
= FindLetter(message
[i
]);
2053 for (j
= 0; j
< MAX_L_HEIGHT
; j
++)
2054 textLine
[j
] += ld
->line
[j
] + PString(" ");
2058 PINDEX boxSize
= (height
/ (MAX_L_HEIGHT
* 2) ) & 0xffe;
2059 int index
= (int)((PTime() - startTime
).GetMilliSeconds() / 300);
2061 PINDEX maxI
= (width
/ boxSize
) - 2;
2062 for (i
= 0; i
< maxI
; i
++)
2063 for (j
= 0; j
< MAX_L_HEIGHT
; j
++) {
2064 PINDEX ii
= (index
+ i
) % textLine
[0].GetLength();
2065 if (textLine
[j
][ii
] != ' ')
2066 FillRect(resFrame
, width
, height
,
2067 (i
+ 1) * boxSize
, (height
/ 3) + ((j
+ 1) * boxSize
), //x,y start pos
2068 boxSize
, boxSize
, //x,y dimension
2069 250, 00, 00); //red box.
2073 OneVFakeLetterData
*PVideoInputDevice_FakeVideo::FindLetter(char ascii
)
2076 int fontNumLetters
= sizeof(vFakeLetterData
) / sizeof(OneVFakeLetterData
);
2079 for (q
= 0; q
< fontNumLetters
; q
++)
2080 if (vFakeLetterData
[q
].ascii
== ascii
)
2081 return vFakeLetterData
+ q
;
2087 /////////////////////////////////////////////////////////////////////////////////////////////////////////
2090 /**This class defines a NULL video output device.
2091 This will do precisely nothing with the output.
2093 class PVideoOutputDevice_NULLOutput
: public PVideoOutputDevice
2095 PCLASSINFO(PVideoOutputDevice_NULLOutput
, PVideoOutputDevice
);
2098 /** Create a new video output device.
2100 PVideoOutputDevice_NULLOutput();
2102 /**Get a list of all of the drivers available.
2104 static PStringList
GetOutputDeviceNames();
2106 virtual PStringList
GetDeviceNames() const
2107 { return GetOutputDeviceNames(); }
2109 /**Open the device given the device name.
2112 const PString
& deviceName
, /// Device name to open
2113 BOOL startImmediate
= TRUE
/// Immediately start device
2116 /**Start the video device I/O.
2120 /**Stop the video device I/O capture.
2124 /**Close the device.
2126 virtual BOOL
Close();
2128 /**Determine if the device is currently open.
2130 virtual BOOL
IsOpen();
2132 /**Get the maximum frame size in bytes.
2134 Note a particular device may be able to provide variable length
2135 frames (eg motion JPEG) so will be the maximum size of all frames.
2137 virtual PINDEX
GetMaxFrameBytes();
2139 /**Set a section of the output frame buffer.
2141 virtual BOOL
SetFrameData(
2147 BOOL endFrame
= TRUE
2150 /**Indicate frame may be displayed.
2152 virtual BOOL
EndFrame();
2155 PCREATE_VIDOUTPUT_PLUGIN(NULLOutput
, PVideoOutputDevice_NULLOutput
);
2157 ///////////////////////////////////////////////////////////////////////////////
2158 // PVideoOutputDevice_NULLOutput
2160 PVideoOutputDevice_NULLOutput::PVideoOutputDevice_NULLOutput()
2162 deviceName
= "NULL";
2166 BOOL
PVideoOutputDevice_NULLOutput::Open(const PString
& /*deviceName*/,
2167 BOOL
/*startImmediate*/)
2172 BOOL
PVideoOutputDevice_NULLOutput::Close()
2177 BOOL
PVideoOutputDevice_NULLOutput::Start()
2182 BOOL
PVideoOutputDevice_NULLOutput::Stop()
2187 BOOL
PVideoOutputDevice_NULLOutput::IsOpen()
2193 PStringList
PVideoOutputDevice_NULLOutput::GetOutputDeviceNames()
2201 PINDEX
PVideoOutputDevice_NULLOutput::GetMaxFrameBytes()
2203 return CalculateFrameBytes(frameWidth
, frameHeight
, colourFormat
);
2207 BOOL
PVideoOutputDevice_NULLOutput::SetFrameData(unsigned /*x*/, unsigned /*y*/,
2208 unsigned /*width*/, unsigned /*height*/,
2209 const BYTE
* /*data*/,
2216 BOOL
PVideoOutputDevice_NULLOutput::EndFrame()
2222 // End Of File ///////////////////////////////////////////////////////////////