|
|
//==========================================================================;
//
// 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 - 1999 Microsoft Corporation. All Rights Reserved.
//
//==========================================================================;
#include "strmini.h"
#include "ksmedia.h"
#include "capmain.h"
#include "capdebug.h"
#include "vbixfer.h"
#include "vbidata.h"
/*
** DEBUG variables to play with */ #if DBG
unsigned short dCCScanWave = 0; unsigned short dCCScanLog = 0; unsigned short dCCLogOnce = 1; unsigned short dCCEncode5A = 0; #endif //DBG
/*
** CC_ImageSynth() ** ** Copies canned CC bytes ** ** Arguments: ** ** pSrb - The stream request block for the Video stream ** ** Returns: ** Nothing ** ** Side Effects: none */
void CC_ImageSynth ( IN OUT PHW_STREAM_REQUEST_BLOCK pSrb ) { PSTREAMEX pStrmEx = pSrb->StreamObject->HwStreamExtension; int StreamNumber = pSrb->StreamObject->StreamNumber; PKSSTREAM_HEADER pStreamHeader = pSrb->CommandData.DataBufferArray; PCC_HW_FIELD pCCfield = (PCC_HW_FIELD)pStreamHeader->Data; unsigned int field; unsigned int cc_index;
DEBUG_ASSERT(pSrb->NumberOfBuffers == 1);
if (pSrb->CommandData.DataBufferArray->FrameExtent < sizeof (CC_HW_FIELD)) { DbgLogError(("testcap: CC output pin handed buffer size %d, need %d\n", pSrb->CommandData.DataBufferArray->FrameExtent, sizeof (CC_HW_FIELD)));
TRAP; return; }
field = (unsigned int)(pStrmEx->VBIFrameInfo.PictureNumber % CCfieldCount);
RtlZeroMemory(pCCfield, sizeof (*pCCfield)); cc_index = 0;
pCCfield->PictureNumber = pStrmEx->VBIFrameInfo.PictureNumber; pCCfield->fieldFlags = (field & 1)? KS_VBI_FLAG_FIELD1 : KS_VBI_FLAG_FIELD2; field >>= 1;
SETBIT(pCCfield->ScanlinesRequested.DwordBitArray, 21); if (KS_VBI_FLAG_FIELD1 == pCCfield->fieldFlags) { pCCfield->Lines[cc_index].Decoded[0] = CCfields[field][0]; pCCfield->Lines[cc_index].Decoded[1] = CCfields[field][1]; } else { pCCfield->Lines[cc_index].Decoded[0] = 0; pCCfield->Lines[cc_index].Decoded[1] = 0; } //DbgKdPrint(("%c%c", CCfields[field][0] & 0x7F, CCfields[field][1] & 0x7F));
++cc_index;
pStreamHeader->DataUsed = sizeof (CC_HW_FIELD); }
/*
** CC_EncodeWaveform() ** ** Writes out a CC waveform encoding the supplied data bytes ** ** Arguments: ** ** waveform - the buffer for the CC waveform data ** cc1 - the first byte to encode into the waveform ** cc2 - the second byte to encode into the waveform ** ** Returns: ** Nothing ** ** Side Effects: overwrites waveform with an EIA-608 signal */ void CC_EncodeWaveform( unsigned char *waveform, unsigned char cc1, unsigned char cc2) { unsigned int waveIdx; unsigned char DC_zero = CCsampleWave[0]; unsigned char DC_one = CCsampleWave[34]; unsigned short DC_last;
// 455/8 = 56.875 bytes per CC bit at KS_VBISAMPLINGRATE_5X_NABTS(~28.6mhz)
unsigned int CCstride = 455;
unsigned char *samp, *end, byte; unsigned int bit, done;
#if DBG
if (dCCEncode5A) { cc1 = 0x5A; cc2 = 0x5A; }
if (dCCScanWave) { // Scan EIGHT bits worth of samples for low / high DC values
for (samp=CCsampleWave, end=CCsampleWave+CCstride; samp < end; ++samp) { if (*samp > DC_one) DC_one = *samp; else if (*samp < DC_zero) DC_zero = *samp; }
for (samp = CCsampleWave + 500; samp < &CCsampleWave[550] ; ++samp) { if (*samp >= DC_one - 5) break; } waveIdx = (unsigned int)((samp - CCsampleWave) * 8);
if (dCCScanLog) { DbgKdPrint(("testcap::CC_EncodeWaveform: DC_zero = %u, DC_one = %u, waveIdx = %u\n", DC_zero, DC_one, waveIdx/8)); dCCScanLog = 0; } } else { #endif //DBG
waveIdx = CCsampleWaveDataOffset * 8; DC_zero = CCsampleWaveDC_zero; DC_one = CCsampleWaveDC_one; #if DBG
}
#endif //DBG
// Copy Run-in bytes and first three bits as-is
RtlCopyMemory(waveform, CCsampleWave, waveIdx/8); DC_last = waveform[waveIdx/8 - 1] * 4;
// Now encode the requested bytes
samp = &waveform[waveIdx/8]; for (byte = cc1, done = 0; ; byte = cc2, done = 1) { unsigned int bitpos;
for (bitpos = 0; bitpos < 8; ++bitpos) { bit = byte & 1; byte >>= 1; for (end = &waveform[(waveIdx + CCstride)/8]; samp < end; ++samp) { if (bit == 1) { if (DC_last/4 < DC_one) { DC_last += 7; if (DC_last/4 > DC_one) DC_last = DC_one * 4; } } else /* bit == 0 */ { if (DC_last/4 > DC_zero) { DC_last -= 7; if (DC_last/4 < DC_zero) DC_last = DC_zero * 4; } } ASSERT(samp < &waveform[768*2]); *samp = DC_last/4; } waveIdx += CCstride; }
if (done) break; }
// Finish up at DC_zero
for (end = &waveform[768*2]; samp < end; ++samp) { if (DC_last/4 > DC_zero) { DC_last -= 7; if (DC_last/4 < DC_zero) DC_last = DC_zero * 4; } *samp = DC_last/4; } }
/*
** NABTS_ImageSynth() ** ** Copies canned NABTS bytes ** ** Arguments: ** ** pSrb - The stream request block for the Video stream ** ** Returns: ** Nothing ** ** Side Effects: none */
unsigned char HammingEncode[16] = { 0x15, 0x02, 0x49, 0x5E, 0x64, 0x73, 0x38, 0x2F, 0xD0, 0xC7, 0x8C, 0x9B, 0xA1, 0xB6, 0xFD, 0xEA };
void NABTS_ImageSynth ( IN OUT PHW_STREAM_REQUEST_BLOCK pSrb ) { PSTREAMEX pStrmEx = pSrb->StreamObject->HwStreamExtension; int StreamNumber = pSrb->StreamObject->StreamNumber;
PKSSTREAM_HEADER pStreamHeader = pSrb->CommandData.DataBufferArray; PNABTS_BUFFER pNbuf = (PNABTS_BUFFER)pStreamHeader->Data;
unsigned int field;
#ifdef VBIDATA_NABTS
// Check to make sure that the supplied buffer is large enough
if (pSrb->CommandData.DataBufferArray->FrameExtent < sizeof (NABTS_BUFFER)) { DbgLogError(("testcap: NABTS output pin handed buffer size %d, need %d\n", pSrb->CommandData.DataBufferArray->FrameExtent, sizeof (NABTS_BUFFER)));
TRAP; return; }
DEBUG_ASSERT (pSrb->NumberOfBuffers == 1);
pNbuf->PictureNumber = pStrmEx->VBIFrameInfo.PictureNumber;
// Copy the next apropriate field
field = (unsigned int)(pStrmEx->VBIFrameInfo.PictureNumber % NABTSfieldCount); RtlCopyMemory(pNbuf, NABTSfields[field], sizeof (NABTS_BUFFER));
#else /*VBIDATA_NABTS*/
unsigned char i, line, ci; PNABTS_BUFFER_LINE pNline;
// Check to make sure that the supplied buffer is large enough
if (pSrb->CommandData.DataBufferArray->FrameExtent < sizeof (NABTS_BUFFER)) { DbgLogError(("testcap: NABTS output pin handed buffer size %d, need %d\n", pSrb->CommandData.DataBufferArray->FrameExtent, sizeof (NABTS_BUFFER)));
TRAP; return; }
// Create a test pattern
RtlZeroMemory(pNbuf, sizeof (NABTS_BUFFER));
ci = (unsigned char)(pStrmEx->VBIFrameInfo.PictureNumber % 15); pNbuf->PictureNumber = pStrmEx->VBIFrameInfo.PictureNumber; for (line = 10, pNline = pNbuf->NabtsLines; line < 21; ++line, ++pNline) { SETBIT(pNbuf->ScanlinesRequested.DwordBitArray, line);
pNline->Confidence = 102; // We're 102% sure this NABTS is OK
// NABTS Header bytes
pNline->Bytes[00] = pNline->Bytes[01] = 0x55; pNline->Bytes[02] = 0xE7;
// Set GroupID 0x8F4
pNline->Bytes[03] = HammingEncode[0x8]; pNline->Bytes[04] = HammingEncode[0xF]; pNline->Bytes[05] = HammingEncode[0x4];
pNline->Bytes[06] = HammingEncode[ci]; pNline->Bytes[07] = HammingEncode[0x0]; // PS = Reg, Full, No suffix
// NABTS Payload
i = 8; pNline->Bytes[i++] = 0xA0; // Mark the start of payload,
pNline->Bytes[i++] = 0xA0; // just for fun
pNline->Bytes[i++] = ci; // Put frame # into payload
pNline->Bytes[i++] = line; // Put line # into payload
// The rest zeros for now...
}
#endif /*VBIDATA_NABTS*/
pStreamHeader->DataUsed = sizeof (NABTS_BUFFER); }
/*
** VBI_ImageSynth() ** ** Copies canned VBI samples ** ** Arguments: ** ** pSrb - The stream request block for the Video stream ** ImageXferCommands - Index specifying the image to generate ** ** Returns: ** Nothing ** ** Side Effects: none */ void VBI_ImageSynth ( IN OUT PHW_STREAM_REQUEST_BLOCK pSrb ) { PSTREAMEX pStrmEx = pSrb->StreamObject->HwStreamExtension; int StreamNumber = pSrb->StreamObject->StreamNumber;
PKSSTREAM_HEADER pStreamHeader = pSrb->CommandData.DataBufferArray; PUCHAR pImage = pStreamHeader->Data;
unsigned int field, cc_field; unsigned char cc1, cc2;
DEBUG_ASSERT (pSrb->NumberOfBuffers == 1);
// Check to make sure that the supplied buffer is large enough
if (pSrb->CommandData.DataBufferArray->FrameExtent < VBIfieldSize) { DbgLogError(("testcap: VBI output pin handed buffer size %d, need %d\n", pSrb->CommandData.DataBufferArray->FrameExtent, VBIfieldSize)); TRAP; return; }
// Copy the next apropriate field
field = (unsigned int)(pStrmEx->VBIFrameInfo.PictureNumber % VBIfieldCount); RtlCopyMemory(pImage, VBIsamples[field], VBIfieldSize);
// Now mangle the CC waveform to match the HW data
if (field & 1) { cc_field = (unsigned int) (pStrmEx->VBIFrameInfo.PictureNumber >> 1) % CCfieldCount; cc1 = CCfields[cc_field][0]; cc2 = CCfields[cc_field][1]; } else { cc1 = 0; cc2 = 0; } CC_EncodeWaveform(VBIsamples[field][21-10], cc1, cc2);
// Report back the actual number of bytes copied to the destination buffer
pStreamHeader->DataUsed = VBIfieldSize; }
|