diff options
Diffstat (limited to 'src/video_out/xvmc_mocomp.c')
-rw-r--r-- | src/video_out/xvmc_mocomp.c | 274 |
1 files changed, 274 insertions, 0 deletions
diff --git a/src/video_out/xvmc_mocomp.c b/src/video_out/xvmc_mocomp.c new file mode 100644 index 000000000..94c6e9906 --- /dev/null +++ b/src/video_out/xvmc_mocomp.c @@ -0,0 +1,274 @@ +/* + * Copyright (C) 2000-2004 the xine project + * + * This file is part of xine, a free video player. + * + * * xine 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. + * + * xine 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 + * + * $Id: xvmc_mocomp.c,v 1.1 2004/09/28 18:49:40 miguelfreitas Exp $ + * + * XvMC image support by Jack Kelliher + */ + +#include "xxmc.h" + + +static void calc_DMV(int DMV[][2], int *dmvector, + int mvx, int mvy, int picture_structure, int top_field_first) { + + if (picture_structure==VO_BOTH_FIELDS) { + if (top_field_first) { + /* vector for prediction of top field from bottom field */ + DMV[0][0] = ((mvx +(mvx>0))>>1) + dmvector[0]; + DMV[0][1] = ((mvy +(mvy>0))>>1) + dmvector[1] - 1; + + /* vector for prediction of bottom field from top field */ + DMV[1][0] = ((3*mvx+(mvx>0))>>1) + dmvector[0]; + DMV[1][1] = ((3*mvy+(mvy>0))>>1) + dmvector[1] + 1; + } + else { + /* vector for prediction of top field from bottom field */ + DMV[0][0] = ((3*mvx+(mvx>0))>>1) + dmvector[0]; + DMV[0][1] = ((3*mvy+(mvy>0))>>1) + dmvector[1] - 1; + + /* vector for prediction of bottom field from top field */ + DMV[1][0] = ((mvx +(mvx>0))>>1) + dmvector[0]; + DMV[1][1] = ((mvy +(mvy>0))>>1) + dmvector[1] + 1; + } + } + else { + /* vector for prediction from field of opposite 'parity' */ + DMV[0][0] = ((mvx+(mvx>0))>>1) + dmvector[0]; + DMV[0][1] = ((mvy+(mvy>0))>>1) + dmvector[1]; + + /* correct for vertical field shift */ + if (picture_structure==VO_TOP_FIELD) + DMV[0][1]--; + else + DMV[0][1]++; + + } +} + + + + +static void xvmc_render_macro_blocks(vo_frame_t *current_image, + vo_frame_t *backward_ref_image, + vo_frame_t *forward_ref_image, + int picture_structure, + int second_field, + xvmc_macroblocks_t *macroblocks) { + xxmc_driver_t *this = (xxmc_driver_t *) current_image->driver; + xxmc_frame_t *current_frame = (xxmc_frame_t *) current_image; + xxmc_frame_t *forward_frame = (xxmc_frame_t *) forward_ref_image; + xxmc_frame_t *backward_frame = (xxmc_frame_t *) backward_ref_image; + + lprintf ("xvmc_render_macro_blocks\n"); + lprintf ("slices %d 0x%08lx 0x%08lx 0x%08lx\n", + macroblocks->slices, + (long) current_frame, (long) backward_frame, + (long) forward_frame); + + XVMCLOCKDISPLAY( this->display); + XvMCRenderSurface(this->display, &this->context, picture_structure, + current_frame->xvmc_surf, + forward_frame ? forward_frame->xvmc_surf : NULL, + backward_frame ? backward_frame->xvmc_surf : NULL, + second_field, + macroblocks->slices, 0, ¯oblocks->macro_blocks, + ¯oblocks->blocks); + XVMCUNLOCKDISPLAY( this->display); +} + + + +void xxmc_xvmc_proc_macro_block(int x, int y, int mb_type, int motion_type, + int (*mv_field_sel)[2], int *dmvector, int cbp, + int dct_type, vo_frame_t *current_frame, + vo_frame_t *forward_ref_frame, + vo_frame_t *backward_ref_frame, int picture_structure, + int second_field, int (*f_mot_pmv)[2], int (*b_mot_pmv)[2]) +{ + xxmc_driver_t *this = (xxmc_driver_t *) current_frame->driver; + xvmc_macroblocks_t *mbs = &this->macroblocks; + int top_field_first = current_frame->top_field_first; + int picture_coding_type = current_frame->picture_coding_type; + + xvmc_context_reader_lock( &this->xvmc_lock ); + mbs->macroblockptr->x = x; + mbs->macroblockptr->y = y; + + if(mb_type & XINE_MACROBLOCK_INTRA) { + mbs->macroblockptr->macroblock_type = XVMC_MB_TYPE_INTRA; + } + else { + mbs->macroblockptr->macroblock_type = 0; + /* XvMC doesn't support skips */ + if(!(mb_type & (XINE_MACROBLOCK_MOTION_BACKWARD | XINE_MACROBLOCK_MOTION_FORWARD))) { + mb_type |= XINE_MACROBLOCK_MOTION_FORWARD; + motion_type = (picture_structure == VO_BOTH_FIELDS) ? XINE_MC_FRAME : XINE_MC_FIELD; + mbs->macroblockptr->PMV[0][0][0] = 0; + mbs->macroblockptr->PMV[0][0][1] = 0; + } + else { + if(mb_type & XINE_MACROBLOCK_MOTION_BACKWARD) { + mbs->macroblockptr->macroblock_type |= XVMC_MB_TYPE_MOTION_BACKWARD; + mbs->macroblockptr->PMV[0][1][0] = b_mot_pmv[0][0]; + mbs->macroblockptr->PMV[0][1][1] = b_mot_pmv[0][1]; + mbs->macroblockptr->PMV[1][1][0] = b_mot_pmv[1][0]; + mbs->macroblockptr->PMV[1][1][1] = b_mot_pmv[1][1]; + + } + + if(mb_type & XINE_MACROBLOCK_MOTION_FORWARD) { + mbs->macroblockptr->macroblock_type |= XVMC_MB_TYPE_MOTION_FORWARD; + mbs->macroblockptr->PMV[0][0][0] = f_mot_pmv[0][0]; + mbs->macroblockptr->PMV[0][0][1] = f_mot_pmv[0][1]; + mbs->macroblockptr->PMV[1][0][0] = f_mot_pmv[1][0]; + mbs->macroblockptr->PMV[1][0][1] = f_mot_pmv[1][1]; + } + } + + if((mb_type & XINE_MACROBLOCK_PATTERN) && cbp) + mbs->macroblockptr->macroblock_type |= XVMC_MB_TYPE_PATTERN; + + mbs->macroblockptr->motion_type = motion_type; + + if(motion_type == XINE_MC_DMV) { + int DMV[2][2]; + + if(picture_structure == VO_BOTH_FIELDS) { + calc_DMV(DMV,dmvector, f_mot_pmv[0][0], + f_mot_pmv[0][1]>>1, picture_structure, + top_field_first); + + mbs->macroblockptr->PMV[1][0][0] = DMV[0][0]; + mbs->macroblockptr->PMV[1][0][1] = DMV[0][1]; + mbs->macroblockptr->PMV[1][1][0] = DMV[1][0]; + mbs->macroblockptr->PMV[1][1][1] = DMV[1][1]; + } + else { + calc_DMV(DMV,dmvector, f_mot_pmv[0][0], + f_mot_pmv[0][1]>>1, picture_structure, + top_field_first); + + mbs->macroblockptr->PMV[0][1][0] = DMV[0][0]; + mbs->macroblockptr->PMV[0][1][1] = DMV[0][1]; + } + } + + if((motion_type == XINE_MC_FIELD) || (motion_type == XINE_MC_16X8)) { + mbs->macroblockptr->motion_vertical_field_select = 0; + if(mv_field_sel[0][0]) + mbs->macroblockptr->motion_vertical_field_select |= 1; + if(mv_field_sel[0][1]) + mbs->macroblockptr->motion_vertical_field_select |= 2; + if(mv_field_sel[1][0]) + mbs->macroblockptr->motion_vertical_field_select |= 4; + if(mv_field_sel[1][1]) + mbs->macroblockptr->motion_vertical_field_select |= 8; + } + } /* else of if(mb_type & XINE_MACROBLOCK_INTRA) */ + + mbs->macroblockptr->index = ((unsigned long)mbs->xine_mc.blockptr - + (unsigned long)mbs->xine_mc.blockbaseptr) >> 7; + + mbs->macroblockptr->dct_type = dct_type; + mbs->macroblockptr->coded_block_pattern = cbp; + + cbp &= 0x3F; + mbs->macroblockptr->coded_block_pattern = cbp; + + while(cbp) { + if(cbp & 1) mbs->macroblockptr->index--; + cbp >>= 1; + } + +#ifdef PRINTDATA + printf("\n"); + printf("-- %04d %04d %02x %02x %02x %02x",mbs->macroblockptr->x,mbs->macroblockptr->y,mbs->macroblockptr->macroblock_type, + mbs->macroblockptr->motion_type,mbs->macroblockptr->motion_vertical_field_select,mbs->macroblockptr->dct_type); + printf(" [%04d %04d %04d %04d %04d %04d %04d %04d] ", + mbs->macroblockptr->PMV[0][0][0],mbs->macroblockptr->PMV[0][0][1],mbs->macroblockptr->PMV[0][1][0],mbs->macroblockptr->PMV[0][1][1], + mbs->macroblockptr->PMV[1][0][0],mbs->macroblockptr->PMV[1][0][1],mbs->macroblockptr->PMV[1][1][0],mbs->macroblockptr->PMV[1][1][1]); + + printf(" %04d %04x\n",mbs->macroblockptr->index,mbs->macroblockptr->coded_block_pattern); +#endif + + mbs->num_blocks++; + mbs->macroblockptr++; + + if(mbs->num_blocks == mbs->slices) { +#ifdef PRINTDATA + printf("macroblockptr %lx", mbs->macroblockptr); + printf("** RenderSurface %04d %04x\n",picture_structure, + second_field ? XVMC_SECOND_FIELD : 0); + fflush(stdout); +#endif +#ifdef PRINTFRAME + printf(" target %08x past %08x future %08x\n", + current_frame, + forward_ref_frame, + backward_ref_frame); +#endif +#ifdef PRINTFRAME + if (picture_coding_type == XINE_PICT_P_TYPE) + printf(" coding type P_TYPE\n"); + if (picture_coding_type == XINE_PICT_I_TYPE) + printf(" coding type I_TYPE\n"); + if (picture_coding_type == XINE_PICT_B_TYPE) + printf(" coding type B_TYPE\n"); + if (picture_coding_type == XINE_PICT_D_TYPE) + printf(" coding type D_TYPE\n"); + fflush(stdout); +#endif + + if (picture_coding_type == XINE_PICT_B_TYPE) + xvmc_render_macro_blocks( + current_frame, + backward_ref_frame, + forward_ref_frame, + picture_structure, + second_field ? XVMC_SECOND_FIELD : 0, + mbs); + if (picture_coding_type == XINE_PICT_P_TYPE) + xvmc_render_macro_blocks( + current_frame, + NULL, + forward_ref_frame, + picture_structure, + second_field ? XVMC_SECOND_FIELD : 0, + mbs); + if (picture_coding_type == XINE_PICT_I_TYPE) + xvmc_render_macro_blocks( + current_frame, + NULL, + NULL, + picture_structure, + second_field ? XVMC_SECOND_FIELD : 0, + mbs); + + mbs->num_blocks = 0; + mbs->macroblockptr = mbs->macroblockbaseptr; + mbs->xine_mc.blockptr = mbs->xine_mc.blockbaseptr; + } + + xvmc_context_reader_unlock( &this->xvmc_lock ); + +} + + + |