1 /*
2 * Copyright (c) 2009-2017, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file media_libva_putsurface_linux.cpp
24 //! \brief libva(and its extension) putsurface linux implementaion
25 //!
26
27 #include <stdio.h>
28 #include <string.h>
29 #include <stdlib.h>
30 #include <stdarg.h>
31
32 #include <fcntl.h> //open
33 #include <sys/stat.h> //fstat
34 #include <unistd.h> //read, lseek
35 #include <dlfcn.h> //dlopen,dlsym,dlclose
36 #include <time.h> //get_clocktime
37 #include <errno.h> //errno
38 #include <assert.h> //assert
39
40 #include <sys/mman.h>
41 #include <dlfcn.h>
42 #include <sys/ioctl.h>
43 #include <X11/Xlib.h>
44 #include <X11/Xutil.h>
45
46 #include "media_libva_putsurface_linux.h"
47 #include "media_libva_util.h"
48 #include "media_libva_common.h"
49 #include "media_libva_vp.h"
50
51 extern MOS_FORMAT VpGetFormatFromMediaFormat(DDI_MEDIA_FORMAT mf);
52 extern VPHAL_CSPACE DdiVp_GetColorSpaceFromMediaFormat(DDI_MEDIA_FORMAT mf);
53 extern MOS_TILE_TYPE VpGetTileTypeFromMediaTileType(uint32_t mediaTileType);
54
55 /* Closes and disposed any allocated data */
dso_close(struct dso_handle * h)56 void dso_close(struct dso_handle *h)
57 {
58 if (!h){
59 return;
60 }
61
62 if (h->handle) {
63 if (h->handle != RTLD_DEFAULT)
64 dlclose(h->handle);
65 h->handle = nullptr;
66 }
67 free(h);
68 }
69
70 /* Opens the named shared library */
dso_open(const char * path)71 struct dso_handle * dso_open(const char *path)
72 {
73 struct dso_handle *h = nullptr;
74
75 h = (dso_handle *)calloc(1, sizeof(*h));
76 if (!h){
77 return nullptr;
78 }
79
80 if (path) {
81 h->handle = dlopen(path, RTLD_LAZY|RTLD_LOCAL);
82 if (!h->handle)
83 goto error;
84 }
85 else{
86 h->handle = RTLD_DEFAULT;
87 }
88 return h;
89
90 error:
91 dso_close(h);
92 return nullptr;
93 }
94
95 /* Load function name from one dynamic lib */
get_symbol(struct dso_handle * h,void * func_vptr,const char * name)96 static bool get_symbol(struct dso_handle *h, void *func_vptr, const char *name)
97 {
98 DDI_CHK_NULL(h, "nullptr h", false);
99 DDI_CHK_NULL(func_vptr, "nullptr func_vptr", false);
100
101 dso_generic_func func;
102 dso_generic_func * const func_ptr = (dso_generic_func*) func_vptr;
103 const char *error = nullptr;
104
105 dlerror();
106 func = (dso_generic_func)dlsym(h->handle, name);
107 error = dlerror();
108 if (error) {
109 fprintf(stderr, "error: failed to resolve %s(): %s\n", name, error);
110 return false;
111 }
112 *func_ptr = func;
113 return true;
114 }
115
116 //!
117 //! \brief Loads function name from vtable
118 //!
119 //! \param [in] h
120 //! Dso handle
121 //! \param [in] vtable
122 //! VA api table
123 //! \param [in] vtable_length
124 //! Length of VA api table
125 //! \param [in] symbols
126 //! Dso symbol
127 //!
128 //! \return bool
129 //! true if call success, else false
130 //!
131 bool
dso_get_symbols(struct dso_handle * h,void * vtable,uint32_t vtable_length,const struct dso_symbol * symbols)132 dso_get_symbols(
133 struct dso_handle *h,
134 void *vtable,
135 uint32_t vtable_length,
136 const struct dso_symbol *symbols
137 )
138 {
139 DDI_CHK_NULL(h, "nullptr h", false);
140
141 const struct dso_symbol *s = nullptr;
142 if (nullptr == symbols)
143 {
144 return VA_STATUS_ERROR_INVALID_PARAMETER;
145 }
146 for (s = symbols; s->name != nullptr; s++) {
147 if (s->offset + sizeof(dso_generic_func) > vtable_length)
148 return false;
149 if (!get_symbol(h, ((char *)vtable) + s->offset, s->name))
150 return false;
151 }
152 return true;
153 }
154
output_dri_init(VADriverContextP ctx)155 bool output_dri_init(VADriverContextP ctx)
156 {
157 DDI_CHK_NULL(ctx, "nullptr ctx", false);
158
159 PDDI_MEDIA_CONTEXT mediaDrvCtx = nullptr;
160 mediaDrvCtx = DdiMedia_GetMediaContext(ctx);
161 DDI_CHK_NULL(mediaDrvCtx, "nullptr ctx", false);
162
163 struct dso_handle *dso_handle = nullptr;
164 struct dri_vtable *dri_vtable = nullptr;
165
166 mediaDrvCtx->dri_output = nullptr;
167
168 static const struct dso_symbol symbols[] = {
169 { "va_dri_get_drawable",
170 offsetof(struct dri_vtable, get_drawable) },
171 { "va_dri_get_rendering_buffer",
172 offsetof(struct dri_vtable, get_rendering_buffer) },
173 { "va_dri_swap_buffer",
174 offsetof(struct dri_vtable, swap_buffer) },
175 { nullptr, }
176 };
177
178 mediaDrvCtx->dri_output = (va_dri_output*) calloc(1, sizeof(struct va_dri_output));
179 if (!mediaDrvCtx->dri_output){
180 goto error;
181 }
182
183 mediaDrvCtx->dri_output->handle = dso_open(LIBVA_X11_NAME);
184 if (!mediaDrvCtx->dri_output->handle){
185 free(mediaDrvCtx->dri_output);
186 mediaDrvCtx->dri_output = nullptr;
187 goto error;
188 }
189
190 dso_handle = mediaDrvCtx->dri_output->handle;
191 dri_vtable = &mediaDrvCtx->dri_output->vtable;
192 if (!dso_get_symbols(dso_handle, dri_vtable, sizeof(*dri_vtable), symbols)){
193 dso_close(mediaDrvCtx->dri_output->handle);
194 free(mediaDrvCtx->dri_output);
195 mediaDrvCtx->dri_output = nullptr;
196 goto error;
197 }
198 return true;
199
200 error:
201 return false;
202 }
203
204 void
Rect_init(RECT * rect,int16_t destx,int16_t desty,uint16_t destw,uint16_t desth)205 inline Rect_init(
206 RECT *rect,
207 int16_t destx,
208 int16_t desty,
209 uint16_t destw,
210 uint16_t desth
211 )
212 {
213 if (nullptr == rect)
214 {
215 return;
216 }
217 rect->left = destx;
218 rect->top = desty;
219 rect->right = destx + destw;
220 rect->bottom = desty + desth;
221 }
222
DdiCodec_PutSurfaceLinuxVphalExt(VADriverContextP ctx,VASurfaceID surface,void * draw,int16_t srcx,int16_t srcy,uint16_t srcw,uint16_t srch,int16_t destx,int16_t desty,uint16_t destw,uint16_t desth,VARectangle * cliprects,uint32_t number_cliprects,uint32_t flags)223 VAStatus DdiCodec_PutSurfaceLinuxVphalExt(
224 VADriverContextP ctx,
225 VASurfaceID surface,
226 void *draw, /* Drawable of window system */
227 int16_t srcx,
228 int16_t srcy,
229 uint16_t srcw,
230 uint16_t srch,
231 int16_t destx,
232 int16_t desty,
233 uint16_t destw,
234 uint16_t desth,
235 VARectangle *cliprects, /* client supplied clip list */
236 uint32_t number_cliprects, /* number of clip rects in the clip list */
237 uint32_t flags /* de-interlacing flags */
238 )
239 {
240 GC gc;
241 int32_t depth;
242 Visual* visual;
243 XImage* ximg;
244 int32_t surf_width;
245 int32_t surf_height;
246 PDDI_MEDIA_CONTEXT mediaDrvCtx;
247 PDDI_MEDIA_SURFACE dstSurfBuffObj;
248
249 TypeXCreateGC pfn_XCreateGC = nullptr;
250 TypeXFreeGC pfn_XFreeGC = nullptr;
251 TypeXCreateImage pfn_XCreateImage = nullptr;
252 TypeXDestroyImage pfn_XDestroyImage = nullptr;
253 TypeXPutImage pfn_XPutImage = nullptr;
254
255 if (nullptr == draw)
256 {
257 return VA_STATUS_ERROR_UNKNOWN;
258 }
259
260 visual = nullptr;
261 ximg = nullptr;
262 mediaDrvCtx = DdiMedia_GetMediaContext(ctx);
263 dstSurfBuffObj = DdiMedia_GetSurfaceFromVASurfaceID(mediaDrvCtx, surface);
264
265 if (nullptr == dstSurfBuffObj)
266 {
267 return VA_STATUS_ERROR_UNKNOWN;
268 }
269
270 if (nullptr == mediaDrvCtx->X11FuncTable ||
271 nullptr == mediaDrvCtx->X11FuncTable->pfnXCreateGC ||
272 nullptr == mediaDrvCtx->X11FuncTable->pfnXFreeGC ||
273 nullptr == mediaDrvCtx->X11FuncTable->pfnXCreateImage ||
274 nullptr == mediaDrvCtx->X11FuncTable->pfnXDestroyImage ||
275 nullptr == mediaDrvCtx->X11FuncTable->pfnXPutImage)
276 {
277 return VA_STATUS_ERROR_UNKNOWN;
278 }
279
280 pfn_XCreateGC = (TypeXCreateGC)(mediaDrvCtx->X11FuncTable->pfnXCreateGC);
281 pfn_XFreeGC = (TypeXFreeGC)(mediaDrvCtx->X11FuncTable->pfnXFreeGC);
282 pfn_XCreateImage = (TypeXCreateImage)(mediaDrvCtx->X11FuncTable->pfnXCreateImage);
283 pfn_XDestroyImage = (TypeXDestroyImage)(mediaDrvCtx->X11FuncTable->pfnXDestroyImage);
284 pfn_XPutImage = (TypeXPutImage)(mediaDrvCtx->X11FuncTable->pfnXPutImage);
285
286 surf_width = dstSurfBuffObj->iWidth;
287 surf_height = dstSurfBuffObj->iHeight;
288
289 visual = DefaultVisual(ctx->native_dpy, ctx->x11_screen);
290 gc = (*pfn_XCreateGC)((Display*)ctx->native_dpy, (Drawable)draw, 0, nullptr);
291 depth = DefaultDepth(ctx->native_dpy, ctx->x11_screen);
292
293 if (TrueColor != visual->c_class)
294 {
295 DDI_ASSERTMESSAGE("Default visual of X display must be TrueColor.");
296 (*pfn_XFreeGC)((Display*)ctx->native_dpy, gc);
297 return VA_STATUS_ERROR_UNKNOWN;
298 }
299
300 ximg = (*pfn_XCreateImage)((Display*)ctx->native_dpy, visual, depth, ZPixmap, 0, nullptr,surf_width, surf_height, 32, 0 );
301
302 if (nullptr == ximg)
303 {
304 return VA_STATUS_ERROR_ALLOCATION_FAILED;
305 }
306
307 if (ximg->bits_per_pixel != 32)
308 {
309 DDI_ASSERTMESSAGE("Display uses %d bits/pixel this not supported.",ximg->bits_per_pixel);
310 (*pfn_XDestroyImage)(ximg);
311 (*pfn_XFreeGC)((Display*)ctx->native_dpy, gc);
312 return VA_STATUS_ERROR_UNKNOWN;
313 }
314
315 ximg->data = (char *)DdiMediaUtil_LockSurface(dstSurfBuffObj, (MOS_LOCKFLAG_READONLY | MOS_LOCKFLAG_WRITEONLY));
316
317 if (nullptr == ximg->data)
318 {
319 DdiMediaUtil_UnlockSurface(dstSurfBuffObj);
320 (*pfn_XDestroyImage)(ximg);
321 (*pfn_XFreeGC)((Display*)ctx->native_dpy, gc);
322 return VA_STATUS_ERROR_ALLOCATION_FAILED;
323 }
324
325 (*pfn_XPutImage)((Display*)ctx->native_dpy, (Drawable)draw, gc, ximg, 0, 0, destx, desty, surf_width, surf_height);
326
327 DdiMediaUtil_UnlockSurface(dstSurfBuffObj);
328 ximg->data = nullptr;
329
330 if (nullptr != ximg)
331 {
332 (*pfn_XDestroyImage)(ximg);
333 }
334
335 (*pfn_XFreeGC)((Display*)ctx->native_dpy, gc);
336
337 return VA_STATUS_SUCCESS;
338 }
339
DdiCodec_PutSurfaceLinuxHW(VADriverContextP ctx,VASurfaceID surface,void * draw,int16_t srcx,int16_t srcy,uint16_t srcw,uint16_t srch,int16_t destx,int16_t desty,uint16_t destw,uint16_t desth,VARectangle * cliprects,uint32_t number_cliprects,uint32_t flags)340 VAStatus DdiCodec_PutSurfaceLinuxHW(
341 VADriverContextP ctx,
342 VASurfaceID surface,
343 void* draw, /* Drawable of window system */
344 int16_t srcx,
345 int16_t srcy,
346 uint16_t srcw,
347 uint16_t srch,
348 int16_t destx,
349 int16_t desty,
350 uint16_t destw,
351 uint16_t desth,
352 VARectangle *cliprects, /* client supplied clip list */
353 uint32_t number_cliprects, /* number of clip rects in the clip list */
354 uint32_t flags /* de-interlacing flags */
355 )
356 {
357 VpBase *vpHal = nullptr;
358 int32_t ovRenderIndex = 0;
359 VPHAL_SURFACE Surf;
360 VPHAL_SURFACE target;
361 VPHAL_RENDER_PARAMS renderParams;
362 VPHAL_COLORFILL_PARAMS colorFill;
363
364 MOS_STATUS eStatus = MOS_STATUS_INVALID_PARAMETER;
365 RECT srcRect = { 0, 0, 0, 0 };
366 RECT dstRect = { 0, 0, 0, 0 };
367 PDDI_MEDIA_CONTEXT mediaCtx;
368 PDDI_MEDIA_SURFACE bufferObject;
369 uint32_t width,height,pitch;
370 uint32_t drawable_tiling_mode;
371 uint32_t drawable_swizzle_mode;
372 MOS_ALLOC_GFXRES_PARAMS allocParams;
373 MOS_TILE_TYPE tileType;
374
375 uint32_t ctxType;
376 PDDI_VP_CONTEXT vpCtx;
377 struct dri_drawable* dri_drawable = nullptr;
378 union dri_buffer* buffer = nullptr;
379
380 GMM_RESCREATE_PARAMS gmmParams;
381
382 mediaCtx = DdiMedia_GetMediaContext(ctx);
383 DDI_CHK_NULL(mediaCtx, "Null mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT);
384 DDI_CHK_NULL(mediaCtx->dri_output, "Null mediaDrvCtx->dri_output", VA_STATUS_ERROR_INVALID_PARAMETER);
385 DDI_CHK_NULL(mediaCtx->pSurfaceHeap, "Null mediaDrvCtx->pSurfaceHeap", VA_STATUS_ERROR_INVALID_PARAMETER);
386 DDI_CHK_NULL(mediaCtx->pGmmClientContext, "Null mediaCtx->pGmmClientContext", VA_STATUS_ERROR_INVALID_PARAMETER);
387 DDI_CHK_LESS((uint32_t)surface, mediaCtx->pSurfaceHeap->uiAllocatedHeapElements, "Invalid surfaceId", VA_STATUS_ERROR_INVALID_SURFACE);
388
389 struct dri_vtable * const dri_vtable = &mediaCtx->dri_output->vtable;
390 DDI_CHK_NULL(dri_vtable, "Null dri_vtable", VA_STATUS_ERROR_INVALID_PARAMETER);
391
392 dri_drawable = dri_vtable->get_drawable(ctx, (Drawable)draw);
393 DDI_CHK_NULL(dri_drawable, "Null dri_drawable", VA_STATUS_ERROR_INVALID_PARAMETER);
394 buffer = dri_vtable->get_rendering_buffer(ctx, dri_drawable);
395 DDI_CHK_NULL(buffer, "Null buffer", VA_STATUS_ERROR_INVALID_PARAMETER);
396
397 bufferObject = DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, surface);
398 DDI_CHK_NULL(bufferObject, "Null bufferObject", VA_STATUS_ERROR_INVALID_SURFACE);
399 DdiMediaUtil_MediaPrintFps();
400 pitch = bufferObject->iPitch;
401
402 vpCtx = nullptr;
403 if (nullptr != mediaCtx->pVpCtxHeap->pHeapBase)
404 {
405 vpCtx = (PDDI_VP_CONTEXT)DdiMedia_GetContextFromContextID(ctx, (VAContextID)(0 + DDI_MEDIA_VACONTEXTID_OFFSET_VP), &ctxType);
406 DDI_CHK_NULL(vpCtx, "Null vpCtx", VA_STATUS_ERROR_INVALID_PARAMETER);
407 vpHal = vpCtx->pVpHal;
408 DDI_CHK_NULL(vpHal, "Null vpHal", VA_STATUS_ERROR_INVALID_PARAMETER);
409 }
410 else
411 {
412 return VA_STATUS_ERROR_INVALID_CONTEXT;
413 }
414
415 // Zero memory
416 MOS_ZeroMemory(&Surf, sizeof(Surf));
417 MOS_ZeroMemory(&target, sizeof(target));
418 MOS_ZeroMemory(&renderParams, sizeof(renderParams));
419 MOS_ZeroMemory(&gmmParams, sizeof(gmmParams));
420
421 renderParams.Component = COMPONENT_LibVA;
422
423 //Init source rectangle
424 Rect_init(&srcRect, srcx, srcy, srcw, srch);
425 Rect_init(&dstRect, destx, desty, destw, desth);
426
427 if( destx + destw > dri_drawable->x + dri_drawable->width )
428 {
429 //return VA_STATUS_ERROR_INVALID_PARAMETER;
430 dstRect.right = dri_drawable->x + dri_drawable->width - destx;
431 if(dstRect.right <= 0)
432 {
433 return VA_STATUS_SUCCESS;
434 }
435 }
436 if(desty + desth > dri_drawable->y + dri_drawable->height)
437 {
438 dstRect.bottom = dri_drawable->y + dri_drawable->height - desty;
439 if(dstRect.bottom <= 0)
440 {
441 return VA_STATUS_SUCCESS;
442 }
443 }
444 // Source Surface Information
445 Surf.Format = VpGetFormatFromMediaFormat(bufferObject->format); // Surface format
446 Surf.SurfType = SURF_IN_PRIMARY; // Surface type (context)
447 Surf.SampleType = SAMPLE_PROGRESSIVE;
448 Surf.ScalingMode = VPHAL_SCALING_AVS;
449
450 Surf.OsResource.Format = VpGetFormatFromMediaFormat(bufferObject->format);
451 Surf.OsResource.iWidth = bufferObject->iWidth;
452 Surf.OsResource.iHeight = bufferObject->iHeight;
453 Surf.OsResource.iPitch = bufferObject->iPitch;
454 Surf.OsResource.iCount = 0;
455 Surf.OsResource.TileType = VpGetTileTypeFromMediaTileType(bufferObject->TileType);
456 Surf.OsResource.bMapped = bufferObject->bMapped;
457 Surf.OsResource.bo = bufferObject->bo;
458 Surf.OsResource.pGmmResInfo = bufferObject->pGmmResourceInfo;
459
460 Surf.dwWidth = bufferObject->iWidth;
461 Surf.dwHeight = bufferObject->iHeight;
462 Surf.dwPitch = bufferObject->iPitch;
463 Surf.TileType = VpGetTileTypeFromMediaTileType(bufferObject->TileType);
464 Surf.ColorSpace = DdiVp_GetColorSpaceFromMediaFormat(bufferObject->format);
465 Surf.ExtendedGamut = false;
466 Surf.rcSrc = srcRect;
467 Surf.rcDst = dstRect;
468
469 MOS_LINUX_BO* drawable_bo = mos_bo_create_from_name(mediaCtx->pDrmBufMgr, "rendering buffer", buffer->dri2.name);
470
471
472 if (nullptr == drawable_bo)
473 {
474 return VA_STATUS_ERROR_ALLOCATION_FAILED;
475 }
476
477 if (!mos_bo_get_tiling(drawable_bo, &drawable_tiling_mode, &drawable_swizzle_mode))
478 {
479 switch (drawable_tiling_mode)
480 {
481 case TILING_Y:
482 tileType = MOS_TILE_Y;
483 break;
484 case TILING_X:
485 tileType = MOS_TILE_X;
486 gmmParams.Flags.Info.TiledX = true;
487 break;
488 case TILING_NONE:
489 tileType = MOS_TILE_LINEAR;
490 gmmParams.Flags.Info.Linear = true;
491 break;
492 default:
493 drawable_tiling_mode = TILING_NONE;
494 tileType = MOS_TILE_LINEAR;
495 gmmParams.Flags.Info.Linear = true;
496 break;
497 }
498 }
499 else
500 {
501 target.OsResource.TileType = (MOS_TILE_TYPE)TILING_NONE;
502 tileType = MOS_TILE_LINEAR;
503 gmmParams.Flags.Info.Linear = true;
504 }
505 gmmParams.Flags.Info.LocalOnly = MEDIA_IS_SKU(&mediaCtx->SkuTable, FtrLocalMemory);
506
507 target.Format = Format_A8R8G8B8;
508 target.SurfType = SURF_OUT_RENDERTARGET;
509
510 //init target retangle
511 Rect_init(&srcRect, dri_drawable->x, dri_drawable->y, dri_drawable->width, dri_drawable->height);
512 Rect_init(&dstRect, dri_drawable->x, dri_drawable->y, dri_drawable->width, dri_drawable->height);
513
514 // Create GmmResourceInfo
515 gmmParams.Flags.Gpu.Video = true;
516 gmmParams.BaseWidth = dri_drawable->width;
517 gmmParams.BaseHeight = dri_drawable->height;
518 gmmParams.ArraySize = 1;
519 gmmParams.Type = RESOURCE_2D;
520 gmmParams.Format = GMM_FORMAT_R8G8B8A8_UNORM_TYPE;
521 //gmmParams.Format = GMM_FORMAT_B8G8R8A8_UNORM_TYPE;
522 target.OsResource.pGmmResInfo = mediaCtx->pGmmClientContext->CreateResInfoObject(&gmmParams);
523 if (nullptr == target.OsResource.pGmmResInfo)
524 {
525 mos_bo_unreference(drawable_bo);
526 return VA_STATUS_ERROR_ALLOCATION_FAILED;
527 }
528
529 target.OsResource.iWidth = dri_drawable->width;
530 target.OsResource.iHeight = dri_drawable->height;
531 target.OsResource.iPitch = buffer->dri2.pitch;
532 target.OsResource.Format = Format_A8R8G8B8;
533 target.OsResource.iCount = 0;
534 target.OsResource.bo = drawable_bo;
535 target.OsResource.pData = (uint8_t *)drawable_bo->virt;
536 target.OsResource.TileType = tileType;
537 target.TileType = tileType;
538 target.dwWidth = dri_drawable->width;
539 target.dwHeight = dri_drawable->height;
540 target.dwPitch = target.OsResource.iPitch;
541 target.ColorSpace = CSpace_sRGB;
542 target.ExtendedGamut = false;
543 target.rcSrc = srcRect;
544 target.rcDst = dstRect;
545
546 renderParams.uSrcCount = 1;
547 renderParams.uDstCount = 1;
548 renderParams.pSrc[0] = &Surf;
549 renderParams.pTarget[0] = ⌖
550 renderParams.pColorFillParams = &colorFill;
551 renderParams.pColorFillParams->Color = 0xFF000000;
552 renderParams.pColorFillParams->bYCbCr = false;
553 renderParams.pColorFillParams->CSpace = CSpace_sRGB;
554
555 DdiMediaUtil_LockMutex(&mediaCtx->PutSurfaceRenderMutex);
556 eStatus = vpHal->Render(&renderParams);
557 if (MOS_FAILED(eStatus))
558 {
559 DdiMediaUtil_UnLockMutex(&mediaCtx->PutSurfaceRenderMutex);
560 mos_bo_unreference(drawable_bo);
561 return VA_STATUS_ERROR_OPERATION_FAILED;
562 }
563
564 DdiMediaUtil_UnLockMutex(&mediaCtx->PutSurfaceRenderMutex);
565 mos_bo_unreference(drawable_bo);
566 target.OsResource.bo = nullptr;
567 DdiMediaUtil_LockMutex(&mediaCtx->PutSurfaceSwapBufferMutex);
568 dri_vtable->swap_buffer(ctx, dri_drawable);
569 DdiMediaUtil_UnLockMutex(&mediaCtx->PutSurfaceSwapBufferMutex);
570
571 mediaCtx->pGmmClientContext->DestroyResInfoObject(target.OsResource.pGmmResInfo);
572 target.OsResource.pGmmResInfo = nullptr;
573
574 return VA_STATUS_SUCCESS;
575 }
576
577 #ifndef ANDROID
578 // move from media_libva_putsurface_linux.c
DdiMedia_mask2shift(unsigned long mask)579 static unsigned long DdiMedia_mask2shift(unsigned long mask)
580 {
581 unsigned long shift = 0;
582 while((mask & 0x1) == 0)
583 {
584 mask = mask >> 1;
585 shift++;
586 }
587 return shift;
588 }
DdiMedia_yuv2pixel(uint32_t * pixel,int32_t y,int32_t u,int32_t v,unsigned long rshift,unsigned long rmask,unsigned long gshift,unsigned long gmask,unsigned long bshift,unsigned long bmask)589 static void DdiMedia_yuv2pixel(uint32_t *pixel, int32_t y, int32_t u, int32_t v,
590 unsigned long rshift, unsigned long rmask,
591 unsigned long gshift, unsigned long gmask,
592 unsigned long bshift, unsigned long bmask)
593 {
594 DDI_CHK_NULL(pixel, "nullptr pixel", );
595 /* Warning, magic values ahead */
596 int32_t r = y + ((351 * (v-128)) >> 8);
597 int32_t g = y - (((179 * (v-128)) + (86 * (u-128))) >> 8);
598 int32_t b = y + ((444 * (u-128)) >> 8);
599
600 if (r > 255) r = 255;
601 if (g > 255) g = 255;
602 if (b > 255) b = 255;
603 if (r < 0) r = 0;
604 if (g < 0) g = 0;
605 if (b < 0) b = 0;
606
607 *pixel = (uint32_t)(((r << rshift) & rmask) | ((g << gshift) & gmask) |((b << bshift) & bmask));
608 }
609
610 #define YUV_444P_TO_ARGB() \
611 srcY = umdContextY + pitch * srcy;\
612 srcU = srcY + pitch * ((mediaSurface->iHeight));\
613 srcV = srcU + pitch * ((mediaSurface->iHeight));\
614 \
615 for(y = srcy; y < (srcy + height); y += 1) \
616 {\
617 for(x = srcx; x < (srcx + width); x += 1) \
618 {\
619 y1 = *(srcY + x); \
620 u1 = *(srcU + x);\
621 v1 = *(srcV + x);\
622 \
623 pixel = (uint32_t *)(ximg->data + (y * ximg->bytes_per_line) + (x * (ximg->bits_per_pixel >> 3)));\
624 DdiMedia_yuv2pixel(pixel, y1, u1, v1, rshift, rmask, gshift, gmask, bshift, bmask);\
625 \
626 }\
627 srcY += pitch;\
628 srcU += pitch;\
629 srcV += pitch;\
630 }
631
632 #define YUV_422H_TO_ARGB()\
633 srcY = umdContextY + pitch * srcy;\
634 srcU = srcY + pitch * mediaSurface->iHeight;\
635 srcV = srcU + pitch * mediaSurface->iHeight;\
636 \
637 for(y = srcy; y < (srcy + height); y += 1)\
638 {\
639 for(x = srcx; x < (srcx + width); x += 2)\
640 {\
641 y1 = *(srcY + x);\
642 y2 = *(srcY + x + 1);\
643 u1 = *(srcU + x / 2);\
644 v1 = *(srcV + x / 2);\
645 \
646 pixel = (uint32_t *)(ximg->data + (y * ximg->bytes_per_line) + (x * (ximg->bits_per_pixel >> 3)));\
647 DdiMedia_yuv2pixel(pixel, y1, u1, v1, rshift, rmask, gshift, gmask, bshift, bmask);\
648 pixel = (uint32_t *)(ximg->data + (y * ximg->bytes_per_line) + ((x + 1) * (ximg->bits_per_pixel >> 3)));\
649 DdiMedia_yuv2pixel(pixel, y2, u1, v1, rshift, rmask, gshift, gmask, bshift, bmask);\
650 }\
651 srcY += pitch;\
652 srcU += pitch;\
653 srcV += pitch;\
654 }
655
656 #define YUV_422V_TO_ARGB() \
657 srcY = umdContextY + pitch * srcy;\
658 srcU = srcY + pitch * mediaSurface->iHeight;\
659 srcV = srcU + pitch * mediaSurface->iHeight / 2;\
660 \
661 for(y = srcy; y < (srcy + width); y += 1)\
662 {\
663 for(x = srcx; x < (srcx + height); x += 2)\
664 {\
665 y1 = *(srcY + x * pitch);\
666 y2 = *(srcY + (x + 1) * pitch);\
667 u1 = *(srcU + (x / 2) * pitch);\
668 v1 = *(srcV + (x / 2) * pitch);\
669 \
670 pixel = (uint32_t *)(ximg->data + (x * ximg->bytes_per_line) + (y * (ximg->bits_per_pixel >> 3)));\
671 DdiMedia_yuv2pixel(pixel, y1, u1, v1, rshift, rmask, gshift, gmask, bshift, bmask);\
672 pixel = (uint32_t *)(ximg->data + (x* ximg->bytes_per_line) + ((y + 1) * (ximg->bits_per_pixel >> 3)));\
673 DdiMedia_yuv2pixel(pixel, y2, u1, v1, rshift, rmask, gshift, gmask, bshift, bmask);\
674 \
675 }\
676 \
677 srcY += 1;\
678 srcU += 1;\
679 srcV += 1;\
680 }
681
682 #define YUV_IMC3_TO_ARGB() \
683 srcY = umdContextY + pitch * srcy;\
684 srcU = srcY + pitch * mediaSurface->iHeight;\
685 srcV = srcU + pitch * mediaSurface->iHeight / 2;\
686 \
687 for(y = srcy; y < (srcy + height); y += 2) \
688 {\
689 for(x = srcx; x < (srcx + width); x += 2) \
690 {\
691 y1 = *(srcY + x);\
692 y2 = *(srcY + x + 1);\
693 y3 = *(srcY + x + pitch);\
694 y4 = *(srcY + x + pitch + 1);\
695 \
696 u1 = *(srcU + x / 2);\
697 v1 = *(srcV + x / 2);\
698 \
699 pixel = (uint32_t *)(ximg->data + (y * ximg->bytes_per_line) + (x * (ximg->bits_per_pixel >> 3)));\
700 DdiMedia_yuv2pixel(pixel, y1, u1, v1, rshift, rmask, gshift, gmask, bshift, bmask);\
701 pixel = (uint32_t *)(ximg->data + (y * ximg->bytes_per_line) + ((x + 1) * (ximg->bits_per_pixel >> 3)));\
702 DdiMedia_yuv2pixel(pixel, y2, u1, v1, rshift, rmask, gshift, gmask, bshift, bmask);\
703 pixel = (uint32_t *)(ximg->data + ((y + 1) * ximg->bytes_per_line) + (x * (ximg->bits_per_pixel >> 3)));\
704 DdiMedia_yuv2pixel(pixel, y3, u1, v1, rshift, rmask, gshift, gmask, bshift, bmask);\
705 pixel = (uint32_t *)(ximg->data + ((y + 1) * ximg->bytes_per_line) + ((x + 1) * (ximg->bits_per_pixel >> 3)));\
706 DdiMedia_yuv2pixel(pixel, y4, u1, v1, rshift, rmask, gshift, gmask, bshift, bmask); \
707 }\
708 srcY += pitch * 2;\
709 srcU += pitch;\
710 srcV += pitch;\
711 }
712
713 #define YUV_411P_TO_ARGB() \
714 srcY = umdContextY + pitch * srcy;\
715 srcU = srcY + pitch * mediaSurface->iHeight;\
716 srcV = srcU + pitch * mediaSurface->iHeight;\
717 \
718 for(y = srcy; y < (srcy + height); y += 1)\
719 {\
720 for(x = srcx; x < (srcx + width); x += 4)\
721 {\
722 y1 = *(srcY + x);\
723 y2 = *(srcY + x + 1);\
724 y3 = *(srcY + x + 2);\
725 y4 = *(srcY + x + 3);\
726 \
727 u1 = *(srcU + x / 4);\
728 v1 = *(srcV + x / 4);\
729 \
730 pixel = (uint32_t *)(ximg->data + (y * ximg->bytes_per_line) + (x * (ximg->bits_per_pixel >> 3)));\
731 DdiMedia_yuv2pixel(pixel, y1, u1, v1, rshift, rmask, gshift, gmask, bshift, bmask);\
732 pixel = (uint32_t *)(ximg->data + (y * ximg->bytes_per_line) + ((x + 1) * (ximg->bits_per_pixel >> 3)));\
733 DdiMedia_yuv2pixel(pixel, y2, u1, v1, rshift, rmask, gshift, gmask, bshift, bmask);\
734 pixel = (uint32_t *)(ximg->data + ((y ) * ximg->bytes_per_line) + ((x+2) * (ximg->bits_per_pixel >> 3)));\
735 DdiMedia_yuv2pixel(pixel, y3, u1, v1, rshift, rmask, gshift, gmask, bshift, bmask);\
736 pixel = (uint32_t *)(ximg->data + ((y) * ximg->bytes_per_line) + ((x + 3) * (ximg->bits_per_pixel >> 3)));\
737 DdiMedia_yuv2pixel(pixel, y4, u1, v1, rshift, rmask, gshift, gmask, bshift, bmask);\
738 }\
739 srcY += pitch;\
740 srcU += pitch;\
741 srcV += pitch;\
742 }
743
744 #define YUV_400P_TO_ARGB()\
745 srcY = umdContextY + pitch * srcy;\
746 srcU = srcY;\
747 srcV = srcY;\
748 \
749 for(y = srcy; y < (srcy + height); y += 2)\
750 {\
751 for(x = srcx; x < (srcx + width); x += 2)\
752 {\
753 y1 = *(srcY + x);\
754 y2 = *(srcY + x + 1);\
755 y3 = *(srcY + x + pitch);\
756 y4 = *(srcY + x + pitch + 1);\
757 \
758 u1 = 128;\
759 v1 = 128;\
760 pixel = (uint32_t *)(ximg->data + (y * ximg->bytes_per_line) + (x * (ximg->bits_per_pixel >> 3)));\
761 DdiMedia_yuv2pixel(pixel, y1, u1, v1, rshift, rmask, gshift, gmask, bshift, bmask);\
762 pixel = (uint32_t *)(ximg->data + (y * ximg->bytes_per_line) + ((x + 1) * (ximg->bits_per_pixel >> 3)));\
763 DdiMedia_yuv2pixel(pixel, y2, u1, v1, rshift, rmask, gshift, gmask, bshift, bmask);\
764 pixel = (uint32_t *)(ximg->data + ((y + 1) * ximg->bytes_per_line) + (x * (ximg->bits_per_pixel >> 3)));\
765 DdiMedia_yuv2pixel(pixel, y3, u1, v1, rshift, rmask, gshift, gmask, bshift, bmask);\
766 pixel = (uint32_t *)(ximg->data + ((y + 1) * ximg->bytes_per_line) + ((x + 1) * (ximg->bits_per_pixel >> 3)));\
767 DdiMedia_yuv2pixel(pixel, y4, u1, v1, rshift, rmask, gshift, gmask, bshift, bmask);\
768 }\
769 srcY += pitch * 2;\
770 srcU += pitch;\
771 srcV += pitch;\
772 }
773
774 #define YUV_NV12_TO_ARGB()\
775 srcY = umdContextY + pitch * srcy;\
776 srcU = srcY + pitch * mediaSurface->iHeight;\
777 srcV = srcU + 1;\
778 \
779 for(y = srcy; y < (srcy + height); y += 2)\
780 {\
781 for(x = srcx; x < (srcx + width); x += 2)\
782 {\
783 y1 = *(srcY + x);\
784 y2 = *(srcY + x + 1);\
785 y3 = *(srcY + x + pitch);\
786 y4 = *(srcY + x + pitch + 1);\
787 \
788 u1 = *(srcU + x);\
789 v1 = *(srcU + x +1);\
790 pixel = (uint32_t *)(ximg->data + (y * ximg->bytes_per_line) + (x * (ximg->bits_per_pixel >> 3)));\
791 DdiMedia_yuv2pixel(pixel, y1, u1, v1, rshift, rmask, gshift, gmask, bshift, bmask);\
792 pixel = (uint32_t *)(ximg->data + (y * ximg->bytes_per_line) + ((x + 1) * (ximg->bits_per_pixel >> 3)));\
793 DdiMedia_yuv2pixel(pixel, y2, u1, v1, rshift, rmask, gshift, gmask, bshift, bmask);\
794 pixel = (uint32_t *)(ximg->data + ((y + 1) * ximg->bytes_per_line) + (x * (ximg->bits_per_pixel >> 3)));\
795 DdiMedia_yuv2pixel(pixel, y3, u1, v1, rshift, rmask, gshift, gmask, bshift, bmask);\
796 pixel = (uint32_t *)(ximg->data + ((y + 1) * ximg->bytes_per_line) + ((x + 1) * (ximg->bits_per_pixel >> 3)));\
797 DdiMedia_yuv2pixel(pixel, y4, u1, v1, rshift, rmask, gshift, gmask, bshift, bmask);\
798 }\
799 srcY += pitch * 2;\
800 srcU += pitch;\
801 }
802
DdiMedia_PutSurfaceLinuxSW(VADriverContextP ctx,VASurfaceID surface,void * draw,int16_t srcx,int16_t srcy,uint16_t srcw,uint16_t srch,int16_t destx,int16_t desty,uint16_t destw,uint16_t desth,VARectangle * cliprects,uint32_t number_cliprects,uint32_t flags)803 VAStatus DdiMedia_PutSurfaceLinuxSW(
804 VADriverContextP ctx,
805 VASurfaceID surface,
806 void* draw, /* Drawable of window system */
807 int16_t srcx,
808 int16_t srcy,
809 uint16_t srcw,
810 uint16_t srch,
811 int16_t destx,
812 int16_t desty,
813 uint16_t destw,
814 uint16_t desth,
815 VARectangle *cliprects, /* client supplied clip list */
816 uint32_t number_cliprects, /* number of clip rects in the clip list */
817 uint32_t flags /* de-interlacing flags */
818 )
819 {
820 PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx);
821 DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx.", VA_STATUS_ERROR_INVALID_CONTEXT);
822
823 DDI_CHK_NULL(mediaCtx->X11FuncTable, "nullptr X11FuncTable", VA_STATUS_ERROR_INVALID_CONTEXT);
824 DDI_CHK_NULL(mediaCtx->X11FuncTable->pfnXCreateGC, "nullptr pfnXCreateGC", VA_STATUS_ERROR_INVALID_CONTEXT);
825 DDI_CHK_NULL(mediaCtx->X11FuncTable->pfnXFreeGC, "nullptr pfnXFreeGC", VA_STATUS_ERROR_INVALID_CONTEXT);
826 DDI_CHK_NULL(mediaCtx->X11FuncTable->pfnXCreateImage, "nullptr pfnXCreateImage", VA_STATUS_ERROR_INVALID_CONTEXT);
827 DDI_CHK_NULL(mediaCtx->X11FuncTable->pfnXDestroyImage, "nullptr pfnXDestroyImage", VA_STATUS_ERROR_INVALID_CONTEXT);
828 DDI_CHK_NULL(mediaCtx->X11FuncTable->pfnXPutImage, "nullptr pfnXPutImage", VA_STATUS_ERROR_INVALID_CONTEXT);
829
830 TypeXCreateGC pfn_XCreateGC = (TypeXCreateGC)(mediaCtx->X11FuncTable->pfnXCreateGC);
831 TypeXFreeGC pfn_XFreeGC = (TypeXFreeGC)(mediaCtx->X11FuncTable->pfnXFreeGC);
832 TypeXCreateImage pfn_XCreateImage = (TypeXCreateImage)(mediaCtx->X11FuncTable->pfnXCreateImage);
833 TypeXDestroyImage pfn_XDestroyImage = (TypeXDestroyImage)(mediaCtx->X11FuncTable->pfnXDestroyImage);
834 TypeXPutImage pfn_XPutImage = (TypeXPutImage)(mediaCtx->X11FuncTable->pfnXPutImage);
835
836 DDI_MEDIA_SURFACE *mediaSurface = DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, surface);
837 DDI_CHK_NULL(mediaSurface, "nullptr mediaSurface.", VA_STATUS_ERROR_INVALID_SURFACE);
838
839 uint16_t width = 0;
840 if (srcw <= destw)
841 width = srcw;
842 else
843 width = destw;
844
845 uint16_t height = 0;
846 if (srch <= desth)
847 height = srch;
848 else
849 height = desth;
850
851 int32_t pitch = mediaSurface->iPitch;
852 uint32_t adjustU = 1;
853 uint32_t adjustD = 1;
854 switch(mediaSurface->format)
855 {
856 case Media_Format_422H:
857 case Media_Format_444P:
858 case Media_Format_411P:
859 adjustU = 3;
860 adjustD = 1;
861 break;
862 case Media_Format_400P:
863 adjustU = 1;
864 adjustD = 1;
865 break;
866 case Media_Format_422V:
867 case Media_Format_IMC3:
868 adjustU = 2;
869 adjustD = 1;
870 break;
871 case Media_Format_NV12:
872 adjustU = 3;
873 adjustD = 2;
874 break;
875 default:
876 DDI_ASSERTMESSAGE("Color Format is not supported: %d",mediaSurface->format);
877 return VA_STATUS_ERROR_INVALID_VALUE;
878 }
879
880 uint32_t surfaceSize = pitch * mediaSurface->iHeight * adjustU / adjustD;
881 uint8_t *dispTempBuffer = (uint8_t *)malloc(surfaceSize);
882 if (dispTempBuffer == nullptr)
883 {
884 DdiMediaUtil_UnlockSurface(mediaSurface);
885 return VA_STATUS_ERROR_ALLOCATION_FAILED;
886 }
887
888 uint8_t *umdContextY = dispTempBuffer;
889 uint8_t *ptr = (uint8_t*)DdiMediaUtil_LockSurface(mediaSurface, (MOS_LOCKFLAG_READONLY | MOS_LOCKFLAG_WRITEONLY));
890 MOS_STATUS eStatus = MOS_SecureMemcpy(umdContextY, surfaceSize, ptr, surfaceSize);
891
892 if (eStatus != MOS_STATUS_SUCCESS)
893 {
894 MOS_FreeMemory(dispTempBuffer);
895 DDI_ASSERTMESSAGE("DDI:Failed to copy surface buffer data!");
896 return VA_STATUS_ERROR_OPERATION_FAILED;
897 }
898
899 Visual *visual = DefaultVisual(ctx->native_dpy, ctx->x11_screen);
900 GC gc = (*pfn_XCreateGC)((Display*)ctx->native_dpy, (Drawable)draw, 0, nullptr);
901
902 if (TrueColor != visual->c_class)
903 {
904 (*pfn_XFreeGC)((Display*)ctx->native_dpy, gc);
905 MOS_FreeMemory(dispTempBuffer);
906 return VA_STATUS_ERROR_UNKNOWN;
907 }
908
909 unsigned long rmask = visual->red_mask;
910 unsigned long gmask = visual->green_mask;
911 unsigned long bmask = visual->blue_mask;
912
913 unsigned long rshift = DdiMedia_mask2shift(rmask);
914 unsigned long gshift = DdiMedia_mask2shift(gmask);
915 unsigned long bshift = DdiMedia_mask2shift(bmask);
916
917 int32_t depth = DefaultDepth(ctx->native_dpy, ctx->x11_screen);
918 XImage *ximg = (*pfn_XCreateImage)((Display*)ctx->native_dpy, visual, depth, ZPixmap, 0, nullptr,width, height, 32, 0 );
919 if (ximg == nullptr)
920 {
921 MOS_FreeMemory(dispTempBuffer);
922 return VA_STATUS_ERROR_ALLOCATION_FAILED;
923 }
924
925 if (ximg->bits_per_pixel != 32)
926 {
927 (*pfn_XDestroyImage)(ximg);
928 (*pfn_XFreeGC)((Display*)ctx->native_dpy, gc);
929 MOS_FreeMemory(dispTempBuffer);
930 return VA_STATUS_ERROR_UNKNOWN;
931 }
932
933 ximg->data = (char *) malloc(ximg->bytes_per_line * MOS_ALIGN_CEIL(height, 2)); // If height is odd, need to add it by one for we process two lines per iteration
934 if (nullptr == ximg->data)
935 {
936 (*pfn_XDestroyImage)(ximg);
937 (*pfn_XFreeGC)((Display*)ctx->native_dpy, gc);
938 MOS_FreeMemory(dispTempBuffer);
939 return VA_STATUS_ERROR_ALLOCATION_FAILED;
940 }
941
942 int32_t x = 0;
943 int32_t y = 0;
944 uint8_t *srcY = nullptr;
945 uint8_t *srcU = nullptr;
946 uint8_t *srcV = nullptr;
947 uint32_t *pixel = nullptr;
948 int32_t y1 = 0, y2 = 0, y3 = 0, y4 = 0, u1 = 0, v1 = 0;
949 switch(mediaSurface->format)
950 {
951 case Media_Format_444P:
952 YUV_444P_TO_ARGB();
953 break;
954 case Media_Format_422H:
955 YUV_422H_TO_ARGB();
956 break;
957 case Media_Format_422V:
958 YUV_422V_TO_ARGB();
959 break;
960 case Media_Format_IMC3:
961 YUV_IMC3_TO_ARGB();
962 break;
963 case Media_Format_411P:
964 YUV_411P_TO_ARGB();
965 break;
966 case Media_Format_400P:
967 YUV_400P_TO_ARGB();
968 break;
969 case Media_Format_NV12:
970 YUV_NV12_TO_ARGB();
971 break;
972 default:
973 DDI_ASSERTMESSAGE("Color Format is not supported: %d", mediaSurface->format);
974 }
975
976 DdiMediaUtil_UnlockSurface(mediaSurface);
977
978 (*pfn_XPutImage)((Display*)ctx->native_dpy,(Drawable)draw, gc, ximg, 0, 0, destx, desty, destw, desth);
979
980 if (ximg != nullptr)
981 {
982 (*pfn_XDestroyImage)(ximg);
983 }
984 (*pfn_XFreeGC)((Display*)ctx->native_dpy, gc);
985 MOS_FreeMemory(dispTempBuffer);
986 return VA_STATUS_SUCCESS;
987 }
988
DdiMedia_PutSurfaceDummy(VADriverContextP ctx,VASurfaceID surface,void * draw,int16_t srcx,int16_t srcy,uint16_t srcw,uint16_t srch,int16_t destx,int16_t desty,uint16_t destw,uint16_t desth,VARectangle * cliprects,uint32_t number_cliprects,uint32_t flags)989 VAStatus DdiMedia_PutSurfaceDummy(
990 VADriverContextP ctx,
991 VASurfaceID surface,
992 void *draw, /* Drawable of window system */
993 int16_t srcx,
994 int16_t srcy,
995 uint16_t srcw,
996 uint16_t srch,
997 int16_t destx,
998 int16_t desty,
999 uint16_t destw,
1000 uint16_t desth,
1001 VARectangle *cliprects, /* client supplied clip list */
1002 uint32_t number_cliprects, /* number of clip rects in the clip list */
1003 uint32_t flags /* de-interlacing flags */
1004 )
1005 {
1006 return VA_STATUS_ERROR_UNIMPLEMENTED;
1007 }
1008
1009 #endif
1010