h261dec.c
来自「symbian 下的helix player源代码」· C语言 代码 · 共 1,645 行 · 第 1/5 页
C
1,645 行
return (H261_ERROR);
}
}
#endif // TESTING
#ifdef ANNOTATE_PICTURE
// saveOrRestoreReconPicture
static void saveOrRestoreReconPicture( PICTURE *pic, // Picture to be saved or restored
int restore // Save if 0, otherwise restore
)
{
#define MAX_BYTES ((176*144*3)/2)
int nBytes;
static PIXEL savePic[MAX_BYTES];
nBytes = (pic->y.nhor * pic->y.nvert * 3) >> 1;
// Packed format is assumed
if (nBytes > MAX_BYTES) {
H261ErrMsg("Error in saveOrRestoreReconPicture\n");
exit(0);
} else if (restore) { // Restore the saved picture
memcpy( pic->y.ptr, savePic, nBytes ); /* Flawfinder: ignore */
} else { // Save picture for next decoding
memcpy( savePic, pic->y.ptr, nBytes ); /* Flawfinder: ignore */
}
}
// annotatePicture - Draw motion vectors etc.
static void annotatePicture( PICTURE *pic, MACROBLOCK_DESCR mb[])
{
int xSize, ySize, numMb, i, x, y;
PIXEL *upperLeft;
xSize = pic->y.nhor;
ySize = pic->y.nvert;
numMb = (xSize * ySize) >> 8;
for (i = 0; i < numMb; ++i) {
x = 16 * mb[i].x;
y = 16 * mb[i].y;
upperLeft = pic->y.ptr + x + y * pic->y.hoffset;
annotateMacroblock( upperLeft, pic->y.hoffset, &mb[i],
-x, xSize - 1 - x,
-y, ySize - 1 - y );
}
}
#define WHITE (255)
#define BLACK (0)
#define BLACK_THRESHOLD (192) // Paint with black if pixel is brighter than threshold
// Limit x to interval [low,high]
#define LIMIT( low, x, high ) max( low, min( x, high ))
// annotateMacroblock
static void annotateMacroblock( PIXEL data[], int xdim, MACROBLOCK_DESCR *mb,
int xMin, int xMax, int yMin, int yMax )
{
switch (mb->mtype)
{
case MTYPE_SKIP:
// Do nothing
break;
case MTYPE263_INTER:
case MTYPE263_INTER_Q:
// Draw motion vector
drawMv( &data[7 + 7 * xdim], xdim, mb->mv_x, mb->mv_y,
xMin-7, xMax-7, yMin-7, yMax-7 );
break;
case MTYPE263_INTER4V:
// Draw a "plus"
plusMb( data, xdim );
// Draw 4 motion vectors
drawMv( &data[3 + 3 * xdim], xdim, mb->blkMvX[0], mb->blkMvY[0],
xMin-3, xMax-3, yMin-3, yMax-3 );
drawMv( &data[11 + 3 * xdim], xdim, mb->blkMvX[1], mb->blkMvY[1],
xMin-11, xMax-11, yMin-3, yMax-3 );
drawMv( &data[3 + 11 * xdim], xdim, mb->blkMvX[2], mb->blkMvY[2],
xMin-3, xMax-3, yMin-11, yMax-11 );
drawMv( &data[11 + 11 * xdim], xdim, mb->blkMvX[3], mb->blkMvY[3],
xMin-11, xMax-11, yMin-11, yMax-11 );
break;
case MTYPE263_INTRA:
case MTYPE263_INTRA_Q:
// Draw motion vector and mark block with a cross
drawMv( &data[7 + 7 * xdim], xdim, mb->mv_x, mb->mv_y,
xMin-7, xMax-7, yMin-7, yMax-7 );
crossMb( data, xdim );
break;
default:
// Fill block with white
fillMb( data, xdim );
break;
}
}
// drawMv - Draw motion vector starting in (0,0)
static void drawMv( PIXEL data[], int xdim, int mvX, int mvY,
int xMin, int xMax, int yMin, int yMax )
{
if (mvX == 0 && mvY == 0) {
// Draw a circle
markPixel( &data[-xdim] );
markPixel( &data[-xdim + 1] );
markPixel( &data[-1] );
markPixel( &data[2] );
markPixel( &data[xdim - 1] );
markPixel( &data[xdim + 2] );
markPixel( &data[2*xdim] );
markPixel( &data[2*xdim+1] );
} else { // Draw motion vector
// Divide by 2 (one frac. bit); round "away" from 0
/*if (mvX > 0) ++mvX;
mvX >>= 1;
if (mvY > 0) ++mvY;
mvY >>= 1;*/ // Leave mv's scaled up by factor of 2
// Clip to picture rectangle
mvX = LIMIT( xMin, mvX, xMax );
mvY = LIMIT( yMin, mvY, yMax );
DrawVector( data, xdim, 0, 0, mvX, mvY );
}
}
// plusMb - Mark block with a "plus"
static void plusMb( PIXEL data[], int xdim )
{
int col;
// Horizontal line
data += 7 * xdim;
for (col = 5; col <= 9; ++col) {
markPixel( &data[col] );
}
// Vertical line
markPixel( &data[7 - 2 * xdim] );
markPixel( &data[7 - 1 * xdim] );
markPixel( &data[7 + 1 * xdim] );
markPixel( &data[7 + 2 * xdim] );
}
// crossMb - Mark block with a cross
static void crossMb( PIXEL data[], int xdim )
{
int row;
for (row = 0; row < 16; ++row) {
markPixel( &data[row] );
markPixel( &data[15 - row] );
data += xdim;
}
}
// fillMb - Fill block with white
static void fillMb( PIXEL data[], int xdim )
{
int row, col;
for (row = 0; row < 16; ++row) {
for (col = 0; col < 16; ++col) {
markPixel( &data[col] );
}
data += xdim;
}
}
// markPixel - Set pixel to white if < 192, otherwise set it to black
static void markPixel( PIXEL *pixel )
{
if (*pixel < BLACK_THRESHOLD) {
*pixel = WHITE;
} else {
*pixel = BLACK;
}
}
///////////// Graphics routines /////////////
#include <stdlib.h>
#include <math.h>
// Static function declarations
static int DrawVector( unsigned char data[], int xdim, int x1, int y1, int x2, int y2 );
static int drawVec( unsigned char data[], int xdim, int x1, int y1 );
// DrawVector - Draw vector from (x1,y1) to (x2,y2)
static int DrawVector( unsigned char data[], int xdim, int x1, int y1, int x2, int y2 )
{
int x, y;
if (y1 == y2) { // Draw horizontal line
data += y1 * xdim;
for (x = min(x1,x2); x <= max(x1,x2); ++x) markPixel( &data[x] );
} else if (x1 == x2) { // Draw vertical line
data += min(y1,y2) * xdim;
for (y = min(y1,y2); y <= max(y1,y2); ++y) {
markPixel( &data[x1] );
data += xdim;
}
} else if (x2 > x1) { // Use (x1,y1) as origin
data += x1 + y1 * xdim;
drawVec( data, xdim, x2-x1, y2-y1 );
} else { // Use (x2,y2) as origin
data += x2 + y2 * xdim;
drawVec( data, xdim, x1-x2, y1-y2 );
}
return(1);
}
// drawVec - Draw vector from origin to (x1,y1)
// Assumes that x1 > 0, and y1 != 0
// Draw pixels that are within 0.5 units distance of vector
static int drawVec( unsigned char data[], int xdim, int x1, int y1 )
{
int x, y, xLast, xNew;
float fX1, fY1, fNorm, fA, fB, fXstep, fX, fDist;
if (y1 < 0) {
y1 = -y1;
xdim = -xdim;
}
// Now, both x1 and y1 are >0
// Compute equation for line: ax + by = 0, where (a,b) is normal vector of length 1
// The distance between (x,y) and the line is the inner product: abs(ax + by)
fX1 = (float)x1;
fY1 = (float)y1;
fNorm = (float) sqrt( fX1*fX1 + fY1*fY1);
fA = -fY1 / fNorm; // fA < 0
fB = fX1 / fNorm; // fB > 0
fXstep = fX1 / fY1; // x increment per row
// First row
fX = (float)(0.5 * fXstep); // Intersection with y=0.5
xLast = (int)fX; // Truncate (Note: fX > 0; int always truncates towards zero)
for (x = 0; x <= xLast; ++x) markPixel( &data[x] );
// Intermediate rows
for (y = 1; y < y1; ++y) {
data += xdim;
// Check distance to (xLast, y)
fDist = fA * (float)xLast + fB * (float)y; // fDist > 0
if (fDist < 0.4999) {
markPixel( &data[xLast] );
} else if (fDist + fA - fB > -0.4999) { // Check distance to (xLast+1, y-1)
//fDist = fA * (float)(xLast+1) + fB * (float)(y-1); // fDist < 0
markPixel( &data[xLast+1 - xdim] );
}
fX += fXstep; // Intersection with y+0.5
xNew = (int)fX;
for (x = xLast + 1; x <= xNew; ++x) markPixel( &data[x] );
xLast = xNew;
}
// Last row (y = y1)
data += xdim;
// Check distance to (xLast, y1)
fDist = fA * (float)xLast + fB * (float)y1; // fDist > 0
if (fDist < 0.4999) {
markPixel( &data[xLast] );
} else if (fDist + fA - fB > -0.4999) { // Check distance to (xLast+1, y1-1)
markPixel( &data[xLast+1 - xdim] );
}
for (x = xLast + 1; x <= x1; ++x) markPixel( &data[x] );
return(1);
}
#endif /* ANNOTATE_PICTURE */
/*
// Compute checksums for picture (used for debugging only)
static int checkPicture( PICTURE pic );
static int checkComponent( COMPONENT comp );
static PIXEL encPic[176*144], decPic[176*144], diffPic[176*144];
extern int storePicture( PICTURE pic, int picNum )
{
int i, j;
PIXEL *in, *out;
in = pic.y.ptr;
if (picNum == 0)
out = encPic;
else
out = decPic;
for (i = 0; i < pic.y.nvert; i++) {
for (j = 0; j < pic.y.nhor; j++) {
out[j] = in[j];
}
in += pic.y.hoffset;
out += pic.y.nhor;
}
return( 1 );
}
static int checkPicture( PICTURE pic )
{
int y, cb, cr, i;
static int sum = 0;
storePicture( pic, 1 );
y = checkComponent( pic.y );
cb = checkComponent( pic.cb );
cr = checkComponent( pic.cr );
sum += y + cb + cr;
for (i = 0; i < 176*144; ++i)
diffPic[i] = encPic[i] - decPic[i];
return( sum );
}
static int checkComponent( COMPONENT comp )
{
int i, j, sum;
PIXEL *p;
sum = 0, p = comp.ptr;
for (i = 0; i < comp.nvert; i++) {
for (j = 0; j < comp.nhor; j++) {
sum += p[j];
}
p += comp.hoffset;
}
return( sum );
}
*/
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?