Leaked source code of windows server 2003
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.

403 lines
13 KiB

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <windows.h>
  5. #include <wincon.h>
  6. #include <conio.h>
  7. #include <ccdecode.h>
  8. #define ENTRIES(a) (sizeof(a)/sizeof(*(a)))
  9. #define CONCURRENT_READS 180
  10. #define READ_BUFFER_SIZE 2
  11. /* Update statistics every n milliseconds (16ms is generally too fast) */
  12. #define UPDATE_PERIOD 100
  13. void
  14. PrintStatistics( ICCDecode &Driver, int row, int column, BOOL bSavePosition)
  15. {
  16. HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
  17. COORD Pos = {(short)row, (short)column};
  18. CONSOLE_SCREEN_BUFFER_INFO SavedPos;
  19. VBICODECFILTERING_STATISTICS_CC Statistics;
  20. VBICODECFILTERING_STATISTICS_CC_PIN PinStatistics;
  21. VBICODECFILTERING_SCANLINES ScanlinesRequested, ScanlinesDiscovered;
  22. VBICODECFILTERING_CC_SUBSTREAMS VideoFieldsRequested, VideoFieldsDiscovered;
  23. char szBuffer[11][80];
  24. if ( bSavePosition )
  25. GetConsoleScreenBufferInfo( hStdout, &SavedPos );
  26. SetConsoleCursorPosition( hStdout, Pos );
  27. if ( Driver.GetCodecStatistics( Statistics ) == 0 )
  28. {
  29. memset( &ScanlinesRequested, 0, sizeof(ScanlinesRequested) );
  30. memset( &ScanlinesDiscovered, 0, sizeof(ScanlinesDiscovered) );
  31. memset( &VideoFieldsRequested, 0, sizeof(VideoFieldsRequested) );
  32. memset( &VideoFieldsDiscovered, 0, sizeof(VideoFieldsDiscovered) );
  33. Driver.m_ScanlinesRequested.GetValue(&ScanlinesRequested);
  34. Driver.m_SubstreamsRequested.GetValue(&VideoFieldsRequested);
  35. Driver.m_ScanlinesDiscovered.GetValue(&ScanlinesDiscovered);
  36. Driver.m_SubstreamsDiscovered.GetValue(&VideoFieldsDiscovered);
  37. sprintf(szBuffer[0], "-----R:%08x:%08x----- CC Codec Statistics ------D:%08x:%08x-----",
  38. ScanlinesRequested.DwordBitArray[0], VideoFieldsRequested.SubstreamMask,
  39. ScanlinesDiscovered.DwordBitArray[0], VideoFieldsDiscovered.SubstreamMask );
  40. sprintf(szBuffer[1], "InputSRBsProcessed: %u, OutputSRBsProcessed: %u, SRBsIgnored: %u",
  41. Statistics.Common.InputSRBsProcessed, Statistics.Common.OutputSRBsProcessed, Statistics.Common.SRBsIgnored );
  42. sprintf(szBuffer[2], "InputSRBsMissing: %u, OutputSRBsMissing: %u, OutputFailures: %u",
  43. Statistics.Common.InputSRBsMissing, Statistics.Common.OutputSRBsMissing, Statistics.Common.OutputFailures );
  44. sprintf(szBuffer[3], "InternalErrors: %u, ExternalErrors: %u, InputDiscontinuities: %u",
  45. Statistics.Common.InternalErrors, Statistics.Common.ExternalErrors, Statistics.Common.InputDiscontinuities );
  46. sprintf(szBuffer[4], "DSPFailures: %u, TvTunerChanges: %u, VBIHeaderChanges: %u",
  47. Statistics.Common.DSPFailures, Statistics.Common.TvTunerChanges, Statistics.Common.VBIHeaderChanges );
  48. sprintf(szBuffer[5], "LineConfidenceAvg: %u, BytesOutput: %u",
  49. Statistics.Common.LineConfidenceAvg, Statistics.Common.BytesOutput );
  50. }
  51. if ( Driver.GetPinStatistics( PinStatistics ) == 0 )
  52. {
  53. memset( &ScanlinesRequested, 0, sizeof(ScanlinesRequested) );
  54. memset( &ScanlinesDiscovered, 0, sizeof(ScanlinesDiscovered) );
  55. memset( &VideoFieldsRequested, 0, sizeof(VideoFieldsRequested) );
  56. memset( &VideoFieldsDiscovered, 0, sizeof(VideoFieldsDiscovered) );
  57. Driver.m_OutputPin.m_ScanlinesRequested.GetValue(&ScanlinesRequested);
  58. Driver.m_OutputPin.m_SubstreamsRequested.GetValue(&VideoFieldsRequested);
  59. Driver.m_OutputPin.m_ScanlinesDiscovered.GetValue(&ScanlinesDiscovered);
  60. Driver.m_OutputPin.m_SubstreamsDiscovered.GetValue(&VideoFieldsDiscovered);
  61. sprintf(szBuffer[6], "-----R:%08x:%08x------- CCPin Statistics -------D:%08x:%08x-----",
  62. ScanlinesRequested.DwordBitArray[0], VideoFieldsRequested.SubstreamMask,
  63. ScanlinesDiscovered.DwordBitArray[0], VideoFieldsDiscovered.SubstreamMask );
  64. sprintf(szBuffer[7], "SRBsProcessed: %u, SRBsMissing: %u, SRBsIgnored: %u",
  65. PinStatistics.Common.SRBsProcessed, PinStatistics.Common.SRBsMissing, PinStatistics.Common.SRBsIgnored );
  66. sprintf(szBuffer[8], "InternalErrors: %u, ExternalErrors: %u, Discontinuities: %u",
  67. PinStatistics.Common.InternalErrors, PinStatistics.Common.ExternalErrors, PinStatistics.Common.Discontinuities );
  68. sprintf(szBuffer[9], "LineConfidenceAvg: %u, BytesOutput: %u",
  69. PinStatistics.Common.LineConfidenceAvg, PinStatistics.Common.BytesOutput );
  70. sprintf(szBuffer[10], "===============================================================================");
  71. printf("%-79.79s\n%-79.79s\n%-79.79s\n%-79.79s\n%-79.79s\n%-79.79s\n%-79.79s\n%-79.79s\n%-79.79s\n%-79.79s\n%-79.79s\n",
  72. szBuffer[0], szBuffer[1], szBuffer[2], szBuffer[3], szBuffer[4],
  73. szBuffer[5], szBuffer[6], szBuffer[7], szBuffer[8], szBuffer[9],
  74. szBuffer[10] );
  75. }
  76. if ( bSavePosition )
  77. SetConsoleCursorPosition( hStdout, SavedPos.dwCursorPosition );
  78. }
  79. void
  80. interpret_Vchip(unsigned char *buf, int buflen)
  81. {
  82. static int m_bGetVChip = FALSE;
  83. static int m_bGetCurrentOnEven = FALSE;
  84. //long lLevel = -1;
  85. unsigned char *bp, *ep;
  86. bp = buf;
  87. ep = &buf[buflen];
  88. while (bp < ep)
  89. {
  90. UCHAR ucData = *bp++;
  91. if ( m_bGetVChip )
  92. {
  93. // state is we are looking for vchip data
  94. if ( ucData & 0x40 )
  95. {
  96. UCHAR ucData2;
  97. if (bp >= ep)
  98. break;
  99. // it's a valid char, get the next one
  100. ucData2 = *bp++;
  101. // we have a valid one, determine what it is
  102. if ( !(ucData & 0x08) )
  103. {
  104. // MPAA
  105. UCHAR ucMPAA = (ucData & 0x07);
  106. printf("\bVChip MPAA-" );
  107. switch ( ucMPAA )
  108. {
  109. case 0x00:
  110. printf("NONE");
  111. break;
  112. case 0x01:
  113. printf("G");
  114. break;
  115. case 0x02:
  116. printf("PG");
  117. break;
  118. case 0x03:
  119. printf("PG13");
  120. break;
  121. case 0x04:
  122. printf("R");
  123. break;
  124. case 0x05:
  125. printf("NC17");
  126. break;
  127. case 0x06:
  128. printf("X");
  129. break;
  130. case 0x07:
  131. printf("NOTRATED");
  132. break;
  133. }
  134. printf("\n");
  135. }
  136. else if ( !(ucData & 0x10 ) )
  137. {
  138. // TV Parental Guidelines
  139. if ( ucData2 & 0x40 )
  140. {
  141. UCHAR ucTVParental = (ucData2 & 0x07);
  142. printf("\bVChip TVP-" );
  143. switch ( ucTVParental )
  144. {
  145. case 0x00:
  146. printf("NONE");
  147. break;
  148. case 0x01:
  149. printf("Y");
  150. break;
  151. case 0x02:
  152. printf("Y7");
  153. break;
  154. case 0x03:
  155. printf("G");
  156. break;
  157. case 0x04:
  158. printf("PG");
  159. break;
  160. case 0x05:
  161. printf("TV14");
  162. break;
  163. case 0x06:
  164. printf("TVMA");
  165. break;
  166. case 0x07:
  167. printf("NONE");
  168. break;
  169. }
  170. // Now do the TV sub-codes:
  171. if (ucData & 0x20)
  172. printf(" D");
  173. if (ucData2 & 0x20) {
  174. printf(" ");
  175. if (0x02 == ucTVParental)
  176. printf("F");
  177. printf("V");
  178. }
  179. if (ucData2 & 0x10)
  180. printf(" S");
  181. if (ucData2 & 0x08)
  182. printf(" L");
  183. printf("\n");
  184. }
  185. else
  186. {
  187. printf("VChip NonUS- 0x%02x 0x%02x\n", ucData, ucData2 );
  188. // non-US system
  189. }
  190. }
  191. else
  192. {
  193. // it's not a valid vchip char
  194. m_bGetVChip = FALSE;
  195. }
  196. }
  197. else
  198. {
  199. // it's not a valid vchip char
  200. m_bGetVChip = FALSE;
  201. }
  202. }
  203. else if ( m_bGetCurrentOnEven )
  204. {
  205. // state is we have started Current Class
  206. if ( ucData == 0x05 )
  207. {
  208. m_bGetVChip = TRUE;
  209. }
  210. m_bGetCurrentOnEven = FALSE;
  211. }
  212. else
  213. {
  214. // state is something else
  215. if ( ucData == 0x01 || ucData == 0x02 )
  216. {
  217. m_bGetCurrentOnEven = TRUE;
  218. }
  219. }
  220. }
  221. }
  222. int __cdecl
  223. main( int argc, char *argv[] )
  224. {
  225. int nStatus = 0;
  226. int arg = 1; // Next unparsed command line parameter
  227. const int bDoVchip = arg < argc && strcmp(argv[arg],"-v") == 0 ? arg++ : 0;
  228. const int bStatistics = arg < argc && strcmp(argv[arg],"-s") == 0 ? arg++ : 0;
  229. long nLastUpdate = 0;
  230. const int nScanline = arg < argc ? atoi(argv[arg++]) : 21; // Closed Captioning Scanline(21)
  231. int nSubstream = KS_CC_SUBSTREAM_ODD;
  232. unsigned char VchipBuffer[128], *vcp = VchipBuffer;
  233. int VchipBytes = 0;
  234. if ( nScanline )
  235. {
  236. try {
  237. ICCDecode Driver;
  238. if ( Driver.IsValid() )
  239. {
  240. SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL );
  241. if ( bStatistics )
  242. PrintStatistics( Driver, 0, 0, FALSE );
  243. if ( (nStatus = Driver.ClearRequestedScanlines() ) == 0)
  244. {
  245. printf( "Starting decoding%s on line %d", bDoVchip? " [VCHIP mode]":"", nScanline ); // No newline, see below
  246. if ( (nStatus = Driver.AddRequestedScanline(nScanline) ) != 0)
  247. {
  248. fprintf( stderr, "\nFailed to AddRequestedScanlines(%d)=%d\n", nScanline, nStatus );
  249. return nStatus;
  250. }
  251. }
  252. else
  253. {
  254. fprintf( stderr, "\nFailed to ClearRequestedScanlines()=%d\n", nStatus );
  255. return nStatus;
  256. }
  257. if ( ( nStatus = Driver.ClearRequestedVideoFields() ) == 0 )
  258. {
  259. do
  260. {
  261. if ( arg < argc )
  262. if ( !(nSubstream = atoi( argv[arg] ) ) )
  263. printf( "Invalid substream: '%s'\n", argv[arg] );
  264. printf( ", Substream %d", nSubstream );
  265. if ( ( nStatus = Driver.AddRequestedVideoField(nSubstream) ) != 0 )
  266. {
  267. fprintf( stderr, "\nFailed to AddRequestedVideoField(%d)=%d\n", nSubstream, nStatus );
  268. return nStatus;
  269. }
  270. }
  271. while ( ++arg < argc );
  272. }
  273. else
  274. {
  275. fprintf( stderr, "\nFailed to ClearRequestedVideoFields()=%d\n", nStatus );
  276. return nStatus;
  277. }
  278. printf("\n");
  279. int nNextRead = 0;//, nNextCompleted = 0;
  280. DWORD nBytes = 0;
  281. OVERLAPPED Overlapped[CONCURRENT_READS] = {0};
  282. BYTE ccdata[CONCURRENT_READS][READ_BUFFER_SIZE];
  283. for( nNextRead = 0; !nStatus && nNextRead < CONCURRENT_READS; nNextRead++ )
  284. {
  285. if ( !( Overlapped[nNextRead].hEvent = CreateEvent( NULL, TRUE, FALSE, NULL ) ) )
  286. {
  287. nStatus = GetLastError();
  288. break;
  289. }
  290. nStatus = Driver.ReadData( ccdata[nNextRead], READ_BUFFER_SIZE, &nBytes, Overlapped + nNextRead );
  291. if ( !nStatus || nStatus == ERROR_IO_PENDING )
  292. nStatus = 0;
  293. else
  294. break;
  295. }
  296. nNextRead = 0;
  297. while ( !nStatus && !_kbhit() )
  298. {
  299. if ( !(nStatus = Driver.GetOverlappedResult(Overlapped+nNextRead, &nBytes, FALSE ) ) )
  300. {
  301. nBytes = min(nBytes, READ_BUFFER_SIZE);
  302. for(DWORD i=0; i<nBytes; i++ )
  303. ccdata[nNextRead][i] &= 0x7F;
  304. //printf( "CC Data #%d=%d:[%.*s]\n", nNextRead, nBytes, nBytes, ccdata[nNextRead] );
  305. if (bDoVchip)
  306. {
  307. unsigned int i;
  308. for (i = 0; i < nBytes && vcp < &VchipBuffer[sizeof (VchipBuffer)]; ++i, ++VchipBytes)
  309. *vcp++ = ccdata[nNextRead][i];
  310. if (VchipBytes >= sizeof (VchipBuffer)) {
  311. printf(".");
  312. //printf( "interpret_Vchip([%.*s], %d)\n", VchipBytes, ccdata[nNextRead], VchipBytes );
  313. interpret_Vchip((unsigned char *)VchipBuffer, VchipBytes);
  314. vcp = VchipBuffer;
  315. VchipBytes = 0;
  316. }
  317. }
  318. else
  319. printf("%.*s", nBytes, ccdata[nNextRead]);
  320. nStatus = Driver.ReadData( ccdata[nNextRead], READ_BUFFER_SIZE, &nBytes, Overlapped + nNextRead );
  321. if ( !nStatus || nStatus == ERROR_IO_PENDING )
  322. {
  323. nNextRead = ++nNextRead % CONCURRENT_READS;
  324. nStatus = 0;
  325. }
  326. }
  327. else if ( nStatus == ERROR_IO_INCOMPLETE || nStatus == ERROR_IO_PENDING )
  328. {
  329. Sleep(10); // Chill out a few milliseconds so we don't run full tilt.
  330. nStatus = 0;
  331. }
  332. if ( bStatistics && GetTickCount()-nLastUpdate > UPDATE_PERIOD )
  333. {
  334. PrintStatistics( Driver, 0, 0, TRUE );
  335. nLastUpdate = GetTickCount();
  336. }
  337. }
  338. // Drain any chars pressed
  339. while ( _kbhit() )
  340. _getch();
  341. }
  342. }
  343. catch (...)
  344. {
  345. nStatus = GetLastError();
  346. }
  347. }
  348. else
  349. printf( "CC TESTAPP Syntax: TESTAPP [-v][-s] [scanline [substream1 [substream2] ] ]\n" );
  350. if ( nStatus )
  351. fprintf( stderr, "Program failed with LastErrorCode=%d!\n", nStatus );
  352. return nStatus;
  353. }