📄 block.c
字号:
/*===========================================================================* * block.c * * * * Block routines * * * * EXPORTED PROCEDURES: * * ComputeDiffDCTBlock * * ComputeDiffDCTs * * ComputeMotionBlock * * ComputeMotionLumBlock * * LumBlockMAD * * LumMotionError * * LumMotionErrorSubSampled * * LumAddMotionError * * AddMotionBlock * * BlockToData * * BlockifyFrame * * * * NOTES: MAD = Mean Absolute Difference * * * *===========================================================================*//* * 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: /n/picasso/project/mpeg/mpeg_dist/mpeg_encode/RCS/block.c,v 1.16 1995/08/07 21:43:29 smoot Exp $ * $Log: block.c,v $ * Revision 1.16 1995/08/07 21:43:29 smoot * restructured lumdiff so it read better and used a switch instead of ifs * * Revision 1.15 1995/06/21 22:21:16 smoot * added TUNEing options * * Revision 1.14 1995/05/08 22:47:45 smoot * typechecking better * * Revision 1.13 1995/05/08 22:44:14 smoot * added prototypes (postdct.h) * * Revision 1.12 1995/05/02 21:44:07 smoot * added tuneing parameters * * Revision 1.11 1995/03/31 23:50:45 smoot * removed block bound (moved to opts.c) * * Revision 1.10 1995/03/29 20:12:39 smoot * added block_bound for TUNEing * * Revision 1.9 1995/02/01 21:43:55 smoot * cleanup * * Revision 1.8 1995/01/19 23:52:43 smoot * Made computeDiffDCTs able to rule out changes to the pattern (diff too small) * * Revision 1.7 1995/01/19 23:07:17 eyhung * Changed copyrights * * Revision 1.6 1994/11/12 02:11:44 keving * nothing * * Revision 1.5 1993/12/22 19:19:01 keving * nothing * * Revision 1.5 1993/12/22 19:19:01 keving * nothing * * Revision 1.4 1993/07/22 22:23:43 keving * nothing * * Revision 1.3 1993/06/30 20:06:09 keving * nothing * * Revision 1.2 1993/06/03 21:08:08 keving * nothing * * Revision 1.1 1993/04/08 21:31:59 keving * nothing * *//*==============* * HEADER FILES * *==============*/#include "all.h"#include "mtypes.h"#include "frames.h"#include "bitio.h"#include "prototypes.h"#include "fsize.h"#include "opts.h"#include "postdct.h"#undef ABS#define ABS(x) ((x < 0) ? (-x) : x)#define TRUNCATE_UINT8(x) ((x < 0) ? 0 : ((x > 255) ? 255 : x))/*==================* * GLOBAL VARIABLES * *==================*/extern Block **dct, **dctb, **dctr;/*===========================* * COMPUTE DCT OF DIFFERENCE * *===========================*//*===========================================================================* * * ComputeDiffDCTBlock * * compute current-motionBlock, take the DCT, and put the difference * back into current * * RETURNS: current block modified * * SIDE EFFECTS: none * *===========================================================================*/booleanComputeDiffDCTBlock(current, dest, motionBlock) Block current, dest, motionBlock;{ register int x, y, diff = 0; for ( y = 0; y < 8; y++ ) { for ( x = 0; x < 8; x++ ) { current[y][x] -= motionBlock[y][x]; diff += ABS(current[y][x]); } } /* Kill the block if change is too small */ /* (block_bound defaults to 128, see opts.c) */ if (diff < block_bound) return FALSE; mp_fwd_dct_block2(current, dest); return TRUE;}/*===========================================================================* * * ComputeDiffDCTs * * appropriate (according to pattern, the coded block pattern) blocks * of 'current' are diff'ed and DCT'd. * * RETURNS: current blocks modified * * SIDE EFFECTS: Can remove too-small difference blocks from pattern * * PRECONDITIONS: appropriate blocks of 'current' have not yet been * modified * *===========================================================================*/voidComputeDiffDCTs(current, prev, by, bx, my, mx, pattern) MpegFrame *current; MpegFrame *prev; int by; int bx; int my; int mx; int *pattern;{ Block motionBlock; if (collect_quant && (collect_quant_detailed & 1)) fprintf(collect_quant_fp, "l\n"); if ( *pattern & 0x20 ) { ComputeMotionBlock(prev->ref_y, by, bx, my, mx, motionBlock); if (!ComputeDiffDCTBlock(current->y_blocks[by][bx], dct[by][bx], motionBlock)) *pattern^=0x20; } if ( *pattern & 0x10 ) { ComputeMotionBlock(prev->ref_y, by, bx+1, my, mx, motionBlock); if (!ComputeDiffDCTBlock(current->y_blocks[by][bx+1], dct[by][bx+1], motionBlock)) *pattern^=0x10; } if ( *pattern & 0x8 ) { ComputeMotionBlock(prev->ref_y, by+1, bx, my, mx, motionBlock); if (!ComputeDiffDCTBlock(current->y_blocks[by+1][bx], dct[by+1][bx], motionBlock)) *pattern^=0x8; } if ( *pattern & 0x4 ) { ComputeMotionBlock(prev->ref_y, by+1, bx+1, my, mx, motionBlock); if (!ComputeDiffDCTBlock(current->y_blocks[by+1][bx+1], dct[by+1][bx+1], motionBlock)) *pattern^=0x4; } if (collect_quant && (collect_quant_detailed & 1)) fprintf(collect_quant_fp, "c\n"); if ( *pattern & 0x2 ) { ComputeMotionBlock(prev->ref_cb, by >> 1, bx >> 1, my/2, mx/2, motionBlock); if (!ComputeDiffDCTBlock(current->cb_blocks[by >> 1][bx >> 1], dctb[by >> 1][bx >> 1], motionBlock)) *pattern^=0x2; } if ( *pattern & 0x1 ) { ComputeMotionBlock(prev->ref_cr, by >> 1, bx >> 1, my/2, mx/2, motionBlock); if (!ComputeDiffDCTBlock(current->cr_blocks[by >> 1][bx >> 1], dctr[by >> 1][bx >> 1], motionBlock)) *pattern^=0x1; }} /*======================* * COMPUTE MOTION BLOCK * *======================*//*===========================================================================* * * ComputeMotionBlock * * compute the motion-compensated block * * RETURNS: motionBlock * * SIDE EFFECTS: none * * PRECONDITIONS: motion vector MUST be valid * * NOTE: could try to speed this up using halfX, halfY, halfBoth, * but then would have to compute for chrominance, and it's just * not worth the trouble (this procedure is not called relatively * often -- a constant number of times per macroblock) * *===========================================================================*/voidComputeMotionBlock(prev, by, bx, my, mx, motionBlock) uint8 **prev; int by; int bx; int my; int mx; Block motionBlock;{ register int fy, fx; register int y; register int16 *destPtr; register uint8 *srcPtr; register uint8 *srcPtr2; boolean xHalf, yHalf; xHalf = (ABS(mx) % 2 == 1); yHalf = (ABS(my) % 2 == 1); MOTION_TO_FRAME_COORD(by, bx, (my/2), (mx/2), fy, fx); if ( xHalf && yHalf ) { /* really should be fy+y-1 and fy+y so do (fy-1)+y = fy+y-1 and (fy-1)+y+1 = fy+y */ if ( my < 0 ) { fy--; } if ( mx < 0 ) { fx--; } for ( y = 0; y < 8; y++ ) { destPtr = motionBlock[y]; srcPtr = &(prev[fy+y][fx]); srcPtr2 = &(prev[fy+y+1][fx]); destPtr[0] = (srcPtr[0]+srcPtr[1]+srcPtr2[0]+srcPtr2[1]+2)>>2; destPtr[1] = (srcPtr[1]+srcPtr[2]+srcPtr2[1]+srcPtr2[2]+2)>>2; destPtr[2] = (srcPtr[2]+srcPtr[3]+srcPtr2[2]+srcPtr2[3]+2)>>2; destPtr[3] = (srcPtr[3]+srcPtr[4]+srcPtr2[3]+srcPtr2[4]+2)>>2; destPtr[4] = (srcPtr[4]+srcPtr[5]+srcPtr2[4]+srcPtr2[5]+2)>>2; destPtr[5] = (srcPtr[5]+srcPtr[6]+srcPtr2[5]+srcPtr2[6]+2)>>2; destPtr[6] = (srcPtr[6]+srcPtr[7]+srcPtr2[6]+srcPtr2[7]+2)>>2; destPtr[7] = (srcPtr[7]+srcPtr[8]+srcPtr2[7]+srcPtr2[8]+2)>>2; } } else if ( xHalf ) { if ( mx < 0 ) { fx--; } for ( y = 0; y < 8; y++ ) { destPtr = motionBlock[y]; srcPtr = &(prev[fy+y][fx]); destPtr[0] = (srcPtr[0]+srcPtr[1]+1)>>1; destPtr[1] = (srcPtr[1]+srcPtr[2]+1)>>1; destPtr[2] = (srcPtr[2]+srcPtr[3]+1)>>1; destPtr[3] = (srcPtr[3]+srcPtr[4]+1)>>1; destPtr[4] = (srcPtr[4]+srcPtr[5]+1)>>1; destPtr[5] = (srcPtr[5]+srcPtr[6]+1)>>1; destPtr[6] = (srcPtr[6]+srcPtr[7]+1)>>1; destPtr[7] = (srcPtr[7]+srcPtr[8]+1)>>1; } } else if ( yHalf ) { if ( my < 0 ) { fy--; } for ( y = 0; y < 8; y++ ) { destPtr = motionBlock[y]; srcPtr = &(prev[fy+y][fx]); srcPtr2 = &(prev[fy+y+1][fx]); destPtr[0] = (srcPtr[0]+srcPtr2[0]+1)>>1; destPtr[1] = (srcPtr[1]+srcPtr2[1]+1)>>1; destPtr[2] = (srcPtr[2]+srcPtr2[2]+1)>>1; destPtr[3] = (srcPtr[3]+srcPtr2[3]+1)>>1; destPtr[4] = (srcPtr[4]+srcPtr2[4]+1)>>1; destPtr[5] = (srcPtr[5]+srcPtr2[5]+1)>>1; destPtr[6] = (srcPtr[6]+srcPtr2[6]+1)>>1; destPtr[7] = (srcPtr[7]+srcPtr2[7]+1)>>1; } } else { for ( y = 0; y < 8; y++ ) { destPtr = motionBlock[y]; srcPtr = &(prev[fy+y][fx]); destPtr[0] = (uint8) srcPtr[0]; destPtr[1] = (uint8) srcPtr[1]; destPtr[2] = (uint8) srcPtr[2]; destPtr[3] = (uint8) srcPtr[3]; destPtr[4] = (uint8) srcPtr[4]; destPtr[5] = (uint8) srcPtr[5]; destPtr[6] = (uint8) srcPtr[6]; destPtr[7] = (uint8) srcPtr[7]; } }}/*===========================================================================* * * ComputeMotionLumBlock * * compute the motion-compensated luminance block * * RETURNS: motionBlock * * SIDE EFFECTS: none * * PRECONDITIONS: motion vector MUST be valid * * NOTE: see ComputeMotionBlock * *===========================================================================*/voidComputeMotionLumBlock(prevFrame, by, bx, my, mx, motionBlock) MpegFrame *prevFrame; int by; int bx; int my; int mx; LumBlock motionBlock;{ register uint8 *across; register int32 *macross; register int y; uint8 **prev; int fy, fx; boolean xHalf, yHalf; xHalf = (ABS(mx) % 2 == 1); yHalf = (ABS(my) % 2 == 1); MOTION_TO_FRAME_COORD(by, bx, my/2, mx/2, fy, fx); if ( xHalf ) { if ( mx < 0 ) { fx--; } if ( yHalf ) { if ( my < 0 ) { fy--; } prev = prevFrame->halfBoth; } else { prev = prevFrame->halfX; } } else if ( yHalf ) { if ( my < 0 ) { fy--; } prev = prevFrame->halfY; } else { prev = prevFrame->ref_y; } for ( y = 0; y < 16; y++ ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -