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.

391 lines
17 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. ;
  15. ; Declaration:
  16. ; void MBEncodeVLC (
  17. ; char * pMBRVS_Luma,
  18. ; char * pMBRVS_Chroma,
  19. ; unsigned int CodedBlkPattern,
  20. ; unsigned char ** pBitStream,
  21. ; unsigned char * pBitOffset,
  22. ; int IntraFlag,
  23. ; int MMxFlag
  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\e15vlc.asv 1.9 21 Oct 1996 09:06:42 RHAZRA $
  37. ;
  38. ; $Log: S:\h26x\src\enc\e15vlc.asv $
  39. ;//
  40. ;// Rev 1.9 21 Oct 1996 09:06:42 RHAZRA
  41. ;//
  42. ;// Check for 0 level and change to 127 if so.
  43. ;//
  44. ;// Rev 1.8 01 Nov 1995 08:59:14 DBRUCKS
  45. ;// Don't output EOB on empty INTRA
  46. ;//
  47. ;// Rev 1.7 23 Oct 1995 16:38:08 DBRUCKS
  48. ;// fix sizeof VLC TCOEF Table
  49. ;//
  50. ;// Rev 1.6 28 Sep 1995 11:58:04 BECHOLS
  51. ;// Added exception code to handle the special case where the first code of
  52. ;// an inter block is 11s, and I change it to 1s per the spec. I also added
  53. ;// a read to PutBits to preload the cache for the write. I also looped the
  54. ;// main function to reduce code size.
  55. ;//
  56. ;// Rev 1.5 26 Sep 1995 13:32:24 DBRUCKS
  57. ;// write EOB after DC in empty Intra
  58. ;//
  59. ;// Rev 1.4 25 Sep 1995 17:23:12 BECHOLS
  60. ;// Modified the code to write what I think will be a valid H261 bit stream.
  61. ;// Also modified the code for optimum performance.
  62. ;//
  63. ;// Rev 1.3 21 Sep 1995 18:17:14 BECHOLS
  64. ;//
  65. ;// Change the way I handle the VLC table called VLC_TCOEF_TBL to account
  66. ;// for its new format as initialized in E1MBENC.CPP. The code is work in prog
  67. ;//
  68. ;// Rev 1.2 20 Sep 1995 17:34:42 BECHOLS
  69. ;//
  70. ;// made correction to macro.
  71. ;//
  72. ;// Rev 1.1 20 Sep 1995 16:56:54 BECHOLS
  73. ;//
  74. ;// Updated to the optimized version, and removed the TCOEF_LAST_TBL
  75. ;// because H261 doesn't use it. I changed the TCOEF_TBL to a single
  76. ;// DWORD and will pack the size and code to save data space.
  77. ;
  78. ; -- ========================================================================
  79. .486
  80. .MODEL flat, c
  81. ; ++ ========================================================================
  82. ; Name mangling in C++ forces me to declare these tables in the ASM file
  83. ; and make them externally available to C++ as extern "C" ...
  84. ; -- ========================================================================
  85. PUBLIC FLC_INTRADC
  86. PUBLIC VLC_TCOEF_TBL
  87. TCOEF_ESCAPE_FIELDLEN EQU 6
  88. TCOEF_ESCAPE_FIELDVAL EQU 1
  89. TCOEF_EOB_FIELDLEN EQU 2
  90. TCOEF_EOB_FIELDVAL EQU 2
  91. TCOEF_RUN_FIELDLEN EQU 6
  92. TCOEF_LEVEL_FIELDLEN EQU 8
  93. MAX_TABLE_LEVEL EQU 12
  94. ; ++ ========================================================================
  95. ; RLS (Run Level Sign) Structure is defined just to make the code a little
  96. ; more readable.
  97. ; -- ========================================================================
  98. RLS STRUCT
  99. Run BYTE ?
  100. Level BYTE ?
  101. Sign BYTE ?
  102. RLS ENDS
  103. ; ++ ========================================================================
  104. ; The PutBits macro puts a Variable Length Code into the bit stream. It
  105. ; expects registers to contain the correct information as follows.
  106. ; EDX -- Field Length
  107. ; EAX -- Field Value
  108. ; EDI -- Pointer to the Bitstream Pointer
  109. ; EBX -- Pointer to the Bitstream Offset
  110. ; The contents of EDI and EBX are modified and EDX and EAX are trashed.
  111. ; -- ========================================================================
  112. PutBits MACRO
  113. push esi
  114. push ecx
  115. xor ecx, ecx
  116. mov cl, BYTE PTR [ebx] ;; Get the Bit Offset.
  117. add edx, ecx ;; Add it to the field length.
  118. mov ecx, 32 ;; EAX <<= (32 - (EDX + [EBX]))
  119. sub ecx, edx ;; EDX = Field Length + Bit Offset.
  120. mov esi, DWORD PTR [edi] ;; Set ESI to Bit Stream.
  121. shl eax, cl ;;
  122. bswap eax ;; Swaps byte order in EAX.
  123. mov ecx, DWORD PTR [esi] ;; Preload cache.
  124. or DWORD PTR [esi], eax ;; Write value to bit stream.
  125. mov eax, edx
  126. shr eax, 3
  127. add [edi], eax ;; Update Bit Stream Pointer.
  128. and edx, 000000007h
  129. mov BYTE PTR [ebx], dl ;; Update Bit Stream Offset.
  130. pop ecx
  131. pop esi
  132. ENDM
  133. ; ++ ========================================================================
  134. ; PutRunLev macro writes the ESCAPE code and Last bit, then the RUN length,
  135. ; and then the LEVEL into the stream. It assumes the following registers.
  136. ; ESI -- Pointer to RLE stream.
  137. ; EDI -- Pointer to the Bitstream Pointer
  138. ; EBX -- Pointer to the Bitstream Offset
  139. ; The contents of EDI and EBX are modified and EDX, ECX and EAX are trashed.
  140. ; -- ========================================================================
  141. PutRunLev MACRO
  142. LOCAL NotZero, NoClamp, NotNegative
  143. mov eax, TCOEF_ESCAPE_FIELDVAL
  144. mov edx, TCOEF_ESCAPE_FIELDLEN
  145. PutBits ;; Write ESCAPE.
  146. mov al, (RLS PTR [esi]).Run ;; Retrieve Run Length.
  147. mov edx, TCOEF_RUN_FIELDLEN
  148. PutBits ;; Write RUN length.
  149. mov al, (RLS PTR [esi]).Level ;; Retrieve Level.
  150. sub eax, 1 ; new
  151. NotZero:
  152. cmp eax, 127 ; new - was 128
  153. jb NoClamp
  154. mov eax, 126 ; new - was 127
  155. NoClamp:
  156. add eax, 1 ; new
  157. cmp (RLS PTR [esi]).Sign, 0FFh
  158. jne NotNegative
  159. mov ecx, eax
  160. xor eax, eax
  161. sub eax, ecx
  162. and eax, 0000000FFh
  163. NotNegative:
  164. mov edx, TCOEF_LEVEL_FIELDLEN
  165. PutBits ;; Write LEVEL.
  166. ENDM
  167. ; ++ ========================================================================
  168. ; PutVLC macro writes the Variable Length Code and its sign bit into the
  169. ; bit stream. It expects the registers to be set up as follows.
  170. ; EDX -- VLC Code Length
  171. ; ECX -- First Code Written Flag.
  172. ; EAX -- VLC Bit Code
  173. ; ESI -- Pointer to RLE stream.
  174. ; EDI -- Pointer to the Bitstream Pointer
  175. ; EBX -- Pointer to the Bitstream Offset
  176. ; It checks ECX and if Zero (0) then it must check for the special case of
  177. ; code length of 3 which indicates the special case code. The contents of
  178. ; EDI and EBX are modified and EDX, ECX, and EAX are trashed.
  179. ; -- ========================================================================
  180. PutVLC MACRO
  181. LOCAL NotSpecial
  182. cmp ecx, 0 ;; If this is the first code to
  183. jnz NotSpecial ;; get written and it is the
  184. cmp edx, 3 ;; the special code for an inter
  185. jnz NotSpecial ;; block, then we need to change
  186. and eax, 000000003h ;; the code and its length, before
  187. dec edx ;; writing it to the stream.
  188. NotSpecial:
  189. mov cl, (RLS PTR [esi]).Sign ;; Get sign bit which is [ 0 | -1 ]
  190. and ecx, 000000001h ;; Mask off all but the low bit
  191. or eax, ecx ;; and place it in VLC.
  192. PutBits ;; Write the signed VLC into stream.
  193. ENDM
  194. ; ++ ========================================================================
  195. ; IndexTable macro determines the pointer value as indexed into the table
  196. ; of coefficients. It assumes the following registers.
  197. ; ESI -- Pointer to RLE stream.
  198. ; EAX -- The level which is one (1) based.
  199. ; EDX -- The base pointer to the coefficient array.
  200. ; The EDX register is modified, EAX is trashed, and ECX is preserved
  201. ; -- ========================================================================
  202. IndexTable MACRO
  203. push ecx ;; Save first code written flag.
  204. lea edx, VLC_TCOEF_TBL ;; Point to proper table,
  205. dec eax ;; Zero base the level value.
  206. shl eax, 6 ;; EAX is # of run values per level
  207. mov ecx, eax ;; added to the run value.
  208. xor eax, eax ;;
  209. mov al, (RLS PTR [esi]).Run ;;
  210. add eax, ecx ;;
  211. shl eax, 2 ;; The array has DWORDs (4 bytes)
  212. add edx, eax ;; Add the index to the array.
  213. pop ecx ;; Restore first code written flag.
  214. ENDM
  215. ; ++ ========================================================================
  216. ; WriteOneCode macro takes one RLE code from the triplet list and VLC
  217. ; encodes it, and writes it to the bit stream. It expects that the
  218. ; following registers will be set as shown. It checks ECX and if Zero (0)
  219. ; then it must check for the special case of Run == 0 and Level == 1.
  220. ; ESI -- Pointer to RLE stream.
  221. ; EDI -- Pointer to the Bitstream Pointer.
  222. ; EBX -- Pointer to the Bitstream Offset.
  223. ; ECX -- First Code Written Flag.
  224. ; The contents of EDI and EBX are modified and EDX , ECX, and EAX
  225. ; are trashed.
  226. ; -- ========================================================================
  227. WriteOneCode MACRO
  228. LOCAL RunLevel, VLCDone, NotZero
  229. mov al, (RLS PTR [esi]).Level ;; Get the level value and check
  230. test al, al ;; NEW
  231. jnz NotZero ;; NEW
  232. mov al, 127 ;; NEW
  233. NotZero: ;; NEW
  234. cmp eax, MAX_TABLE_LEVEL ;; it against the max table level.
  235. jg RunLevel ;;
  236. IndexTable ;; Sets EDX to table index
  237. mov eax, DWORD PTR [edx] ;; Get the VLC code from table.
  238. cmp eax, 00000FFFFh ;; Is this an escape indicator?
  239. je RunLevel ;; If so then do RLE processing.
  240. mov edx, eax
  241. and eax, 00000FFFFh
  242. shr edx, 16
  243. PutVLC ;; Write the Variable code.
  244. jmp VLCDone
  245. RunLevel:
  246. PutRunLev ;; Write the ESC RUN LEV stuff.
  247. VLCDone:
  248. ENDM
  249. ; ++ ========================================================================
  250. ; WriteIntraDC macro writes the Intra DC value into the bit stream. It
  251. ; expects the following registers to be set correctly.
  252. ; ESI -- Pointer to RLE stream.
  253. ; EDI -- Pointer to the Bitstream Pointer
  254. ; EBX -- Pointer to the Bitstream Offset
  255. ; The contents of EDI and EBX are modified, ESI is updated, and EDX and
  256. ; EAX are preserved.
  257. ; -- ========================================================================
  258. WriteIntraDC MACRO
  259. push eax
  260. push edx
  261. lea edx, FLC_INTRADC ;; Form index into Intra DC
  262. mov al, (RLS PTR [esi]).Level ;; array.
  263. add edx, eax ;;
  264. mov al, BYTE PTR [edx] ;; Get Intra DC value.
  265. mov edx, 8 ;; Set size of write to 8 bits.
  266. PutBits ;; Write the Intra DC value.
  267. add esi, SIZEOF RLS ;; Point to next triplet.
  268. pop edx
  269. pop eax
  270. ENDM
  271. ; ++ ========================================================================
  272. ; WriteEndOfBlock macro writes the end of block code into the stream. It
  273. ; assumes the the registers will be set up as follows.
  274. ; EDI -- Pointer to the Bitstream Pointer
  275. ; EBX -- Pointer to the Bitstream Offset
  276. ; The contents of EDI and EBX are modified, and EDX and EAX are trashed.
  277. ; -- ========================================================================
  278. WriteEndOfBlock MACRO
  279. mov eax, TCOEF_EOB_FIELDVAL
  280. mov edx, TCOEF_EOB_FIELDLEN
  281. PutBits ;; Write EOB.
  282. ENDM
  283. ; ++ ========================================================================
  284. ; WriteOneBlock macro writes all the coefficients for a single block of the
  285. ; macroblock. It assumes that the registers will be set as follows.
  286. ; ESI -- Pointer to RLE stream.
  287. ; EDI -- Pointer to the Bitstream Pointer
  288. ; EBX -- Pointer to the Bitstream Offset
  289. ; EDX -- Coded Block Pattern (CBP)
  290. ; ECX -- Intra/Inter Flag
  291. ; EAX -- CBP Mask.
  292. ; The contents of EDI and EBX are modified and EDX , ECX, and EAX are
  293. ; preserved.
  294. ; -- ========================================================================
  295. WriteOneBlock MACRO
  296. LOCAL NotIntra, WriteDone, WriteCodes, WriteExit
  297. push eax
  298. push edx
  299. cmp ecx, 1 ;; Check to see if this is an
  300. jne NotIntra ;; Intra block, and if so,
  301. WriteIntraDC ;; write the DC value.
  302. and eax, edx ;; Check CBP to see if done.
  303. jnz WriteCodes
  304. WriteEndOfBlock
  305. jmp WriteExit
  306. NotIntra:
  307. and eax, edx ;; Check CBP to see if done.
  308. jnz WriteCodes
  309. jmp WriteExit
  310. WriteCodes:
  311. mov al, (RLS PTR [esi]).Run ;; Get the RUN value.
  312. cmp eax, 0000000FFh ;; Check to see if done.
  313. je WriteDone ;; If not, then continue to
  314. WriteOneCode ;; write the codes in this
  315. add esi, SIZEOF RLS ;; block until done.
  316. mov ecx, 1 ;; Flag WriteOneCode that not
  317. jmp WriteCodes ;; first code.
  318. WriteDone:
  319. WriteEndOfBlock
  320. add esi, SIZEOF RLS ;; Bump to next block.
  321. WriteExit:
  322. pop edx
  323. pop eax
  324. ENDM
  325. .DATA
  326. FLC_INTRADC DB 256 DUP (?)
  327. VLC_TCOEF_TBL DD (64 * 16) DUP (?)
  328. .CODE
  329. ; ++ ========================================================================
  330. ; This is the C function call entry point. This function variable length
  331. ; encodes an entire macroblock, one block at a time.
  332. ; -- ========================================================================
  333. MBEncodeVLC PROC PUBLIC USES edi esi ebx ecx, pMBRVS_Luma:DWORD, pMBRVS_Chroma:DWORD, CodedBlockPattern:DWORD, ppBitStream:DWORD, pBitOffset:DWORD, IntraFlag:DWORD, MMxFlag:DWORD
  334. mov esi, pMBRVS_Luma
  335. mov edi, ppBitStream
  336. mov ebx, pBitOffset
  337. mov edx, CodedBlockPattern
  338. mov esi, [esi]
  339. mov eax, 1 ; CBP Mask.
  340. LumaWriteLoop:
  341. test eax, 000000010h ; When EAX bit shifts to this
  342. jnz LumaBlocksDone ; position, we are done with Luma.
  343. mov ecx, IntraFlag
  344. WriteOneBlock
  345. shl eax, 1 ; Shift CBP mask to next block.
  346. jmp LumaWriteLoop
  347. LumaBlocksDone:
  348. mov ecx, MMxFlag
  349. test ecx, 1
  350. jz ChromaWriteLoop
  351. mov ecx, pMBRVS_Luma
  352. mov [ecx],esi
  353. mov ecx, pMBRVS_Chroma
  354. mov esi,[ecx]
  355. ChromaWriteLoop:
  356. test eax, 000000040h ; When EAX bit shifts to this
  357. jnz ChromaBlocksDone ; position, we are done.
  358. mov ecx, IntraFlag
  359. WriteOneBlock
  360. shl eax, 1 ; Shift CBP mask to next block.
  361. jmp ChromaWriteLoop
  362. ChromaBlocksDone:
  363. mov eax, pMBRVS_Chroma
  364. mov ecx, MMxFlag
  365. test ecx, 1
  366. jz MacroBlockDone
  367. mov [eax],esi
  368. MacroBlockDone:
  369. ret
  370. MBEncodeVLC ENDP
  371. END