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

📄 bframe.c

📁 linux下将各类格式图片转换工具
💻 C
📖 第 1 页 / 共 3 页
字号:
/*===========================================================================* * bframe.c * *	Procedures concerned with the B-frame encoding *===========================================================================*//* * Copyright (c) 1995 The Regents of the University of California. * All rights reserved. * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose, without fee, and without written agreement is * hereby granted, provided that the above copyright notice and the following * two paragraphs appear in all copies of this software. * * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. *//*==============* * HEADER FILES * *==============*/#include "all.h"#include <sys/param.h>#include <assert.h>#include "ppm.h"#include "mtypes.h"#include "bitio.h"#include "frames.h"#include "prototypes.h"#include "fsize.h"#include "param.h"#include "mheaders.h"#include "postdct.h"#include "rate.h"#include "opts.h"#include "specifics.h"/*==================* * STATIC VARIABLES * *==================*/static int numBIBlocks = 0;static int numBBBlocks = 0;static int numBSkipped = 0;static int numBIBits = 0;static int numBBBits = 0;static int numFrames = 0;static int numFrameBits = 0;static int32 totalTime = 0;static int qscaleB;static float    totalSNR = 0.0;static float	totalPSNR = 0.0;static int numBFOBlocks = 0;    /* forward only */static int numBBABlocks = 0;    /* backward only */static int numBINBlocks = 0;    /* interpolate */static int numBFOBits = 0;static int numBBABits = 0;static int numBINBits = 0;/*====================* * EXTERNAL VARIABLES * *====================*/extern Block **dct, **dctr, **dctb;extern dct_data_type **dct_data;#define NO_MOTION 0#define MOTION 1#define SKIP 2  /* used in useMotion in dct_data *//*===============================* * INTERNAL PROCEDURE prototypes * *===============================*/static boolean	MotionSufficient _ANSI_ARGS_((MpegFrame *curr, LumBlock currBlock, MpegFrame *prev, MpegFrame *next,			 int by, int bx, int mode, int fmy, int fmx,			 int bmy, int bmx));static void	ComputeBMotionBlock _ANSI_ARGS_((MpegFrame *prev, MpegFrame *next,			       int by, int bx, int mode, int fmy, int fmx,			       int bmy, int bmx, Block motionBlock, int type));static void	ComputeBDiffDCTs _ANSI_ARGS_((MpegFrame *current, MpegFrame *prev, MpegFrame *next,			 int by, int bx, int mode, int fmy, int fmx, 			 int bmy, int bmx, int *pattern));static boolean	DoBIntraCode _ANSI_ARGS_((MpegFrame *current, MpegFrame *prev, MpegFrame *next,		     int by, int bx, int mode, int fmy, int fmx, int bmy,		     int bmx));static int ComputeBlockColorDiff _ANSI_ARGS_((Block current, Block motionBlock));/*=====================* * EXPORTED PROCEDURES * *=====================*//*===========================================================================* * * GenBFrame * *	generate a B-frame from previous and next frames, adding the result *	to the given bit bucket * * RETURNS:	frame appended to bb * * SIDE EFFECTS:    none * *===========================================================================*/voidGenBFrame(BitBucket * const bb,           MpegFrame * const curr,           MpegFrame * const prev,           MpegFrame * const next) {    extern int **bfmvHistogram;    extern int **bbmvHistogram;    FlatBlock fba[6], fb[6];    Block     dec[6];    int32 y_dc_pred, cr_dc_pred, cb_dc_pred;    int x, y;    int	fMotionX = 0, fMotionY = 0;    int bMotionX = 0, bMotionY = 0;    int	oldFMotionX = 0, oldFMotionY = 0;    int oldBMotionX = 0, oldBMotionY = 0;    int	oldMode = MOTION_FORWARD;    int	mode = MOTION_FORWARD;    int	offsetX, offsetY;    int	tempX, tempY;    int	fMotionXrem = 0, fMotionXquot = 0;    int	fMotionYrem = 0, fMotionYquot = 0;    int	bMotionXrem = 0, bMotionXquot = 0;    int	bMotionYrem = 0, bMotionYquot = 0;    int	pattern;    int	numIBlocks = 0, numBBlocks = 0;    int numSkipped = 0, totalBits;    int	numIBits = 0,   numBBits = 0;    boolean	lastIntra = TRUE;    boolean    motionForward, motionBackward;    int	    totalFrameBits;    int32    startTime, endTime;    int lastX, lastY;    int lastBlockX, lastBlockY;    int ix, iy;    LumBlock currentBlock;    int         fy, fx;    boolean	make_skip_block;    int	mbAddrInc = 1;    int	mbAddress;    int	    slicePos;    float   snr[3], psnr[3];    int	    idx;    int     QScale;    BlockMV *info;    int     bitstreamMode, newQScale;    int     rc_blockStart=0;    boolean overflowChange=FALSE;    int overflowValue = 0;    assert(prev != NULL);    assert(next != NULL);    if (collect_quant) {fprintf(collect_quant_fp, "# B\n");}    if (dct == NULL) AllocDctBlocks();    numFrames++;    totalFrameBits = bb->cumulativeBits;    startTime = time_elapsed();    /*   Rate Control */    bitstreamMode = getRateMode();    if (bitstreamMode == FIXED_RATE) {        targetRateControl(curr);    }     QScale = GetBQScale();    Mhead_GenPictureHeader(bb, B_FRAME, curr->id, fCodeB);    /* Check for Qscale change */    if (specificsOn) {        newQScale = SpecLookup(curr->id, 0, 0 /* junk */, &info, QScale);        if (newQScale != -1) {            QScale = newQScale;        }        /* check for slice */        newQScale = SpecLookup(curr->id, 1, 1, &info, QScale);        if (newQScale != -1) {            QScale = newQScale;        }    }    Mhead_GenSliceHeader(bb, 1, QScale, NULL, 0);    Frame_AllocBlocks(curr);    BlockifyFrame(curr);    if ( printSNR ) {        Frame_AllocDecoded(curr, FALSE);    }    /* for I-blocks */    y_dc_pred = cr_dc_pred = cb_dc_pred = 128;    totalBits = bb->cumulativeBits;    if ( ! pixelFullSearch ) {        if ( ! prev->halfComputed ) {            ComputeHalfPixelData(prev);        }        if ( ! next->halfComputed ) {            ComputeHalfPixelData(next);        }    }    lastBlockX = Fsize_x>>3;    lastBlockY = Fsize_y>>3;    lastX = lastBlockX-2;    lastY = lastBlockY-2;    mbAddress = 0;    /* find motion vectors and do dcts */    /* In this first loop, all MVs are in half-pixel scope, (if FULL       is set then they will be multiples of 2).  This is not true in       the second loop.     */    for (y = 0;  y < lastBlockY;  y += 2) {        for (x = 0;  x < lastBlockX;  x += 2) {            slicePos = (mbAddress % blocksPerSlice);            /* compute currentBlock */            BLOCK_TO_FRAME_COORD(y, x, fy, fx);            for ( iy = 0; iy < 16; iy++ ) {                for ( ix = 0; ix < 16; ix++ ) {                    currentBlock[iy][ix] = (int16)curr->orig_y[fy+iy][fx+ix];                }            }	                if (slicePos == 0) {                oldFMotionX = 0;	oldFMotionY = 0;                oldBMotionX = 0;	oldBMotionY = 0;                oldMode = MOTION_FORWARD;                lastIntra = TRUE;            }            /* STEP 1:  Select Forward, Backward, or Interpolated motion                vectors */            /* see if old motion is good enough */            /* but force last block to be non-skipped */            /* can only skip if:             *     1)  not the last block in frame             *     2)  not the last block in slice             *     3)  not the first block in slice             *     4)  previous block was not intra-coded             */            if ( ((y < lastY) || (x < lastX)) &&                 (slicePos+1 != blocksPerSlice) &&                 (slicePos != 0) &&                 (! lastIntra) &&                 (BSkipBlocks) ) {                make_skip_block = MotionSufficient(curr, currentBlock,                                                    prev, next,                                                    y, x, oldMode,                                                   oldFMotionY, oldFMotionX,                                                   oldBMotionY, oldBMotionX);            } else {                make_skip_block = FALSE;            }            if ( make_skip_block ) {            skip_it:                /* skipped macro block */                dct_data[y][x].useMotion = SKIP;            } else {                if (specificsOn) {                    (void) SpecLookup(curr->id, 2, mbAddress, &info, QScale);                    if (info == (BlockMV*)NULL) goto gosearch;                    else {                        switch (info->typ) {                        case TYP_SKIP:                            goto skip_it;                        case TYP_FORW:                            fMotionX = info->fx;                            fMotionY = info->fy;                            mode = MOTION_FORWARD;                            break;                        case TYP_BACK:                            bMotionX = info->bx;                            bMotionY = info->by;                            mode = MOTION_BACKWARD;                            break;                        case TYP_BOTH:                            fMotionX = info->fx;                            fMotionY = info->fy;                            bMotionX = info->bx;                            bMotionY = info->by;                            mode = MOTION_INTERPOLATE;                            break;                        default:                            pm_error("Unreachable code in GenBFrame!");                            goto gosearch;                        }                        goto skipsearch;                    }}            gosearch:		/* do bsearch */                mode = BMotionSearch(currentBlock, prev, next, y, x, &fMotionY,                                     &fMotionX, &bMotionY, &bMotionX, mode);            skipsearch:	                                      /* STEP 2:  INTRA OR NON-INTRA CODING */                if ( IntraPBAllowed &&                      DoBIntraCode(curr, prev, next, y, x, mode,                                   fMotionY, fMotionX, bMotionY, bMotionX) ) {                    /* output I-block inside a B-frame */                    numIBlocks++;                    oldFMotionX = 0;	oldFMotionY = 0;                    oldBMotionX = 0;	oldBMotionY = 0;                    lastIntra = TRUE;                    dct_data[y][x].useMotion = NO_MOTION;                    oldMode = MOTION_FORWARD;                    /* calculate forward dct's */                    if (collect_quant && (collect_quant_detailed & 1))                         fprintf(collect_quant_fp, "l\n");                    mp_fwd_dct_block2(curr->y_blocks[y][x], dct[y][x]);                    mp_fwd_dct_block2(curr->y_blocks[y][x+1], dct[y][x+1]);                    mp_fwd_dct_block2(curr->y_blocks[y+1][x], dct[y+1][x]);                    mp_fwd_dct_block2(curr->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(curr->cb_blocks[y>>1][x>>1],                                       dctb[y>>1][x>>1]);                    mp_fwd_dct_block2(curr->cr_blocks[y>>1][x>>1],                                       dctr[y>>1][x>>1]);                } else { /* dct P/Bi/B block */                    pattern = 63;                    lastIntra = FALSE;                    numBBlocks++;                    dct_data[y][x].mode = mode;                    oldMode = mode;                    dct_data[y][x].fmotionX = fMotionX;                    dct_data[y][x].fmotionY = fMotionY;                    dct_data[y][x].bmotionX = bMotionX;                    dct_data[y][x].bmotionY = bMotionY;                    switch (mode) {                    case MOTION_FORWARD:                        numBFOBlocks++;                        oldFMotionX = fMotionX;		oldFMotionY = fMotionY;                        break;                    case MOTION_BACKWARD:                        numBBABlocks++;                        oldBMotionX = bMotionX;		oldBMotionY = bMotionY;                        break;                    case MOTION_INTERPOLATE:                        numBINBlocks++;                        oldFMotionX = fMotionX;		oldFMotionY = fMotionY;                        oldBMotionX = bMotionX;		oldBMotionY = bMotionY;                        break;                    default:                        pm_error("INTERNAL ERROR:  Illegal mode: %d", mode);                    }	                        ComputeBDiffDCTs(curr, prev, next, y, x, mode, fMotionY,                                     fMotionX, bMotionY, bMotionX, &pattern);	                        dct_data[y][x].pattern = pattern;                    dct_data[y][x].useMotion = MOTION;                    if ( computeMVHist ) {                        assert(fMotionX+searchRangeB+1 >= 0);                        assert(fMotionY+searchRangeB+1 >= 0);                        assert(fMotionX+searchRangeB+1 <= 2*searchRangeB+2);                        assert(fMotionY+searchRangeB+1 <= 2*searchRangeB+2);                        assert(bMotionX+searchRangeB+1 >= 0);                        assert(bMotionY+searchRangeB+1 >= 0);                        assert(bMotionX+searchRangeB+1 <= 2*searchRangeB+2);                        assert(bMotionY+searchRangeB+1 <= 2*searchRangeB+2);                        bfmvHistogram[fMotionX+searchRangeB+1][fMotionY+searchRangeB+1]++;                        bbmvHistogram[bMotionX+searchRangeB+1][bMotionY+searchRangeB+1]++;                    }                } /* motion-block */            } /* not skipped */            mbAddress++;        }    }    /* reset everything */    oldFMotionX = 0;	oldFMotionY = 0;    oldBMotionX = 0;	oldBMotionY = 0;    oldMode = MOTION_FORWARD;    lastIntra = TRUE;    y_dc_pred = cr_dc_pred = cb_dc_pred = 128;    mbAddress = 0;    /* Now generate the frame */    for (y = 0; y < lastBlockY; y += 2) {      for (x = 0; x < lastBlockX; x += 2) {	slicePos = (mbAddress % blocksPerSlice);	if ( (slicePos == 0) && (mbAddress != 0) ) {

⌨️ 快捷键说明

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