slang: No need to purify source text for tokeniser.
[mesa.git] / src / xvmc / surface.c
1 #include <assert.h>
2 #include <X11/Xlib.h>
3 #include <X11/extensions/XvMC.h>
4 #include <X11/Xlibint.h>
5 #include <vl_display.h>
6 #include <vl_screen.h>
7 #include <vl_context.h>
8 #include <vl_surface.h>
9 #include <vl_types.h>
10
11 static enum vlMacroBlockType TypeToVL(int xvmc_mb_type)
12 {
13 if (xvmc_mb_type & XVMC_MB_TYPE_INTRA)
14 return vlMacroBlockTypeIntra;
15 if ((xvmc_mb_type & (XVMC_MB_TYPE_MOTION_FORWARD | XVMC_MB_TYPE_MOTION_BACKWARD)) == XVMC_MB_TYPE_MOTION_FORWARD)
16 return vlMacroBlockTypeFwdPredicted;
17 if ((xvmc_mb_type & (XVMC_MB_TYPE_MOTION_FORWARD | XVMC_MB_TYPE_MOTION_BACKWARD)) == XVMC_MB_TYPE_MOTION_BACKWARD)
18 return vlMacroBlockTypeBkwdPredicted;
19 if ((xvmc_mb_type & (XVMC_MB_TYPE_MOTION_FORWARD | XVMC_MB_TYPE_MOTION_BACKWARD)) == (XVMC_MB_TYPE_MOTION_FORWARD | XVMC_MB_TYPE_MOTION_BACKWARD))
20 return vlMacroBlockTypeBiPredicted;
21
22 assert(0);
23
24 return -1;
25 }
26
27 static enum vlPictureType PictureToVL(int xvmc_pic)
28 {
29 switch (xvmc_pic)
30 {
31 case XVMC_TOP_FIELD:
32 return vlPictureTypeTopField;
33 case XVMC_BOTTOM_FIELD:
34 return vlPictureTypeBottomField;
35 case XVMC_FRAME_PICTURE:
36 return vlPictureTypeFrame;
37 default:
38 assert(0);
39 }
40
41 return -1;
42 }
43
44 static enum vlMotionType MotionToVL(int xvmc_motion_type, int xvmc_dct_type)
45 {
46 switch (xvmc_motion_type)
47 {
48 case XVMC_PREDICTION_FRAME:
49 return xvmc_dct_type == XVMC_DCT_TYPE_FIELD ? vlMotionType16x8 : vlMotionTypeFrame;
50 case XVMC_PREDICTION_FIELD:
51 return vlMotionTypeField;
52 case XVMC_PREDICTION_DUAL_PRIME:
53 return vlMotionTypeDualPrime;
54 default:
55 assert(0);
56 }
57
58 return -1;
59 }
60
61 Status XvMCCreateSurface(Display *display, XvMCContext *context, XvMCSurface *surface)
62 {
63 struct vlContext *vl_ctx;
64 struct vlSurface *vl_sfc;
65 Display *dpy = display;
66
67 assert(display);
68
69 if (!context)
70 return XvMCBadContext;
71 if (!surface)
72 return XvMCBadSurface;
73
74 vl_ctx = context->privData;
75
76 assert(display == vlGetNativeDisplay(vlGetDisplay(vlContextGetScreen(vl_ctx))));
77
78 if (vlCreateSurface(vlContextGetScreen(vl_ctx),
79 context->width, context->height,
80 vlGetPictureFormat(vl_ctx),
81 &vl_sfc))
82 {
83 return BadAlloc;
84 }
85
86 vlBindToContext(vl_sfc, vl_ctx);
87
88 surface->surface_id = XAllocID(display);
89 surface->context_id = context->context_id;
90 surface->surface_type_id = context->surface_type_id;
91 surface->width = context->width;
92 surface->height = context->height;
93 surface->privData = vl_sfc;
94
95 SyncHandle();
96 return Success;
97 }
98
99 Status XvMCRenderSurface
100 (
101 Display *display,
102 XvMCContext *context,
103 unsigned int picture_structure,
104 XvMCSurface *target_surface,
105 XvMCSurface *past_surface,
106 XvMCSurface *future_surface,
107 unsigned int flags,
108 unsigned int num_macroblocks,
109 unsigned int first_macroblock,
110 XvMCMacroBlockArray *macroblocks,
111 XvMCBlockArray *blocks
112 )
113 {
114 struct vlContext *vl_ctx;
115 struct vlSurface *target_vl_surface;
116 struct vlSurface *past_vl_surface;
117 struct vlSurface *future_vl_surface;
118 struct vlMpeg2MacroBlockBatch batch;
119 struct vlMpeg2MacroBlock vl_macroblocks[num_macroblocks];
120 unsigned int i;
121
122 assert(display);
123
124 if (!context)
125 return XvMCBadContext;
126 if (!target_surface)
127 return XvMCBadSurface;
128
129 if
130 (
131 picture_structure != XVMC_TOP_FIELD &&
132 picture_structure != XVMC_BOTTOM_FIELD &&
133 picture_structure != XVMC_FRAME_PICTURE
134 )
135 return BadValue;
136 if (future_surface && !past_surface)
137 return BadMatch;
138
139 vl_ctx = context->privData;
140
141 assert(display == vlGetNativeDisplay(vlGetDisplay(vlContextGetScreen(vl_ctx))));
142
143 target_vl_surface = target_surface->privData;
144 past_vl_surface = past_surface ? past_surface->privData : NULL;
145 future_vl_surface = future_surface ? future_surface->privData : NULL;
146
147 assert(context->context_id == target_surface->context_id);
148 assert(!past_surface || context->context_id == past_surface->context_id);
149 assert(!future_surface || context->context_id == future_surface->context_id);
150
151 assert(macroblocks);
152 assert(blocks);
153
154 assert(macroblocks->context_id == context->context_id);
155 assert(blocks->context_id == context->context_id);
156
157 assert(flags == 0 || flags == XVMC_SECOND_FIELD);
158
159 batch.past_surface = past_vl_surface;
160 batch.future_surface = future_vl_surface;
161 batch.picture_type = PictureToVL(picture_structure);
162 batch.field_order = flags & XVMC_SECOND_FIELD ? vlFieldOrderSecond : vlFieldOrderFirst;
163 batch.num_macroblocks = num_macroblocks;
164 batch.macroblocks = vl_macroblocks;
165
166 for (i = 0; i < num_macroblocks; ++i)
167 {
168 unsigned int j = first_macroblock + i;
169
170 unsigned int k, l, m;
171
172 batch.macroblocks[i].mbx = macroblocks->macro_blocks[j].x;
173 batch.macroblocks[i].mby = macroblocks->macro_blocks[j].y;
174 batch.macroblocks[i].mb_type = TypeToVL(macroblocks->macro_blocks[j].macroblock_type);
175 if (batch.macroblocks[i].mb_type != vlMacroBlockTypeIntra)
176 batch.macroblocks[i].mo_type = MotionToVL(macroblocks->macro_blocks[j].motion_type, macroblocks->macro_blocks[j].dct_type);
177 batch.macroblocks[i].dct_type = macroblocks->macro_blocks[j].dct_type == XVMC_DCT_TYPE_FIELD ? vlDCTTypeFieldCoded : vlDCTTypeFrameCoded;
178
179 for (k = 0; k < 2; ++k)
180 for (l = 0; l < 2; ++l)
181 for (m = 0; m < 2; ++m)
182 batch.macroblocks[i].PMV[k][l][m] = macroblocks->macro_blocks[j].PMV[k][l][m];
183
184 batch.macroblocks[i].cbp = macroblocks->macro_blocks[j].coded_block_pattern;
185 batch.macroblocks[i].blocks = blocks->blocks + (macroblocks->macro_blocks[j].index * 64);
186 }
187
188 vlRenderMacroBlocksMpeg2(&batch, target_vl_surface);
189
190 return Success;
191 }
192
193 Status XvMCFlushSurface(Display *display, XvMCSurface *surface)
194 {
195 struct vlSurface *vl_sfc;
196
197 assert(display);
198
199 if (!surface)
200 return XvMCBadSurface;
201
202 vl_sfc = surface->privData;
203
204 assert(display == vlGetNativeDisplay(vlGetDisplay(vlSurfaceGetScreen(vl_sfc))));
205
206 vlSurfaceFlush(vl_sfc);
207
208 return Success;
209 }
210
211 Status XvMCSyncSurface(Display *display, XvMCSurface *surface)
212 {
213 struct vlSurface *vl_sfc;
214
215 assert(display);
216
217 if (!surface)
218 return XvMCBadSurface;
219
220 vl_sfc = surface->privData;
221
222 assert(display == vlGetNativeDisplay(vlGetDisplay(vlSurfaceGetScreen(vl_sfc))));
223
224 vlSurfaceSync(vl_sfc);
225
226 return Success;
227 }
228
229 Status XvMCPutSurface
230 (
231 Display *display,
232 XvMCSurface *surface,
233 Drawable drawable,
234 short srcx,
235 short srcy,
236 unsigned short srcw,
237 unsigned short srch,
238 short destx,
239 short desty,
240 unsigned short destw,
241 unsigned short desth,
242 int flags
243 )
244 {
245 Window root;
246 int x, y;
247 unsigned int width, height;
248 unsigned int border_width;
249 unsigned int depth;
250 struct vlSurface *vl_sfc;
251
252 assert(display);
253
254 if (!surface)
255 return XvMCBadSurface;
256
257 if (XGetGeometry(display, drawable, &root, &x, &y, &width, &height, &border_width, &depth) == BadDrawable)
258 return BadDrawable;
259
260 assert(flags == XVMC_TOP_FIELD || flags == XVMC_BOTTOM_FIELD || flags == XVMC_FRAME_PICTURE);
261
262 /* TODO: Correct for negative srcx,srcy & destx,desty by clipping */
263
264 assert(srcx + srcw - 1 < surface->width);
265 assert(srcy + srch - 1 < surface->height);
266 /* XXX: Some apps (mplayer) hit these asserts because they call
267 * this function after the window has been resized by the WM
268 * but before they've handled the corresponding XEvent and
269 * know about the new dimensions. The output will be clipped
270 * for a few frames until the app updates destw and desth.
271 */
272 /*assert(destx + destw - 1 < width);
273 assert(desty + desth - 1 < height);*/
274
275 vl_sfc = surface->privData;
276
277 vlPutPicture(vl_sfc, drawable, srcx, srcy, srcw, srch, destx, desty, destw, desth, width, height, PictureToVL(flags));
278
279 return Success;
280 }
281
282 Status XvMCGetSurfaceStatus(Display *display, XvMCSurface *surface, int *status)
283 {
284 struct vlSurface *vl_sfc;
285 enum vlResourceStatus res_status;
286
287 assert(display);
288
289 if (!surface)
290 return XvMCBadSurface;
291
292 assert(status);
293
294 vl_sfc = surface->privData;
295
296 assert(display == vlGetNativeDisplay(vlGetDisplay(vlSurfaceGetScreen(vl_sfc))));
297
298 vlSurfaceGetStatus(vl_sfc, &res_status);
299
300 switch (res_status)
301 {
302 case vlResourceStatusFree:
303 {
304 *status = 0;
305 break;
306 }
307 case vlResourceStatusRendering:
308 {
309 *status = XVMC_RENDERING;
310 break;
311 }
312 case vlResourceStatusDisplaying:
313 {
314 *status = XVMC_DISPLAYING;
315 break;
316 }
317 default:
318 assert(0);
319 }
320
321 return Success;
322 }
323
324 Status XvMCDestroySurface(Display *display, XvMCSurface *surface)
325 {
326 struct vlSurface *vl_sfc;
327
328 assert(display);
329
330 if (!surface)
331 return XvMCBadSurface;
332
333 vl_sfc = surface->privData;
334
335 assert(display == vlGetNativeDisplay(vlGetDisplay(vlSurfaceGetScreen(vl_sfc))));
336
337 vlDestroySurface(vl_sfc);
338
339 return Success;
340 }
341
342 Status XvMCHideSurface(Display *display, XvMCSurface *surface)
343 {
344 struct vlSurface *vl_sfc;
345
346 assert(display);
347
348 if (!surface)
349 return XvMCBadSurface;
350
351 vl_sfc = surface->privData;
352
353 assert(display == vlGetNativeDisplay(vlGetDisplay(vlSurfaceGetScreen(vl_sfc))));
354
355 /* No op, only for overlaid rendering */
356
357 return Success;
358 }