📄 fame_motion_pmvfast.c
字号:
/* libfame - Fast Assembly MPEG Encoder Library Copyright (C) 2000-2001 Damien Vincent This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/#include <stdio.h>#include <stdlib.h>#include "fame.h"#include "fame_malloc.h"#include "fame_motion.h"#include "fame_motion_pmvfast.h"#ifdef HAS_MMX#include "mad_mmx.h"#else#include "mad_int.h"#endif#undef DEBUG#undef STAT#define COMPENSATE_MV_OVERHEAD#ifdef COMPENSATE_MV_OVERHEADstatic const int mv_length[] = { 0, 2, 3, 4, 6, 7, 7, 7, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 12, 12};#define COMPENSATE_LAMBA 1/* TODO: lookup table */static inline int mv_overhead(fame_motion_vector_t *pmv, int dx, int dy, const int fcode, const int quant){ int size = 0; int pdx, pdy; pdx = dx - pmv->dx; pdy = dy - pmv->dy; if(pdx != 0) { if (pdx < 0) pdx = -pdx; pdx += (1 << (fcode - 1)) - 1; pdx >>= (fcode - 1); if (pdx > 32) pdx = 32; size += mv_length[pdx] + 1 + fcode - 1; } else size ++; if(pdy != 0) { if (pdy < 0) pdy = -pdy; pdy += (1 << (fcode - 1)) - 1; pdy >>= (fcode - 1); if (pdy > 32) pdy = 32; size += mv_length[pdy] + 1 + fcode - 1; } else size ++; return(COMPENSATE_LAMBA*size*quant); }#else#define mv_overhead(pmv, dx, dy, fcode, quant) 0#endif#ifdef DEBUGstatic FILE *debug_log;#endif#ifdef STATstatic FILE *stat_log;#endiftypedef struct{ int num_picture; int num_intra; int num_median; int num_early; int num_16x16; int num_8x8; int num_largediamond; int num_smalldiamond; int num_eval;} stat_motion_pmvfast;stat_motion_pmvfast motionstat;/******************** PUBLIC DEFINITIONS ********************/static void pmvfast_init(fame_motion_t *motion, int mb_width, int mb_height, unsigned int flags);static void pmvfast_close(fame_motion_t *motion);static void pmvfast_enter(fame_motion_t *motion, fame_yuv_t **ref, fame_yuv_t *current, unsigned char *shape, int search_range);static fame_motion_coding_t pmvfast_estimation(fame_motion_t *motion, int mb_x, int mb_y, fame_motion_vector_t *vectors, unsigned char quant);static void pmvfast_leave(fame_motion_t *motion);FAME_CONSTRUCTOR(fame_motion_pmvfast_t){ fame_motion_t_constructor(FAME_MOTION(this)); FAME_OBJECT(this)->name = "predictive motion estimation"; this->FAME_OVERLOADED(init) = FAME_MOTION(this)->init; FAME_MOTION(this)->init = pmvfast_init; this->FAME_OVERLOADED(close) = FAME_MOTION(this)->close; FAME_MOTION(this)->close = pmvfast_close; this->FAME_OVERLOADED(enter) = FAME_MOTION(this)->enter; FAME_MOTION(this)->enter = pmvfast_enter; this->FAME_OVERLOADED(leave) = FAME_MOTION(this)->leave; FAME_MOTION(this)->leave = pmvfast_leave; FAME_MOTION(this)->estimation = pmvfast_estimation; return(this);}/******************** PRIVATE DEFINITIONS ********************/#define MEDIAN(a,b,c) ((b)<(a))?(((c)>(a))?(a):(((c)<(b))?(b):(c))):(((c)<(a))?(a):(((c)>(b))?(b):(c)))typedef struct{ int dx; int dy; int index_direction; /* the index of the direction : index = index(dx,dy) */} direction_t;typedef struct{ int nbre; direction_t *directions;} tab_direction_t;#define NULL_MOTION 1#define INFINITE_ERROR 0xFFFFU#define MOTION_INTRA 0x0001#define MOTION_INTER 0x0002#define SIZE_MB 16#define SIZE_SB 8#define THRESHOLD0 256#define LOWER_LIMIT_THRESHOLD1 512#define UPPER_LIMIT_THRESHOLD1 1024#define UPPER_LIMIT_THRESHOLD2 1792#define THRESHOLD_SMALLDIAMOND 1536#define THRESHOLD8x8 256static inline void get_error(fame_yuv_t **ref, unsigned char *current, unsigned char *shape, fame_motion_vector_t *vectors, int offset[4], int edged_offset[4], int pitch, compute_error_t eval_error, int number);static inline int check_vector(fame_yuv_t **ref, unsigned char *current, unsigned char *shape, int x, int y, int width, int height, fame_motion_vector_t *pvector, fame_motion_vector_t *vectors, int offset[4], int edged_offset[4], int pitch, compute_error_t eval_error, fame_motion_vector_t *pmv, int fcode, int quant, int unrestricted);static inline int check_zero_vector(fame_yuv_t **ref, unsigned char *current, unsigned char *shape, int x, int y, int width, int height, fame_motion_vector_t *vectors, int offset[4], int edged_offset[4], int pitch, compute_error_t eval_error, fame_motion_vector_t *pmv, int fcode, int quant);static void find_macroblockvector(fame_yuv_t **ref, unsigned char *current, unsigned char *shape, int offset[4], int edged_offset[4], int x, int y, int width, int height, int pitch, tab_direction_t *table, int search_range, int step, int count, compute_error_t eval_error, fame_motion_vector_t *mv, fame_motion_vector_t *pmv, int fcode, int quant, int unrestricted);static void find_blockvector(fame_yuv_t **ref, unsigned char *current, unsigned char *shape, int offset, int edged_offset, int x, int y, int width, int height, int pitch, tab_direction_t *table, int search_range, int step, int count, compute_error_t eval_error, fame_motion_vector_t *mv, fame_motion_vector_t *pmv, int fcode, int quant, int unrestricted);/* motion tables *//* large diamond: * 4 * 5 3 * 6 1 2 * 7 9 * 8 */static direction_t td_block_largediamond0[9] ={ { 0, 0, 1}, { 2, 0, 2}, { 1, 1, 3}, { 0, 2, 4}, {-1, 1, 5}, {-2, 0, 6}, {-1,-1, 7}, { 0,-2, 8}, { 1,-1, 9}};static direction_t td_block_largediamond1[8] ={ { 2, 0, 2}, { 1, 1, 3}, { 0, 2, 4}, {-1, 1, 5}, {-2, 0, 6}, {-1,-1, 7}, { 0,-2, 8}, { 1,-1, 9}};static direction_t td_block_largediamond2[5] ={ { 2, 0, 2}, { 1, 1, 3}, { 0, 2, 4}, { 0,-2, 8}, { 1,-1, 9}};static direction_t td_block_largediamond3[3] ={ { 2, 0, 2}, { 1, 1, 3}, { 0, 2, 4}};static direction_t td_block_largediamond4[5] ={ { 2, 0, 2}, { 1, 1, 3}, { 0, 2, 4}, {-1, 1, 5}, {-2, 0, 6}};static direction_t td_block_largediamond5[3] ={ {-1, 1, 5}, {-2, 0, 6}, { 0, 2, 4}};static direction_t td_block_largediamond6[5] ={ { 0, 2, 4}, {-1, 1, 5}, {-2, 0, 6}, {-1,-1, 7}, { 0,-2, 8}};static direction_t td_block_largediamond7[3] ={ {-2, 0, 6}, {-1,-1, 7}, { 0,-2, 8}};static direction_t td_block_largediamond8[5] ={ { 2, 0, 2}, {-2, 0, 6}, {-1,-1, 7}, { 0,-2, 8}, { 1,-1, 9}};static direction_t td_block_largediamond9[3] ={ { 2, 0, 2}, { 0,-2, 8}, { 1,-1, 9}};static tab_direction_t td_block_largediamond[10] ={ {9,td_block_largediamond0}, {8,td_block_largediamond1}, {5,td_block_largediamond2}, {3,td_block_largediamond3}, {5,td_block_largediamond4}, {3,td_block_largediamond5}, {5,td_block_largediamond6}, {3,td_block_largediamond7}, {5,td_block_largediamond8}, {3,td_block_largediamond9}};/* small diamond: * 3 * 4 1 2 * 5 */static direction_t td_block_smalldiamond0[5] ={ { 0, 0, 1}, { 1, 0, 2}, { 0, 1, 3}, {-1, 0, 4}, { 0,-1, 5}};static direction_t td_block_smalldiamond1[4] ={ { 1, 0, 2}, { 0, 1, 3}, {-1, 0, 4}, { 0,-1, 5} };static direction_t td_block_smalldiamond2[3] ={ { 1, 0, 2}, { 0, 1, 3}, { 0,-1, 5} };static direction_t td_block_smalldiamond3[3] ={ { 1, 0, 2}, { 0, 1, 3}, {-1, 0, 4}};static direction_t td_block_smalldiamond4[3] ={ { 0, 1, 3}, {-1, 0, 4}, { 0,-1, 5} };static direction_t td_block_smalldiamond5[3] ={ { 1, 0, 2}, {-1, 0, 4}, { 0,-1, 5} };static tab_direction_t td_block_smalldiamond[6] ={ {5,td_block_smalldiamond0}, {4,td_block_smalldiamond1}, {3,td_block_smalldiamond2}, {3,td_block_smalldiamond3}, {3,td_block_smalldiamond4}, {3,td_block_smalldiamond5}};/* gradient descent: * 5 4 3 * 6 1 2 * 7 8 9 */static direction_t td_block_bbgds0[9] ={ { 0, 0, 1}, { 1, 0, 2}, { 1, 1, 3}, { 0, 1, 4}, {-1, 1, 5}, {-1, 0, 6}, {-1,-1, 7}, { 0,-1, 8}, { 1,-1, 9}};static direction_t td_block_bbgds1[8] ={ { 1, 0, 2}, { 1, 1, 3}, { 0, 1, 4}, {-1, 1, 5}, {-1, 0, 6}, {-1,-1, 7}, { 0,-1, 8}, { 1,-1, 9}};static direction_t td_block_bbgds2[3] ={ { 1, 0, 2}, { 1, 1, 3}, { 1,-1, 9}};static direction_t td_block_bbgds3[5] ={ { 1, 0, 2}, { 1, 1, 3}, { 0, 1, 4}, {-1, 1, 5}, { 1,-1, 9}};static direction_t td_block_bbgds4[3] ={ { 1, 1, 3}, { 0, 1, 4}, {-1, 1, 5}};static direction_t td_block_bbgds5[5] ={ { 1, 1, 3}, { 0, 1, 4}, {-1, 1, 5}, {-1, 0, 6}, {-1,-1, 7}};static direction_t td_block_bbgds6[3] ={ {-1, 1, 5}, {-1, 0, 6}, {-1,-1, 7}};static direction_t td_block_bbgds7[5] ={ {-1, 1, 5}, {-1, 0, 6}, {-1,-1, 7}, { 0,-1, 8}, { 1,-1, 9}};static direction_t td_block_bbgds8[3] ={ {-1,-1, 7}, { 0,-1, 8}, { 1,-1, 9}};static direction_t td_block_bbgds9[5] ={ { 1, 0, 2}, { 1, 1, 3}, {-1,-1, 7}, { 0,-1, 8}, { 1,-1, 9}};static tab_direction_t td_block_bbgds[10] ={ {9,td_block_bbgds0}, {8,td_block_bbgds1}, {3,td_block_bbgds2}, {5,td_block_bbgds3}, {3,td_block_bbgds4}, {5,td_block_bbgds5}, {3,td_block_bbgds6}, {5,td_block_bbgds7}, {3,td_block_bbgds8}, {5,td_block_bbgds9}};/******************** PUBLIC FUNCTIONS ********************/static void pmvfast_init(fame_motion_t *motion, int mb_width,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -