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