📄 vfakeio.cxx
字号:
case eOriginalMovingBlocks : GrabOriginalMovingBlocksFrame(destFrame); break; case eText : GrabTextVideoFrame(destFrame); break; case eNTSCTest : GrabNTSCTestFrame(destFrame); break; default : return FALSE; } if (NULL != converter) { if (!converter->Convert(destFrame, destFrame, bytesReturned)) return FALSE; } if (bytesReturned != NULL) *bytesReturned = videoFrameSize; return TRUE;}void PVideoInputDevice_FakeVideo::FillRect(BYTE * frame, int xPos, int initialYPos, 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. if (bytesPerPixel > 2) { for (int y = 0; y < rectHeight; y++) { BYTE * ptr = frame + (initialYPos+y)*scanLineWidth + xPos*bytesPerPixel; for (int x = 0; x < rectWidth; x++) { *ptr++ = (BYTE)r; *ptr++ = (BYTE)g; *ptr++ = (BYTE)b; if (bytesPerPixel > 3) *ptr++ = 0; } } return; } int yPos = initialYPos; int offset = ( yPos * frameWidth ) + xPos; int colourOffset = ( (yPos * frameWidth) >> 2) + (xPos >> 1); int Y = ( 257 * r + 504 * g + 98 * b)/1000 + 16; int Cb = (-148 * r - 291 * g + 439 * b)/1000 + 128; int Cr = ( 439 * r - 368 * g - 71 * b)/1000 + 128; unsigned char * Yptr = frame + offset; unsigned char * CbPtr = frame + (frameWidth * frameHeight) + colourOffset; unsigned char * CrPtr = frame + (frameWidth * frameHeight) + (frameWidth * frameHeight/4) + colourOffset; int rr ; int halfRectWidth = rectWidth >> 1; int halfWidth = frameWidth >> 1; for (rr = 0; rr < rectHeight;rr+=2) { memset(Yptr, Y, rectWidth); Yptr += frameWidth; memset(Yptr, Y, rectWidth); Yptr += frameWidth; memset(CbPtr, Cb, halfRectWidth); memset(CrPtr, Cr, halfRectWidth); CbPtr += halfWidth; CrPtr += halfWidth; }}void PVideoInputDevice_FakeVideo::GrabBouncingBoxes(BYTE *resFrame){ FillRect(resFrame, 0, 0, frameWidth, frameHeight, //Fill the whole frame with the colour. 200,200,200); //a light grey colour. double t= (grabCount%50) -25 ; double h= t*t*frameHeight*0.85/625; int yBox = (int)h; yBox= (yBox>>1) * 2; //yBox is even. int boxHeight= (int)(frameHeight*0.1); boxHeight= (boxHeight >>1) * 2; int boxWidth = (int)(frameWidth*0.1); boxWidth = (boxWidth >>1) * 2; FillRect(resFrame, frameWidth >> 2, yBox, boxWidth, boxHeight, 255, 0, 0); // Red Box. t= (grabCount%40) -20 ; h= t*t*frameHeight*0.85/400 ; yBox = (int)h; yBox= (yBox>>1) * 2; //yBox is even. FillRect(resFrame, frameWidth>>1, yBox, boxWidth, boxHeight, 0, 255, 0); // Green t= (grabCount%100) -50 ; h= t*t*frameHeight*0.85/2500; yBox = (int)h; yBox= (yBox>>1) * 2; //yBox is even. FillRect(resFrame, (frameWidth>>1) + (frameWidth>>2), yBox, boxWidth, boxHeight, 0, 0, 255); // Blue}void PVideoInputDevice_FakeVideo::GrabNTSCTestFrame(BYTE *resFrame){ // Test image # 1 // A static image is generated, consisting of a series of coloured block. // Sample NTSC test frame is found at http://www.displaymate.com/patterns.html // static int row1[7][3] = { { 204, 204, 204 }, // 80% grey { 255, 255, 0 }, // yellow { 0, 255, 255 }, // cyan { 0, 255, 0 }, // green { 255, 0, 255 }, // magenta { 255, 0, 0 }, // red { 0, 0, 255 }, // blue }; static int row2[7][3] = { { 0, 0, 255 }, // blue { 19, 19, 19 }, // black { 255, 0, 255 }, // magenta { 19, 19, 19 }, // black { 0, 255, 255 }, // cyan { 19, 19, 19 }, // black { 204, 204, 204 }, // grey }; static int row3a[4][3] = { { 8, 62, 89 }, // I { 255, 255, 255 }, // white { 58, 0, 126 }, // +Q { 19, 19, 19 }, // black }; static int row3b[3][3] = { { 0, 0, 0 }, // 3.5 { 19, 19, 19 }, // 7.5 { 38, 38, 38 }, // 11.5 }; static int row3c[3] = { 19, 19, 19 }; int row1Height = (int)(0.66 * frameHeight); int row2Height = (int)((0.75 * frameHeight) - row1Height); row1Height = (row1Height>>1)*2; //Require that height is even. row2Height = (row2Height>>1)*2; int row3Height = frameHeight - row1Height - row2Height; int columns[8]; PINDEX i; for(i=0;i<7;i++) { columns[i]= i*frameWidth/7; columns[i]= (columns[i]>>1)*2; // require that columns[i] is even. } columns[7] = frameWidth; // first row for (i = 0; i < 6; i++) FillRect(resFrame, columns[i], 0, columns[i+1]-columns[i], row1Height, //x,y,w,h row1[i][0], row1[i][1], row1[i][2]); // rgb // second row for (i = 0; i < 7; i++) FillRect(resFrame, columns[i], row1Height, columns[i+1]-columns[i], row2Height, row2[i][0], row2[i][1], row2[i][2]); // third row int columnBot[5]; for (i=0; i<4; i++) { columnBot[i]= i*columns[5]/4; columnBot[i] = 2 * (columnBot[i]>>1); } columnBot[4]= columns[5]; for (i = 0; i < 4; i++) FillRect(resFrame, columnBot[i],row1Height + row2Height, columnBot[i+1]-columnBot[i], row3Height, row3a[i][0], row3a[i][1], row3a[i][2]); for (i=0; i<3; i++) { columnBot[i] = columns[4]+(i*frameWidth)/(7*3); columnBot[i] = 2 * (columnBot[i]>>1); //Force even. } columnBot[3]= columns[5]; for (i = 0; i < 3; i++) FillRect(resFrame, columnBot[i], row1Height + row2Height, columnBot[i+1] - columnBot[i], row3Height, row3b[i][0], row3b[i][1], row3b[i][2]); FillRect(resFrame, columns[6], row1Height + row2Height, columns[7] - columns[6], row3Height, row3c[0], row3c[1], row3c[2]);}void PVideoInputDevice_FakeVideo::GrabMovingBlocksTestFrame(BYTE * resFrame){ // Test image # 2 /*Brightness is set to alter, left to right. Colour component alters top to bottom. Image contains lots of high and low resolution areas. */ unsigned wi,hi, colourIndex,colNo, boxSize; #define COL(b,x,y) ((b+x+y)%7) static int background[7][3] = { { 254, 254, 254 }, // white { 255, 255, 0 }, // yellow { 0, 255, 255 }, // cyan { 0, 255, 0 }, // green { 255, 0, 255 }, // magenta { 255, 0, 0 }, // red { 0, 0, 255 }, // blue }; int columns[9]; int heights[9]; int offset; offset = (frameWidth >> 3) & 0xffe; for(wi = 0; wi < 8; wi++) columns[wi] = wi * offset; columns[8] = frameWidth; offset = (frameHeight >> 3) & 0xffe; for(hi = 0; hi < 9; hi++) heights[hi] = hi * offset; heights[8] = frameHeight; grabCount++; colourIndex = time(NULL);//time in seconds since last epoch. // Provides a difference if run on two ohphone sessions. colNo = (colourIndex / 10) % 7; //Every 10 seconds, coloured background blocks move. for(hi = 0; hi < 8; hi++) //Fill the background in. for(wi = 0 ; wi < 8; wi++) { FillRect(resFrame, columns[wi], heights[hi], columns[wi + 1] - columns[wi], heights[hi + 1] - heights[hi], background[COL(colNo, wi, hi)][0], background[COL(colNo, wi, hi)][1], background[COL(colNo, wi, hi)][2]); } //Draw a black box rapidly moving down the left of the window. boxSize= frameHeight / 10; hi = ((3 * colourIndex) % (frameHeight-boxSize)) & 0xffe; //Make certain hi is even. FillRect(resFrame, 10, hi, boxSize, boxSize, 0, 0, 0); //Black Box. //Draw four parallel black lines, which move up the middle of the window. colourIndex = colourIndex / 3; //Every three seconds, lines move. for(wi = 0; wi < 2; wi++) columns[wi]= (((wi + 1) * frameWidth) / 3) & 0xffe;// Force columns to be even. hi = colourIndex % ((frameHeight - 16) / 2); hi = (frameHeight - 16) - (hi * 2); //hi is even, Lines move in opp. direction to box. unsigned yi; for(yi = 0; yi < 4; yi++) FillRect(resFrame, columns[0], hi+(yi * 4), columns[1] - columns[0], 2, 0, 0, 0);}void PVideoInputDevice_FakeVideo::GrabMovingLineTestFrame(BYTE *resFrame){ // Test image # 3 // Faster image generation. Same every times system runs. // Colours cycle through. Have a vertical lines style of pattern. // There is a horizontal bar which moves down the screen . static int v=0; int r,g,b; v++; r = (200+v) & 255; g = (100+v) & 255; b = (000+v) & 255; FillRect(resFrame, 0, 0,frameWidth, frameHeight, r, g, b); int hi = (v % (frameHeight-2) >> 1) *2; FillRect(resFrame, 0, hi, frameWidth, 2, 0, 0, 0);}void PVideoInputDevice_FakeVideo::GrabBlankImage(BYTE *resFrame){ // Change colour every second, cycle is: // black, red, green, yellow, blue, magenta, cyan, white int mask = grabCount/frameRate; FillRect(resFrame, 0, 0, frameWidth, frameHeight, //Fill the whole frame with the colour. (mask&1) ? 255 : 0, // red (mask&2) ? 255 : 0, // green (mask&4) ? 255 : 0);//blue}void PVideoInputDevice_FakeVideo::GrabOriginalMovingBlocksFrame(BYTE *frame){ unsigned wi,hi,colourIndex,colourNumber; int framesize = frameWidth*frameHeight; static int gCount=0; gCount++; colourIndex = gCount/10; colourNumber= (colourIndex/10)%7; //Every 10 seconds, coloured background blocks move. for(hi=0; hi<frameHeight; hi++) //slow moving group of lines going upwards. for(wi=0; wi<frameWidth; wi++) if ( (wi>frameWidth/3)&&(wi<frameWidth*2/3)&& ( ((gCount+hi)%frameHeight)<16)&& ( (hi%4)<2) ) frame[(hi*frameWidth)+wi] = 16; else frame[(hi*frameWidth)+wi] = (BYTE)(((colourNumber+((wi*7)/frameWidth))%7)*35+26); for(hi=1; hi<=frameHeight; hi++) //fast moving block going downwards. for(wi=frameWidth/9; wi<(2*frameWidth/9); wi++) if( (( (gCount*4)+hi)%frameHeight)<20) frame[((frameHeight-hi)*frameWidth)+wi] = 16; unsigned halfWidth = frameWidth/2; unsigned halfHeight = frameHeight/2; for(hi=1; hi<halfHeight; hi++) for(wi=0; wi<halfWidth; wi++) frame[framesize+(hi*halfWidth)+wi] = (BYTE)(((((hi*7)/halfHeight)+colourNumber)%7)*35+26);}void PVideoInputDevice_FakeVideo::GrabTextVideoFrame(BYTE *resFrame){ PINDEX i, j; static PTime startTime; grabCount++; FillRect(resFrame, 0, 0, frameWidth, frameHeight, //Fill the whole frame with the colour. 200, 200, 200); //a light grey colour. if (textLine[0].GetLength() < 2) { PStringStream message; message << PProcess::Current().GetUserName() << " on " << PProcess::Current().GetOSName() << ":" << PProcess::Current().GetOSHardware(); PINDEX nChars = message.GetLength(); OneVFakeLetterData *ld; for (j = 0; j < MAX_L_HEIGHT; j++) textLine[j] = ""; for (i = 0; i < (nChars + 2); i++){ if (i >= nChars) ld = FindLetter(' '); else ld = FindLetter(message[i]); if (ld == NULL) continue; for (j = 0; j < MAX_L_HEIGHT; j++) textLine[j] += ld->line[j] + PString(" "); } } PINDEX boxSize = (frameHeight / (MAX_L_HEIGHT * 2) ) & 0xffe; int index = (int)((PTime() - startTime).GetMilliSeconds() / 300); PINDEX maxI = (frameWidth / boxSize) - 2; for (i = 0; i < maxI; i++) for (j = 0; j < MAX_L_HEIGHT; j++) { PINDEX ii = (index + i) % textLine[0].GetLength(); if (textLine[j][ii] != ' ') FillRect(resFrame, (i + 1) * boxSize, (frameHeight / 3) + ((j + 1) * boxSize), //x,y start pos boxSize, boxSize, //x,y dimension 250, 00, 00); //red box. }}OneVFakeLetterData *PVideoInputDevice_FakeVideo::FindLetter(char ascii){ int q; int fontNumLetters = sizeof(vFakeLetterData) / sizeof(OneVFakeLetterData); if (ascii == '\t') ascii = ' '; for (q = 0; q < fontNumLetters; q++) if (vFakeLetterData[q].ascii == ascii) return vFakeLetterData + q; return NULL;}//////////////////////////////////////////////////////////////////////////////////////////////////////////**This class defines a NULL video output device. This will do precisely nothing with the output. */class PVideoOutputDevice_NULLOutput : public PVideoOutputDevice{ PCLASSINFO(PVideoOutputDevice_NULLOutput, PVideoOutputDevice); public: /** Create a new video output device. */ PVideoOutputDevice_NULLOutput(); /**Get a list of all of the drivers available. */ static PStringList GetOutputDeviceNames(); virtual PStringList GetDeviceNames() const { return GetOutputDeviceNames(); } /**Open the device given the device name. */ virtual BOOL Open( const PString & deviceName, /// Device name to open BOOL startImmediate = TRUE /// Immediately start device ); /**Start the video device I/O. */ BOOL Start(); /**Stop the video device I/O capture. */ BOOL Stop(); /**Close the device. */ virtual BOOL Close(); /**Determine if the device is currently open. */ virtual BOOL IsOpen(); /**Get the maximum frame size in bytes. Note a particular device may be able to provide variable length frames (eg motion JPEG) so will be the maximum size of all frames. */ virtual PINDEX GetMaxFrameBytes(); /**Set a section of the output frame buffer. */ virtual BOOL SetFrameData( unsigned x, unsigned y, unsigned width, unsigned height, const BYTE * data, BOOL endFrame = TRUE ); /**Indicate frame may be displayed. */ virtual BOOL EndFrame();};PCREATE_VIDOUTPUT_PLUGIN(NULLOutput);///////////////////////////////////////////////////////////////////////////////// PVideoOutputDevice_NULLOutputPVideoOutputDevice_NULLOutput::PVideoOutputDevice_NULLOutput(){ deviceName = "NULL";}BOOL PVideoOutputDevice_NULLOutput::Open(const PString & /*deviceName*/, BOOL /*startImmediate*/){ return TRUE;}BOOL PVideoOutputDevice_NULLOutput::Close(){ return TRUE;}BOOL PVideoOutputDevice_NULLOutput::Start(){ return TRUE;}BOOL PVideoOutputDevice_NULLOutput::Stop(){ return TRUE;}BOOL PVideoOutputDevice_NULLOutput::IsOpen(){ return TRUE;}PStringList PVideoOutputDevice_NULLOutput::GetOutputDeviceNames(){ PStringList list; list += "NULL"; return list;}PINDEX PVideoOutputDevice_NULLOutput::GetMaxFrameBytes(){ return GetMaxFrameBytesConverted(CalculateFrameBytes(frameWidth, frameHeight, colourFormat));}BOOL PVideoOutputDevice_NULLOutput::SetFrameData(unsigned /*x*/, unsigned /*y*/, unsigned /*width*/, unsigned /*height*/, const BYTE * /*data*/, BOOL /*endFrame*/){ return TRUE;}BOOL PVideoOutputDevice_NULLOutput::EndFrame(){ return TRUE;}// End Of File ///////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -