/* * Copyright (C) 2000-2004 the xine project * Copyright (C) 2004 the Unichrome 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_vld.c,v 1.2 2004/10/03 12:36:15 totte67 Exp $ * * xvmc_vld.c, X11 decoding accelerated video extension interface for xine * * Author: Thomas Hellström, (2004) */ #include "xxmc.h" #include #ifdef HAVE_VLDXVMC void xvmc_vld_frame(struct vo_frame_s *this_gen) { vo_frame_t *this = (vo_frame_t *) this_gen; xxmc_frame_t *cf = (xxmc_frame_t *) this; xine_vld_frame_t *vft = &(cf->xxmc_data.vld_frame); xxmc_frame_t *ff = (xxmc_frame_t *) vft->forward_reference_frame, *bf = (xxmc_frame_t *) vft->backward_reference_frame; XvMCMpegControl ctl; xxmc_driver_t *driver = (xxmc_driver_t *) cf->vo_frame.driver; XvMCSurface *fs=0, *bs=0; XvMCQMatrix qmx; ctl.BHMV_range = vft->mv_ranges[0][0]; ctl.BVMV_range = vft->mv_ranges[0][1]; ctl.FHMV_range = vft->mv_ranges[1][0]; ctl.FVMV_range = vft->mv_ranges[1][1]; ctl.picture_structure = vft->picture_structure; ctl.intra_dc_precision = vft->intra_dc_precision; ctl.picture_coding_type = vft->picture_coding_type; ctl.mpeg_coding = (vft->mpeg_coding == 0) ? XVMC_MPEG_1 : XVMC_MPEG_2; ctl.flags = 0; ctl.flags |= (vft->progressive_sequence) ? XVMC_PROGRESSIVE_SEQUENCE : 0 ; ctl.flags |= (vft->scan) ? XVMC_ALTERNATE_SCAN : XVMC_ZIG_ZAG_SCAN; ctl.flags |= (vft->pred_dct_frame) ? XVMC_PRED_DCT_FRAME : XVMC_PRED_DCT_FIELD; ctl.flags |= (this->top_field_first) ? XVMC_TOP_FIELD_FIRST : XVMC_BOTTOM_FIELD_FIRST; ctl.flags |= (vft->concealment_motion_vectors) ? XVMC_CONCEALMENT_MOTION_VECTORS : 0 ; ctl.flags |= (vft->q_scale_type) ? XVMC_Q_SCALE_TYPE : 0; ctl.flags |= (vft->intra_vlc_format) ? XVMC_INTRA_VLC_FORMAT : 0; ctl.flags |= (vft->second_field) ? XVMC_SECOND_FIELD : 0 ; if (ff) fs=ff->xvmc_surf; if (bf) bs=bf->xvmc_surf; /* * Below is for interlaced streams and second_field. */ if (ctl.picture_coding_type == XVMC_P_PICTURE) bs = cf->xvmc_surf; if ((qmx.load_intra_quantiser_matrix = vft->load_intra_quantizer_matrix)) { memcpy(qmx.intra_quantiser_matrix,vft->intra_quantizer_matrix, sizeof(qmx.intra_quantiser_matrix)); } if ((qmx.load_non_intra_quantiser_matrix = vft->load_non_intra_quantizer_matrix)) { memcpy(qmx.non_intra_quantiser_matrix,vft->non_intra_quantizer_matrix, sizeof(qmx.non_intra_quantiser_matrix)); } qmx.load_chroma_intra_quantiser_matrix = 0; qmx.load_chroma_non_intra_quantiser_matrix = 0; xvmc_context_reader_lock( &driver->xvmc_lock ); if ( ! xxmc_xvmc_surface_valid( driver, cf->xvmc_surf)) { cf->xxmc_data.result = 128; xvmc_context_reader_unlock( &driver->xvmc_lock ); return; } XVMCLOCKDISPLAY( driver->display ); XvMCLoadQMatrix(driver->display, &driver->context, &qmx); while((cf->xxmc_data.result = XvMCBeginSurface(driver->display, &driver->context, cf->xvmc_surf, fs, bs, &ctl))); XVMCUNLOCKDISPLAY( driver->display ); xvmc_context_reader_unlock( &driver->xvmc_lock ); driver->cpu_saver = 0.; } void xvmc_vld_slice(vo_frame_t *this_gen) { xxmc_frame_t *cf = (xxmc_frame_t *) this_gen; xxmc_driver_t *driver = (xxmc_driver_t *) cf->vo_frame.driver; xvmc_context_reader_lock( &driver->xvmc_lock ); if ( ! xxmc_xvmc_surface_valid( driver, cf->xvmc_surf)) { cf->xxmc_data.result = 128; xvmc_context_reader_unlock( &driver->xvmc_lock ); return; } XVMCLOCKDISPLAY( driver->display ); cf->xxmc_data.result = XvMCPutSlice2(driver->display,&driver->context,cf->xxmc_data.slice_data, cf->xxmc_data.slice_data_size,cf->xxmc_data.slice_code); /* * If CPU-saving mode is enabled, sleep after every xxmc->sleep slice. This will free * up the cpu while the decoder is working on the slice. The value of xxmc->sleep is calculated * so that the decoder thread sleeps at most 50% of the frame delay, * assuming a 2.6 kernel clock of 1000 Hz. */ XVMCUNLOCKDISPLAY( driver->display ); xvmc_context_reader_unlock( &driver->xvmc_lock ); if (driver->cpu_save_enabled) { driver->cpu_saver += 1.; if (driver->cpu_saver >= cf->xxmc_data.sleep) { usleep(1); driver->cpu_saver -= cf->xxmc_data.sleep; } } } #endif