summaryrefslogtreecommitdiff
path: root/src/video_out/xvmc_mocomp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_out/xvmc_mocomp.c')
-rw-r--r--src/video_out/xvmc_mocomp.c274
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, &macroblocks->macro_blocks,
+ &macroblocks->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 );
+
+}
+
+
+