1 /*
2 * Copyright (C) 2000-2020 the xine project
3 *
4 * This file is part of xine, a free video player.
5 *
6 * * xine is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * xine is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 *
20 * XvMC image support by Jack Kelliher
21 */
22
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include "xxmc.h"
28
29
calc_DMV(int DMV[][2],int * dmvector,int mvx,int mvy,int picture_structure,int top_field_first)30 static void calc_DMV(int DMV[][2], int *dmvector,
31 int mvx, int mvy, int picture_structure, int top_field_first) {
32
33 if (picture_structure==VO_BOTH_FIELDS) {
34 if (top_field_first) {
35 /* vector for prediction of top field from bottom field */
36 DMV[0][0] = ((mvx +(mvx>0))>>1) + dmvector[0];
37 DMV[0][1] = ((mvy +(mvy>0))>>1) + dmvector[1] - 1;
38
39 /* vector for prediction of bottom field from top field */
40 DMV[1][0] = ((3*mvx+(mvx>0))>>1) + dmvector[0];
41 DMV[1][1] = ((3*mvy+(mvy>0))>>1) + dmvector[1] + 1;
42 }
43 else {
44 /* vector for prediction of top field from bottom field */
45 DMV[0][0] = ((3*mvx+(mvx>0))>>1) + dmvector[0];
46 DMV[0][1] = ((3*mvy+(mvy>0))>>1) + dmvector[1] - 1;
47
48 /* vector for prediction of bottom field from top field */
49 DMV[1][0] = ((mvx +(mvx>0))>>1) + dmvector[0];
50 DMV[1][1] = ((mvy +(mvy>0))>>1) + dmvector[1] + 1;
51 }
52 }
53 else {
54 /* vector for prediction from field of opposite 'parity' */
55 DMV[0][0] = ((mvx+(mvx>0))>>1) + dmvector[0];
56 DMV[0][1] = ((mvy+(mvy>0))>>1) + dmvector[1];
57
58 /* correct for vertical field shift */
59 if (picture_structure==VO_TOP_FIELD)
60 DMV[0][1]--;
61 else
62 DMV[0][1]++;
63
64 }
65 }
66
67
68
69
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)70 static void xvmc_render_macro_blocks(vo_frame_t *current_image,
71 vo_frame_t *backward_ref_image,
72 vo_frame_t *forward_ref_image,
73 int picture_structure,
74 int second_field,
75 xvmc_macroblocks_t *macroblocks) {
76 xxmc_driver_t *this = (xxmc_driver_t *) current_image->driver;
77 xxmc_frame_t *current_frame = XXMC_FRAME(current_image);
78 xxmc_frame_t *forward_frame = XXMC_FRAME(forward_ref_image);
79 xxmc_frame_t *backward_frame = XXMC_FRAME(backward_ref_image);
80 int flags;
81
82 lprintf ("xvmc_render_macro_blocks\n");
83 lprintf ("slices %d 0x%08lx 0x%08lx 0x%08lx\n",
84 macroblocks->slices,
85 (long) current_frame, (long) backward_frame,
86 (long) forward_frame);
87
88 flags = second_field;
89
90 XVMCLOCKDISPLAY( this->display);
91 XvMCRenderSurface(this->display, &this->context, picture_structure,
92 current_frame->xvmc_surf,
93 forward_frame ? forward_frame->xvmc_surf : NULL,
94 backward_frame ? backward_frame->xvmc_surf : NULL,
95 flags,
96 macroblocks->slices, 0, ¯oblocks->macro_blocks,
97 ¯oblocks->blocks);
98 XVMCUNLOCKDISPLAY( this->display);
99 }
100
101
102
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])103 void xxmc_xvmc_proc_macro_block(int x, int y, int mb_type, int motion_type,
104 int (*mv_field_sel)[2], int *dmvector, int cbp,
105 int dct_type, vo_frame_t *current_frame,
106 vo_frame_t *forward_ref_frame,
107 vo_frame_t *backward_ref_frame, int picture_structure,
108 int second_field, int (*f_mot_pmv)[2], int (*b_mot_pmv)[2])
109 {
110 xxmc_driver_t *this = (xxmc_driver_t *) current_frame->driver;
111 xvmc_macroblocks_t *mbs = &this->macroblocks;
112 int top_field_first = current_frame->top_field_first;
113 int picture_coding_type = current_frame->picture_coding_type;
114
115 mbs->macroblockptr->x = x;
116 mbs->macroblockptr->y = y;
117
118 if(mb_type & XINE_MACROBLOCK_INTRA) {
119 mbs->macroblockptr->macroblock_type = XVMC_MB_TYPE_INTRA;
120 }
121 else {
122 mbs->macroblockptr->macroblock_type = 0;
123 /* XvMC doesn't support skips */
124 if(!(mb_type & (XINE_MACROBLOCK_MOTION_BACKWARD | XINE_MACROBLOCK_MOTION_FORWARD))) {
125 mb_type |= XINE_MACROBLOCK_MOTION_FORWARD;
126 motion_type = (picture_structure == VO_BOTH_FIELDS) ? XINE_MC_FRAME : XINE_MC_FIELD;
127 mbs->macroblockptr->PMV[0][0][0] = 0;
128 mbs->macroblockptr->PMV[0][0][1] = 0;
129 }
130 else {
131 if(mb_type & XINE_MACROBLOCK_MOTION_BACKWARD) {
132 mbs->macroblockptr->macroblock_type |= XVMC_MB_TYPE_MOTION_BACKWARD;
133 mbs->macroblockptr->PMV[0][1][0] = b_mot_pmv[0][0];
134 mbs->macroblockptr->PMV[0][1][1] = b_mot_pmv[0][1];
135 mbs->macroblockptr->PMV[1][1][0] = b_mot_pmv[1][0];
136 mbs->macroblockptr->PMV[1][1][1] = b_mot_pmv[1][1];
137
138 }
139
140 if(mb_type & XINE_MACROBLOCK_MOTION_FORWARD) {
141 mbs->macroblockptr->macroblock_type |= XVMC_MB_TYPE_MOTION_FORWARD;
142 mbs->macroblockptr->PMV[0][0][0] = f_mot_pmv[0][0];
143 mbs->macroblockptr->PMV[0][0][1] = f_mot_pmv[0][1];
144 mbs->macroblockptr->PMV[1][0][0] = f_mot_pmv[1][0];
145 mbs->macroblockptr->PMV[1][0][1] = f_mot_pmv[1][1];
146 }
147 }
148
149 if((mb_type & XINE_MACROBLOCK_PATTERN) && cbp)
150 mbs->macroblockptr->macroblock_type |= XVMC_MB_TYPE_PATTERN;
151
152 mbs->macroblockptr->motion_type = motion_type;
153
154 if(motion_type == XINE_MC_DMV) {
155 int DMV[2][2];
156
157 if(picture_structure == VO_BOTH_FIELDS) {
158 calc_DMV(DMV,dmvector, f_mot_pmv[0][0],
159 f_mot_pmv[0][1]>>1, picture_structure,
160 top_field_first);
161
162 mbs->macroblockptr->PMV[1][0][0] = DMV[0][0];
163 mbs->macroblockptr->PMV[1][0][1] = DMV[0][1];
164 mbs->macroblockptr->PMV[1][1][0] = DMV[1][0];
165 mbs->macroblockptr->PMV[1][1][1] = DMV[1][1];
166 }
167 else {
168 calc_DMV(DMV,dmvector, f_mot_pmv[0][0],
169 f_mot_pmv[0][1]>>1, picture_structure,
170 top_field_first);
171
172 mbs->macroblockptr->PMV[0][1][0] = DMV[0][0];
173 mbs->macroblockptr->PMV[0][1][1] = DMV[0][1];
174 }
175 }
176
177 if((motion_type == XINE_MC_FIELD) || (motion_type == XINE_MC_16X8)) {
178 mbs->macroblockptr->motion_vertical_field_select = 0;
179 if(mv_field_sel[0][0])
180 mbs->macroblockptr->motion_vertical_field_select |= 1;
181 if(mv_field_sel[0][1])
182 mbs->macroblockptr->motion_vertical_field_select |= 2;
183 if(mv_field_sel[1][0])
184 mbs->macroblockptr->motion_vertical_field_select |= 4;
185 if(mv_field_sel[1][1])
186 mbs->macroblockptr->motion_vertical_field_select |= 8;
187 }
188 } /* else of if(mb_type & XINE_MACROBLOCK_INTRA) */
189
190 mbs->macroblockptr->index = ((unsigned long)mbs->xine_mc.blockptr -
191 (unsigned long)mbs->xine_mc.blockbaseptr) >> 7;
192
193 mbs->macroblockptr->dct_type = dct_type;
194 mbs->macroblockptr->coded_block_pattern = cbp;
195
196 cbp &= 0x3F;
197 mbs->macroblockptr->coded_block_pattern = cbp;
198
199 while(cbp) {
200 if(cbp & 1) mbs->macroblockptr->index--;
201 cbp >>= 1;
202 }
203
204 #ifdef PRINTDATA
205 printf("\n");
206 printf("-- %04d %04d %02x %02x %02x %02x",mbs->macroblockptr->x,mbs->macroblockptr->y,mbs->macroblockptr->macroblock_type,
207 mbs->macroblockptr->motion_type,mbs->macroblockptr->motion_vertical_field_select,mbs->macroblockptr->dct_type);
208 printf(" [%04d %04d %04d %04d %04d %04d %04d %04d] ",
209 mbs->macroblockptr->PMV[0][0][0],mbs->macroblockptr->PMV[0][0][1],mbs->macroblockptr->PMV[0][1][0],mbs->macroblockptr->PMV[0][1][1],
210 mbs->macroblockptr->PMV[1][0][0],mbs->macroblockptr->PMV[1][0][1],mbs->macroblockptr->PMV[1][1][0],mbs->macroblockptr->PMV[1][1][1]);
211
212 printf(" %04d %04x\n",mbs->macroblockptr->index,mbs->macroblockptr->coded_block_pattern);
213 #endif
214
215 mbs->num_blocks++;
216 mbs->macroblockptr++;
217
218 if(mbs->num_blocks == mbs->slices) {
219 #ifdef PRINTDATA
220 printf("macroblockptr %lx", mbs->macroblockptr);
221 printf("** RenderSurface %04d %04x\n",picture_structure,
222 second_field ? XVMC_SECOND_FIELD : 0);
223 fflush(stdout);
224 #endif
225 #ifdef PRINTFRAME
226 printf(" target %08x past %08x future %08x\n",
227 current_frame,
228 forward_ref_frame,
229 backward_ref_frame);
230 #endif
231 #ifdef PRINTFRAME
232 if (picture_coding_type == XINE_PICT_P_TYPE)
233 printf(" coding type P_TYPE\n");
234 if (picture_coding_type == XINE_PICT_I_TYPE)
235 printf(" coding type I_TYPE\n");
236 if (picture_coding_type == XINE_PICT_B_TYPE)
237 printf(" coding type B_TYPE\n");
238 if (picture_coding_type == XINE_PICT_D_TYPE)
239 printf(" coding type D_TYPE\n");
240 fflush(stdout);
241 #endif
242
243 xvmc_render_macro_blocks(
244 current_frame,
245 (picture_coding_type == XINE_PICT_B_TYPE) ?
246 backward_ref_frame : NULL,
247 (picture_coding_type != XINE_PICT_I_TYPE) ?
248 forward_ref_frame : NULL,
249 picture_structure,
250 second_field ? XVMC_SECOND_FIELD : 0,
251 mbs);
252
253 mbs->num_blocks = 0;
254 mbs->macroblockptr = mbs->macroblockbaseptr;
255 mbs->xine_mc.blockptr = mbs->xine_mc.blockbaseptr;
256 }
257 }
258
259
260
261