⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pframe.c

📁 linux下将各类格式图片转换工具
💻 C
📖 第 1 页 / 共 3 页
字号:
/*===========================================================================* * pframe.c								      *									      *	Procedures concerned with generation of P-frames		      *									      * EXPORTED PROCEDURES:							      *	GenPFrame							      *	ResetPFrameStats						      *	ShowPFrameSummary						      *	EstimateSecondsPerPFrame					      *	ComputeHalfPixelData						      *	SetPQScale							      *	GetPQScale							      *                                                                            * NOTE:  when motion vectors are passed as arguments, they are passed as     *        twice their value.  In other words, a motion vector of (3,4) will   *        be passed as (6,8).  This allows half-pixel motion vectors to be    *        passed as integers.  This is true throughout the program.           *									      *===========================================================================*//*==============* * HEADER FILES * *==============*/#include <assert.h>#include <sys/param.h>#include "pm.h"#include "all.h"#include "mtypes.h"#include "bitio.h"#include "frames.h"#include "motion_search.h"#include "prototypes.h"#include "param.h"#include "mheaders.h"#include "fsize.h"#include "postdct.h"#include "mpeg.h"#include "parallel.h"#include "rate.h"#include "opts.h"#include "specifics.h"/*==================* * STATIC VARIABLES * *==================*/static int32	zeroDiff;static int      numPIBlocks = 0;static int      numPPBlocks = 0;static int      numPSkipped = 0;static int      numPIBits = 0;static int      numPPBits = 0;static int      numFrames = 0;static int      numFrameBits = 0;static int32    totalTime = 0;static int      qscaleP;static float	totalSNR = 0.0;static float	totalPSNR = 0.0;extern Block    **dct, **dctr, **dctb;extern dct_data_type   **dct_data;/*=====================* * INTERNAL PROCEDURES * *=====================*//*===========================================================================* * *			      USER-MODIFIABLE * * ZeroMotionBetter * *	decide if (0,0) motion is better than the given motion vector * * RETURNS:	TRUE if (0,0) is better, FALSE if (my,mx) is better * * SIDE EFFECTS:    none * * PRECONDITIONS:	The relevant block in 'current' is valid (it has not *			been dct'd).  'zeroDiff' has already been computed *			as the LumMotionError() with (0,0) motion * * NOTES:	This procedure follows the algorithm described on *		page D-48 of the MPEG-1 specification * *===========================================================================*/static booleanZeroMotionBetter(currentBlock, prev, by, bx, my, mx)    LumBlock currentBlock;    MpegFrame *prev;    int by;    int bx;    int my;    int mx;{    int	bestDiff;    int CompareMode;    /* Junk needed to adapt for TUNEing */     CompareMode = SearchCompareMode;    SearchCompareMode = DEFAULT_SEARCH;    bestDiff = LumMotionError(currentBlock, prev, by, bx, my, mx, 0x7fffffff);    SearchCompareMode = CompareMode;    if ( zeroDiff < 256*3 ) {	if ( 2*bestDiff >= zeroDiff ) {	    return TRUE;	}    } else {	if ( 11*bestDiff >= 10*zeroDiff ) {	    return TRUE;	}    }    return FALSE;}/*===========================================================================* * *			      USER-MODIFIABLE * * DoIntraCode * *	decide if intra coding is necessary * * RETURNS:	TRUE if intra-block coding is better; FALSE if not * * SIDE EFFECTS:    none * * PRECONDITIONS:	The relevant block in 'current' is valid (it has not *			been dct'd). * * NOTES:	This procedure follows the algorithm described on *		page D-49 of the MPEG-1 specification * *===========================================================================*/static booleanDoIntraCode(currentBlock, prev, by, bx, motionY, motionX)    LumBlock currentBlock;    MpegFrame *prev;    int by;    int bx;    int motionY;    int motionX;{    int	    x, y;    int32 sum = 0, vard = 0, varc = 0, dif;    int32 currPixel, prevPixel;    LumBlock	motionBlock;    ComputeMotionLumBlock(prev, by, bx, motionY, motionX, motionBlock);    for ( y = 0; y < 16; y++ ) {	for ( x = 0; x < 16; x++ ) {	    currPixel = currentBlock[y][x];	    prevPixel = motionBlock[y][x];	    sum += currPixel;	    varc += currPixel*currPixel;	    dif = currPixel - prevPixel;	    vard += dif*dif;	}    }    vard >>= 8;		/* divide by 256; assumes mean is close to zero */    varc = (varc>>8) - (sum>>8)*(sum>>8);    if ( vard <= 64 ) {	return FALSE;    } else if ( vard < varc ) {	return FALSE;    } else {	return TRUE;    }}/*===========================================================================* * *			      USER-MODIFIABLE * * ZeroMotionSufficient * *	decide if zero motion is sufficient without DCT correction * * RETURNS:	TRUE no DCT required; FALSE otherwise * * SIDE EFFECTS:    none * * PRECONDITIONS:	The relevant block in 'current' is raw YCC data * *===========================================================================*/static booleanZeroMotionSufficient(currentBlock, prev, by, bx)    LumBlock currentBlock;    MpegFrame *prev;    int by;    int bx;{    LumBlock	motionBlock;    register int    fy, fx;    register int    x, y;    fy = by*DCTSIZE;    fx = bx*DCTSIZE;    for ( y = 0; y < 16; y++ ) {	for ( x = 0; x < 16; x++ ) {	    motionBlock[y][x] = prev->ref_y[fy+y][fx+x];	}    }    zeroDiff = LumBlockMAD(currentBlock, motionBlock, 0x7fffffff);    return (zeroDiff <= 256);}			     #ifdef UNUSED_PROCEDURESstatic voidComputeAndPrintPframeMAD(currentBlock, prev, by, bx, my, mbx, numBlock)    LumBlock currentBlock;    MpegFrame *prev;    int by;    int bx;    int my;    int mx;    int numBlock;{    LumBlock	lumMotionBlock;    int32   mad;    ComputeMotionLumBlock(prev, by, bx, my, mx, lumMotionBlock);    mad = LumBlockMAD(currentBlock, lumMotionBlock, 0x7fffffff);    if (! realQuiet) {	fprintf(stdout, "%d %d\n", numBlock, mad);    }}#endifstatic void computeCurrentBlock(MpegFrame * const current,                     int const y, int const x, LumBlock currentBlock) {    int fy, fx;    int iy;    BLOCK_TO_FRAME_COORD(y, x, fy, fx);    for ( iy = 0; iy < 16; iy++ ) {        int ix;        for ( ix = 0; ix < 16; ix++ ) {            currentBlock[iy][ix] =                 (int16)current->orig_y[fy+iy][fx+ix];        }    }}static voidcomputeMotionVectors(bool        const specificsOn,                      bool        const IntraPBAllowed,                     MpegFrame * const current,                      MpegFrame * const prev,                     int         const mbAddress,                     BlockMV **  const infoP,                     int         const QScale,                      LumBlock          currentBlock,                     int         const y,                      int         const x,                     bool *      const useMotionP,                      int *       const motionYP,                      int *       const motionXP) {    bool useCached;    BlockMV * info;    /* See if we have a cached answer */    if (specificsOn) {        SpecLookup(current->id, 2, mbAddress, &info, QScale);        if (info != (BlockMV*)NULL)             useCached = TRUE;        else            useCached = FALSE;    } else        useCached = FALSE;    if (useCached) {        if (info->typ == TYP_SKIP) {            *motionXP = *motionYP = 0;            *useMotionP = TRUE;        } else {		/* assume P, since we're a P frame.... */            *motionXP = info->fx;            *motionYP = info->fy;            *useMotionP = TRUE;        }    } else {        /* see if we should use motion vectors, and if so, what those         * vectors should be         */        if (ZeroMotionSufficient(currentBlock, prev, y, x)) {            *motionXP = 0;            *motionYP = 0;            *useMotionP = TRUE;        } else {            int motionY, motionX;            motionY = 0; motionX = 0;  /* initial values */            PMotionSearch(currentBlock, prev, y, x, &motionY, &motionX);            if (ZeroMotionBetter(currentBlock, prev, y, x,                                  motionY, motionX)) {                *motionYP = 0;                *motionXP = 0;            } else {                *motionYP = motionY;                *motionXP = motionX;            }            if (IntraPBAllowed)                 *useMotionP = (! DoIntraCode(currentBlock, prev, y, x,                                             motionY, motionX));            else                *useMotionP = TRUE;        }    }    *infoP = info;}static voidcalculateForwardDcts(MpegFrame * const current,                      int const y, int const x,                     Block ** const dct) {    /* calculate forward dct's */    if (collect_quant && (collect_quant_detailed & 1))         fprintf(collect_quant_fp, "l\n");    mp_fwd_dct_block2(current->y_blocks[y][x], dct[y][x]);    mp_fwd_dct_block2(current->y_blocks[y][x+1], dct[y][x+1]);    mp_fwd_dct_block2(current->y_blocks[y+1][x], dct[y+1][x]);    mp_fwd_dct_block2(current->y_blocks[y+1][x+1], dct[y+1][x+1]);    if (collect_quant && (collect_quant_detailed & 1))         fprintf(collect_quant_fp, "c\n");    mp_fwd_dct_block2(current->cb_blocks[y>>1][x>>1],                       dctb[y>>1][x>>1]);    mp_fwd_dct_block2(current->cr_blocks[y>>1][x>>1],                       dctr[y>>1][x>>1]);}static voidcomputeMotionAndDct(int const lastBlockY, int const lastBlockX,                    bool const specificsOn, bool const IntraPBAllowed,                    MpegFrame * const current, MpegFrame * const prev,                    BlockMV ** const infoP, int const QScale,                    int const searchRangeP, Block ** const dct,                    int * const numPBlocksP, int * const numIBlocksP,                    int ** const pmvHistogram) {/*----------------------------------------------------------------------------   Loop through the frame finding motion/not and DCTing-----------------------------------------------------------------------------*/    int mbAddress;    int y;    mbAddress = 0;                            for (y = 0; y < lastBlockY; y += 2) {        int x;        for (x = 0; x < lastBlockX; x += 2) {            LumBlock currentBlock;            int motionY, motionX;            bool useMotion;            computeCurrentBlock(current, y, x, currentBlock);            computeMotionVectors(specificsOn,  IntraPBAllowed,                                 current, prev, mbAddress, infoP,                                 QScale, currentBlock, y, x,                                 &useMotion, &motionY, &motionX);            dct_data[y][x].useMotion = useMotion;            if (useMotion) {                int pattern;                (*numPBlocksP)++;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -