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.
 
 
 
 
 
 

765 lines
18 KiB

/* *************************************************************************
** INTEL Corporation Proprietary Information
**
** This listing is supplied under the terms of a license
** agreement with INTEL Corporation and may not be copied
** nor disclosed except in accordance with the terms of
** that agreement.
**
** Copyright (c) 1995 Intel Corporation.
** Copyright (c) 1996 Intel Corporation.
** All Rights Reserved.
**
** *************************************************************************
*/
#include "precomp.h"
/* map of coded and not-coded blocks */
extern char coded_map[][22+1];
/* QP map */
extern char QP_map[][22];
#if defined(H263P) // { if defined(H263P)
/* table for de-blocking filter */
/* currently requires 2048 bytes */
signed char dxQP[64][32];
#if 0 // { 0
static void HorizEdgeFilter(unsigned char *rec,
int width,
int height,
int pitch,
int shift) {
int i, j, k;
int d, delta;
int mbc;
int mod_div = 1 << shift;
unsigned char *r = rec + (pitch << 3);
unsigned char *r_2 = r - (pitch << 1);
unsigned char *r_1 = r - pitch;
unsigned char *r1 = r + pitch;
char *pcoded_row0 = &coded_map[8>>shift][0];
char *pcoded_row1 = pcoded_row0 + sizeof(coded_map[0]);
char *pQP_map = &QP_map[0][0];
for (j = 8; j < height; ) {
for (i = 0; i < width; i += 8) {
mbc = i >> shift;
if (pcoded_row0[mbc+1] || pcoded_row1[mbc+1]) {
for (k = i; k < i+8; k++) {
d = (r_2[k]+(r_2[k]<<1)-(r_1[k]<<3)+(r[k]<<3)-(r1[k]+(r1[k]<<1)))>>4;
if (d && (d >= -32) && (d < 32)) {
delta = dxQP[d+32][pQP_map[mbc]];
r[k] = ClampTbl[r[k]-delta+CLAMP_BIAS];
r_1[k] = ClampTbl[r_1[k]+delta+CLAMP_BIAS];
}
}
}
}
r_2 += (pitch<<3);
r_1 += (pitch<<3);
r += (pitch<<3);
r1 += (pitch<<3);
if (0 == ((j+=8)%mod_div)) {
pcoded_row0 += sizeof(coded_map[0]);
pcoded_row1 += sizeof(coded_map[0]);
pQP_map += sizeof(QP_map[0]);
}
}
}
static void VertEdgeFilter(unsigned char *rec,
int width,
int height,
int pitch,
int shift) {
unsigned char *r = rec;
int i, j, k;
int mbc;
int d, delta;
int mod_div = 1 << shift;
char *pcoded_row1 = &coded_map[1][0];
char *pQP_map = &QP_map[0][0];
for (j = 0; j < height; ) {
for (i = 8; i < width; i += 8) {
mbc = i >> shift;
if (pcoded_row1[mbc] || pcoded_row1[mbc+1]) {
for (k = 0; k < 8; k++) {
d = (r[i-2]+(r[i-2]<<1)-(r[i-1]<<3)+(r[i]<<3)-(r[i+1]+(r[i+1]<<1)))>>4;
if (d && (d > -32) && (d < 32)) {
delta = dxQP[d+32][pQP_map[mbc]];
r[i] = ClampTbl[r[i]-delta+CLAMP_BIAS];
r[i-1] = ClampTbl[r[i-1]+delta+CLAMP_BIAS];
}
r += pitch;
}
r -= pitch<<3;
}
}
r += pitch<<3;
if (0 == ((j+=8)%mod_div)) {
pcoded_row1 += sizeof(coded_map[0]);
pQP_map += sizeof(QP_map[0]);
}
}
}
#else // }{ 0
__declspec(naked)
static void HorizEdgeFilter(unsigned char *rec,
int width,
int height,
int pitch,
int shift) {
// Permanent (callee-save) registers - ebx, esi, edi, ebp
// Temporary (caller-save) registers - eax, ecx, edx
//
// Stack frame layout
// | shift | + 68
// | pitch | + 64
// | height | + 60
// | width | + 56
// | rec | + 52
// -----------------------------
// | return addr | + 48
// | saved ebp | + 44
// | saved ebx | + 40
// | saved esi | + 36
// | saved edi | + 32
#define LOCALSIZE 32
#define SHIFT 68
#define PITCH_PARM 64
#define HEIGHT 60
#define WIDTH 56
#define REC 52
#define LOOP_I 28
#define LOOP_J 24
#define LOOP_K 20
#define PCODED_ROW0 16
#define PCODED_ROW1 12
#define PQP_MAP 8
#define MBC 4
#define LOOP_K_LIMIT 0
_asm {
push ebp
push ebx
push esi
push edi
sub esp, LOCALSIZE
// r = rec + (pitch << 3)
// r_2 = r - (pitch << 1)
// r_1 = r - pitch
// r1 = r + pitch
// assign(esi, r_2)
// assign(edi, r1)
// assign(ebp, pitch)
mov ebp, [esp + PITCH_PARM]
mov esi, [esp + REC]
lea esi, [esi + ebp*4]
lea esi, [esi + ebp*2]
lea edi, [esi + ebp*2]
lea edi, [edi + ebp]
// pcoded_row0 = &coded_map[8>>shift][0]
// pcoded_row1 = pcoded_row0 + sizeof(coded_map[0])
// pQP_map = &QP_map[0][0]
mov eax, 8
mov ecx, [esp + SHIFT]
shr eax, cl
mov ebx, TYPE coded_map[0]
imul eax, ebx
lea eax, [coded_map + eax]
mov [esp + PCODED_ROW0], eax
add eax, ebx
mov [esp + PCODED_ROW1], eax
lea eax, [QP_map]
mov [esp + PQP_MAP], eax
// for (j = 8; j < height; )
mov DWORD PTR [esp + LOOP_J], 8
L1:
// for (i = 0; i < width; i += 8)
mov DWORD PTR [esp + LOOP_I], 0
L2:
// mbc = i >> shift
// if (pcoded_row0[mbc+1] || pcoded_row1[mbc+1])
mov eax, [esp + LOOP_I]
mov ecx, [esp + SHIFT]
shr eax, cl
mov ebx, [esp + PCODED_ROW0]
mov [esp + MBC], eax
mov cl, [ebx+eax+1]
mov ebx, [esp + PCODED_ROW1]
test ecx, ecx
jnz L3
mov cl, [ebx+eax+1]
test ecx, ecx
jz L4
L3:
// for (k = i; k < i+8; k++)
mov eax, [esp + LOOP_I]
xor ebx, ebx
add eax, 8
// read r_1[k]
mov bl, [esi+ebp]
mov [esp + LOOP_K_LIMIT], eax
xor eax, eax
L5:
// d = (r_2[k]+(r_2[k]<<1)-(r_1[k]<<3)+(r[k]<<3)-(r1[k]+(r1[k]<<1)))>>4
// read r_2[k]
mov al, [esi]
xor ecx, ecx
// read r[k]
mov cl, [esi+ebp*2]
xor edx, edx
// read r1[k] and compute r_2[k]*3
mov dl, [edi]
lea eax,[eax+eax*2]
// compute r_1[k]*8 and r[k]*8
lea ebx, [ebx*8]
lea ecx, [ecx*8]
// compute r1[k]*3 and (r_2[k]*3 - r_1[k]*8)
lea edx, [edx+edx*2]
sub eax, ebx
// compute (r_2[k]*3 - r_1[k]*8 + r[k]*8)
add eax, ecx
xor ecx, ecx
// compute (r_2[k]*3 - r_1[k]*8 + r[k]*8 - r1[k]*3)
sub eax, edx
xor edx, edx
// compute (r_2[k]*3 - r_1[k]*8 + r[k]*8 - r1[k]*3) >> 4
sar eax, 4
mov ebx, [esp + PQP_MAP]
// if (d && (d >= -32) && (d < 32))
add ebx, [esp + MBC]
test eax, eax
jz L6
cmp eax, -32
jl L6
cmp eax, 32
jge L6
// delta = dxQP[d+32][pQP_map[mbc]]
// r[k] = ClampTbl[r[k]-delta+CLAMP_BIAS]
// r_1[k] = ClampTbl[r_1[k]+delta+CLAMP_BIAS]
lea eax, [eax + 32]
mov cl, [ebx]
shl eax, 5
mov dl, [esi+ebp]
mov al, dxQP[eax+ecx]
mov cl, [esi+ebp*2]
movsx eax, al
sub ecx, eax
mov dl, ClampTbl[edx + eax + CLAMP_BIAS]
mov cl, ClampTbl[ecx + CLAMP_BIAS]
mov [esi+ebp], dl
mov [esi+ebp*2], cl
nop
L6:
mov edx, [esp + LOOP_I]
inc esi
inc edx
inc edi
xor eax, eax
xor ebx, ebx
mov [esp + LOOP_I], edx
mov bl, [esi+ebp]
cmp edx, [esp + LOOP_K_LIMIT]
jl L5
jmp L4a
L4:
mov eax, [esp + LOOP_I]
lea esi, [esi+8]
add eax, 8
lea edi, [edi+8]
mov [esp + LOOP_I],eax
nop
L4a:
mov eax, [esp + LOOP_I]
cmp eax, [esp + WIDTH]
jl L2
// r_2 += (pitch<<3)
// r_1 += (pitch<<3)
// r += (pitch<<3)
// r1 += (pitch<<3)
mov eax, ebp
shl eax, 3
sub eax, [esp + WIDTH]
lea esi, [esi + eax]
lea edi, [edi + eax]
// if (0 == ((j+=8)%mod_div))
mov eax, [esp + LOOP_J]
add eax, 8
mov [esp + LOOP_J], eax
mov ebx, eax
mov ecx, [esp + SHIFT]
shr eax, cl
shl eax, cl
sub ebx, eax
jnz L7
// pcoded_row0 += sizeof(coded_map[0])
// pcoded_row1 += sizeof(coded_map[0])
// pQP_map += sizeof(QP_map[0])
mov eax, [esp + PCODED_ROW0]
mov ebx, [esp + PCODED_ROW1]
mov ecx, [esp + PQP_MAP]
add eax, TYPE coded_map[0]
add ebx, TYPE coded_map[0]
add ecx, TYPE QP_map[0]
mov [esp + PCODED_ROW0], eax
mov [esp + PCODED_ROW1], ebx
mov [esp + PQP_MAP], ecx
L7:
mov eax, [esp + LOOP_J]
cmp eax, [esp + HEIGHT]
jl L1
add esp, LOCALSIZE
pop edi
pop esi
pop ebx
pop ebp
ret
}
}
#undef LOCALSIZE
#undef SHIFT
#undef PITCH_PARM
#undef HEIGHT
#undef WIDTH
#undef REC
#undef LOOP_I
#undef LOOP_J
#undef LOOP_K
#undef PCODED_ROW0
#undef PCODED_ROW1
#undef PQP_MAP
#undef MBC
#undef LOOP_K_LIMIT
__declspec(naked)
static void VertEdgeFilter(unsigned char *rec,
int width,
int height,
int pitch,
int shift) {
// Permanent (callee-save) registers - ebx, esi, edi, ebp
// Temporary (caller-save) registers - eax, ecx, edx
//
// Stack frame layout
// | shift | + 56
// | pitch | + 52
// | height | + 48
// | width | + 44
// | rec | + 40
// -----------------------------
// | return addr | + 36
// | saved ebp | + 32
// | saved ebx | + 28
// | saved esi | + 24
// | saved edi | + 20
#define LOCALSIZE 20
#define SHIFT 56
#define PITCH_PARM 52
#define HEIGHT 48
#define WIDTH 44
#define REC 40
#define LOOP_K 16
#define LOOP_J 12
#define PCODED_ROW1 8
#define PQP_MAP 4
#define MBC 0
_asm {
push ebp
push ebx
push esi
push edi
sub esp, LOCALSIZE
// assign(esi, r)
mov esi, [esp + REC]
// assign(edi, pitch)
mov edi, [esp + PITCH_PARM]
// pcoded_row1 = &coded_map[1][0]
mov eax, TYPE coded_map[0]
lea eax, [coded_map + eax]
mov [esp + PCODED_ROW1], eax
// pQP_map = &QP_map[0][0]
lea eax, [QP_map]
mov [esp + PQP_MAP], eax
// for (j = 0; j < height; )
xor eax, eax
mov [esp + LOOP_J], eax
L1:
// for (i = 8; i < width; i += 8)
// assign(ebp,i)
mov ebp, 8
// mbc = i >> shift
L2:
mov eax, ebp
mov ecx, [esp + SHIFT]
shr eax, cl
mov [esp + MBC], eax
// if (pcoded_row1[mbc] || pcoded_row1[mbc+1])
xor ecx, ecx
mov ebx, [esp + PCODED_ROW1]
mov cl, [ebx+eax]
test ecx, ecx
jnz L3
mov cl, [ebx+eax+1]
test ecx, ecx
jz L4
L3:
// for (k = 0; k < 8; k++)
mov DWORD PTR [esp + LOOP_K], 8
xor eax, eax
xor ebx, ebx
xor ecx, ecx
xor edx, edx
L5:
// d = (r[i-2]+(r[i-2]<<1)-(r[i-1]<<3)+(r[i]<<3)-(r[i+1]+(r[i+1]<<1)))>>4
// read r[i-2] and r[i]
mov al, [esi+ebp-2]
mov bl, [esi+ebp]
// read r[i-1] and r[i+1]
mov cl, [esi+ebp-1]
mov dl, [esi+ebp+1]
// compute r[i-2]*3 and r[i]*8
lea eax, [eax+eax*2]
lea ebx, [ebx*8]
// compute r[i-1]*8 and r[i+1]*3
lea ecx, [ecx*8]
lea edx, [edx+edx*2]
// compute (r[i-2]*3 + r[i]*8) and (r[i-1]*8 + r[i+1]*3)
add eax, ebx
add ecx, edx
// compute (r[i-2]*3 - r[i-1]*8 + r[i]*8 - r[i+1]*3)
sub eax, ecx
xor ecx, ecx
// compute ((r[i-2]*3 - r[i-1]*8 + r[i]*8 - r[i+1]*3) >> 4)
sar eax, 4
xor edx, edx
// if (d && (d >= -32) && (d < 32))
test eax, eax
jz L6
cmp eax, -32
jl L6
cmp eax, 32
jge L6
// delta = dxQP[d+32][pQP_map[mbc]]
// r[i] = ClampTbl[r[i]-delta+CLAMP_BIAS]
// r[i-1] = ClampTbl[r[i-1]+delta+CLAMP_BIAS]
lea eax, [eax + 32]
mov ebx, [esp + PQP_MAP]
shl eax, 5
add ebx, [esp + MBC]
mov cl, [ebx]
xor ebx, ebx
mov al, dxQP[eax+ecx]
mov bl, [esi+ebp]
movsx eax, al
sub ebx, eax
mov cl, [esi+ebp-1]
mov bl, ClampTbl[ebx + CLAMP_BIAS]
mov cl, ClampTbl[ecx + eax + CLAMP_BIAS]
mov [esi+ebp], bl
mov [esi+ebp-1], cl
L6:
add esi, edi
mov eax, [esp + LOOP_K]
xor ebx, ebx
dec eax
mov [esp + LOOP_K], eax
jnz L5
// r -= (pitch<<3)
mov eax, edi
shl eax, 3
sub esi, eax
L4:
add ebp, 8
cmp ebp, [esp + WIDTH]
jl L2
// r += (pitch<<3)
mov eax, edi
shl eax, 3
lea esi, [esi + eax]
// if (0 == ((j+=8)%mod_div))
mov eax, [esp + LOOP_J]
add eax, 8
mov [esp + LOOP_J], eax
mov ebx, eax
mov ecx, [esp + SHIFT]
shr eax, cl
shl eax, cl
sub ebx, eax
jnz L7
// pcoded_row1 += sizeof(coded_map[0])
// pQP_map += sizeof(QP_map[0])
mov eax, [esp + PCODED_ROW1]
mov ebx, [esp + PQP_MAP]
add eax, TYPE coded_map[0]
add ebx, TYPE QP_map[0]
mov [esp + PCODED_ROW1], eax
mov [esp + PQP_MAP], ebx
L7:
mov eax, [esp + LOOP_J]
cmp eax, [esp + HEIGHT]
jl L1
add esp, LOCALSIZE
pop edi
pop esi
pop ebx
pop ebp
ret
}
}
#undef LOCALSIZE
#undef SHIFT
#undef PITCH_PARM
#undef HEIGHT
#undef WIDTH
#undef REC
#undef LOOP_K
#undef LOOP_J
#undef PCODED_ROW1
#undef PQP_MAP
#undef MBC
#endif // } 0
#define abs(x) (((x)>0)?(x):(-(x)))
#define sign(x) (((x)<0)?(-1):(1))
void InitEdgeFilterTab()
{
int d,QP;
for (d = 0; d < 64; d++) { // -32 <= d < 32
for (QP = 0; QP < 32; QP++) { // 0 <= QP < 32
dxQP[d][QP] = sign(d-32)*(max(0,(abs(d-32)-max(0,((2*abs(d-32))-QP)))));
}
}
}
/**********************************************************************
*
* Name: EdgeFilter
* Description: performs deblocking filtering on
* reconstructed frames
*
* Input: pointers to reconstructed frame and difference
* image
* Returns:
* Side effects:
*
* Date: 951129 Author: [email protected]
* [email protected]
* Modified for annex J in H.263+: 961120 Karl O. Lillevold
*
***********************************************************************/
// C version of block edge filter functions
// takes about 3 ms for QCIF and 12 ms for CIF on a Pentium 120.
void EdgeFilter(unsigned char *lum,
unsigned char *Cb,
unsigned char *Cr,
int width, int height, int pitch) {
/* Luma */
HorizEdgeFilter(lum, width, height, pitch, 4);
VertEdgeFilter (lum, width, height, pitch, 4);
/* Chroma */
HorizEdgeFilter(Cb, width>>1, height>>1, pitch, 3);
VertEdgeFilter (Cb, width>>1, height>>1, pitch, 3);
HorizEdgeFilter(Cr, width>>1, height>>1, pitch, 3);
VertEdgeFilter (Cr, width>>1, height>>1, pitch, 3);
return;
}
#else // Karl's original version }{
/* currently requires 11232 bytes */
signed char dtab[352*32];
/***********************************************************************/
static void HorizEdgeFilter(unsigned char *rec,
int width, int height, int pitch, int chr)
{
int i,j,k;
int delta;
int mbc, mbr, do_filter;
unsigned char *r_2, *r_1, *r, *r1;
signed char *deltatab;
/* horizontal edges */
r = rec + 8*pitch;
r_2 = r - 2*pitch;
r_1 = r - pitch;
r1 = r + pitch;
for (j = 8; j < height; j += 8) {
for (i = 0; i < width; i += 8) {
if (!chr) {
mbr = (j >> 4);
mbc = (i >> 4);
}
else {
mbr = (j >> 3);
mbc = (i >> 3);
}
deltatab = dtab + 176 + 351 * (QP_map[mbr][mbc] - 1);
do_filter = coded_map[mbr+1][mbc+1] || coded_map[mbr][mbc+1];
if (do_filter) {
for (k = i; k < i+8; k++) {
delta = (int)deltatab[ (( (int)(*(r_2 + k) * 3) -
(int)(*(r_1 + k) * 8) +
(int)(*(r + k) * 8) -
(int)(*(r1 + k) * 3)) >>4)];
*(r + k) = ClampTbl[ (int)(*(r + k)) - delta + CLAMP_BIAS];
*(r_1 + k) = ClampTbl[ (int)(*(r_1 + k)) + delta + CLAMP_BIAS];
}
}
}
r += (pitch<<3);
r1 += (pitch<<3);
r_1 += (pitch<<3);
r_2 += (pitch<<3);
}
return;
}
static void VertEdgeFilter(unsigned char *rec,
int width, int height, int pitch, int chr)
{
int i,j,k;
int delta;
int mbc, mbr;
int do_filter;
signed char *deltatab;
unsigned char *r;
/* vertical edges */
for (i = 8; i < width; i += 8)
{
r = rec;
for (j = 0; j < height; j +=8)
{
if (!chr) {
mbr = (j >> 4);
mbc = (i >> 4);
}
else {
mbr = (j >> 3);
mbc = (i >> 3);
}
deltatab = dtab + 176 + 351 * (QP_map[mbr][mbc] - 1);
do_filter = coded_map[mbr+1][mbc+1] || coded_map[mbr+1][mbc];
if (do_filter) {
for (k = 0; k < 8; k++) {
delta = (int)deltatab[(( (int)(*(r + i-2 ) * 3) -
(int)(*(r + i-1 ) * 8) +
(int)(*(r + i ) * 8) -
(int)(*(r + i+1 ) * 3) ) >>4)];
*(r + i ) = ClampTbl[ (int)(*(r + i )) - delta + CLAMP_BIAS];
*(r + i-1 ) = ClampTbl[ (int)(*(r + i-1)) + delta + CLAMP_BIAS];
r += pitch;
}
}
else {
r += (pitch<<3);
}
}
}
return;
}
/**********************************************************************
*
* Name: EdgeFilter
* Description: performs deblocking filtering on
* reconstructed frames
*
* Input: pointers to reconstructed frame and difference
* image
* Returns:
* Side effects:
*
* Date: 951129 Author: [email protected]
* [email protected]
* Modified for annex J in H.263+: 961120 Karl O. Lillevold
*
***********************************************************************/
void EdgeFilter(unsigned char *lum,
unsigned char *Cb,
unsigned char *Cr,
int width, int height, int pitch)
{
/* Luma */
HorizEdgeFilter(lum, width, height, pitch, 0);
VertEdgeFilter (lum, width, height, pitch, 0);
/* Chroma */
HorizEdgeFilter(Cb, width>>1, height>>1, pitch, 1);
VertEdgeFilter (Cb, width>>1, height>>1, pitch, 1);
HorizEdgeFilter(Cr, width>>1, height>>1, pitch, 1);
VertEdgeFilter (Cr, width>>1, height>>1, pitch, 1);
return;
}
#define sign(a) ((a) < 0 ? -1 : 1)
void InitEdgeFilterTab()
{
int i,QP;
for (QP = 1; QP <= 31; QP++) {
for (i = -176; i <= 175; i++) {
dtab[i+176 +(QP-1)*351] = sign(i) * (max(0,abs(i)-max(0,2*abs(i) - QP)));
}
}
}
#endif // } if defined(H263P)