📄 vdec_motion.c
字号:
/***************************************************************************** * vdec_motion.c : motion compensation routines ***************************************************************************** * Copyright (C) 1999, 2000 VideoLAN * * Authors: * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. *****************************************************************************//***************************************************************************** * Preamble *****************************************************************************/#include "defs.h"#include <sys/types.h> /* on BSD, uio.h needs types.h */#include <sys/uio.h> /* for input.h */#include "config.h"#include "common.h"#include "threads.h"#include "mtime.h"#include "plugins.h"#include "intf_msg.h"#include "input.h"#include "decoder_fifo.h"#include "video.h"#include "video_output.h"#include "vdec_idct.h"#include "video_decoder.h"#include "vdec_motion.h"#include "vpar_blocks.h"#include "vpar_headers.h"#include "vpar_synchro.h"#include "video_parser.h"#include "video_fifo.h"#define __MotionComponents(width,height) \void MotionComponent_x_y_copy_##width##_##height (); \void MotionComponent_X_y_copy_##width##_##height (); \void MotionComponent_x_Y_copy_##width##_##height (); \void MotionComponent_X_Y_copy_##width##_##height (); \void MotionComponent_x_y_avg_##width##_##height (); \void MotionComponent_X_y_avg_##width##_##height (); \void MotionComponent_x_Y_avg_##width##_##height (); \void MotionComponent_X_Y_avg_##width##_##height ();__MotionComponents (16,16) /* 444, 422, 420 */__MotionComponents (16,8) /* 444, 422, 420 */__MotionComponents (8,8) /* 422, 420 */__MotionComponents (8,4) /* 420 */#if 0__MotionComponents (8,16) /* 422 */#endif#define ___callTheRightOne(width,height) \ if ((i_width == width) && (i_height == height)) \ { \ if (!b_average) \ { \ switch (i_select) \ { \ case 0: \ MotionComponent_x_y_copy_##width##_##height (p_src, p_dest, \ i_stride); \ break; \ case 1: \ MotionComponent_X_y_copy_##width##_##height (p_src, p_dest, \ i_stride); \ break; \ case 2: \ MotionComponent_x_Y_copy_##width##_##height (p_src, p_dest, \ i_stride, \ i_step); \ break; \ case 3: \ MotionComponent_X_Y_copy_##width##_##height (p_src, p_dest, \ i_stride, \ i_step); \ break; \ } \ } \ else \ { \ switch (i_select) \ { \ case 0: \ MotionComponent_x_y_avg_##width##_##height (p_src, p_dest, \ i_stride); \ break; \ case 1: \ MotionComponent_X_y_avg_##width##_##height (p_src, p_dest, \ i_stride); \ break; \ case 2: \ MotionComponent_x_Y_avg_##width##_##height (p_src, p_dest, \ i_stride, \ i_step); \ break; \ case 3: \ MotionComponent_X_Y_avg_##width##_##height (p_src, p_dest, \ i_stride, \ i_step); \ break; \ } \ } \ }/***************************************************************************** * vdec_MotionComponent : last stage of motion compensation *****************************************************************************/static __inline__ void MotionComponent( yuv_data_t * p_src, /* source block */ yuv_data_t * p_dest, /* dest block */ int i_width, /* (explicit) width of block */ int i_height, /* (explicit) height of block */ int i_stride, /* number of coeffs to jump * between each predicted line */ int i_step, /* number of coeffs to jump to * go to the next line of the * field */ int i_select, /* half-pel vectors */ boolean_t b_average /* (explicit) averaging of several * predictions */ ){___callTheRightOne (16,16)___callTheRightOne (16,8)___callTheRightOne (8,8)___callTheRightOne (8,4)#if 0___callTheRightOne (8,16)#endif}/***************************************************************************** * Motion420 : motion compensation for a 4:2:0 macroblock *****************************************************************************/static __inline__ void Motion420( macroblock_t * p_mb, /* destination macroblock */ picture_t * p_source, /* source picture */ boolean_t b_source_field, /* source field */ boolean_t b_dest_field, /* destination field */ int i_mv_x, int i_mv_y, /* motion vector coordinates, * in half pels */ int i_l_stride, /* number of coeffs to jump to * go to the next predicted * line */ int i_c_stride, int i_height, /* height of the block to * predict, in luminance * (explicit) */ int i_offset, /* position of the first * predicted line (explicit) */ boolean_t b_average /* (explicit) averaging of * several predictions */ ){ /* Temporary variables to avoid recalculating things twice */ int i_source_offset, i_dest_offset, i_c_height, i_c_select; i_source_offset = (p_mb->i_l_x + (i_mv_x >> 1)) + (p_mb->i_motion_l_y + i_offset + (i_mv_y >> 1) + b_source_field) * p_mb->p_picture->i_width; if( i_source_offset >= p_source->i_width * p_source->i_height ) { intf_ErrMsg( "vdec error: bad motion vector\n" ); return; } /* Luminance */ MotionComponent( /* source */ p_source->p_y + i_source_offset, /* destination */ p_mb->p_picture->p_y + (p_mb->i_l_x) + (p_mb->i_motion_l_y + b_dest_field) * p_mb->p_picture->i_width, /* prediction width and height */ 16, i_height, /* stride */ i_l_stride, p_mb->i_l_stride, /* select */ ((i_mv_y & 1) << 1) | (i_mv_x & 1), b_average ); i_source_offset = (p_mb->i_c_x + ((i_mv_x/2) >> 1)) + ((p_mb->i_motion_c_y + (i_offset >> 1) + ((i_mv_y/2) >> 1)) + b_source_field) * p_mb->p_picture->i_chroma_width; if( i_source_offset >= (p_source->i_width * p_source->i_height) / 4 ) { intf_ErrMsg( "vdec error: bad motion vector\n" ); return; } i_dest_offset = (p_mb->i_c_x) + (p_mb->i_motion_c_y + b_dest_field) * p_mb->p_picture->i_chroma_width; i_c_height = i_height >> 1; i_c_select = (((i_mv_y/2) & 1) << 1) | ((i_mv_x/2) & 1); /* Chrominance Cr */ MotionComponent( p_source->p_u + i_source_offset, p_mb->p_picture->p_u + i_dest_offset, 8, i_c_height, i_c_stride, p_mb->i_c_stride, i_c_select, b_average ); /* Chrominance Cb */ MotionComponent( p_source->p_v + i_source_offset, p_mb->p_picture->p_v + i_dest_offset, 8, i_c_height, i_c_stride, p_mb->i_c_stride, i_c_select, b_average );}/*****************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -