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.

185 lines
5.2 KiB

  1. /**********************************************************************
  2. Copyright (c) 1994 - 1997 Microsoft Corporation. All Rights Reserved.
  3. VITCDecode, Ken Greenebaum / David Maymudes, November 1996
  4. A generic vertical interval timecode decoder. Pass it 8 bit video lines
  5. samples and it will decode the VITC timecode encoded therein.
  6. This code based on the VITC description in John Ratcliff's Timecode; A user's
  7. guide (second edition)
  8. **********************************************************************/
  9. #include <stdio.h>
  10. #include <wtypes.h>
  11. #include "vtcdcode.h"
  12. /**********************************************************************
  13. helper function to decode raw VITC bits found in the bit buffer
  14. **********************************************************************/
  15. int
  16. compute(int bitNumber, int numBits, int bits[])
  17. {
  18. int value = 0;
  19. int count;
  20. int index;
  21. index = bitNumber;
  22. for(count = 0; count < numBits; count++) {
  23. value+= bits[index] << count;
  24. index = (index+1);
  25. }
  26. return(value);
  27. }
  28. /**********************************************************************
  29. initialize internal state
  30. **********************************************************************/
  31. VITCdecoder::VITCdecoder()
  32. {
  33. // values to reset
  34. _validTimeCode = 0; // no, we don't have a valid timecode, yet
  35. // should scan buffer for these
  36. // !!! completely arbitrary!
  37. _low = 80;
  38. _high = 120;
  39. }
  40. /**********************************************************************
  41. Decode and return the user bits from the raw VITC decoded bits in the
  42. ring buffer.
  43. Returns True if there is a valid timecode in the ring buffer
  44. In general this is only true immediately after the decode method returns
  45. a non-zero timecode sample sync
  46. **********************************************************************/
  47. int
  48. VITCdecoder::getUserBits(VITCuserBits *bits)
  49. {
  50. if(_validTimeCode) { // verify that valid timecode is in buffer
  51. bits->user1 = compute( 6, 4, _bits);
  52. bits->user2 = compute(16, 4, _bits);
  53. bits->user3 = compute(26, 4, _bits);
  54. bits->user4 = compute(36, 4, _bits);
  55. bits->user5 = compute(46, 4, _bits);
  56. bits->user6 = compute(56, 4, _bits);
  57. bits->user7 = compute(66, 4, _bits);
  58. bits->user8 = compute(76, 4, _bits);
  59. }
  60. return(_validTimeCode);
  61. }
  62. /**********************************************************************
  63. Decode and return the TimeCode from the raw VITC decoded bits.
  64. Returns True if there is a valid timecode,,
  65. In general this is only true immediately after the decode method returns
  66. a non-zero timecode sample sync
  67. **********************************************************************/
  68. int
  69. VITCdecoder::getTimeCode(TimeCode *tc)
  70. {
  71. if(_validTimeCode) { // verify that valid timecode is in buffer
  72. int hour, minute, second, frame;
  73. frame = compute( 2, 4, _bits); // frame units 0-3 1,2,4,8
  74. frame += 10*compute(12, 2, _bits); // frame tens 0-1 1,2
  75. second = compute(22, 4, _bits);
  76. second+= 10*compute(32, 3, _bits);
  77. minute = compute(42, 4, _bits);
  78. minute+= 10*compute(52, 3, _bits);
  79. hour = compute(62, 4, _bits);
  80. hour += 10*compute(72, 2, _bits);
  81. tc->SetTime(hour, minute, second, frame); // XXX for now
  82. }
  83. return(_validTimeCode);
  84. }
  85. // !!! really this should be adaptive, by looking for the first bit transition.
  86. // this formula found by looking at VITC data from one tape on a BT-848, I found that
  87. // bits took 1/96th of a line, starting at 3.5/96ths in.
  88. int bitStart(int bit, int lineWidth)
  89. {
  90. return (lineWidth * (bit + 3) + lineWidth / 2) / 96;
  91. }
  92. /**********************************************************************
  93. Accept a new line of video, decode the bits present in it, and return
  94. whether a timeCode was completed being decoded.
  95. **********************************************************************/
  96. int
  97. VITCdecoder::decodeBuffer(BYTE *buf, int bufferSize)
  98. {
  99. int bit;
  100. int badbits = 0;
  101. int startPos = bitStart(0, bufferSize);
  102. for (bit = 0; bit < 90; bit++) {
  103. int endPos = bitStart(bit+1, bufferSize);
  104. // !!! arbitrarily don't look at first/last two pixels so as to avoid
  105. // edges of bits
  106. int len = endPos - startPos - 4;
  107. DWORD total = 0;
  108. for (int pos = startPos+2; pos < endPos-2; pos++) {
  109. total += (DWORD) buf[pos];
  110. }
  111. // printf("bit %d: %d (%d-%d)\n", bit, total / len, startPos, endPos);
  112. if (total < _low * len) {
  113. // record 0
  114. _bits[bit] = 0;
  115. } else if (total > _high * len) {
  116. // record 1
  117. _bits[bit] = 1;
  118. } else {
  119. // record error
  120. _bits[bit] = -1;
  121. badbits++;
  122. }
  123. startPos = endPos;
  124. // !!! should terminate loop immediately if there's a problem to save time
  125. }
  126. // printf("%d bad bits\n", badbits);
  127. _validTimeCode = (badbits == 0);
  128. // check sync bits
  129. if (badbits == 0) {
  130. for (bit = 0; bit < 90; bit += 10) {
  131. if (_bits[bit] != 1) {
  132. // printf("bit %d should be 1\n", bit);
  133. _validTimeCode = 0;
  134. }
  135. if (_bits[bit+1] != 0) {
  136. // printf("bit %d should be 0\n", bit+1);
  137. _validTimeCode = 0;
  138. }
  139. }
  140. }
  141. // !!! should also check CRC in last few bits
  142. return _validTimeCode;
  143. }