h263pdec.c
来自「symbian 下的helix player源代码」· C语言 代码 · 共 783 行 · 第 1/2 页
C
783 行
// This routine applies the H.263+ deblocking filter to a decoded picture. Note
// That this routine is NOT H.263+ compliant because it applies the filter after the
// reconstructed picture has already been clipped to 0,255
void ApplyDeblockingFilter( PICTURE * pic, MACROBLOCK_DESCR * mb, S32 Bframe)
{
int i,h,v;
int numhor=pic->y.nhor>>4; // number of mb per row
int numvert=pic->y.nvert>>4; // number of mb per col
int nummb = numhor*numvert;
int off = pic->y.hoffset;
#ifdef REPLACE_MACROS
PIXEL *pLuma, *pCb, *pCr;
#endif
void (*pApplyHorizontalDeblockingFilter)(PIXEL *, PIXEL *, int);
void (*pApplyVerticalDeblockingFilter)(PIXEL *, PIXEL *, int);
#if defined(COMPILE_MMX)
#if (_MSC_VER>=1100)
if(cpuid_is_mmx_deblo_on()) {
//do mmx if compiler switch AND initialized AND detected
pApplyHorizontalDeblockingFilter = ApplyHorizontalDeblockingFilterMMX;
pApplyVerticalDeblockingFilter = ApplyVerticalDeblockingFilterMMX;
} else
#else
#pragma message("need MSVC 5.0 or higher to compile MMX - MMX disabled")
#endif
#endif
{
pApplyHorizontalDeblockingFilter = ApplyHorizontalDeblockingFilter;
pApplyVerticalDeblockingFilter = ApplyVerticalDeblockingFilter;
}
#ifdef VVPROFILER
S32 ret;
S32 nVvProfNb = 6;
if(!pVvProf[nVvProfNb]) pVvProf[nVvProfNb] = newCVvDebugTimer();//memory leak on destruction
StartTime(pVvProf[nVvProfNb]);
#endif
#ifdef REPLACE_MACROS
//aw using pointers instead of macros
pLuma = pic->y.ptr;
pCb = pic->cb.ptr;
pCr = pic->cr.ptr;
assert(off==16*numhor);
#endif
if(ClipTable==NULL) InitializeClipTable();
for(i=0,v=0; v<numvert; v++
#ifdef REPLACE_MACROS
, pLuma += 15*off,
pCb += 7*pic->cb.hoffset + pic->cb.hoffset/2,
pCr += 7*pic->cr.hoffset + pic->cr.hoffset/2
#endif
) {
for(h=0; h<numhor; h++, i++
#ifdef REPLACE_MACROS
, pLuma+=16, pCb+=8, pCr+=8
#endif
) {
int qp;
if(mb[i].mtype == MTYPE_SKIP) {
// Here we check to see if the macroblock below us is coded. If it is then we need to
// filter our bottom horizontal edges. Note that we need to use the quant value of the
// block below
if(v<numvert-1 && mb[i+numhor].mtype != MTYPE_SKIP) {
qp = Bframe ? mb[i+numhor].Bquant : mb[i+numhor].quant;
InitializeDiffCutoffTable(qp);
#ifndef REPLACE_MACROS
pApplyHorizontalDeblockingFilter(BlockLumaPtr(pic,&mb[i],2), BlockLumaPtr(pic,&mb[i+numhor],0), off);
pApplyHorizontalDeblockingFilter(BlockLumaPtr(pic,&mb[i],3), BlockLumaPtr(pic,&mb[i+numhor],1), off);
pApplyHorizontalDeblockingFilter(MacroBlockCbPtr(pic, &mb[i]), MacroBlockCbPtr(pic,&mb[i+numhor]), pic->cb.hoffset);
pApplyHorizontalDeblockingFilter(MacroBlockCrPtr(pic, &mb[i]), MacroBlockCrPtr(pic,&mb[i+numhor]), pic->cr.hoffset);
#else
assert(BlockLumaPtr(pic,&mb[i],2) == pLuma + 8*off);assert(BlockLumaPtr(pic,&mb[i+numhor],0) == pLuma + 16*off);
assert(BlockLumaPtr(pic,&mb[i],3) == pLuma + 8*off +8);assert(BlockLumaPtr(pic,&mb[i+numhor],1) == pLuma + 16*off +8);
assert(MacroBlockCbPtr(pic, &mb[i]) == pCb);assert(MacroBlockCbPtr(pic,&mb[i+numhor]) == pCb + 8*pic->cb.hoffset);
assert(MacroBlockCrPtr(pic, &mb[i]) == pCr);assert(MacroBlockCrPtr(pic,&mb[i+numhor]) == pCr + 8*pic->cr.hoffset);
pApplyHorizontalDeblockingFilter(pLuma + 8*off, pLuma + 16*off, off);
pApplyHorizontalDeblockingFilter(pLuma + 8*off +8, pLuma + 16*off +8, off);
pApplyHorizontalDeblockingFilter(pCb, pCb + 8*pic->cb.hoffset, pic->cb.hoffset);
pApplyHorizontalDeblockingFilter(pCr, pCr + 8*pic->cr.hoffset, pic->cr.hoffset);
#endif
}
// Here we check to see if the macroblock to the left of us is coded. If so do our left vertical
// edges
if(h && mb[i-1].mtype != MTYPE_SKIP) {
qp = Bframe ? mb[i-1].Bquant : mb[i-1].quant;
InitializeDiffCutoffTable(qp);
#ifndef REPLACE_MACROS
pApplyVerticalDeblockingFilter(BlockLumaPtr(pic,&mb[i-1],1), BlockLumaPtr(pic,&mb[i],0), off);
pApplyVerticalDeblockingFilter(BlockLumaPtr(pic,&mb[i-1],3), BlockLumaPtr(pic,&mb[i],2), off);
pApplyVerticalDeblockingFilter(MacroBlockCbPtr(pic, &mb[i-1]), MacroBlockCbPtr(pic,&mb[i]), pic->cb.hoffset);
pApplyVerticalDeblockingFilter(MacroBlockCrPtr(pic, &mb[i-1]), MacroBlockCrPtr(pic,&mb[i]), pic->cr.hoffset);
#else
assert(BlockLumaPtr(pic,&mb[i-1],1) == pLuma -8);assert(BlockLumaPtr(pic,&mb[i],0) == pLuma);
assert(BlockLumaPtr(pic,&mb[i-1],3) == pLuma + 8*off -8);assert(BlockLumaPtr(pic,&mb[i],2) == pLuma + 8*off);
assert(MacroBlockCbPtr(pic, &mb[i-1]) == pCb -8);assert(MacroBlockCbPtr(pic,&mb[i]) == pCb);
assert(MacroBlockCrPtr(pic, &mb[i-1]) == pCr -8);assert(MacroBlockCrPtr(pic,&mb[i]) == pCr);
pApplyVerticalDeblockingFilter(pLuma -8, pLuma, off);
pApplyVerticalDeblockingFilter(pLuma + 8*off -8, pLuma + 8*off, off);
pApplyVerticalDeblockingFilter(pCb -8, pCb, pic->cb.hoffset);
pApplyVerticalDeblockingFilter(pCr -8, pCr, pic->cr.hoffset);
#endif
}
} else {
qp = Bframe ? mb[i].Bquant : mb[i].quant;
InitializeDiffCutoffTable(qp);
// First do the first two horizontal edges
#ifndef REPLACE_MACROS
pApplyHorizontalDeblockingFilter(BlockLumaPtr(pic,&mb[i],0), BlockLumaPtr(pic,&mb[i],2), off);
pApplyHorizontalDeblockingFilter(BlockLumaPtr(pic,&mb[i],1), BlockLumaPtr(pic,&mb[i],3), off);
#else
assert(BlockLumaPtr(pic,&mb[i],0) == pLuma);assert(BlockLumaPtr(pic,&mb[i],2) == pLuma + 8*off);
assert(BlockLumaPtr(pic,&mb[i],1) == pLuma +8);assert(BlockLumaPtr(pic,&mb[i],3) == pLuma + 8*off +8);
pApplyHorizontalDeblockingFilter(pLuma, pLuma + 8*off, off);
pApplyHorizontalDeblockingFilter(pLuma +8, pLuma + 8*off +8, off);
#endif
// Now do the first two vertical edges; don't filter if the left edge is a picture edge
if(h) {
#ifndef REPLACE_MACROS
pApplyVerticalDeblockingFilter(BlockLumaPtr(pic,&mb[i-1],1), BlockLumaPtr(pic,&mb[i],0), off);
#else
assert(BlockLumaPtr(pic,&mb[i-1],1) == pLuma -8);assert(BlockLumaPtr(pic,&mb[i],0) == pLuma);
pApplyVerticalDeblockingFilter(pLuma -8, pLuma, off);
#endif
}
#ifndef REPLACE_MACROS
pApplyVerticalDeblockingFilter(BlockLumaPtr(pic,&mb[i],0), BlockLumaPtr(pic,&mb[i],1), off);
#else
assert(BlockLumaPtr(pic,&mb[i],0) == pLuma);assert(BlockLumaPtr(pic,&mb[i],1) == pLuma +8);
pApplyVerticalDeblockingFilter(pLuma, pLuma +8, off);
#endif
// Now do the bottom two horizontal edges; don't filter if we are at a bottom edge of the picture
if(v < numvert-1) {
// Use quantization parameter for lower macroblock if it was coded
if(mb[i+numhor].mtype != MTYPE_SKIP) {
InitializeDiffCutoffTable(Bframe ? mb[i+numhor].Bquant : mb[i+numhor].quant);
}
#ifndef REPLACE_MACROS
pApplyHorizontalDeblockingFilter(BlockLumaPtr(pic,&mb[i],2), BlockLumaPtr(pic,&mb[i+numhor],0),
off);
pApplyHorizontalDeblockingFilter(BlockLumaPtr(pic,&mb[i],3), BlockLumaPtr(pic,&mb[i+numhor],1),
off);
#else
assert(BlockLumaPtr(pic,&mb[i],2) == pLuma + 8*off);assert(BlockLumaPtr(pic,&mb[i+numhor],0) == pLuma + 16*off);
assert(BlockLumaPtr(pic,&mb[i],3) == pLuma + 8*off +8);assert(BlockLumaPtr(pic,&mb[i+numhor],1) == pLuma + 16*off +8);
pApplyHorizontalDeblockingFilter(pLuma + 8*off, pLuma + 16*off, off);
pApplyHorizontalDeblockingFilter(pLuma + 8*off +8, pLuma + 16*off +8, off);
#endif
// restore quantization parameter of current macroblock
InitializeDiffCutoffTable(qp);
}
// Lastly do the lower two vertical edges; don't filter if the left edge is a picture edge
if(h) {
#ifndef REPLACE_MACROS
pApplyVerticalDeblockingFilter(BlockLumaPtr(pic,&mb[i-1],3), BlockLumaPtr(pic,&mb[i],2), off);
#else
assert(BlockLumaPtr(pic,&mb[i-1],3) == pLuma + 8*off - 8);assert(BlockLumaPtr(pic,&mb[i],2) == pLuma +8*off);
pApplyVerticalDeblockingFilter(pLuma + 8*off - 8, pLuma +8*off, off);
#endif
}
#ifndef REPLACE_MACROS
pApplyVerticalDeblockingFilter(BlockLumaPtr(pic,&mb[i],2), BlockLumaPtr(pic,&mb[i],3), off);
#else
assert(BlockLumaPtr(pic,&mb[i],2) == pLuma + 8*off);assert(BlockLumaPtr(pic,&mb[i],3) == pLuma + 8*off +8);
pApplyVerticalDeblockingFilter(pLuma + 8*off, pLuma + 8*off +8, off);
#endif
// Now apply the filters to the chroma
if(v < numvert-1) {
#ifndef REPLACE_MACROS
pApplyHorizontalDeblockingFilter(MacroBlockCbPtr(pic, &mb[i]), MacroBlockCbPtr(pic,&mb[i+numhor]), pic->cb.hoffset);
pApplyHorizontalDeblockingFilter(MacroBlockCrPtr(pic, &mb[i]), MacroBlockCrPtr(pic,&mb[i+numhor]), pic->cr.hoffset);
#else
assert(MacroBlockCbPtr(pic, &mb[i]) == pCb);assert(MacroBlockCbPtr(pic,&mb[i+numhor]) == pCb +8*pic->cb.hoffset);
assert(MacroBlockCrPtr(pic, &mb[i]) == pCr);assert(MacroBlockCrPtr(pic,&mb[i+numhor]) == pCr +8*pic->cr.hoffset);
pApplyHorizontalDeblockingFilter(pCb, pCb +8*pic->cb.hoffset, pic->cb.hoffset);
pApplyHorizontalDeblockingFilter(pCr, pCr +8*pic->cr.hoffset, pic->cr.hoffset);
#endif
}
if(h) {
#ifndef REPLACE_MACROS
pApplyVerticalDeblockingFilter(MacroBlockCbPtr(pic, &mb[i-1]), MacroBlockCbPtr(pic,&mb[i]), pic->cb.hoffset);
pApplyVerticalDeblockingFilter(MacroBlockCrPtr(pic, &mb[i-1]), MacroBlockCrPtr(pic,&mb[i]), pic->cr.hoffset);
#else
assert(MacroBlockCbPtr(pic, &mb[i-1]) == pCb -8);assert(MacroBlockCbPtr(pic,&mb[i]) == pCb);
assert(MacroBlockCrPtr(pic, &mb[i-1]) == pCr -8);assert(MacroBlockCrPtr(pic,&mb[i]) == pCr);
pApplyVerticalDeblockingFilter(pCb -8, pCb, pic->cb.hoffset);
pApplyVerticalDeblockingFilter(pCr -8, pCr, pic->cr.hoffset);
#endif
}
}
}
}
//clear the mmx state
#if defined(COMPILE_MMX)
#if (_MSC_VER>=1100)
if(cpuid_is_mmx_deblo_on()) {
__asm emms
}
#endif
#endif
#ifdef VVPROFILER
StopAndAccuTime(pVvProf[nVvProfNb]);
#endif
}
/******************************************************************************************/
//////////////////////////////////////////////////////////////////////////////
// Deblocking filter for Reduced Resolution Update mode
//
static void vertFilterRRUmode( PIXEL * right, int offset, int len )
{
int i, valLeft, valRight;
for(i=0; i < len; i++) {
valLeft = right[-1];
valRight = right[0];
right[-1] = (3 * valLeft + 1 * valRight + 2) >> 2;
right[0] = (1 * valLeft + 3 * valRight + 2) >> 2;
right += offset;
}
}
static void horFilterRRUmode( PIXEL * bottom, int offset, int len )
{
int i, valTop, valBottom;
PIXEL *top;
top = bottom - offset;
for(i=0; i < len; i++) {
valTop = top[0];
valBottom = bottom[0];
top[0] = (3 * valTop + 1 * valBottom + 2) >> 2;
bottom[0] = (1 * valTop + 3 * valBottom + 2) >> 2;
top += 1;
bottom += 1;
}
}
// This routine applies the Reduced-res. Update mode deblocking filter to a decoded picture.
extern void ReducedResDeblockingFilter( PICTURE * pic, MACROBLOCK_DESCR * mb )
{
int i,h,v;
int numhor = (pic->y.nhor + 16) >> 5; // number of mb per row
int numvert= (pic->y.nvert+ 16) >> 5; // number of mb per col
int nummb = numhor*numvert;
int off = pic->y.hoffset;
PIXEL *luma0;
int hSize, vSize, cOffset;
for(i=0,v=0; v<numvert; v++) {
vSize = 32;
if (32 * v + 16 >= pic->y.nvert)
vSize = 16; // MB is truncated at the bottom
for(h=0; h<numhor; h++, i++) {
hSize = 32;
if (32 * h + 16 >= pic->y.nhor)
hSize = 16; // MB is truncated at the right
luma0 = pic->y.ptr + 32 * h + 32 * v * off;
cOffset = 16 * h + 16 * v * pic->cb.hoffset;
// Filter horizontal edge inside block
if (mb[i].mtype != MTYPE_SKIP && vSize == 32) {
horFilterRRUmode( luma0 + 16*off, off, hSize );
}
// Filter horizontal edge at the bottom of the block
if (v < numvert-1 &&
(mb[i].mtype != MTYPE_SKIP || mb[i+numhor].mtype != MTYPE_SKIP)) {
horFilterRRUmode( luma0 + 32*off, off, hSize );
horFilterRRUmode( pic->cb.ptr + cOffset + 16*pic->cb.hoffset,
pic->cb.hoffset, hSize>>1 );
horFilterRRUmode( pic->cr.ptr + cOffset + 16*pic->cr.hoffset,
pic->cr.hoffset, hSize>>1 );
}
// Filter vertical edge at the left of the block
if (h > 0 &&
(mb[i].mtype != MTYPE_SKIP || mb[i-1].mtype != MTYPE_SKIP)) {
vertFilterRRUmode( luma0, off, vSize );
vertFilterRRUmode( pic->cb.ptr + cOffset,
pic->cb.hoffset, vSize>>1 );
vertFilterRRUmode( pic->cr.ptr + cOffset,
pic->cr.hoffset, vSize>>1 );
}
// Filter vertical edge inside block
if (mb[i].mtype != MTYPE_SKIP && hSize == 32) {
vertFilterRRUmode( luma0 + 16, off, vSize );
}
}
}
}
// Alternate Horizontal Scan Order
static int alt_hor_scan[64] = { 0, 1, 2, 3,10,11,12,13,
4, 5, 8, 9,17,16,15,14,
6, 7,19,18,26,27,28,29,
20,21,24,25,30,31,32,33,
22,23,34,35,42,43,44,45,
36,37,40,41,46,47,48,49,
38,39,50,51,56,57,58,59,
52,53,54,55,60,61,62,63};
// Alternate Vertical (MPEG-2) Scan Order
static int alt_ver_scan[64] = { 0, 4, 6,20,22,36,38,52,
1, 5, 7,21,23,37,39,53,
2, 8,19,24,34,40,50,54,
3, 9,18,25,35,41,51,55,
10,17,26,30,42,46,56,60,
11,16,27,31,43,47,57,61,
12,15,28,32,44,48,58,62,
13,14,29,33,45,49,59,63};
static int MyZigZag[64] = { 0, 1, 5, 6, 14, 15, 27, 28,
2, 4, 7, 13, 16, 26, 29, 42,
3, 8, 12, 17, 25, 30, 41, 43,
9, 11, 18, 24, 31, 40, 44, 53,
10, 19, 23, 32, 39, 45, 52, 54,
20, 22, 33, 38, 46, 51, 55, 60,
21, 34, 37, 47, 50, 56, 59, 61,
35, 36, 48, 49, 57, 58, 62, 63
};
static int reorder[8] = {0,4,2,7, 1,5,3,6};
int ireorder[8] = {0,4,2,6, 1,5,7,3};
int inv_alt_hor_scan[64];
int inv_alt_hor_scan_no_reorder[64];
int alt_hor_to_zigzag[64];
int inv_alt_ver_scan[64];
int inv_alt_ver_scan_no_reorder[64];
int alt_ver_to_zigzag[64];
int zigzag_to_zigzag[64];
void InitAdvancedIntraTables()
{
static int initialized=0;
int index,i,j;
if(initialized) return;
initialized = 1;
// Generate inverse scan order vectors
for (index = 0; index < 64; index++) {
i = reorder[index % 8];
j = reorder[index / 8];
inv_alt_ver_scan[ alt_ver_scan[index] ] = i*8 + j;
inv_alt_hor_scan[ alt_hor_scan[index] ] = i*8 + j;
inv_alt_ver_scan_no_reorder[ alt_ver_scan[index] ] = index;
inv_alt_hor_scan_no_reorder[ alt_hor_scan[index] ] = index;
}
// Now do the scan's from alt hor and alt ver to zigzag.
// We need to be careful because the above tables take into
// account the reorderings that come from our DCT. We don't
// want to take that into account, so we apply the ireorder
for(index = 0; index < 64; index++) {
i = ireorder[ inv_alt_ver_scan[index]&7 ];
j = ireorder[ inv_alt_ver_scan[index]>>3 ];
alt_ver_to_zigzag[ index ] = MyZigZag[ i*8 + j ];
i = ireorder[ inv_alt_hor_scan[index]&7 ];
j = ireorder[ inv_alt_hor_scan[index]>>3 ];
alt_hor_to_zigzag[ index ] = MyZigZag[ i*8 + j ];
zigzag_to_zigzag[ index ] = index;
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?