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

; ++ ========================================================================
;
; INTEL CORPORATION PROPRIETARY INFORMATION
;
; This software is supplied under the terms of a license
; agreement or nondisclosure agreement with Intel Corporation
; and may not be copied or disclosed except in accordance
; with the terms of that agreement.
;
; Copyright (c) 1995 Intel Corporation. All Rights Reserved.
;
; ========================================================================
;
;
; Declaration:
; void MBEncodeVLC (
; char * pMBRVS_Luma,
; char * pMBRVS_Chroma,
; unsigned int CodedBlkPattern,
; unsigned char ** pBitStream,
; unsigned char * pBitOffset,
; int IntraFlag,
; int MMxFlag
; );
; Description:
; This function encodes a macroblock's worth of RLE values.
; The RLE values are provided to me in a list of triplets
; where the triplets consist of RUN, LEVEL, and SIGN, where
; each element is a BYTE.
;
; Register Usage:
; ESI -- RLE stream cursor
; EDI -- Bit stream cursor
; EDX -- Bit stream offset
;
; $Header: S:\h26x\src\enc\e15vlc.asv 1.9 21 Oct 1996 09:06:42 RHAZRA $
;
; $Log: S:\h26x\src\enc\e15vlc.asv $
;//
;// Rev 1.9 21 Oct 1996 09:06:42 RHAZRA
;//
;// Check for 0 level and change to 127 if so.
;//
;// Rev 1.8 01 Nov 1995 08:59:14 DBRUCKS
;// Don't output EOB on empty INTRA
;//
;// Rev 1.7 23 Oct 1995 16:38:08 DBRUCKS
;// fix sizeof VLC TCOEF Table
;//
;// Rev 1.6 28 Sep 1995 11:58:04 BECHOLS
;// Added exception code to handle the special case where the first code of
;// an inter block is 11s, and I change it to 1s per the spec. I also added
;// a read to PutBits to preload the cache for the write. I also looped the
;// main function to reduce code size.
;//
;// Rev 1.5 26 Sep 1995 13:32:24 DBRUCKS
;// write EOB after DC in empty Intra
;//
;// Rev 1.4 25 Sep 1995 17:23:12 BECHOLS
;// Modified the code to write what I think will be a valid H261 bit stream.
;// Also modified the code for optimum performance.
;//
;// Rev 1.3 21 Sep 1995 18:17:14 BECHOLS
;//
;// Change the way I handle the VLC table called VLC_TCOEF_TBL to account
;// for its new format as initialized in E1MBENC.CPP. The code is work in prog
;//
;// Rev 1.2 20 Sep 1995 17:34:42 BECHOLS
;//
;// made correction to macro.
;//
;// Rev 1.1 20 Sep 1995 16:56:54 BECHOLS
;//
;// Updated to the optimized version, and removed the TCOEF_LAST_TBL
;// because H261 doesn't use it. I changed the TCOEF_TBL to a single
;// DWORD and will pack the size and code to save data space.
;
; -- ========================================================================
.486
.MODEL flat, c
; ++ ========================================================================
; Name mangling in C++ forces me to declare these tables in the ASM file
; and make them externally available to C++ as extern "C" ...
; -- ========================================================================
PUBLIC FLC_INTRADC
PUBLIC VLC_TCOEF_TBL
TCOEF_ESCAPE_FIELDLEN EQU 6
TCOEF_ESCAPE_FIELDVAL EQU 1
TCOEF_EOB_FIELDLEN EQU 2
TCOEF_EOB_FIELDVAL EQU 2
TCOEF_RUN_FIELDLEN EQU 6
TCOEF_LEVEL_FIELDLEN EQU 8
MAX_TABLE_LEVEL EQU 12
; ++ ========================================================================
; RLS (Run Level Sign) Structure is defined just to make the code a little
; more readable.
; -- ========================================================================
RLS STRUCT
Run BYTE ?
Level BYTE ?
Sign BYTE ?
RLS ENDS
; ++ ========================================================================
; The PutBits macro puts a Variable Length Code into the bit stream. It
; expects registers to contain the correct information as follows.
; EDX -- Field Length
; EAX -- Field Value
; EDI -- Pointer to the Bitstream Pointer
; EBX -- Pointer to the Bitstream Offset
; The contents of EDI and EBX are modified and EDX and EAX are trashed.
; -- ========================================================================
PutBits MACRO
push esi
push ecx
xor ecx, ecx
mov cl, BYTE PTR [ebx] ;; Get the Bit Offset.
add edx, ecx ;; Add it to the field length.
mov ecx, 32 ;; EAX <<= (32 - (EDX + [EBX]))
sub ecx, edx ;; EDX = Field Length + Bit Offset.
mov esi, DWORD PTR [edi] ;; Set ESI to Bit Stream.
shl eax, cl ;;
bswap eax ;; Swaps byte order in EAX.
mov ecx, DWORD PTR [esi] ;; Preload cache.
or DWORD PTR [esi], eax ;; Write value to bit stream.
mov eax, edx
shr eax, 3
add [edi], eax ;; Update Bit Stream Pointer.
and edx, 000000007h
mov BYTE PTR [ebx], dl ;; Update Bit Stream Offset.
pop ecx
pop esi
ENDM
; ++ ========================================================================
; PutRunLev macro writes the ESCAPE code and Last bit, then the RUN length,
; and then the LEVEL into the stream. It assumes the following registers.
; ESI -- Pointer to RLE stream.
; EDI -- Pointer to the Bitstream Pointer
; EBX -- Pointer to the Bitstream Offset
; The contents of EDI and EBX are modified and EDX, ECX and EAX are trashed.
; -- ========================================================================
PutRunLev MACRO
LOCAL NotZero, NoClamp, NotNegative
mov eax, TCOEF_ESCAPE_FIELDVAL
mov edx, TCOEF_ESCAPE_FIELDLEN
PutBits ;; Write ESCAPE.
mov al, (RLS PTR [esi]).Run ;; Retrieve Run Length.
mov edx, TCOEF_RUN_FIELDLEN
PutBits ;; Write RUN length.
mov al, (RLS PTR [esi]).Level ;; Retrieve Level.
sub eax, 1 ; new
NotZero:
cmp eax, 127 ; new - was 128
jb NoClamp
mov eax, 126 ; new - was 127
NoClamp:
add eax, 1 ; new
cmp (RLS PTR [esi]).Sign, 0FFh
jne NotNegative
mov ecx, eax
xor eax, eax
sub eax, ecx
and eax, 0000000FFh
NotNegative:
mov edx, TCOEF_LEVEL_FIELDLEN
PutBits ;; Write LEVEL.
ENDM
; ++ ========================================================================
; PutVLC macro writes the Variable Length Code and its sign bit into the
; bit stream. It expects the registers to be set up as follows.
; EDX -- VLC Code Length
; ECX -- First Code Written Flag.
; EAX -- VLC Bit Code
; ESI -- Pointer to RLE stream.
; EDI -- Pointer to the Bitstream Pointer
; EBX -- Pointer to the Bitstream Offset
; It checks ECX and if Zero (0) then it must check for the special case of
; code length of 3 which indicates the special case code. The contents of
; EDI and EBX are modified and EDX, ECX, and EAX are trashed.
; -- ========================================================================
PutVLC MACRO
LOCAL NotSpecial
cmp ecx, 0 ;; If this is the first code to
jnz NotSpecial ;; get written and it is the
cmp edx, 3 ;; the special code for an inter
jnz NotSpecial ;; block, then we need to change
and eax, 000000003h ;; the code and its length, before
dec edx ;; writing it to the stream.
NotSpecial:
mov cl, (RLS PTR [esi]).Sign ;; Get sign bit which is [ 0 | -1 ]
and ecx, 000000001h ;; Mask off all but the low bit
or eax, ecx ;; and place it in VLC.
PutBits ;; Write the signed VLC into stream.
ENDM
; ++ ========================================================================
; IndexTable macro determines the pointer value as indexed into the table
; of coefficients. It assumes the following registers.
; ESI -- Pointer to RLE stream.
; EAX -- The level which is one (1) based.
; EDX -- The base pointer to the coefficient array.
; The EDX register is modified, EAX is trashed, and ECX is preserved
; -- ========================================================================
IndexTable MACRO
push ecx ;; Save first code written flag.
lea edx, VLC_TCOEF_TBL ;; Point to proper table,
dec eax ;; Zero base the level value.
shl eax, 6 ;; EAX is # of run values per level
mov ecx, eax ;; added to the run value.
xor eax, eax ;;
mov al, (RLS PTR [esi]).Run ;;
add eax, ecx ;;
shl eax, 2 ;; The array has DWORDs (4 bytes)
add edx, eax ;; Add the index to the array.
pop ecx ;; Restore first code written flag.
ENDM
; ++ ========================================================================
; WriteOneCode macro takes one RLE code from the triplet list and VLC
; encodes it, and writes it to the bit stream. It expects that the
; following registers will be set as shown. It checks ECX and if Zero (0)
; then it must check for the special case of Run == 0 and Level == 1.
; ESI -- Pointer to RLE stream.
; EDI -- Pointer to the Bitstream Pointer.
; EBX -- Pointer to the Bitstream Offset.
; ECX -- First Code Written Flag.
; The contents of EDI and EBX are modified and EDX , ECX, and EAX
; are trashed.
; -- ========================================================================
WriteOneCode MACRO
LOCAL RunLevel, VLCDone, NotZero
mov al, (RLS PTR [esi]).Level ;; Get the level value and check
test al, al ;; NEW
jnz NotZero ;; NEW
mov al, 127 ;; NEW
NotZero: ;; NEW
cmp eax, MAX_TABLE_LEVEL ;; it against the max table level.
jg RunLevel ;;
IndexTable ;; Sets EDX to table index
mov eax, DWORD PTR [edx] ;; Get the VLC code from table.
cmp eax, 00000FFFFh ;; Is this an escape indicator?
je RunLevel ;; If so then do RLE processing.
mov edx, eax
and eax, 00000FFFFh
shr edx, 16
PutVLC ;; Write the Variable code.
jmp VLCDone
RunLevel:
PutRunLev ;; Write the ESC RUN LEV stuff.
VLCDone:
ENDM
; ++ ========================================================================
; WriteIntraDC macro writes the Intra DC value into the bit stream. It
; expects the following registers to be set correctly.
; ESI -- Pointer to RLE stream.
; EDI -- Pointer to the Bitstream Pointer
; EBX -- Pointer to the Bitstream Offset
; The contents of EDI and EBX are modified, ESI is updated, and EDX and
; EAX are preserved.
; -- ========================================================================
WriteIntraDC MACRO
push eax
push edx
lea edx, FLC_INTRADC ;; Form index into Intra DC
mov al, (RLS PTR [esi]).Level ;; array.
add edx, eax ;;
mov al, BYTE PTR [edx] ;; Get Intra DC value.
mov edx, 8 ;; Set size of write to 8 bits.
PutBits ;; Write the Intra DC value.
add esi, SIZEOF RLS ;; Point to next triplet.
pop edx
pop eax
ENDM
; ++ ========================================================================
; WriteEndOfBlock macro writes the end of block code into the stream. It
; assumes the the registers will be set up as follows.
; EDI -- Pointer to the Bitstream Pointer
; EBX -- Pointer to the Bitstream Offset
; The contents of EDI and EBX are modified, and EDX and EAX are trashed.
; -- ========================================================================
WriteEndOfBlock MACRO
mov eax, TCOEF_EOB_FIELDVAL
mov edx, TCOEF_EOB_FIELDLEN
PutBits ;; Write EOB.
ENDM
; ++ ========================================================================
; WriteOneBlock macro writes all the coefficients for a single block of the
; macroblock. It assumes that the registers will be set as follows.
; ESI -- Pointer to RLE stream.
; EDI -- Pointer to the Bitstream Pointer
; EBX -- Pointer to the Bitstream Offset
; EDX -- Coded Block Pattern (CBP)
; ECX -- Intra/Inter Flag
; EAX -- CBP Mask.
; The contents of EDI and EBX are modified and EDX , ECX, and EAX are
; preserved.
; -- ========================================================================
WriteOneBlock MACRO
LOCAL NotIntra, WriteDone, WriteCodes, WriteExit
push eax
push edx
cmp ecx, 1 ;; Check to see if this is an
jne NotIntra ;; Intra block, and if so,
WriteIntraDC ;; write the DC value.
and eax, edx ;; Check CBP to see if done.
jnz WriteCodes
WriteEndOfBlock
jmp WriteExit
NotIntra:
and eax, edx ;; Check CBP to see if done.
jnz WriteCodes
jmp WriteExit
WriteCodes:
mov al, (RLS PTR [esi]).Run ;; Get the RUN value.
cmp eax, 0000000FFh ;; Check to see if done.
je WriteDone ;; If not, then continue to
WriteOneCode ;; write the codes in this
add esi, SIZEOF RLS ;; block until done.
mov ecx, 1 ;; Flag WriteOneCode that not
jmp WriteCodes ;; first code.
WriteDone:
WriteEndOfBlock
add esi, SIZEOF RLS ;; Bump to next block.
WriteExit:
pop edx
pop eax
ENDM
.DATA
FLC_INTRADC DB 256 DUP (?)
VLC_TCOEF_TBL DD (64 * 16) DUP (?)
.CODE
; ++ ========================================================================
; This is the C function call entry point. This function variable length
; encodes an entire macroblock, one block at a time.
; -- ========================================================================
MBEncodeVLC PROC PUBLIC USES edi esi ebx ecx, pMBRVS_Luma:DWORD, pMBRVS_Chroma:DWORD, CodedBlockPattern:DWORD, ppBitStream:DWORD, pBitOffset:DWORD, IntraFlag:DWORD, MMxFlag:DWORD
mov esi, pMBRVS_Luma
mov edi, ppBitStream
mov ebx, pBitOffset
mov edx, CodedBlockPattern
mov esi, [esi]
mov eax, 1 ; CBP Mask.
LumaWriteLoop:
test eax, 000000010h ; When EAX bit shifts to this
jnz LumaBlocksDone ; position, we are done with Luma.
mov ecx, IntraFlag
WriteOneBlock
shl eax, 1 ; Shift CBP mask to next block.
jmp LumaWriteLoop
LumaBlocksDone:
mov ecx, MMxFlag
test ecx, 1
jz ChromaWriteLoop
mov ecx, pMBRVS_Luma
mov [ecx],esi
mov ecx, pMBRVS_Chroma
mov esi,[ecx]
ChromaWriteLoop:
test eax, 000000040h ; When EAX bit shifts to this
jnz ChromaBlocksDone ; position, we are done.
mov ecx, IntraFlag
WriteOneBlock
shl eax, 1 ; Shift CBP mask to next block.
jmp ChromaWriteLoop
ChromaBlocksDone:
mov eax, pMBRVS_Chroma
mov ecx, MMxFlag
test ecx, 1
jz MacroBlockDone
mov [eax],esi
MacroBlockDone:
ret
MBEncodeVLC ENDP
END