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.

377 lines
16 KiB

  1. ; ++ ========================================================================
  2. ;
  3. ; INTEL CORPORATION PROPRIETARY INFORMATION
  4. ;
  5. ; This software is supplied under the terms of a license
  6. ; agreement or nondisclosure agreement with Intel Corporation
  7. ; and may not be copied or disclosed except in accordance
  8. ; with the terms of that agreement.
  9. ;
  10. ; Copyright (c) 1995 Intel Corporation. All Rights Reserved.
  11. ;
  12. ; ========================================================================
  13. ;
  14. ; Declaration:
  15. ; void MBEncodeVLC (
  16. ; char * pMBRVS_Luma,
  17. ; char * pMBRVS_Chroma,
  18. ; unsigned int CodedBlkPattern,
  19. ; unsigned char ** pBitStream,
  20. ; unsigned char * pBitOffset,
  21. ; int IntraFlag,
  22. ; int MMxFlag
  23. ; );
  24. ;
  25. ; Description:
  26. ; This function encodes a macroblock's worth of RLE values.
  27. ; The RLE values are provided to me in a list of triplets
  28. ; where the triplets consist of RUN, LEVEL, and SIGN, where
  29. ; each element is a BYTE.
  30. ;
  31. ; Register Usage:
  32. ; ESI -- RLE stream cursor
  33. ; EDI -- Bit stream cursor
  34. ; EDX -- Bit stream offset
  35. ;
  36. ; $Header: S:\h26x\src\enc\e35vlc.asv 1.6 11 Oct 1996 16:44:22 BECHOLS $
  37. ;
  38. ; $Log: S:\h26x\src\enc\e35vlc.asv $
  39. ;//
  40. ;// Rev 1.6 11 Oct 1996 16:44:22 BECHOLS
  41. ;// Added a check, so that I won't choke on a zero level, even though
  42. ;// by rights the level should never be zero.
  43. ;//
  44. ;// Rev 1.5 05 Sep 1996 18:37:46 KLILLEVO
  45. ;// fixed bug which occured when value is zero after quantization
  46. ;// and run-length encoding
  47. ;//
  48. ;// Rev 1.4 15 Mar 1996 15:56:48 BECHOLS
  49. ;//
  50. ;// Changed to support separate passes over the luma and chroma.
  51. ;//
  52. ;// Rev 1.3 03 Oct 1995 20:40:40 BECHOLS
  53. ;//
  54. ;// Modified the code to reduce the code size to about .5K of cache and
  55. ;// about 4K of data. Added cache preloading, and write the VLC and sign
  56. ;// in one operation. I believe I handle the clamping correctly.
  57. ;//
  58. ;// Rev 1.2 22 Sep 1995 18:31:04 BECHOLS
  59. ;// Added clamping for the positive values as well as the negative.
  60. ;//
  61. ;// Rev 1.1 14 Sep 1995 11:45:36 BECHOLS
  62. ;// I used WDIS.EXE to determine where I could get better performance.
  63. ;// The changes I made have improved the performance by 30%.
  64. ;
  65. ; -- ========================================================================
  66. .486
  67. .MODEL flat, c
  68. ; ++ ========================================================================
  69. ; Name mangling in C++ forces me to declare these tables in the ASM file
  70. ; and make them externally available to C++ as extern "C" ...
  71. ; -- ========================================================================
  72. PUBLIC FLC_INTRADC
  73. PUBLIC VLC_TCOEF_TBL
  74. PUBLIC VLC_TCOEF_LAST_TBL
  75. ; ++ ========================================================================
  76. ; These constants were variable in the C version, but will actually never
  77. ; change being set by the H263 specification.
  78. ; -- ========================================================================
  79. TCOEF_ESCAPE_FIELDLEN EQU 7
  80. TCOEF_ESCAPE_FIELDVAL EQU 3
  81. TCOEF_RUN_FIELDLEN EQU 6
  82. TCOEF_LEVEL_FIELDLEN EQU 8
  83. ; ++ ========================================================================
  84. ; RLS (Run Level Sign) Structure is defined just to make the code a little
  85. ; more readable.
  86. ; -- ========================================================================
  87. RLS STRUCT
  88. Run BYTE ?
  89. Level BYTE ?
  90. Sign BYTE ?
  91. RLS ENDS
  92. ; ++ ========================================================================
  93. ; The PutBits macro puts a Variable Length Code into the bit stream. It
  94. ; expects registers to contain the correct information as follows.
  95. ; EDX -- Field Length
  96. ; EAX -- Field Value
  97. ; EDI -- Pointer to the Bitstream Pointer
  98. ; EBX -- Pointer to the Bitstream Offset
  99. ; The contents of EDI and EBX are modified and EDX and EAX are trashed.
  100. ; -- ========================================================================
  101. PutBits MACRO
  102. push esi
  103. push ecx
  104. xor ecx, ecx
  105. mov cl, BYTE PTR [ebx] ;; Get the Bit Offset.
  106. add edx, ecx ;; Add it to the field length.
  107. mov ecx, 32 ;; EAX <<= (32 - (EDX + [EBX]))
  108. sub ecx, edx ;; EDX = Field Length + Bit Offset.
  109. mov esi, DWORD PTR [edi] ;; Set ESI to Bit Stream.
  110. shl eax, cl ;;
  111. bswap eax ;; Swaps byte order in EAX.
  112. mov ecx, DWORD PTR [esi] ;; Preload cache.
  113. or DWORD PTR [esi], eax ;; Write value to bit stream.
  114. mov eax, edx
  115. shr eax, 3
  116. add [edi], eax ;; Update Bit Stream Pointer.
  117. and edx, 000000007h
  118. mov BYTE PTR [ebx], dl ;; Update Bit Stream Offset.
  119. pop ecx
  120. pop esi
  121. ENDM
  122. ; ++ ========================================================================
  123. ; PutRunLev macro writes the ESCAPE code and Last bit, then the RUN length,
  124. ; and then the LEVEL into the stream. It assumes the following registers.
  125. ; ECX -- Last Bit
  126. ; ESI -- Pointer to RLE stream.
  127. ; EDI -- Pointer to the Bitstream Pointer
  128. ; EBX -- Pointer to the Bitstream Offset
  129. ; The contents of EDI and EBX are modified and EDX and EAX are trashed.
  130. ; -- ========================================================================
  131. PutRunLev MACRO
  132. LOCAL NoClamp, NotNegative, NotZero
  133. mov eax, TCOEF_ESCAPE_FIELDVAL
  134. mov edx, TCOEF_ESCAPE_FIELDLEN
  135. PutBits ;; Write ESCAPE.
  136. mov eax, ecx ;; Retrieve Last Bit.
  137. mov edx, 1
  138. PutBits
  139. mov al, (RLS PTR [esi]).Run ;; Retrieve Run Length.
  140. mov edx, TCOEF_RUN_FIELDLEN
  141. PutBits ;; Write RUN length.
  142. mov al, (RLS PTR [esi]).Level ;; Retrieve Level.
  143. sub eax, 1 ; in case it is zero we want it to be modified to 127
  144. NotZero:
  145. cmp eax, 127
  146. jb NoClamp
  147. mov eax, 126
  148. NoClamp:
  149. add eax, 1
  150. cmp (RLS PTR [esi]).Sign, 0FFh
  151. jne NotNegative
  152. mov ecx, eax
  153. xor eax, eax
  154. sub eax, ecx
  155. and eax, 0000000FFh
  156. NotNegative:
  157. mov edx, TCOEF_LEVEL_FIELDLEN
  158. PutBits ;; Write LEVEL.
  159. ENDM
  160. ; ++ ========================================================================
  161. ; PutVLC macro writes the Variable Length Code and its sign bit into the
  162. ; bit stream. It expects the registers to be set up as follows.
  163. ; EDX -- VLC Code Length
  164. ; EAX -- VLC Bit Code
  165. ; ESI -- Pointer to RLE stream.
  166. ; EDI -- Pointer to the Bitstream Pointer
  167. ; EBX -- Pointer to the Bitstream Offset
  168. ; The contents of EDI and EBX are modified and EDX and EAX are trashed.
  169. ; -- ========================================================================
  170. PutVLC MACRO
  171. mov cl, (RLS PTR [esi]).Sign ;; Get sign bit which is [ 0 | -1 ]
  172. and ecx, 000000001h ;; Mask off all but the low bit
  173. or eax, ecx ;; and place it in VLC.
  174. PutBits ;; Write the signed VLC into stream.
  175. ENDM
  176. ; ++ ========================================================================
  177. ; CheckLast macro determines whether this is last RLE code for the block.
  178. ; It assumes the following register.
  179. ; ESI -- Pointer to RLE stream.
  180. ; It sets the following registers for subsequent use.
  181. ; EAX -- Last bit.
  182. ; ECX -- Max Table Level.
  183. ; EDX -- Pointer to the appropriate VLC table.
  184. ; -- ========================================================================
  185. CheckLast MACRO
  186. LOCAL IsLast, CheckDone
  187. cmp (RLS PTR [esi + 3]).Run, 0FFh ;; Check if the last RLE.
  188. je IsLast
  189. xor eax, eax ;; If not then clear last bit,
  190. lea edx, VLC_TCOEF_TBL ;; and point to proper table,
  191. mov ecx, 12 ;; and set max table level.
  192. jmp CheckDone
  193. IsLast:
  194. mov eax, 1 ;; Otherwise set the last bit,
  195. lea edx, VLC_TCOEF_LAST_TBL ;; and point to last coef table,
  196. mov ecx, 3 ;; and set the max table level.
  197. CheckDone:
  198. ENDM
  199. ; ++ ========================================================================
  200. ; IndexTable macro determines the pointer value as indexed into the table
  201. ; of coefficients. It assumes the following registers.
  202. ; ESI -- Pointer to RLE stream.
  203. ; EAX -- The level which is one (1) based.
  204. ; EDX -- The base pointer to the coefficient array.
  205. ; The EDX register is modified, EAX is trashed, and ECX is preserved
  206. ; -- ========================================================================
  207. IndexTable MACRO
  208. push ecx ;; Save the last bit
  209. dec eax ;; Zero base the level value.
  210. shl eax, 6 ;; EAX is # of run values per level
  211. mov ecx, eax ;; added to the run value.
  212. xor eax, eax ;;
  213. mov al, (RLS PTR [esi]).Run ;;
  214. add eax, ecx ;;
  215. shl eax, 2 ;; The array has DWORDs (4 bytes)
  216. add edx, eax ;; Add the index to the array.
  217. pop ecx ;; Restore the last bit.
  218. ENDM
  219. ; ++ ========================================================================
  220. ; WriteOneCode macro takes one RLE code from the triplet list and VLC
  221. ; encodes it, and writes it to the bit stream. It expects that the
  222. ; following registers will be set as shown.
  223. ; ESI -- Pointer to RLE stream.
  224. ; EDI -- Pointer to the Bitstream Pointer
  225. ; EBX -- Pointer to the Bitstream Offset
  226. ; The contents of EDI and EBX are modified and EDX , ECX, and EAX
  227. ; are trashed.
  228. ; -- ========================================================================
  229. WriteOneCode MACRO
  230. LOCAL RunLevel, VLCDone, NotZero
  231. CheckLast
  232. push eax ;; Save last bit
  233. mov al, (RLS PTR [esi]).Level ;; Get the level value and check
  234. test al, al ;; The level should never be zero
  235. jnz NotZero ;; but this fixes the unlikely
  236. mov al, 127 ;; event.
  237. NotZero:
  238. cmp eax, ecx ;; it against the max table level.
  239. pop ecx ;; Restore the last bit.
  240. jg RunLevel ;;
  241. IndexTable ;; Sets EDX to table index
  242. mov eax, DWORD PTR [edx] ;; Get the VLC code from table.
  243. cmp eax, 00000FFFFh ;; Is this an escape indicator?
  244. je RunLevel ;; If so then do RLE processing.
  245. mov edx, eax
  246. and eax, 00000FFFFh
  247. shr edx, 16
  248. PutVLC ;; Write the Variable code.
  249. jmp VLCDone
  250. RunLevel:
  251. PutRunLev ;; Write the ESC RUN LEV stuff.
  252. VLCDone:
  253. ENDM
  254. ; ++ ========================================================================
  255. ; WriteIntraDC macro writes the Intra DC value into the bit stream. It
  256. ; expects the following registers to be set correctly.
  257. ; ESI -- Pointer to RLE stream.
  258. ; EDI -- Pointer to the Bitstream Pointer
  259. ; EBX -- Pointer to the Bitstream Offset
  260. ; The contents of EDI and EBX are modified, ESI is updated, and EDX and
  261. ; EAX are preserved.
  262. ; -- ========================================================================
  263. WriteIntraDC MACRO
  264. push eax
  265. push edx
  266. lea edx, FLC_INTRADC ;; Form index into Intra DC
  267. mov al, (RLS PTR [esi]).Level ;; array.
  268. add edx, eax ;;
  269. mov al, BYTE PTR [edx] ;; Get Intra DC value.
  270. mov edx, 8 ;; Set size of write to 8 bits.
  271. PutBits ;; Write the Intra DC value.
  272. add esi, SIZEOF RLS ;; Point to next triplet.
  273. pop edx
  274. pop eax
  275. ENDM
  276. ; ++ ========================================================================
  277. ; WriteOneBlock macro writes all the coefficients for a single block of the
  278. ; macroblock. It assumes that the registers will be set as follows.
  279. ; ESI -- Pointer to RLE stream.
  280. ; EDI -- Pointer to the Bitstream Pointer
  281. ; EBX -- Pointer to the Bitstream Offset
  282. ; EDX -- Coded Block Pattern (CBP)
  283. ; ECX -- Intra/Inter Flag
  284. ; EAX -- CBP Mask.
  285. ; The contents of EDI and EBX are modified and EDX , ECX, and EAX are
  286. ; preserved.
  287. ; -- ========================================================================
  288. WriteOneBlock MACRO
  289. LOCAL NotIntra, WriteDone, WriteCodes, WriteExit
  290. push eax
  291. push edx
  292. cmp ecx, 1 ;; Check to see if this is an
  293. jne NotIntra ;; Intra block, and if so,
  294. WriteIntraDC ;; write the DC value.
  295. NotIntra:
  296. and eax, edx ;; Check CBP to see if done.
  297. jz WriteExit
  298. WriteCodes:
  299. mov al, BYTE PTR [esi] ;; Get the RUN value.
  300. cmp eax, 0000000FFh ;; Check to see if done.
  301. je WriteDone
  302. WriteOneCode ;; Continue to write the codes
  303. add esi, SIZEOF RLS ;; in this block until done.
  304. jmp WriteCodes ;;
  305. WriteDone:
  306. add esi, SIZEOF RLS ;; Bump to next block.
  307. WriteExit:
  308. pop edx
  309. pop eax
  310. ENDM
  311. .DATA
  312. FLC_INTRADC DB 256 DUP (?)
  313. VLC_TCOEF_TBL DD (64*12) DUP (?)
  314. VLC_TCOEF_LAST_TBL DD (64*3) DUP (?)
  315. .CODE
  316. ; ++ ========================================================================
  317. ; This is the C function call entry point. This function variable length
  318. ; encodes an entire macroblock, one block at a time.
  319. ; -- ========================================================================
  320. MBEncodeVLC PROC PUBLIC USES edi esi ebx ecx, pMBRVS_Luma:DWORD, pMBRVS_Chroma:DWORD, CodedBlockPattern:DWORD, ppBitStream:DWORD, pBitOffset:DWORD, IntraFlag:DWORD, MMxFlag:DWORD
  321. mov esi, pMBRVS_Luma
  322. mov edi, ppBitStream
  323. mov ebx, pBitOffset
  324. mov edx, CodedBlockPattern
  325. mov esi, [esi]
  326. mov eax, 1 ; CBP Mask.
  327. LumaWriteLoop:
  328. test eax, 000000010h ; When EAX bit shifts to this
  329. jnz LumaBlocksDone ; position, we are done with Luma.
  330. mov ecx, IntraFlag
  331. WriteOneBlock
  332. shl eax, 1 ; Shift CBP mask to next block.
  333. jmp LumaWriteLoop
  334. LumaBlocksDone:
  335. mov ecx, MMxFlag
  336. test ecx, 1
  337. jz ChromaWriteLoop
  338. mov ecx, pMBRVS_Luma
  339. mov [ecx],esi
  340. mov ecx, pMBRVS_Chroma
  341. mov esi,[ecx]
  342. ChromaWriteLoop:
  343. test eax, 000000040h ; When EAX bit shifts to this
  344. jnz ChromaBlocksDone ; position, we are done.
  345. mov ecx, IntraFlag
  346. WriteOneBlock
  347. shl eax, 1 ; Shift CBP mask to next block.
  348. jmp ChromaWriteLoop
  349. ChromaBlocksDone:
  350. mov eax, pMBRVS_Chroma
  351. mov ecx, MMxFlag
  352. test ecx, 1
  353. jz MacroBlockDone
  354. mov [eax],esi
  355. MacroBlockDone:
  356. ret
  357. MBEncodeVLC ENDP
  358. END