Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

348 lines
9.7 KiB

  1. //==========================================================================;
  2. //
  3. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  4. // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  5. // IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  6. // PURPOSE.
  7. //
  8. // Copyright (c) 1992 - 1999 Microsoft Corporation. All Rights Reserved.
  9. //
  10. //==========================================================================;
  11. #include "strmini.h"
  12. #include "ksmedia.h"
  13. #include "capmain.h"
  14. #include "capdebug.h"
  15. #include "vbixfer.h"
  16. #include "vbidata.h"
  17. /*
  18. ** DEBUG variables to play with
  19. */
  20. #if DBG
  21. unsigned short dCCScanWave = 0;
  22. unsigned short dCCScanLog = 0;
  23. unsigned short dCCLogOnce = 1;
  24. unsigned short dCCEncode5A = 0;
  25. #endif //DBG
  26. /*
  27. ** CC_ImageSynth()
  28. **
  29. ** Copies canned CC bytes
  30. **
  31. ** Arguments:
  32. **
  33. ** pSrb - The stream request block for the Video stream
  34. **
  35. ** Returns:
  36. ** Nothing
  37. **
  38. ** Side Effects: none
  39. */
  40. void CC_ImageSynth (
  41. IN OUT PHW_STREAM_REQUEST_BLOCK pSrb
  42. )
  43. {
  44. PSTREAMEX pStrmEx = pSrb->StreamObject->HwStreamExtension;
  45. int StreamNumber = pSrb->StreamObject->StreamNumber;
  46. PKSSTREAM_HEADER pStreamHeader = pSrb->CommandData.DataBufferArray;
  47. PCC_HW_FIELD pCCfield = (PCC_HW_FIELD)pStreamHeader->Data;
  48. unsigned int field;
  49. unsigned int cc_index;
  50. DEBUG_ASSERT(pSrb->NumberOfBuffers == 1);
  51. field = (unsigned int)(pStrmEx->VBIFrameInfo.PictureNumber % CCfieldCount);
  52. RtlZeroMemory(pCCfield, sizeof (*pCCfield));
  53. cc_index = 0;
  54. pCCfield->PictureNumber = pStrmEx->VBIFrameInfo.PictureNumber;
  55. pCCfield->fieldFlags = (field & 1)? KS_VBI_FLAG_FIELD1 : KS_VBI_FLAG_FIELD2;
  56. field >>= 1;
  57. SETBIT(pCCfield->ScanlinesRequested.DwordBitArray, 21);
  58. if (KS_VBI_FLAG_FIELD1 == pCCfield->fieldFlags) {
  59. pCCfield->Lines[cc_index].Decoded[0] = CCfields[field][0];
  60. pCCfield->Lines[cc_index].Decoded[1] = CCfields[field][1];
  61. }
  62. else {
  63. pCCfield->Lines[cc_index].Decoded[0] = 0;
  64. pCCfield->Lines[cc_index].Decoded[1] = 0;
  65. }
  66. //DbgKdPrint(("%c%c", CCfields[field][0] & 0x7F, CCfields[field][1] & 0x7F));
  67. ++cc_index;
  68. pStreamHeader->DataUsed = sizeof (CC_HW_FIELD);
  69. }
  70. /*
  71. ** CC_EncodeWaveform()
  72. **
  73. ** Writes out a CC waveform encoding the supplied data bytes
  74. **
  75. ** Arguments:
  76. **
  77. ** waveform - the buffer for the CC waveform data
  78. ** cc1 - the first byte to encode into the waveform
  79. ** cc2 - the second byte to encode into the waveform
  80. **
  81. ** Returns:
  82. ** Nothing
  83. **
  84. ** Side Effects: overwrites waveform with an EIA-608 signal
  85. */
  86. void CC_EncodeWaveform(
  87. unsigned char *waveform,
  88. unsigned char cc1,
  89. unsigned char cc2)
  90. {
  91. unsigned int waveIdx;
  92. unsigned char DC_zero = CCsampleWave[0];
  93. unsigned char DC_one = CCsampleWave[34];
  94. unsigned short DC_last;
  95. // 455/8 = 56.875 bytes per CC bit at KS_VBISAMPLINGRATE_5X_NABTS(~28.6mhz)
  96. unsigned int CCstride = 455;
  97. unsigned char *samp, *end, byte;
  98. unsigned int bit, done;
  99. #if DBG
  100. if (dCCEncode5A) {
  101. cc1 = 0x5A;
  102. cc2 = 0x5A;
  103. }
  104. if (dCCScanWave) {
  105. // Scan EIGHT bits worth of samples for low / high DC values
  106. for (samp=CCsampleWave, end=CCsampleWave+CCstride; samp < end; ++samp) {
  107. if (*samp > DC_one)
  108. DC_one = *samp;
  109. else if (*samp < DC_zero)
  110. DC_zero = *samp;
  111. }
  112. for (samp = CCsampleWave + 500; samp < &CCsampleWave[550] ; ++samp) {
  113. if (*samp >= DC_one - 5)
  114. break;
  115. }
  116. waveIdx = (unsigned int)((samp - CCsampleWave) * 8);
  117. if (dCCScanLog) {
  118. DbgKdPrint(("testcap::CC_EncodeWaveform: DC_zero = %u, DC_one = %u, waveIdx = %u\n", DC_zero, DC_one, waveIdx/8));
  119. dCCScanLog = 0;
  120. }
  121. }
  122. else {
  123. #endif //DBG
  124. waveIdx = CCsampleWaveDataOffset * 8;
  125. DC_zero = CCsampleWaveDC_zero;
  126. DC_one = CCsampleWaveDC_one;
  127. #if DBG
  128. }
  129. #endif //DBG
  130. // Copy Run-in bytes and first three bits as-is
  131. RtlCopyMemory(waveform, CCsampleWave, waveIdx/8);
  132. DC_last = waveform[waveIdx/8 - 1] * 4;
  133. // Now encode the requested bytes
  134. samp = &waveform[waveIdx/8];
  135. for (byte = cc1, done = 0; ; byte = cc2, done = 1)
  136. {
  137. unsigned int bitpos;
  138. for (bitpos = 0; bitpos < 8; ++bitpos) {
  139. bit = byte & 1;
  140. byte >>= 1;
  141. for (end = &waveform[(waveIdx + CCstride)/8]; samp < end; ++samp) {
  142. if (bit == 1) {
  143. if (DC_last/4 < DC_one) {
  144. DC_last += 7;
  145. if (DC_last/4 > DC_one)
  146. DC_last = DC_one * 4;
  147. }
  148. }
  149. else /* bit == 0 */ {
  150. if (DC_last/4 > DC_zero) {
  151. DC_last -= 7;
  152. if (DC_last/4 < DC_zero)
  153. DC_last = DC_zero * 4;
  154. }
  155. }
  156. ASSERT(samp < &waveform[768*2]);
  157. *samp = DC_last/4;
  158. }
  159. waveIdx += CCstride;
  160. }
  161. if (done)
  162. break;
  163. }
  164. // Finish up at DC_zero
  165. for (end = &waveform[768*2]; samp < end; ++samp) {
  166. if (DC_last/4 > DC_zero) {
  167. DC_last -= 7;
  168. if (DC_last/4 < DC_zero)
  169. DC_last = DC_zero * 4;
  170. }
  171. *samp = DC_last/4;
  172. }
  173. }
  174. /*
  175. ** NABTS_ImageSynth()
  176. **
  177. ** Copies canned NABTS bytes
  178. **
  179. ** Arguments:
  180. **
  181. ** pSrb - The stream request block for the Video stream
  182. **
  183. ** Returns:
  184. ** Nothing
  185. **
  186. ** Side Effects: none
  187. */
  188. unsigned char HammingEncode[16] = {
  189. 0x15, 0x02, 0x49, 0x5E, 0x64, 0x73, 0x38, 0x2F,
  190. 0xD0, 0xC7, 0x8C, 0x9B, 0xA1, 0xB6, 0xFD, 0xEA
  191. };
  192. void NABTS_ImageSynth (
  193. IN OUT PHW_STREAM_REQUEST_BLOCK pSrb
  194. )
  195. {
  196. PSTREAMEX pStrmEx = pSrb->StreamObject->HwStreamExtension;
  197. int StreamNumber = pSrb->StreamObject->StreamNumber;
  198. PKSSTREAM_HEADER pStreamHeader = pSrb->CommandData.DataBufferArray;
  199. PNABTS_BUFFER pNbuf = (PNABTS_BUFFER)pStreamHeader->Data;
  200. unsigned int field;
  201. #ifdef VBIDATA_NABTS
  202. DEBUG_ASSERT (pSrb->NumberOfBuffers == 1);
  203. pNbuf->PictureNumber = pStrmEx->VBIFrameInfo.PictureNumber;
  204. // Copy the next apropriate field
  205. field = (unsigned int)(pStrmEx->VBIFrameInfo.PictureNumber % NABTSfieldCount);
  206. RtlCopyMemory(pNbuf, NABTSfields[field], sizeof (NABTS_BUFFER));
  207. #else /*VBIDATA_NABTS*/
  208. unsigned char i, line, ci;
  209. PNABTS_BUFFER_LINE pNline;
  210. // Create a test pattern
  211. RtlZeroMemory(pNbuf, sizeof (NABTS_BUFFER));
  212. ci = (unsigned char)(pStrmEx->VBIFrameInfo.PictureNumber % 15);
  213. pNbuf->PictureNumber = pStrmEx->VBIFrameInfo.PictureNumber;
  214. for (line = 10, pNline = pNbuf->NabtsLines;
  215. line < 21;
  216. ++line, ++pNline)
  217. {
  218. SETBIT(pNbuf->ScanlinesRequested.DwordBitArray, line);
  219. pNline->Confidence = 102; // We're 102% sure this NABTS is OK
  220. // NABTS Header bytes
  221. pNline->Bytes[00] =
  222. pNline->Bytes[01] = 0x55;
  223. pNline->Bytes[02] = 0xE7;
  224. // Set GroupID 0x8F4
  225. pNline->Bytes[03] = HammingEncode[0x8];
  226. pNline->Bytes[04] = HammingEncode[0xF];
  227. pNline->Bytes[05] = HammingEncode[0x4];
  228. pNline->Bytes[06] = HammingEncode[ci];
  229. pNline->Bytes[07] = HammingEncode[0x0]; // PS = Reg, Full, No suffix
  230. // NABTS Payload
  231. i = 8;
  232. pNline->Bytes[i++] = 0xA0; // Mark the start of payload,
  233. pNline->Bytes[i++] = 0xA0; // just for fun
  234. pNline->Bytes[i++] = ci; // Put frame # into payload
  235. pNline->Bytes[i++] = line; // Put line # into payload
  236. // The rest zeros for now...
  237. }
  238. #endif /*VBIDATA_NABTS*/
  239. pStreamHeader->DataUsed = sizeof (NABTS_BUFFER);
  240. }
  241. /*
  242. ** VBI_ImageSynth()
  243. **
  244. ** Copies canned VBI samples
  245. **
  246. ** Arguments:
  247. **
  248. ** pSrb - The stream request block for the Video stream
  249. ** ImageXferCommands - Index specifying the image to generate
  250. **
  251. ** Returns:
  252. ** Nothing
  253. **
  254. ** Side Effects: none
  255. */
  256. void VBI_ImageSynth (
  257. IN OUT PHW_STREAM_REQUEST_BLOCK pSrb
  258. )
  259. {
  260. PSTREAMEX pStrmEx = pSrb->StreamObject->HwStreamExtension;
  261. int StreamNumber = pSrb->StreamObject->StreamNumber;
  262. PKSSTREAM_HEADER pStreamHeader = pSrb->CommandData.DataBufferArray;
  263. PUCHAR pImage = pStreamHeader->Data;
  264. unsigned int field, cc_field;
  265. unsigned char cc1, cc2;
  266. DEBUG_ASSERT (pSrb->NumberOfBuffers == 1);
  267. // Check to make sure that the supplied buffer is large enough
  268. if (pSrb->CommandData.DataBufferArray->FrameExtent < VBIfieldSize) {
  269. DbgLogError(("testcap: VBI output pin handed buffer size %d, need %d\n",
  270. pSrb->CommandData.DataBufferArray->FrameExtent,
  271. VBIfieldSize));
  272. TRAP;
  273. return;
  274. }
  275. // Copy the next apropriate field
  276. field = (unsigned int)(pStrmEx->VBIFrameInfo.PictureNumber % VBIfieldCount);
  277. RtlCopyMemory(pImage, VBIsamples[field], VBIfieldSize);
  278. // Now mangle the CC waveform to match the HW data
  279. if (field & 1) {
  280. cc_field = (unsigned int)
  281. (pStrmEx->VBIFrameInfo.PictureNumber >> 1) % CCfieldCount;
  282. cc1 = CCfields[cc_field][0];
  283. cc2 = CCfields[cc_field][1];
  284. }
  285. else {
  286. cc1 = 0;
  287. cc2 = 0;
  288. }
  289. CC_EncodeWaveform(VBIsamples[field][21-10], cc1, cc2);
  290. // Report back the actual number of bytes copied to the destination buffer
  291. pStreamHeader->DataUsed = VBIfieldSize;
  292. }