//==========================================================================; // // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR // PURPOSE. // // Copyright (c) 1992 - 1997 Microsoft Corporation. All Rights Reserved. // //==========================================================================; #include "strmini.h" #include "ksmedia.h" #include "capmain.h" #include "capdebug.h" #include "capxfer.h" // // EIA-189-A Standard color bar definitions // // 75% Amplitude, 100% Saturation const static UCHAR NTSCColorBars75Amp100SatRGB24 [3][8] = { // Whi Yel Cya Grn Mag Red Blu Blk 191, 0,191, 0,191, 0,191, 0, // Blue 191,191,191,191, 0, 0, 0, 0, // Green 191,191, 0, 0,191,191, 0, 0, // Red }; // 100% Amplitude, 100% Saturation const static UCHAR NTSCColorBars100Amp100SatRGB24 [3][8] = { // Whi Yel Cya Grn Mag Red Blu Blk 255, 0,255, 0,255, 0,255, 0, // Blue 255,255,255,255, 0, 0, 0, 0, // Green 255,255, 0, 0,255,255, 0, 0, // Red }; const static UCHAR NTSCColorBars100Amp100SatYUV [4][8] = { // Whi Yel Cya Grn Mag Red Blu Blk 128, 16,166, 54,202, 90,240,128, // U 235,211,170,145,106, 81, 41, 16, // Y 128,146, 16, 34,222,240,109,128, // V 235,211,170,145,106, 81, 41, 16 // Y }; /* ** ImageSynth() ** ** Synthesizes NTSC color bars, white, black, and grayscale images ** ** Arguments: ** ** pSrb - The stream request block for the Video stream ** ImageXferCommands - Index specifying the image to generate ** ** Returns: ** ** Nothing ** ** Side Effects: none */ void ImageSynth ( IN OUT PHW_STREAM_REQUEST_BLOCK pSrb, IN ImageXferCommands Command, IN BOOL FlipHorizontal ) { PSTREAMEX pStrmEx = (PSTREAMEX)pSrb->StreamObject->HwStreamExtension; PHW_DEVICE_EXTENSION pHwDevExt = ((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension); int StreamNumber = pSrb->StreamObject->StreamNumber; UINT Line; PUCHAR pLineBuffer; PKSSTREAM_HEADER pDataPacket = pSrb->CommandData.DataBufferArray; PUCHAR pImage = pDataPacket->Data; KS_VIDEOINFOHEADER *pVideoInfoHdr; UINT biWidth; UINT biHeight; UINT biSizeImage; UINT biWidthBytes; UINT biBitCount; UINT LinesToCopy; DWORD biCompression; KIRQL oldIrql; // // Take the lock to avoid race from Set format property that could // from other processor in an MP system // KeAcquireSpinLock( &pStrmEx->lockVideoInfoHeader, &oldIrql ); pVideoInfoHdr = pStrmEx->pVideoInfoHeader; biWidth = pVideoInfoHdr->bmiHeader.biWidth; biHeight = pVideoInfoHdr->bmiHeader.biHeight; biSizeImage = pVideoInfoHdr->bmiHeader.biSizeImage; biWidthBytes = KS_DIBWIDTHBYTES (pVideoInfoHdr->bmiHeader); biBitCount = pVideoInfoHdr->bmiHeader.biBitCount; LinesToCopy = abs (biHeight); biCompression = pVideoInfoHdr->bmiHeader.biCompression; // // release the lock // KeReleaseSpinLock( &pStrmEx->lockVideoInfoHeader, oldIrql ); DEBUG_ASSERT (pSrb->NumberOfBuffers == 1); if (pDataPacket->FrameExtent < biSizeImage) { DbgLogError(("testcap: video output pin handed buffer size %d, need %d\n", pDataPacket->FrameExtent, biSizeImage)); TRAP; return; } #if 0 // Note: set "ulInDebug = 1" in a debugger to view this output with .ntkern DbgLogTrace(("\'TestCap: ImageSynthBegin\n")); DbgLogTrace(("\'TestCap: biSizeImage=%d, DataPacketLength=%d\n", biSizeImage, pDataPacket->DataPacketLength)); DbgLogTrace(("\'TestCap: biWidth=%d biHeight=%d WidthBytes=%d bpp=%d\n", biWidth, biHeight, biWidthBytes, biBitCount)); DbgLogTrace(("\'TestCap: pImage=%x\n", pImage)); #endif // // Synthesize a single line of image data, which will then be replicated // pLineBuffer = &pStrmEx->LineBuffer[0]; if ((biBitCount == 24) && (biCompression == KS_BI_RGB)) { switch (Command) { case IMAGE_XFER_NTSC_EIA_100AMP_100SAT: // 100% saturation { UINT x, col; PUCHAR pT = pLineBuffer; for (x = 0; x < biWidth; x++) { col = (x * 8) / biWidth; col = FlipHorizontal ? (7 - col) : col; *pT++ = NTSCColorBars100Amp100SatRGB24[0][col]; // Red *pT++ = NTSCColorBars100Amp100SatRGB24[1][col]; // Green *pT++ = NTSCColorBars100Amp100SatRGB24[2][col]; // Blue } } break; case IMAGE_XFER_NTSC_EIA_75AMP_100SAT: // 75% Saturation { UINT x, col; PUCHAR pT = pLineBuffer; for (x = 0; x < biWidth; x++) { col = (x * 8) / biWidth; col = FlipHorizontal ? (7 - col) : col; *pT++ = NTSCColorBars75Amp100SatRGB24[0][col]; // Red *pT++ = NTSCColorBars75Amp100SatRGB24[1][col]; // Green *pT++ = NTSCColorBars75Amp100SatRGB24[2][col]; // Blue } } break; case IMAGE_XFER_BLACK: // Camma corrected Grayscale ramp { UINT x, col; PUCHAR pT = pLineBuffer; for (x = 0; x < biWidth; x++) { col = (255 * (x * 10) / biWidth) / 10; col = FlipHorizontal ? (255 - col) : col; *pT++ = (BYTE) col; // Red *pT++ = (BYTE) col; // Green *pT++ = (BYTE) col; // Blue } } break; case IMAGE_XFER_WHITE: // All white RtlFillMemory( pLineBuffer, biWidthBytes, (UCHAR) 255); break; case IMAGE_XFER_GRAY_INCREASING: // grayscale increasing with each image captured RtlFillMemory( pLineBuffer, biWidthBytes, (UCHAR) (pStrmEx->FrameInfo.PictureNumber * 8)); break; default: break; } } // endif RGB24 else if ((biBitCount == 16) && (biCompression == FOURCC_YUV422)) { switch (Command) { case IMAGE_XFER_NTSC_EIA_100AMP_100SAT: default: { UINT x, col; PUCHAR pT = pLineBuffer; for (x = 0; x < (biWidth / 2); x++) { col = (x * 8) / (biWidth / 2); col = FlipHorizontal ? (7 - col) : col; *pT++ = NTSCColorBars100Amp100SatYUV[0][col]; // U *pT++ = NTSCColorBars100Amp100SatYUV[1][col]; // Y *pT++ = NTSCColorBars100Amp100SatYUV[2][col]; // V *pT++ = NTSCColorBars100Amp100SatYUV[3][col]; // Y } } break; } } else { DbgLogError(("\'TestCap: Unknown format in ImageSynth!!!\n")); TRAP; } // // Copy the single line synthesized to all rows of the image // for (Line = 0; Line < LinesToCopy; Line++, pImage += biWidthBytes) { // Show some action on an otherwise static image // This will be a changing grayscale horizontal band // at the bottom of an RGB image and a changing color band at the // top of a YUV image if (Line >= 3 && Line <= 6) { UINT j; for (j = 0; j < biWidthBytes; j++) { *(pImage + j) = (UCHAR) pStrmEx->FrameInfo.PictureNumber; } continue; } // Copy the synthesized line RtlCopyMemory( pImage, pLineBuffer, biWidthBytes); } // // Report back the actual number of bytes copied to the destination buffer // (This can be smaller than the allocated buffer for compressed images) // pDataPacket->DataUsed = biSizeImage; }