3 #include <X11/extensions/XvMC.h>
4 #include <X11/Xlibint.h>
5 #include <vl_display.h>
7 #include <vl_context.h>
8 #include <vl_surface.h>
11 static enum vlMacroBlockType
TypeToVL(int xvmc_mb_type
)
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
;
27 static enum vlPictureType
PictureToVL(int xvmc_pic
)
32 return vlPictureTypeTopField
;
33 case XVMC_BOTTOM_FIELD
:
34 return vlPictureTypeBottomField
;
35 case XVMC_FRAME_PICTURE
:
36 return vlPictureTypeFrame
;
44 static enum vlMotionType
MotionToVL(int xvmc_motion_type
, int xvmc_dct_type
)
46 switch (xvmc_motion_type
)
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
;
61 Status
XvMCCreateSurface(Display
*display
, XvMCContext
*context
, XvMCSurface
*surface
)
63 struct vlContext
*vl_ctx
;
64 struct vlSurface
*vl_sfc
;
65 Display
*dpy
= display
;
70 return XvMCBadContext
;
72 return XvMCBadSurface
;
74 vl_ctx
= context
->privData
;
76 assert(display
== vlGetNativeDisplay(vlGetDisplay(vlContextGetScreen(vl_ctx
))));
78 if (vlCreateSurface(vlContextGetScreen(vl_ctx
),
79 context
->width
, context
->height
,
80 vlGetPictureFormat(vl_ctx
),
86 vlBindToContext(vl_sfc
, vl_ctx
);
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
;
99 Status XvMCRenderSurface
102 XvMCContext
*context
,
103 unsigned int picture_structure
,
104 XvMCSurface
*target_surface
,
105 XvMCSurface
*past_surface
,
106 XvMCSurface
*future_surface
,
108 unsigned int num_macroblocks
,
109 unsigned int first_macroblock
,
110 XvMCMacroBlockArray
*macroblocks
,
111 XvMCBlockArray
*blocks
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
];
125 return XvMCBadContext
;
127 return XvMCBadSurface
;
131 picture_structure
!= XVMC_TOP_FIELD
&&
132 picture_structure
!= XVMC_BOTTOM_FIELD
&&
133 picture_structure
!= XVMC_FRAME_PICTURE
136 if (future_surface
&& !past_surface
)
139 vl_ctx
= context
->privData
;
141 assert(display
== vlGetNativeDisplay(vlGetDisplay(vlContextGetScreen(vl_ctx
))));
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
;
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
);
154 assert(macroblocks
->context_id
== context
->context_id
);
155 assert(blocks
->context_id
== context
->context_id
);
157 assert(flags
== 0 || flags
== XVMC_SECOND_FIELD
);
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
;
166 for (i
= 0; i
< num_macroblocks
; ++i
)
168 unsigned int j
= first_macroblock
+ i
;
170 unsigned int k
, l
, m
;
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
;
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
];
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);
188 vlRenderMacroBlocksMpeg2(&batch
, target_vl_surface
);
193 Status
XvMCFlushSurface(Display
*display
, XvMCSurface
*surface
)
195 struct vlSurface
*vl_sfc
;
200 return XvMCBadSurface
;
202 vl_sfc
= surface
->privData
;
204 assert(display
== vlGetNativeDisplay(vlGetDisplay(vlSurfaceGetScreen(vl_sfc
))));
206 vlSurfaceFlush(vl_sfc
);
211 Status
XvMCSyncSurface(Display
*display
, XvMCSurface
*surface
)
213 struct vlSurface
*vl_sfc
;
218 return XvMCBadSurface
;
220 vl_sfc
= surface
->privData
;
222 assert(display
== vlGetNativeDisplay(vlGetDisplay(vlSurfaceGetScreen(vl_sfc
))));
224 vlSurfaceSync(vl_sfc
);
229 Status XvMCPutSurface
232 XvMCSurface
*surface
,
240 unsigned short destw
,
241 unsigned short desth
,
247 unsigned int width
, height
;
248 unsigned int border_width
;
250 struct vlSurface
*vl_sfc
;
255 return XvMCBadSurface
;
257 if (XGetGeometry(display
, drawable
, &root
, &x
, &y
, &width
, &height
, &border_width
, &depth
) == BadDrawable
)
260 assert(flags
== XVMC_TOP_FIELD
|| flags
== XVMC_BOTTOM_FIELD
|| flags
== XVMC_FRAME_PICTURE
);
262 /* TODO: Correct for negative srcx,srcy & destx,desty by clipping */
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.
272 /*assert(destx + destw - 1 < width);
273 assert(desty + desth - 1 < height);*/
275 vl_sfc
= surface
->privData
;
277 vlPutPicture(vl_sfc
, drawable
, srcx
, srcy
, srcw
, srch
, destx
, desty
, destw
, desth
, width
, height
, PictureToVL(flags
));
282 Status
XvMCGetSurfaceStatus(Display
*display
, XvMCSurface
*surface
, int *status
)
284 struct vlSurface
*vl_sfc
;
285 enum vlResourceStatus res_status
;
290 return XvMCBadSurface
;
294 vl_sfc
= surface
->privData
;
296 assert(display
== vlGetNativeDisplay(vlGetDisplay(vlSurfaceGetScreen(vl_sfc
))));
298 vlSurfaceGetStatus(vl_sfc
, &res_status
);
302 case vlResourceStatusFree
:
307 case vlResourceStatusRendering
:
309 *status
= XVMC_RENDERING
;
312 case vlResourceStatusDisplaying
:
314 *status
= XVMC_DISPLAYING
;
324 Status
XvMCDestroySurface(Display
*display
, XvMCSurface
*surface
)
326 struct vlSurface
*vl_sfc
;
331 return XvMCBadSurface
;
333 vl_sfc
= surface
->privData
;
335 assert(display
== vlGetNativeDisplay(vlGetDisplay(vlSurfaceGetScreen(vl_sfc
))));
337 vlDestroySurface(vl_sfc
);
342 Status
XvMCHideSurface(Display
*display
, XvMCSurface
*surface
)
344 struct vlSurface
*vl_sfc
;
349 return XvMCBadSurface
;
351 vl_sfc
= surface
->privData
;
353 assert(display
== vlGetNativeDisplay(vlGetDisplay(vlSurfaceGetScreen(vl_sfc
))));
355 /* No op, only for overlaid rendering */