video_motion.c

来自「基于linux的DVD播放器程序」· C语言 代码 · 共 519 行 · 第 1/2 页

C
519
字号
/* Ogle - A video player * Copyright (C) 2000, 2001 Bj鰎n Englund, H錵an Hjort * * 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-1307  USA */#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <unistd.h>#include <inttypes.h>#include <signal.h>#include "debug_print.h"#include "video_stream.h"#include "video_types.h"#include "video_tables.h" // only MACROBLOCK_MOTION_FORWARD/BACKWARD#ifdef HAVE_MLIB#include <mlib_types.h>#include <mlib_status.h>#include <mlib_sys.h>#include <mlib_video.h>#include <mlib_algebra.h>#define mlib_VideoIDCTAdd_U8_S16(CURR_BLOCK, COEFFS, STRIDE) \  { \     mlib_VideoIDCT8x8_S16_S16(COEFFS, COEFFS); \     mlib_VideoAddBlock_U8_S16(CURR_BLOCK, COEFFS, STRIDE); \  }#else#ifdef HAVE_MMX#include "mmx.h"#include "mmx_mlib.h"#else#include "c_mlib.h"#endif#endif#include "common.h"extern yuv_image_t *dst_image;extern yuv_image_t *fwd_ref_image;extern yuv_image_t *bwd_ref_image;#ifdef HAVE_MLIBtypedef mlib_status (*mc_function_t)(mlib_u8 *curr_block, mlib_u8 *ref_block, 				     mlib_s32 frm_stride, mlib_s32 fld_stride);#elsetypedef void (*mc_function_t)(uint8_t *curr_block, const uint8_t *ref_block, 			      int32_t frm_stride, int32_t fld_stride);#endif/* [replace/average] [size] [half-pell-mode] */static const mc_function_t motion[2][4][4] = {  {     {       (mc_function_t)mlib_VideoCopyRef_U8_U8_16x16,      mlib_VideoInterpY_U8_U8_16x16,      mlib_VideoInterpX_U8_U8_16x16,      mlib_VideoInterpXY_U8_U8_16x16    },    {  	      (mc_function_t)mlib_VideoCopyRef_U8_U8_16x8,      mlib_VideoInterpY_U8_U8_16x8,      mlib_VideoInterpX_U8_U8_16x8,      mlib_VideoInterpXY_U8_U8_16x8    },    {      (mc_function_t)mlib_VideoCopyRef_U8_U8_8x8,      mlib_VideoInterpY_U8_U8_8x8,      mlib_VideoInterpX_U8_U8_8x8,      mlib_VideoInterpXY_U8_U8_8x8    },    {      (mc_function_t)mlib_VideoCopyRef_U8_U8_8x4,      mlib_VideoInterpY_U8_U8_8x4,      mlib_VideoInterpX_U8_U8_8x4,      mlib_VideoInterpXY_U8_U8_8x4    }  },  {    {       (mc_function_t)mlib_VideoCopyRefAve_U8_U8_16x16,      mlib_VideoInterpAveY_U8_U8_16x16,      mlib_VideoInterpAveX_U8_U8_16x16,      mlib_VideoInterpAveXY_U8_U8_16x16    },    {  	      (mc_function_t)mlib_VideoCopyRefAve_U8_U8_16x8,      mlib_VideoInterpAveY_U8_U8_16x8,      mlib_VideoInterpAveX_U8_U8_16x8,      mlib_VideoInterpAveXY_U8_U8_16x8    },    {      (mc_function_t)mlib_VideoCopyRefAve_U8_U8_8x8,      mlib_VideoInterpAveY_U8_U8_8x8,      mlib_VideoInterpAveX_U8_U8_8x8,      mlib_VideoInterpAveXY_U8_U8_8x8    },    {      (mc_function_t)mlib_VideoCopyRefAve_U8_U8_8x4,      mlib_VideoInterpAveY_U8_U8_8x4,      mlib_VideoInterpAveX_U8_U8_8x4,      mlib_VideoInterpAveXY_U8_U8_8x4    }  }};/* This should be cleand up. */void motion_comp(){  const unsigned int padded_width = seq.mb_width * 16;  DPRINTF(5, "dct_type: %d\n", mb.modes.dct_type);    if(mb.prediction_type == PRED_TYPE_DUAL_PRIME) {    fprintf(stderr, "**** DP remove this when implemented\n");    //exit(1);  }  if(mb.prediction_type == PRED_TYPE_16x8_MC) {    fprintf(stderr, "**** 16x8 MC remove this? check if working first.\n");    //exit(1);  }      if(mb.modes.macroblock_type & MACROBLOCK_MOTION_FORWARD) {    uint8_t *dst_y, *dst_u;//, *dst_v;    uint8_t *block_pred_y, *block_pred_u;//, *pred_v;        DPRINTF(5, "forward_motion_comp\n");    DPRINTF(5, "x: %d, y: %d\n", seq.mb_column, seq.mb_row);    /* Image/Field select */    /* FIXME: Should test for 'is second coded field' not bottom_field. */    if(pic.coding_ext.picture_structure == PIC_STRUCT_BOTTOM_FIELD &&       pic.header.picture_coding_type == PIC_CODING_TYPE_P &&       ((mb.motion_vertical_field_select[0][0] == 0 /* TOP_FIELD */ &&	 pic.coding_ext.picture_structure == PIC_STRUCT_BOTTOM_FIELD) ||	(mb.motion_vertical_field_select[0][0] == 1 /* BOTTOM_FIELD */ &&	 pic.coding_ext.picture_structure == PIC_STRUCT_TOP_FIELD))) {      block_pred_y = dst_image->y;      block_pred_u = dst_image->u;      //pred_v = dst_image->v;    } else {      block_pred_y = fwd_ref_image->y;      block_pred_u = fwd_ref_image->u;      //pred_v = fwd_ref_image->v;    }    dst_y = dst_image->y;    dst_u = dst_image->u;    //dst_v = dst_image->v;        /* Motion vector Origo (block->index) */    /* Prediction destination (block->index) */    if(pic.coding_ext.picture_structure == PIC_STRUCT_FRAME_PICTURE) {      unsigned int x = seq.mb_column;      unsigned int y = seq.mb_row;      block_pred_y += x * 16 + y * 16 * padded_width;      block_pred_u += x * 8 + y * 8 * padded_width/2;      //pred_v += x * 8 + y * 8 * padded_width/2;      dst_y += x * 16 + y * 16 * padded_width;      dst_u += x * 8 + y * 8 * padded_width/2;      //dst_v += x * 8 + y * 8 * padded_width/2;    } else {      unsigned int x = seq.mb_column;      unsigned int y = seq.mb_row;      block_pred_y += x * 16 + y * 16 * padded_width*2;      block_pred_u += x * 8 + y * 8 * padded_width;	      //pred_v += x * 8 + y * 8 * padded_width;	      dst_y += x * 16 + y * 16 * padded_width*2;      dst_u += x * 8 + y * 8 * padded_width;      //dst_v += x * 8 + y * 8 * padded_width;            /* Prediction destination (field) */      if(pic.coding_ext.picture_structure == PIC_STRUCT_BOTTOM_FIELD) {	dst_y += padded_width;	dst_u += padded_width/2;	//dst_v += padded_width/2;      }    }               {      uint8_t *pred_y, *pred_u;//, *pred_v;      int pred_stride, stride;      int half_flags_y, half_flags_uv;      int half_height;      int dd;          /* Motion vector offset */      pred_stride = padded_width;      if(mb.mv_format == MV_FORMAT_FIELD)	pred_stride = padded_width * 2;            pred_y = block_pred_y + 	(mb.vector[0][0][0] >> 1) + 	(mb.vector[0][0][1] >> 1) * pred_stride;      pred_u = block_pred_u + 	((mb.vector[0][0][0]/2) >> 1) + 	((mb.vector[0][0][1]/2) >> 1) * pred_stride/2;      //pred_v +=  ((mb.vector[0][0][0]/2) >> 1) +       //((mb.vector[0][0][1]/2) >> 1) * pred_stride/2;            half_flags_y = 	((mb.vector[0][0][0] << 1) | (mb.vector[0][0][1] & 1)) & 3;      half_flags_uv = 	(((mb.vector[0][0][0]/2) << 1) | ((mb.vector[0][0][1]/2) & 1)) & 3;	      /* Field select */      // This is wong for Dual_Prime...      if(mb.mv_format == MV_FORMAT_FIELD) {	if(mb.motion_vertical_field_select[0][0]) {	  pred_y += padded_width;	  pred_u += padded_width/2;	  //pred_v += padded_width/2;	}      }            if(mb.prediction_type == PRED_TYPE_FIELD_BASED)	stride = padded_width * 2;      else	stride = padded_width;            dd = fwd_ref_image->v - fwd_ref_image->u;      half_height = (mb.motion_vector_count == 2) ? 1 :0; // ??      motion[0][half_height][half_flags_y](dst_y, pred_y, stride, stride);      motion[0][half_height+2][half_flags_uv](dst_u, pred_u, 					      stride/2, stride/2);      motion[0][half_height+2][half_flags_uv](dst_u+dd, pred_u+dd,					      stride/2, stride/2);    }    // Only field_pred in frame_pictures have m.v.c. == 2 except for     // field_pictures with 16x8 MC    if(mb.motion_vector_count == 2) {      uint8_t *pred_y, *pred_u;//, *pred_v;      int pred_stride, stride;      int half_flags_y, half_flags_uv;      int dd;          /* Motion vector offset */      pred_stride = padded_width * 2;             pred_y = block_pred_y + 	(mb.vector[1][0][0] >> 1) + 	(mb.vector[1][0][1] >> 1) * pred_stride;      pred_u = block_pred_u + 

⌨️ 快捷键说明

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