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.

247 lines
9.4 KiB

  1. #include <stdio.h>
  2. #include <ctype.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <conio.h>
  6. #include <windows.h>
  7. #include <wincon.h>
  8. #include <nabtsfec.h>
  9. #define ENTRIES(a) (sizeof(a)/sizeof(*(a)))
  10. #define CONCURRENT_READS 180
  11. #define READ_BUFFER_SIZE sizeof(NABTSFEC_BUFFER)
  12. /* Update statistics every n milliseconds (16ms is generally too fast) */
  13. #define UPDATE_PERIOD 200
  14. unsigned int
  15. atox( char *pszInput )
  16. {
  17. const int HEX = 16;
  18. const int DECIMAL = 10;
  19. const int OCTAL = 8;
  20. char *psz = pszInput;
  21. int radix = DECIMAL;
  22. unsigned int value = 0;
  23. if ( psz )
  24. {
  25. if ( *psz == '0' )
  26. {
  27. ++psz;
  28. if ( *psz == 'x' || *psz == 'X' )
  29. {
  30. ++psz;
  31. radix = HEX;
  32. }
  33. else
  34. {
  35. radix = OCTAL;
  36. }
  37. }
  38. while ( *psz )
  39. {
  40. switch ( radix )
  41. {
  42. case HEX:
  43. *psz = (char)toupper( *psz );
  44. if ( *psz == 'A' || *psz == 'B' || *psz == 'C'
  45. || *psz == 'D' || *psz == 'E' || *psz == 'F' )
  46. {
  47. value *= radix;
  48. value += *psz++ - 'A' + 10;
  49. continue;
  50. }
  51. case DECIMAL:
  52. if ( *psz == '8' || *psz == '9' )
  53. {
  54. value *= radix;
  55. value += *psz++ - '0';
  56. continue;
  57. }
  58. case OCTAL:
  59. if ( *psz == '0' || *psz == '1' || *psz == '2' || *psz == '3'
  60. || *psz == '4' || *psz == '5' || *psz == '6' || *psz == '7' )
  61. {
  62. value *= radix;
  63. value += *psz++ - '0';
  64. continue;
  65. }
  66. default:
  67. printf("Illegal char '%c' found number: '%s'!\n", *psz, radix );
  68. break;
  69. }
  70. }
  71. }
  72. return value;
  73. }
  74. void
  75. PrintStatistics( INabtsFEC &Driver, int row, int column, BOOL bSavePosition)
  76. {
  77. HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
  78. COORD Pos = {(short)row, (short)column};
  79. CONSOLE_SCREEN_BUFFER_INFO SavedPos;
  80. VBICODECFILTERING_STATISTICS_NABTS Statistics;
  81. VBICODECFILTERING_STATISTICS_NABTS_PIN PinStatistics;
  82. if ( Driver.GetCodecStatistics( Statistics ) == 0
  83. && Driver.GetPinStatistics( PinStatistics ) == 0)
  84. {
  85. char szBuffer[13][128] = { 0 };
  86. if ( bSavePosition )
  87. GetConsoleScreenBufferInfo( hStdout, &SavedPos );
  88. SetConsoleCursorPosition( hStdout, Pos );
  89. sprintf(szBuffer[0], "-------------------------- NABTS Codec Statistics -----------------------------");
  90. sprintf(szBuffer[1], "InputSRBsProcessed: %u, OutputSRBsProcessed: %u, SRBsIgnored: %u",
  91. Statistics.Common.InputSRBsProcessed, Statistics.Common.OutputSRBsProcessed, Statistics.Common.SRBsIgnored );
  92. sprintf(szBuffer[2], "InputSRBsMissing: %u, OutputSRBsMissing: %u, OutputFailures: %u",
  93. Statistics.Common.InputSRBsMissing, Statistics.Common.OutputSRBsMissing, Statistics.Common.OutputFailures );
  94. sprintf(szBuffer[3], "InternalErrors: %u, ExternalErrors: %u, InputDiscontinuities: %u",
  95. Statistics.Common.InternalErrors, Statistics.Common.ExternalErrors, Statistics.Common.InputDiscontinuities );
  96. sprintf(szBuffer[4], "DSPFailures: %u, TvTunerChanges: %u, VBIHeaderChanges: %u",
  97. Statistics.Common.DSPFailures, Statistics.Common.TvTunerChanges, Statistics.Common.VBIHeaderChanges );
  98. sprintf(szBuffer[5], "LineConfidenceAvg: %u, BytesOutput: %u, FECBundleBadLines: %u",
  99. Statistics.Common.LineConfidenceAvg, Statistics.Common.BytesOutput, Statistics.FECBundleBadLines );
  100. sprintf(szBuffer[6], "FECQueueOverflows: %u, FECCorrectedLines: %u, FECUncorrectableLines: %u",
  101. Statistics.FECQueueOverflows, Statistics.FECCorrectedLines, Statistics.FECUncorrectableLines );
  102. sprintf(szBuffer[7], "BundlesProcessed: %u, BundlesSent2IP: %u, FilteredLines: %u",
  103. Statistics.BundlesProcessed, Statistics.BundlesSent2IP, Statistics.FilteredLines );
  104. sprintf(szBuffer[8], "---------------------------- FEC Pin Statistics -------------------------------");
  105. sprintf(szBuffer[9], "SRBsProcessed: %u, SRBsMissing: %u, SRBsIgnored: %u",
  106. PinStatistics.Common.SRBsProcessed, PinStatistics.Common.SRBsMissing, PinStatistics.Common.SRBsIgnored );
  107. sprintf(szBuffer[10], "InternalErrors: %u, ExternalErrors: %u, Discontinuities: %u",
  108. PinStatistics.Common.InternalErrors, PinStatistics.Common.ExternalErrors, PinStatistics.Common.Discontinuities );
  109. sprintf(szBuffer[11], "LineConfidenceAvg: %u, BytesOutput: %u",
  110. PinStatistics.Common.LineConfidenceAvg, PinStatistics.Common.BytesOutput );
  111. sprintf(szBuffer[12], "===============================================================================");
  112. 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%-79.79s\n%-79.79s\n",
  113. szBuffer[0], szBuffer[1], szBuffer[2], szBuffer[3], szBuffer[4],
  114. szBuffer[5], szBuffer[6], szBuffer[7], szBuffer[8], szBuffer[9],
  115. szBuffer[10], szBuffer[11], szBuffer[12] );
  116. if ( bSavePosition )
  117. SetConsoleCursorPosition( hStdout, SavedPos.dwCursorPosition );
  118. }
  119. }
  120. int __cdecl
  121. main( int argc, char *argv[] )
  122. {
  123. int nStatus = 0;
  124. int arg = 1; // Next unparsed command line parameter
  125. const int bPrintHelp = arg < argc &&
  126. ( strcmp( argv[arg], "-h" ) || strcmp( argv[arg], "-h" ) ) == 0 ? arg++ : 0;
  127. const int bStatistics = arg < argc && strcmp( argv[arg], "-s" ) == 0 ? arg++ : 0;
  128. long nLastUpdate = 0;
  129. int nSubstream = -1;
  130. if ( !bPrintHelp )
  131. {
  132. try {
  133. INabtsFEC Driver;
  134. if ( Driver.IsValid() )
  135. {
  136. SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL );
  137. if ( bStatistics )
  138. PrintStatistics( Driver, 0, 0, FALSE );
  139. if ( arg < argc )
  140. {
  141. if ( ( nStatus = Driver.ClearRequestedGroups() ) == 0 )
  142. {
  143. do
  144. {
  145. if ( !(nSubstream = atox( argv[arg] ) ) )
  146. printf( "Invalid substream: '%s'\n", argv[arg] );
  147. printf( "GroupID:0x%03X ", nSubstream );
  148. if ( ( nStatus = Driver.AddRequestedGroup(nSubstream) ) != 0 )
  149. {
  150. fprintf( stderr, "\nFailed to AddRequestedGroups(%d)=%d\n", nSubstream, nStatus );
  151. return nStatus;
  152. }
  153. }
  154. while ( ++arg < argc );
  155. }
  156. else
  157. {
  158. fprintf( stderr, "\nFailed to ClearRequestedGroups()=%d\n", nStatus );
  159. return nStatus;
  160. }
  161. printf("\n");
  162. }
  163. else
  164. printf( "Using default GroupIDs\n" );
  165. int nNextRead = 0;
  166. DWORD nBytes = 0;
  167. OVERLAPPED Overlapped[CONCURRENT_READS] = {0};
  168. NABTSFEC_BUFFER NabtsFECBuffer[CONCURRENT_READS];
  169. for( nNextRead = 0; !nStatus && nNextRead < CONCURRENT_READS; nNextRead++ )
  170. {
  171. if ( !( Overlapped[nNextRead].hEvent = CreateEvent( NULL, TRUE, FALSE, NULL ) ) )
  172. {
  173. nStatus = GetLastError();
  174. break;
  175. }
  176. nStatus = Driver.ReadData( NabtsFECBuffer+nNextRead, READ_BUFFER_SIZE, &nBytes, Overlapped + nNextRead );
  177. if ( !nStatus || nStatus == ERROR_IO_PENDING )
  178. nStatus = 0;
  179. else
  180. break;
  181. }
  182. nNextRead = 0;
  183. while ( !nStatus && !_kbhit() )
  184. {
  185. if ( !(nStatus = Driver.GetOverlappedResult(Overlapped+nNextRead, &nBytes, FALSE ) ) )
  186. {
  187. nBytes = min(nBytes, READ_BUFFER_SIZE);
  188. printf("[%03X]", NabtsFECBuffer[nNextRead].groupID );
  189. nStatus = Driver.ReadData( NabtsFECBuffer+nNextRead, READ_BUFFER_SIZE, &nBytes, Overlapped + nNextRead );
  190. if ( !nStatus || nStatus == ERROR_IO_PENDING )
  191. {
  192. nNextRead = ++nNextRead % CONCURRENT_READS;
  193. nStatus = 0;
  194. }
  195. }
  196. else if ( nStatus == ERROR_IO_INCOMPLETE || nStatus == ERROR_IO_PENDING )
  197. {
  198. Sleep(10); // Chill out a few milliseconds so we don't run full tilt.
  199. nStatus = 0;
  200. }
  201. if ( bStatistics && GetTickCount()-nLastUpdate > UPDATE_PERIOD )
  202. {
  203. PrintStatistics( Driver, 0, 0, TRUE );
  204. nLastUpdate = GetTickCount();
  205. }
  206. }
  207. }
  208. }
  209. catch (...)
  210. {
  211. nStatus = GetLastError();
  212. }
  213. }
  214. else
  215. printf( "Syntax: TESTNAB [-s] [ substream1 [substream2] ]\n" );
  216. if ( nStatus )
  217. fprintf( stderr, "Program failed with LastErrorCode=%d!\n", nStatus );
  218. return nStatus;
  219. }