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
)
45 switch (xvmc_motion_type
)
47 case XVMC_PREDICTION_FRAME
:
48 return 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
))));
78 vlContextGetScreen(vl_ctx
),
81 vlGetPictureFormat(vl_ctx
),
85 vlBindToContext(vl_sfc
, vl_ctx
);
87 surface
->surface_id
= XAllocID(display
);
88 surface
->context_id
= context
->context_id
;
89 surface
->surface_type_id
= context
->surface_type_id
;
90 surface
->width
= context
->width
;
91 surface
->height
= context
->height
;
92 surface
->privData
= vl_sfc
;
97 Status XvMCRenderSurface
100 XvMCContext
*context
,
101 unsigned int picture_structure
,
102 XvMCSurface
*target_surface
,
103 XvMCSurface
*past_surface
,
104 XvMCSurface
*future_surface
,
106 unsigned int num_macroblocks
,
107 unsigned int first_macroblock
,
108 XvMCMacroBlockArray
*macroblocks
,
109 XvMCBlockArray
*blocks
112 struct vlContext
*vl_ctx
;
113 struct vlSurface
*target_vl_surface
;
114 struct vlSurface
*past_vl_surface
;
115 struct vlSurface
*future_vl_surface
;
116 struct vlMpeg2MacroBlockBatch batch
;
117 struct vlMpeg2MacroBlock vl_macroblocks
[num_macroblocks
];
123 return XvMCBadContext
;
125 return XvMCBadSurface
;
129 picture_structure
!= XVMC_TOP_FIELD
&&
130 picture_structure
!= XVMC_BOTTOM_FIELD
&&
131 picture_structure
!= XVMC_FRAME_PICTURE
134 if (future_surface
&& !past_surface
)
137 vl_ctx
= context
->privData
;
139 assert(display
== vlGetNativeDisplay(vlGetDisplay(vlContextGetScreen(vl_ctx
))));
141 target_vl_surface
= target_surface
->privData
;
142 past_vl_surface
= past_surface
? past_surface
->privData
: NULL
;
143 future_vl_surface
= future_surface
? future_surface
->privData
: NULL
;
145 assert(context
->context_id
== target_surface
->context_id
);
146 assert(!past_surface
|| context
->context_id
== past_surface
->context_id
);
147 assert(!future_surface
|| context
->context_id
== future_surface
->context_id
);
152 assert(macroblocks
->context_id
== context
->context_id
);
153 assert(blocks
->context_id
== context
->context_id
);
155 assert(flags
== 0 || flags
== XVMC_SECOND_FIELD
);
157 batch
.past_surface
= past_vl_surface
;
158 batch
.future_surface
= future_vl_surface
;
159 batch
.picture_type
= PictureToVL(picture_structure
);
160 batch
.field_order
= flags
& XVMC_SECOND_FIELD
? vlFieldOrderSecond
: vlFieldOrderFirst
;
161 batch
.num_macroblocks
= num_macroblocks
;
162 batch
.macroblocks
= vl_macroblocks
;
164 for (i
= 0; i
< num_macroblocks
; ++i
)
166 unsigned int j
= first_macroblock
+ i
;
168 unsigned int k
, l
, m
;
170 batch
.macroblocks
[i
].mbx
= macroblocks
->macro_blocks
[j
].x
;
171 batch
.macroblocks
[i
].mby
= macroblocks
->macro_blocks
[j
].y
;
172 batch
.macroblocks
[i
].mb_type
= TypeToVL(macroblocks
->macro_blocks
[j
].macroblock_type
);
173 if (batch
.macroblocks
[i
].mb_type
!= vlMacroBlockTypeIntra
)
174 batch
.macroblocks
[i
].mo_type
= MotionToVL(macroblocks
->macro_blocks
[j
].motion_type
);
175 batch
.macroblocks
[i
].dct_type
= macroblocks
->macro_blocks
[j
].dct_type
& XVMC_DCT_TYPE_FIELD
? vlDCTTypeFieldCoded
: vlDCTTypeFrameCoded
;
177 for (k
= 0; k
< 2; ++k
)
178 for (l
= 0; l
< 2; ++l
)
179 for (m
= 0; m
< 2; ++m
)
180 batch
.macroblocks
[i
].PMV
[k
][l
][m
] = macroblocks
->macro_blocks
[j
].PMV
[k
][l
][m
];
182 batch
.macroblocks
[i
].cbp
= macroblocks
->macro_blocks
[j
].coded_block_pattern
;
183 batch
.macroblocks
[i
].blocks
= blocks
->blocks
+ (macroblocks
->macro_blocks
[j
].index
* 64);
186 vlRenderMacroBlocksMpeg2(&batch
, target_vl_surface
);
191 Status
XvMCFlushSurface(Display
*display
, XvMCSurface
*surface
)
193 struct vlSurface
*vl_sfc
;
198 return XvMCBadSurface
;
200 vl_sfc
= surface
->privData
;
202 assert(display
== vlGetNativeDisplay(vlGetDisplay(vlSurfaceGetScreen(vl_sfc
))));
209 Status
XvMCSyncSurface(Display
*display
, XvMCSurface
*surface
)
211 struct vlSurface
*vl_sfc
;
216 return XvMCBadSurface
;
218 vl_sfc
= surface
->privData
;
220 assert(display
== vlGetNativeDisplay(vlGetDisplay(vlSurfaceGetScreen(vl_sfc
))));
227 Status XvMCPutSurface
230 XvMCSurface
*surface
,
238 unsigned short destw
,
239 unsigned short desth
,
245 unsigned int width
, height
;
246 unsigned int border_width
;
248 struct vlSurface
*vl_sfc
;
253 return XvMCBadSurface
;
255 if (XGetGeometry(display
, drawable
, &root
, &x
, &y
, &width
, &height
, &border_width
, &depth
) == BadDrawable
)
258 assert(flags
== XVMC_TOP_FIELD
|| flags
== XVMC_BOTTOM_FIELD
|| flags
== XVMC_FRAME_PICTURE
);
260 /* TODO: Correct for negative srcx,srcy & destx,desty by clipping */
262 assert(srcx
+ srcw
- 1 < surface
->width
);
263 assert(srcy
+ srch
- 1 < surface
->height
);
264 assert(destx
+ destw
- 1 < width
);
265 assert(desty
+ desth
- 1 < height
);
267 vl_sfc
= surface
->privData
;
269 vlPutPicture(vl_sfc
, drawable
, srcx
, srcy
, srcw
, srch
, destx
, desty
, destw
, desth
, PictureToVL(flags
));
274 Status
XvMCGetSurfaceStatus(Display
*display
, XvMCSurface
*surface
, int *status
)
276 struct vlSurface
*vl_sfc
;
281 return XvMCBadSurface
;
285 vl_sfc
= surface
->privData
;
287 assert(display
== vlGetNativeDisplay(vlGetDisplay(vlSurfaceGetScreen(vl_sfc
))));
295 Status
XvMCDestroySurface(Display
*display
, XvMCSurface
*surface
)
297 struct vlSurface
*vl_sfc
;
302 return XvMCBadSurface
;
304 vl_sfc
= surface
->privData
;
306 assert(display
== vlGetNativeDisplay(vlGetDisplay(vlSurfaceGetScreen(vl_sfc
))));
308 vlDestroySurface(vl_sfc
);
313 Status
XvMCHideSurface(Display
*display
, XvMCSurface
*surface
)
315 struct vlSurface
*vl_sfc
;
320 return XvMCBadSurface
;
322 vl_sfc
= surface
->privData
;
324 assert(display
== vlGetNativeDisplay(vlGetDisplay(vlSurfaceGetScreen(vl_sfc
))));
326 /* No op, only for overlaid rendering */