3 #include <X11/extensions/XvMC.h>
4 #include <vl_display.h>
6 #include <vl_context.h>
7 #include <vl_surface.h>
10 static enum vlMacroBlockType
TypeToVL(int xvmc_mb_type
)
12 if (xvmc_mb_type
& XVMC_MB_TYPE_INTRA
)
13 return vlMacroBlockTypeIntra
;
14 if ((xvmc_mb_type
& (XVMC_MB_TYPE_MOTION_FORWARD
| XVMC_MB_TYPE_MOTION_BACKWARD
)) == XVMC_MB_TYPE_MOTION_FORWARD
)
15 return vlMacroBlockTypeFwdPredicted
;
16 if ((xvmc_mb_type
& (XVMC_MB_TYPE_MOTION_FORWARD
| XVMC_MB_TYPE_MOTION_BACKWARD
)) == XVMC_MB_TYPE_MOTION_BACKWARD
)
17 return vlMacroBlockTypeBkwdPredicted
;
18 if ((xvmc_mb_type
& (XVMC_MB_TYPE_MOTION_FORWARD
| XVMC_MB_TYPE_MOTION_BACKWARD
)) == (XVMC_MB_TYPE_MOTION_FORWARD
| XVMC_MB_TYPE_MOTION_BACKWARD
))
19 return vlMacroBlockTypeBiPredicted
;
26 static enum vlPictureType
PictureToVL(int xvmc_pic
)
31 return vlPictureTypeTopField
;
32 case XVMC_BOTTOM_FIELD
:
33 return vlPictureTypeBottomField
;
34 case XVMC_FRAME_PICTURE
:
35 return vlPictureTypeFrame
;
43 static enum vlMotionType
MotionToVL(int xvmc_motion_type
, int xvmc_dct_type
)
45 switch (xvmc_motion_type
)
47 case XVMC_PREDICTION_FRAME
:
48 return xvmc_dct_type
== XVMC_DCT_TYPE_FIELD
? vlMotionType16x8
: vlMotionTypeFrame
;
49 case XVMC_PREDICTION_FIELD
:
50 return vlMotionTypeField
;
51 case XVMC_PREDICTION_DUAL_PRIME
:
52 return vlMotionTypeDualPrime
;
60 Status
XvMCCreateSurface(Display
*display
, XvMCContext
*context
, XvMCSurface
*surface
)
62 struct vlContext
*vl_ctx
;
63 struct vlSurface
*vl_sfc
;
68 return XvMCBadContext
;
70 return XvMCBadSurface
;
72 vl_ctx
= context
->privData
;
74 assert(display
== vlGetNativeDisplay(vlGetDisplay(vlContextGetScreen(vl_ctx
))));
76 if (vlCreateSurface(vlContextGetScreen(vl_ctx
),
77 context
->width
, context
->height
,
78 vlGetPictureFormat(vl_ctx
),
84 vlBindToContext(vl_sfc
, vl_ctx
);
86 surface
->surface_id
= XAllocID(display
);
87 surface
->context_id
= context
->context_id
;
88 surface
->surface_type_id
= context
->surface_type_id
;
89 surface
->width
= context
->width
;
90 surface
->height
= context
->height
;
91 surface
->privData
= vl_sfc
;
96 Status XvMCRenderSurface
100 unsigned int picture_structure
,
101 XvMCSurface
*target_surface
,
102 XvMCSurface
*past_surface
,
103 XvMCSurface
*future_surface
,
105 unsigned int num_macroblocks
,
106 unsigned int first_macroblock
,
107 XvMCMacroBlockArray
*macroblocks
,
108 XvMCBlockArray
*blocks
111 struct vlContext
*vl_ctx
;
112 struct vlSurface
*target_vl_surface
;
113 struct vlSurface
*past_vl_surface
;
114 struct vlSurface
*future_vl_surface
;
115 struct vlMpeg2MacroBlockBatch batch
;
116 struct vlMpeg2MacroBlock vl_macroblocks
[num_macroblocks
];
122 return XvMCBadContext
;
124 return XvMCBadSurface
;
128 picture_structure
!= XVMC_TOP_FIELD
&&
129 picture_structure
!= XVMC_BOTTOM_FIELD
&&
130 picture_structure
!= XVMC_FRAME_PICTURE
133 if (future_surface
&& !past_surface
)
136 vl_ctx
= context
->privData
;
138 assert(display
== vlGetNativeDisplay(vlGetDisplay(vlContextGetScreen(vl_ctx
))));
140 target_vl_surface
= target_surface
->privData
;
141 past_vl_surface
= past_surface
? past_surface
->privData
: NULL
;
142 future_vl_surface
= future_surface
? future_surface
->privData
: NULL
;
144 assert(context
->context_id
== target_surface
->context_id
);
145 assert(!past_surface
|| context
->context_id
== past_surface
->context_id
);
146 assert(!future_surface
|| context
->context_id
== future_surface
->context_id
);
151 assert(macroblocks
->context_id
== context
->context_id
);
152 assert(blocks
->context_id
== context
->context_id
);
154 assert(flags
== 0 || flags
== XVMC_SECOND_FIELD
);
156 batch
.past_surface
= past_vl_surface
;
157 batch
.future_surface
= future_vl_surface
;
158 batch
.picture_type
= PictureToVL(picture_structure
);
159 batch
.field_order
= flags
& XVMC_SECOND_FIELD
? vlFieldOrderSecond
: vlFieldOrderFirst
;
160 batch
.num_macroblocks
= num_macroblocks
;
161 batch
.macroblocks
= vl_macroblocks
;
163 for (i
= 0; i
< num_macroblocks
; ++i
)
165 unsigned int j
= first_macroblock
+ i
;
167 unsigned int k
, l
, m
;
169 batch
.macroblocks
[i
].mbx
= macroblocks
->macro_blocks
[j
].x
;
170 batch
.macroblocks
[i
].mby
= macroblocks
->macro_blocks
[j
].y
;
171 batch
.macroblocks
[i
].mb_type
= TypeToVL(macroblocks
->macro_blocks
[j
].macroblock_type
);
172 if (batch
.macroblocks
[i
].mb_type
!= vlMacroBlockTypeIntra
)
173 batch
.macroblocks
[i
].mo_type
= MotionToVL(macroblocks
->macro_blocks
[j
].motion_type
, macroblocks
->macro_blocks
[j
].dct_type
);
174 batch
.macroblocks
[i
].dct_type
= macroblocks
->macro_blocks
[j
].dct_type
== XVMC_DCT_TYPE_FIELD
? vlDCTTypeFieldCoded
: vlDCTTypeFrameCoded
;
176 for (k
= 0; k
< 2; ++k
)
177 for (l
= 0; l
< 2; ++l
)
178 for (m
= 0; m
< 2; ++m
)
179 batch
.macroblocks
[i
].PMV
[k
][l
][m
] = macroblocks
->macro_blocks
[j
].PMV
[k
][l
][m
];
181 batch
.macroblocks
[i
].cbp
= macroblocks
->macro_blocks
[j
].coded_block_pattern
;
182 batch
.macroblocks
[i
].blocks
= blocks
->blocks
+ (macroblocks
->macro_blocks
[j
].index
* 64);
185 vlRenderMacroBlocksMpeg2(&batch
, target_vl_surface
);
190 Status
XvMCFlushSurface(Display
*display
, XvMCSurface
*surface
)
192 struct vlSurface
*vl_sfc
;
197 return XvMCBadSurface
;
199 vl_sfc
= surface
->privData
;
201 assert(display
== vlGetNativeDisplay(vlGetDisplay(vlSurfaceGetScreen(vl_sfc
))));
203 vlSurfaceFlush(vl_sfc
);
208 Status
XvMCSyncSurface(Display
*display
, XvMCSurface
*surface
)
210 struct vlSurface
*vl_sfc
;
215 return XvMCBadSurface
;
217 vl_sfc
= surface
->privData
;
219 assert(display
== vlGetNativeDisplay(vlGetDisplay(vlSurfaceGetScreen(vl_sfc
))));
221 vlSurfaceSync(vl_sfc
);
226 Status XvMCPutSurface
229 XvMCSurface
*surface
,
237 unsigned short destw
,
238 unsigned short desth
,
244 unsigned int width
, height
;
245 unsigned int border_width
;
247 struct vlSurface
*vl_sfc
;
252 return XvMCBadSurface
;
254 if (XGetGeometry(display
, drawable
, &root
, &x
, &y
, &width
, &height
, &border_width
, &depth
) == BadDrawable
)
257 assert(flags
== XVMC_TOP_FIELD
|| flags
== XVMC_BOTTOM_FIELD
|| flags
== XVMC_FRAME_PICTURE
);
259 /* TODO: Correct for negative srcx,srcy & destx,desty by clipping */
261 assert(srcx
+ srcw
- 1 < surface
->width
);
262 assert(srcy
+ srch
- 1 < surface
->height
);
263 /* XXX: Some apps (mplayer) hit these asserts because they call
264 * this function after the window has been resized by the WM
265 * but before they've handled the corresponding XEvent and
266 * know about the new dimensions. The output will be clipped
267 * for a few frames until the app updates destw and desth.
269 /*assert(destx + destw - 1 < width);
270 assert(desty + desth - 1 < height);*/
272 vl_sfc
= surface
->privData
;
274 vlPutPicture(vl_sfc
, drawable
, srcx
, srcy
, srcw
, srch
, destx
, desty
, destw
, desth
, width
, height
, PictureToVL(flags
));
279 Status
XvMCGetSurfaceStatus(Display
*display
, XvMCSurface
*surface
, int *status
)
281 struct vlSurface
*vl_sfc
;
282 enum vlResourceStatus res_status
;
287 return XvMCBadSurface
;
291 vl_sfc
= surface
->privData
;
293 assert(display
== vlGetNativeDisplay(vlGetDisplay(vlSurfaceGetScreen(vl_sfc
))));
295 vlSurfaceGetStatus(vl_sfc
, &res_status
);
299 case vlResourceStatusFree
:
304 case vlResourceStatusRendering
:
306 *status
= XVMC_RENDERING
;
309 case vlResourceStatusDisplaying
:
311 *status
= XVMC_DISPLAYING
;
321 Status
XvMCDestroySurface(Display
*display
, XvMCSurface
*surface
)
323 struct vlSurface
*vl_sfc
;
328 return XvMCBadSurface
;
330 vl_sfc
= surface
->privData
;
332 assert(display
== vlGetNativeDisplay(vlGetDisplay(vlSurfaceGetScreen(vl_sfc
))));
334 vlDestroySurface(vl_sfc
);
339 Status
XvMCHideSurface(Display
*display
, XvMCSurface
*surface
)
341 struct vlSurface
*vl_sfc
;
346 return XvMCBadSurface
;
348 vl_sfc
= surface
->privData
;
350 assert(display
== vlGetNativeDisplay(vlGetDisplay(vlSurfaceGetScreen(vl_sfc
))));
352 /* No op, only for overlaid rendering */