h263pdec.c
来自「symbian 下的helix player源代码」· C语言 代码 · 共 783 行 · 第 1/2 页
C
783 行
/* ***** BEGIN LICENSE BLOCK *****
* Source last modified: $Id: h263pdec.c,v 1.2.42.1 2004/07/09 01:56:22 hubbe Exp $
*
* Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
*
* The contents of this file, and the files included with this file,
* are subject to the current version of the RealNetworks Public
* Source License (the "RPSL") available at
* http://www.helixcommunity.org/content/rpsl unless you have licensed
* the file under the current version of the RealNetworks Community
* Source License (the "RCSL") available at
* http://www.helixcommunity.org/content/rcsl, in which case the RCSL
* will apply. You may also obtain the license terms directly from
* RealNetworks. You may not use this file except in compliance with
* the RPSL or, if you have a valid RCSL with RealNetworks applicable
* to this file, the RCSL. Please see the applicable RPSL or RCSL for
* the rights, obligations and limitations governing use of the
* contents of the file.
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
* "GPL") in which case the provisions of the GPL are applicable
* instead of those above. If you wish to allow use of your version of
* this file only under the terms of the GPL, and not to allow others
* to use your version of this file under the terms of either the RPSL
* or RCSL, indicate your decision by deleting the provisions above
* and replace them with the notice and other provisions required by
* the GPL. If you do not delete the provisions above, a recipient may
* use your version of this file under the terms of any one of the
* RPSL, the RCSL or the GPL.
*
* This file is part of the Helix DNA Technology. RealNetworks is the
* developer of the Original Code and owns the copyrights in the
* portions it created.
*
* This file, and the files included with this file, is distributed
* and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
* KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
* ENJOYMENT OR NON-INFRINGEMENT.
*
* Technology Compatibility Kit Test Suite(s) Location:
* http://www.helixcommunity.org/content/tck
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** */
//#include <string.h>
#include "dllindex.h"
#include "h261defs.h"
#include "h261func.h"
#include "h263plus.h"
#include <stdio.h>
#include "assert.h"
#ifdef _MACINTOSH
#include <string.h> // for memset
#endif
#ifdef COMPILE_MMX
#include "mmxcpuid.h"
#endif
//#define VVPROFILER
#define REPLACE_MACROS
extern void ApplyVerticalDeblockingFilter( PIXEL * left, PIXEL * right, int offset);
extern void ApplyVerticalDeblockingFilterMMX( PIXEL * left, PIXEL * right, int offset);
extern void ApplyHorizontalDeblockingFilter( PIXEL * top, PIXEL * bottom, int offset);
extern void ApplyHorizontalDeblockingFilterMMX( PIXEL * top, PIXEL * bottom, int offset);
#ifdef VVPROFILER
#include "hvdebtim.h"
extern struct CVvDebugTimer * pVvProf[];
#endif
void PredBframePlus( MACROBLOCK_DESCR * mb, // Macroblock to be predicted
PICTURE * prevPic, // Prev. picture (forward pred)
PICTURE * nextPic, // Next P-picture (backward pred)
PICTURE * Bpic // Output picture where pred is placed
);
// PredBframePlus - Form prediction for B-frame a la H.263+
void PredBframePlus( MACROBLOCK_DESCR * mb, // Macroblock to be predicted
PICTURE * prevPic, // Prev. picture (forward pred)
PICTURE * nextPic, // Next P-picture (backward pred)
PICTURE * Bpic // Output picture where pred is placed
)
{
if(BFRAME_IS_BIDIRECTIONAL(mb))
{
PredBframe(mb,prevPic,nextPic,Bpic);
}
else
{
S8 saveMvX = mb->mv_x;
S8 saveMvY = mb->mv_y;
U8 saveType = mb->mtype;
mb->mv_x = mb->mvdB_x;
mb->mv_y = mb->mvdB_y;
mb->mtype = MTYPE263_INTER;
MotionComp263( mb, prevPic, Bpic );
mb->mv_x = saveMvX;
mb->mv_y = saveMvY;
mb->mtype = saveType;
}
}
//////////////////////////////////////////////////////////////////////////
// Deblocking Filter Mode Functions
//
static U8 ClipTableBase[288];
static U8 * ClipTable=NULL;
static void InitializeClipTable()
{
int i;
if(ClipTable) {
return;
} else {
ClipTable = ClipTableBase + 16;
}
for(i = -16; i<=0; i++) ClipTable[i] = 0x00;
for(i=1 ; i<256; i++) ClipTable[i] = (U8) i;
for(i=256 ; i<272; i++) ClipTable[i] = 0xFF;
}
static S8 DiffCutoffTableBase[351]; // Range [-175, 175]
static S8 * DiffCutoffTable=NULL;
#ifdef COMPILE_MMX
#define SHORTMAX 32767
__int64 g_qp = 0;
// max - qp
__int64 g_max_qp = ((__int64) SHORTMAX)
| (((__int64) SHORTMAX)<<16)
| (((__int64) SHORTMAX)<<32)
| (((__int64) SHORTMAX)<<48);
// max - 2 * (qp)
__int64 g_max_2qp = ((__int64) SHORTMAX )
| (((__int64) SHORTMAX)<<16)
| (((__int64) SHORTMAX)<<32)
| (((__int64) SHORTMAX)<<48);
#endif
static void InitializeDiffCutoffTable(S32 qp)
{
static DiffTableQuantCache=0;
int d, d2;
if(DiffCutoffTable==NULL) {
memset(DiffCutoffTableBase, 0, 351);
DiffCutoffTable = DiffCutoffTableBase + 175;
}
if(DiffTableQuantCache == qp) return;
for(d=0, d2=0; d2<=qp; d++, d2+=2) {
DiffCutoffTable[d] = d;
DiffCutoffTable[-d] = -d;
}
for(;d<=qp;d++) {
DiffCutoffTable[d] = qp - d;
DiffCutoffTable[-d] = -qp + d;
}
for(;d<=DiffTableQuantCache;d++) {
DiffCutoffTable[d] = 0;
DiffCutoffTable[-d] = 0;
}
DiffTableQuantCache = qp;
#ifdef COMPILE_MMX
{
short max_qp, max_2pq;
max_qp = (short)SHORTMAX - (short) qp; // max - pq/2
max_2pq = (short)SHORTMAX - 2*(short)qp; // max - 2 * (pq/2)
g_qp = (((__int64) qp))
| (((__int64) qp)<<16)
| (((__int64) qp)<<32)
| (((__int64) qp)<<48);
g_max_qp = (((__int64) max_qp))
| (((__int64) max_qp)<<16)
| (((__int64) max_qp)<<32)
| (((__int64) max_qp)<<48);
g_max_2qp = (((__int64) max_2pq))
| (((__int64) max_2pq)<<16)
| (((__int64) max_2pq)<<32)
| (((__int64) max_2pq)<<48);
}
#endif
}
#ifdef _DEBUG
static PIXEL * MACROBLOCK_LUMA_PTR(PICTURE * p,MACROBLOCK_DESCR * mb)
{
return ((p)->y.ptr + 16*(mb)->x + 16*(mb)->y*(p)->y.hoffset);
}
static PIXEL * BlockLumaPtr(PICTURE * pic, MACROBLOCK_DESCR * mb, int blk)
{
switch(blk)
{
case 0:
return MACROBLOCK_LUMA_PTR(pic,mb);
case 1:
return MACROBLOCK_LUMA_PTR(pic,mb) + 8;
case 2:
return MACROBLOCK_LUMA_PTR(pic,mb) + 8*pic->y.hoffset;
default:
return MACROBLOCK_LUMA_PTR(pic,mb) + 8*(pic->y.hoffset + 1);
}
}
static PIXEL * MacroBlockCrPtr(PICTURE * pic, MACROBLOCK_DESCR * mb)
{
return pic->cr.ptr + 8*mb->x + 8*mb->y*pic->cr.hoffset;
}
static PIXEL * MacroBlockCbPtr(PICTURE * pic, MACROBLOCK_DESCR * mb)
{
return pic->cb.ptr + 8*mb->x + 8*mb->y*pic->cb.hoffset;
}
#else
#define MACROBLOCK_LUMA_PTR(p, mb) \
((p)->y.ptr + 16*(mb)->x + 16*(mb)->y*(p)->y.hoffset)
#define BlockLumaPtr(pic, mb, blk) \
(MACROBLOCK_LUMA_PTR((pic),(mb)) + 4*((blk)&2)*(pic)->y.hoffset + 8*((blk)&1))
#define MacroBlockCrPtr(pic, mb) \
((pic)->cr.ptr + 8*(mb)->x + 8*(mb)->y*(pic)->cr.hoffset)
#define MacroBlockCbPtr(pic, mb) \
((pic)->cb.ptr + 8*(mb)->x + 8*(mb)->y*(pic)->cb.hoffset)
#endif
/******************************************************************************************/
void ApplyVerticalDeblockingFilter( PIXEL * left, PIXEL * right, int offset)
{
int i;
left += 7;
for(i=0; i<8; i++) {
//8-bit arithmetic might overflow, changing to 32-bit
S32 d = DiffCutoffTable[(3*(S32) left[-1] - 8*(S32)left[0] + 8*(S32)right[0] - 3*(S32)right[1])>>4];
*left = ClipTable[*left + d];
*right = ClipTable[*right - d];
left += offset;
right += offset;
}
}
/*
PIXEL *left01, *right01, *left02, *right02;
static void ApplyVerticalDeblockingFilter( PIXEL * left, PIXEL * right, int offset)
{
int result, ii;
left01 = left;
right01 = right;
left02 = ((PIXEL *)calloc((8*offset)+8, sizeof(*left)));
//left02 += 7;
right02 = ((PIXEL *)calloc((8*offset)+8, sizeof(*right)));
if(!left02 || !right02) return;
//left[-1, 0, -1+offset, 0+offset, ..., -1+7*offset, 0+8*offset]
//right[0, +1, 0+offset, +1+offset, ..., 0+7*offset, +1+8*offset]
for(ii=0; ii<8; ii++) {
left02[-1+ii*offset+7] = left[-1+ii*offset+7];
left02[ 0+ii*offset+7] = left[ 0+ii*offset+7];
right02[ 0+ii*offset] = right[ 0+ii*offset];
right02[+1+ii*offset] = right[+1+ii*offset];
}
//call deblocking filter
ApplyVerticalDeblockingFilterMMX(left01, right01, offset);
ApplyVerticalDeblockingFilterInt(left02, right02, offset);
//compare output
for(ii=0; ii<8; ii++) {
if(
(left02[-1+ii*offset+7] != left01[-1+ii*offset+7])
|| (left02[ 0+ii*offset+7] != left01[ 0+ii*offset+7])
|| (right02[ 0+ii*offset] != right01[ 0+ii*offset])
|| (right02[+1+ii*offset] != right01[+1+ii*offset])
) {
result = ii;
}
}
free(left02);
free(right02);
}
*/
/******************************************************************************************/
void ApplyHorizontalDeblockingFilter( PIXEL * top, PIXEL * bottom, int offset)
{
int i;
PIXEL *next_to_top;
PIXEL *next_after_bottom;
top += 7*offset;
next_to_top = top - offset;
next_after_bottom = bottom + offset;
for(i=0; i<8; i++) {
//8-bit arithmetic might overflow, changing to 32-bit
S32 d = DiffCutoffTable[(3*(S32)next_to_top[0] - 8*(S32)top[0] + 8*(S32)bottom[0] - 3*(S32)next_after_bottom[0])>>4];
*top = ClipTable[*top + d];
*bottom = ClipTable[*bottom - d];
top += 1;
next_to_top += 1;
bottom += 1;
next_after_bottom += 1;
}
}
/*
PIXEL *top01=0, *bottom01=0;
PIXEL *top02=0, *bottom02=0;
static void ApplyHorizontalDeblockingFilter( PIXEL * top, PIXEL * bottom, int offset)
{
int result;
top01 = top;
bottom01 = bottom;
top02 = calloc((7*offset)+8, sizeof(*top));
bottom02 = calloc(offset+8, sizeof(*bottom));
if(!top02 || !bottom02) return;
//top+7*offset [0...7]
//top+6*offset [0...7]
memcpy(top02 + (7*offset), top + (7*offset), 8*sizeof(*top));
memcpy(top02 + (6*offset), top + (6*offset), 8*sizeof(*top));
//bottom[0...7]
//bottom+offset[0...7]
memcpy(bottom02, bottom, 8*sizeof(*bottom));
memcpy(bottom02 + offset, bottom + offset, 8*sizeof(*bottom));
//call deblocking filter
ApplyHorizontalDeblockingFilterMMX(top02, bottom02, offset);
ApplyHorizontalDeblockingFilterInt(top, bottom, offset);
//compare output
if((result = memcmp(top02 + (7*offset), top + (7*offset), 8*sizeof(*top))) != 0) {
PIXEL *point = top + (7*offset);
PIXEL *point02 = top02 + (7*offset);
}
if((result = memcmp(top02 + (6*offset), top + (6*offset), 8*sizeof(*top))) != 0) {
PIXEL *point = top + (6*offset);
PIXEL *point02 = top02 + (6*offset);
}
if((result = memcmp(bottom02, bottom, 8*sizeof(*bottom))) != 0) {
PIXEL *point = bottom;
PIXEL *point02 = bottom02;
}
if((result = memcmp(bottom02 + offset, bottom + offset, 8*sizeof(*bottom))) != 0) {
PIXEL *point = bottom + offset;
PIXEL *point02 = bottom02 + offset;
}
free(top02);
free(bottom02);
}
*/
/******************************************************************************************/
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?