1 /*
2  * Copyright (C) 2000-2020 the xine project
3  * Copyright (C) 2004 the Unichrome project
4  *
5  * This file is part of xine, a free video player.
6  *
7  * xine is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * xine is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
20  *
21  * xvmc_vld.c, X11 decoding accelerated video extension interface for xine
22  *
23  * Author: Thomas Hellström, (2004)
24  */
25 
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29 
30 #include "xxmc.h"
31 #include <unistd.h>
32 
33 #ifdef HAVE_VLDXVMC
xvmc_vld_frame(struct vo_frame_s * this_gen)34 void xvmc_vld_frame(struct vo_frame_s *this_gen)
35 
36 {
37   vo_frame_t *this = (vo_frame_t *) this_gen;
38   xxmc_frame_t
39     *cf = XXMC_FRAME(this);
40   xine_vld_frame_t
41     *vft = &(cf->xxmc_data.vld_frame);
42   xxmc_frame_t
43     *ff = XXMC_FRAME(vft->forward_reference_frame),
44     *bf = XXMC_FRAME(vft->backward_reference_frame);
45   XvMCMpegControl ctl;
46   xxmc_driver_t
47     *driver = (xxmc_driver_t *) cf->vo_frame.driver;
48   XvMCSurface *fs=0, *bs=0;
49   XvMCQMatrix qmx;
50 
51   ctl.BHMV_range = vft->mv_ranges[0][0];
52   ctl.BVMV_range = vft->mv_ranges[0][1];
53   ctl.FHMV_range = vft->mv_ranges[1][0];
54   ctl.FVMV_range = vft->mv_ranges[1][1];
55   ctl.picture_structure = vft->picture_structure;
56   ctl.intra_dc_precision = vft->intra_dc_precision;
57   ctl.picture_coding_type = vft->picture_coding_type;
58   ctl.mpeg_coding = (vft->mpeg_coding == 0) ? XVMC_MPEG_1 : XVMC_MPEG_2;
59   ctl.flags = 0;
60   ctl.flags |= (vft->progressive_sequence) ?
61     XVMC_PROGRESSIVE_SEQUENCE : 0 ;
62   ctl.flags |= (vft->scan) ?
63     XVMC_ALTERNATE_SCAN : XVMC_ZIG_ZAG_SCAN;
64   ctl.flags |= (vft->pred_dct_frame) ?
65     XVMC_PRED_DCT_FRAME : XVMC_PRED_DCT_FIELD;
66   ctl.flags |= (this->top_field_first) ?
67     XVMC_TOP_FIELD_FIRST : XVMC_BOTTOM_FIELD_FIRST;
68   ctl.flags |= (vft->concealment_motion_vectors) ?
69     XVMC_CONCEALMENT_MOTION_VECTORS : 0 ;
70   ctl.flags |= (vft->q_scale_type) ?
71     XVMC_Q_SCALE_TYPE : 0;
72   ctl.flags |= (vft->intra_vlc_format) ?
73     XVMC_INTRA_VLC_FORMAT : 0;
74   ctl.flags |= (vft->second_field) ?
75     XVMC_SECOND_FIELD : 0 ;
76 
77   if (ff) fs=ff->xvmc_surf;
78   if (bf) bs=bf->xvmc_surf;
79 
80   /*
81    * Below is for interlaced streams and second_field.
82    */
83 
84   if (ctl.picture_coding_type == XVMC_P_PICTURE)
85     bs = cf->xvmc_surf;
86 
87   if ((qmx.load_intra_quantiser_matrix = vft->load_intra_quantizer_matrix)) {
88     memcpy(qmx.intra_quantiser_matrix,vft->intra_quantizer_matrix,
89 	   sizeof(qmx.intra_quantiser_matrix));
90   }
91   if ((qmx.load_non_intra_quantiser_matrix = vft->load_non_intra_quantizer_matrix)) {
92     memcpy(qmx.non_intra_quantiser_matrix,vft->non_intra_quantizer_matrix,
93 	   sizeof(qmx.non_intra_quantiser_matrix));
94   }
95   qmx.load_chroma_intra_quantiser_matrix = 0;
96   qmx.load_chroma_non_intra_quantiser_matrix = 0;
97 
98   XVMCLOCKDISPLAY( driver->display );
99   XvMCLoadQMatrix(driver->display, &driver->context, &qmx);
100 
101   while((cf->xxmc_data.result =
102 	 XvMCBeginSurface(driver->display, &driver->context, cf->xvmc_surf,
103 			  fs, bs, &ctl)));
104   XVMCUNLOCKDISPLAY( driver->display );
105   driver->cpu_saver = 0.;
106 }
107 
xvmc_vld_slice(vo_frame_t * this_gen)108 void xvmc_vld_slice(vo_frame_t *this_gen)
109 {
110   xxmc_frame_t
111     *cf = XXMC_FRAME(this_gen);
112   xxmc_driver_t
113     *driver = (xxmc_driver_t *) cf->vo_frame.driver;
114 
115   XVMCLOCKDISPLAY( driver->display );
116   cf->xxmc_data.result =
117     XvMCPutSlice2(driver->display,&driver->context,cf->xxmc_data.slice_data,
118 		  cf->xxmc_data.slice_data_size,cf->xxmc_data.slice_code);
119   /*
120    * If CPU-saving mode is enabled, sleep after every xxmc->sleep slice. This will free
121    * up the cpu while the decoder is working on the slice. The value of xxmc->sleep is calculated
122    * so that the decoder thread sleeps at most 50% of the frame delay,
123    * assuming a 2.6 kernel clock of 1000 Hz.
124    */
125 
126   XVMCUNLOCKDISPLAY( driver->display );
127   if (driver->cpu_save_enabled) {
128     driver->cpu_saver += 1.;
129     if (driver->cpu_saver >= cf->xxmc_data.sleep) {
130       usleep(1);
131       driver->cpu_saver -= cf->xxmc_data.sleep;
132     }
133   }
134 }
135 #endif
136 
137