📄 fame_motion_none.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_motion.h"#include "fame_motion_none.h"#include "mad_int.h" static fame_motion_coding_t none_estimation(fame_motion_t *motion, int mb_x, int mb_y, fame_motion_vector_t *vectors, unsigned char quant);static void find_vector(fame_yuv_t **ref, unsigned char *current, unsigned char *shape, int offset[4], int x, int y, int width, int height, int pitch, int search_range, int step_count, compute_error_t eval_error, fame_motion_vector_t *mv);static void find_subvector(fame_yuv_t **ref, unsigned char *current, unsigned char *shape, int offset, int x, int y, int width, int height, int pitch, int search_range, int step_count, compute_error_t eval_error, fame_motion_vector_t *mv);static void find_half_vector(fame_yuv_t **ref, unsigned char *current, unsigned char *shape, int offset[4], int x, int y, int width, int height, int pitch, compute_error_t eval_error, fame_motion_vector_t *mv);static void find_half_subvector(fame_yuv_t **ref, unsigned char *current, unsigned char *shape, int offset, int x, int y, int width, int height, int pitch, compute_error_t eval_error, fame_motion_vector_t *mv);FAME_CONSTRUCTOR(fame_motion_none_t){ fame_motion_t_constructor(FAME_MOTION(this)); FAME_OBJECT(this)->name = "no motion estimation"; FAME_MOTION(this)->estimation = none_estimation; FAME_MOTION(this)->flags &= ~(FAME_MOTION_BLOCK_SEARCH | FAME_MOTION_SUBPEL_SEARCH); return(this);}/* none_estimation *//* *//* Description: *//* Estimation motion for a macroblock. *//* *//* Arguments: *//* fame_motion_t *motion: the motion estimation *//* int mb_x: x coordinate of the macroblock in macroblock unit *//* int mb_y: y coordinate of the macroblock in macroblock unit *//* fame_motion_vector_t *vectors: predicted vectors for this macroblock *//* *//* Return value: *//* fame_motion_coding_t: intra or inter coded. */static fame_motion_coding_t none_estimation(fame_motion_t *motion, int mb_x, int mb_y, fame_motion_vector_t *vectors, unsigned char quant){ int pitch; unsigned char *current; unsigned char *shape; int x, y, width, height; int offset[4]; int count; int sad_inter, sad_inter4v, mad_inter; fame_motion_vector_t subvectors[4]; int k; x = mb_x << 4; y = mb_y << 4; width = motion->mb_width << 4; height = motion->mb_height << 4; current = motion->current->y; pitch = motion->current->p; shape = motion->shape; /* saturate prediction to borders */ if((x<<1)+vectors[0].dx<0) vectors[0].dx = (-x)<<1; if((y<<1)+vectors[0].dy<0) vectors[0].dy = (-y)<<1; if((x<<1)+vectors[0].dx>((width-16)<<1)) vectors[0].dx = (width-16-x)<<1; if((y<<1)+vectors[0].dy>((height-16)<<1)) vectors[0].dy = (height-16-y)<<1; /* compute zero motion MAD and number of pixels in shape */ offset[0] = y * pitch + x; offset[1] = y * pitch + x+8; offset[2] = (y+8) * pitch + x; offset[3] = (y+8) * pitch + x+8; if(motion->shape) { vectors[0].count = mad_withmask(current+offset[0], shape+offset[0], pitch, &vectors[0].deviation); vectors[1].count = mad_withmask(current+offset[1], shape+offset[1], pitch, &vectors[1].deviation); vectors[2].count = mad_withmask(current+offset[2], shape+offset[2], pitch, &vectors[2].deviation); vectors[3].count = mad_withmask(current+offset[3], shape+offset[3], pitch, &vectors[3].deviation); } else { vectors[0].count = mad_withoutmask(current+offset[0], pitch, &vectors[0].deviation); vectors[1].count = mad_withoutmask(current+offset[1], pitch, &vectors[1].deviation); vectors[2].count = mad_withoutmask(current+offset[2], pitch, &vectors[2].deviation); vectors[3].count = mad_withoutmask(current+offset[3], pitch, &vectors[3].deviation); } /* integer sample 4-step search */ find_vector(motion->ref, current, shape, offset, x, y, width, height, pitch, motion->search_range, 4, motion->MAE8x8, vectors); if(motion->flags & FAME_MOTION_BLOCK_SEARCH) { /* subvector search */ for(k = 0; k < 4; k++) { /* TODO: k depends on shape */ subvectors[k].dx = vectors[k].dx; subvectors[k].dy = vectors[k].dy; subvectors[k].error = vectors[k].error; /* integer sample 2-step search */ find_subvector(motion->ref, current, shape, offset[k], x, y, width, height, pitch, motion->search_range / 4, 2, motion->MAE8x8, &subvectors[k]); /* half sample search */ find_half_subvector(motion->ref, current, shape, offset[k], x, y, width, height, pitch, motion->MAE8x8, &subvectors[k]); } } /* half sample search */ find_half_vector(motion->ref, current, shape, offset, x, y, width, height, pitch, motion->MAE8x8, vectors); sad_inter = vectors[0].error + vectors[1].error + vectors[2].error + vectors[3].error; sad_inter4v = subvectors[0].error + subvectors[1].error + subvectors[2].error + subvectors[3].error; /* TODO: depends on shape */ mad_inter = vectors[0].deviation + vectors[1].deviation + vectors[2].deviation + vectors[3].deviation; count = vectors[0].count + vectors[1].count + vectors[2].count + vectors[3].count; /* inter4v/inter mode decision */ if((motion->flags & FAME_MOTION_BLOCK_SEARCH) && sad_inter4v + ((count>>1)+1) < sad_inter) { /* inter4v prediction */ sad_inter = sad_inter4v; for(k = 0; k < 4; k++) { vectors[k].dx = subvectors[k].dx; vectors[k].dy = subvectors[k].dy; vectors[k].error = subvectors[k].error; } } /* intra/inter mode decision */ if(mad_inter + count + count < sad_inter) return(motion_intra); else return(motion_inter);}/* find_vector *//* *//* Description: *//* Integer sample four-step search. *//* *//* Arguments: *//* fame_yuv_t **ref: reference frames (half-pel) *//* unsigned char *current: current frame *//* unsigned char *shape: current shape *//* int offset[4]: offsets to the blocks *//* int x: x coordinate of the block in pixel unit *//* int y: y coordinate of the block in pixel unit *//* int width: width of the block in pixels *//* int height: height of the block in pixels *//* int pitch: number of pixels to the next line *//* int count: number of pixels in macroblock *//* int search_range: maximum motion range in pixels *//* int search_4v: allow 4 different vectors *//* compute_error_t eval_error: error evaluation function *//* fame_motion_vector_t *mv: motion vectors *//* *//* Notes: *//* The search is centered on the predicted vector(s). *//* The search is made on the Y blocks only. *//* When allowing 4 vectors, the search is performed separetely for each. *//* *//* Return value: *//* None. */static void find_vector(fame_yuv_t **ref, unsigned char *current, unsigned char *shape, int offset[4], int x, int y, int width, int height, int pitch, int search_range, int step_count, compute_error_t eval_error, fame_motion_vector_t *mv){ int motion0, motion1, motion2, motion3; int residual; mv[3].dx = mv[2].dx = mv[1].dx = mv[0].dx; mv[3].dy = mv[2].dy = mv[1].dy = mv[0].dy; residual = (mv[0].dx & 1) + ((mv[0].dy & 1) << 1); motion0 = ((mv[0].dy >> 1) + y) * (pitch + 32) + (mv[0].dx >> 1) + x; motion1 = ((mv[0].dy >> 1) + y) * (pitch + 32) + (mv[0].dx >> 1) + x + 8; motion2 = ((mv[0].dy >> 1) + y + 8) * (pitch + 32) + (mv[0].dx >> 1) + x; motion3 = ((mv[0].dy >> 1) + y + 8) * (pitch + 32) + (mv[0].dx >> 1) + x + 8; /* initial step */ mv[0].error = eval_error(ref[residual]->y+motion0, current+offset[0], shape+offset[0], pitch) - (mv[0].count >> 1); mv[1].error = eval_error(ref[residual]->y+motion1, current+offset[1], shape+offset[1], pitch) - (mv[1].count >> 1); mv[2].error = eval_error(ref[residual]->y+motion2, current+offset[2], shape+offset[2], pitch) - (mv[2].count >> 1); mv[3].error = eval_error(ref[residual]->y+motion3, current+offset[3], shape+offset[3], pitch) - (mv[3].count >> 1);}static void find_subvector(fame_yuv_t **ref, unsigned char *current, unsigned char *shape, int offset, int x, int y, int width, int height, int pitch, int search_range, int step_count, compute_error_t eval_error, fame_motion_vector_t *mv){}/* find_half_vector *//* *//* Description: *//* Refine integer vector(s) to half-pel vector(s). *//* *//* Arguments: *//* fame_yuv_t **ref: reference frames (half-pel) *//* unsigned char *current: current frame *//* unsigned char *shape: current shape *//* int offset[4]: offsets to the blocks *//* int x: x coordinate of the block in pixel unit *//* int y: y coordinate of the block in pixel unit *//* int width: width of the block in pixels *//* int height: height of the block in pixels *//* int pitch: number of pixels to the next line *//* int search_4v: allow 4 different vectors *//* compute_error_t eval_error: error evaluation function *//* fame_motion_vector_t *mv: motion vectors *//* *//* Notes: *//* The search is centered on the integer vector(s). *//* The search is made on the Y blocks only. *//* When allowing 4 vectors, the search is performed separetely for each. *//* *//* Return value: *//* None. */static void find_half_vector(fame_yuv_t **ref, unsigned char *current, unsigned char *shape, int offset[4], int x, int y, int width, int height, int pitch, compute_error_t eval, fame_motion_vector_t *mv){}static void find_half_subvector(fame_yuv_t **ref, unsigned char *current, unsigned char *shape, int offset, int x, int y, int width, int height, int pitch, compute_error_t eval, fame_motion_vector_t *mv){}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -