• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**************************************************************************
2  *
3  * Copyright 2010 Thomas Balling Sørensen & Orasanu Lucian.
4  * Copyright 2014 Advanced Micro Devices, Inc.
5  * All Rights Reserved.
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a
8  * copy of this software and associated documentation files (the
9  * "Software"), to deal in the Software without restriction, including
10  * without limitation the rights to use, copy, modify, merge, publish,
11  * distribute, sub license, and/or sell copies of the Software, and to
12  * permit persons to whom the Software is furnished to do so, subject to
13  * the following conditions:
14  *
15  * The above copyright notice and this permission notice (including the
16  * next paragraph) shall be included in all copies or substantial portions
17  * of the Software.
18  *
19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22  * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR
23  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26  *
27  **************************************************************************/
28 
29 #include "pipe/p_screen.h"
30 #include "pipe/p_video_codec.h"
31 #include "util/u_memory.h"
32 #include "util/u_handle_table.h"
33 #include "util/u_video.h"
34 #include "util/set.h"
35 #include "vl/vl_deint_filter.h"
36 #include "vl/vl_winsys.h"
37 
38 #include "va_private.h"
39 #ifdef HAVE_DRISW_KMS
40 #include "loader/loader.h"
41 #endif
42 
43 #include <va/va_drmcommon.h>
44 
45 static struct VADriverVTable vtable =
46 {
47    &vlVaTerminate,
48    &vlVaQueryConfigProfiles,
49    &vlVaQueryConfigEntrypoints,
50    &vlVaGetConfigAttributes,
51    &vlVaCreateConfig,
52    &vlVaDestroyConfig,
53    &vlVaQueryConfigAttributes,
54    &vlVaCreateSurfaces,
55    &vlVaDestroySurfaces,
56    &vlVaCreateContext,
57    &vlVaDestroyContext,
58    &vlVaCreateBuffer,
59    &vlVaBufferSetNumElements,
60    &vlVaMapBuffer,
61    &vlVaUnmapBuffer,
62    &vlVaDestroyBuffer,
63    &vlVaBeginPicture,
64    &vlVaRenderPicture,
65    &vlVaEndPicture,
66    &vlVaSyncSurface,
67    &vlVaQuerySurfaceStatus,
68    &vlVaQuerySurfaceError,
69    &vlVaPutSurface,
70    &vlVaQueryImageFormats,
71    &vlVaCreateImage,
72    &vlVaDeriveImage,
73    &vlVaDestroyImage,
74    &vlVaSetImagePalette,
75    &vlVaGetImage,
76    &vlVaPutImage,
77    &vlVaQuerySubpictureFormats,
78    &vlVaCreateSubpicture,
79    &vlVaDestroySubpicture,
80    &vlVaSubpictureImage,
81    &vlVaSetSubpictureChromakey,
82    &vlVaSetSubpictureGlobalAlpha,
83    &vlVaAssociateSubpicture,
84    &vlVaDeassociateSubpicture,
85    &vlVaQueryDisplayAttributes,
86    &vlVaGetDisplayAttributes,
87    &vlVaSetDisplayAttributes,
88    &vlVaBufferInfo,
89    &vlVaLockSurface,
90    &vlVaUnlockSurface,
91    NULL, /* DEPRECATED VaGetSurfaceAttributes */
92    &vlVaCreateSurfaces2,
93    &vlVaQuerySurfaceAttributes,
94    &vlVaAcquireBufferHandle,
95    &vlVaReleaseBufferHandle,
96 #if VA_CHECK_VERSION(1, 1, 0)
97    NULL, /* vaCreateMFContext */
98    NULL, /* vaMFAddContext */
99    NULL, /* vaMFReleaseContext */
100    NULL, /* vaMFSubmit */
101    NULL, /* vaCreateBuffer2 */
102    NULL, /* vaQueryProcessingRate */
103    &vlVaExportSurfaceHandle,
104 #endif
105 #if VA_CHECK_VERSION(1, 15, 0)
106    &vlVaSyncSurface2,
107    &vlVaSyncBuffer,
108 #endif
109 #if VA_CHECK_VERSION(1, 21, 0)
110    NULL, /* vaCopy */
111    &vlVaMapBuffer2,
112 #endif
113 };
114 
115 static struct VADriverVTableVPP vtable_vpp =
116 {
117    1,
118    &vlVaQueryVideoProcFilters,
119    &vlVaQueryVideoProcFilterCaps,
120    &vlVaQueryVideoProcPipelineCaps
121 };
122 
123 VA_PUBLIC_API VAStatus
VA_DRIVER_INIT_FUNC(VADriverContextP ctx)124 VA_DRIVER_INIT_FUNC(VADriverContextP ctx)
125 {
126    vlVaDriver *drv;
127 #if defined(GALLIUM_ZINK)
128    const char *drivername = os_get_option_cached("LIBVA_DRIVER_NAME");
129    bool zink = drivername && !strcmp(drivername, "zink");
130 #endif
131 
132    if (!ctx)
133       return VA_STATUS_ERROR_INVALID_CONTEXT;
134 
135    drv = CALLOC(1, sizeof(vlVaDriver));
136    if (!drv)
137       return VA_STATUS_ERROR_ALLOCATION_FAILED;
138 
139    switch (ctx->display_type) {
140 #ifdef _WIN32
141    case VA_DISPLAY_WIN32: {
142 #ifdef GALLIUM_ZINK
143       if (zink)
144          drv->vscreen = vl_kopper_screen_create_win32(ctx->native_dpy);
145 #endif
146       if (!drv->vscreen)
147          drv->vscreen = vl_win32_screen_create(ctx->native_dpy);
148       break;
149    }
150 #else
151    case VA_DISPLAY_ANDROID:
152       FREE(drv);
153       return VA_STATUS_ERROR_UNIMPLEMENTED;
154    case VA_DISPLAY_GLX:
155    case VA_DISPLAY_X11:
156 #ifdef GALLIUM_ZINK
157       if (zink)
158          drv->vscreen = vl_kopper_screen_create_x11(ctx->native_dpy, ctx->x11_screen);
159 #endif
160       if (!drv->vscreen)
161          drv->vscreen = vl_dri3_screen_create(ctx->native_dpy, ctx->x11_screen);
162 #ifdef HAVE_X11_DRI2
163       if (!drv->vscreen)
164          drv->vscreen = vl_dri2_screen_create(ctx->native_dpy, ctx->x11_screen);
165 #endif
166       if (!drv->vscreen)
167          drv->vscreen = vl_xlib_swrast_screen_create(ctx->native_dpy, ctx->x11_screen);
168       break;
169    case VA_DISPLAY_WAYLAND:
170    case VA_DISPLAY_DRM:
171    case VA_DISPLAY_DRM_RENDERNODES: {
172       const struct drm_state *drm_info = (struct drm_state *) ctx->drm_state;
173 
174       if (!drm_info || drm_info->fd < 0) {
175          FREE(drv);
176          return VA_STATUS_ERROR_INVALID_PARAMETER;
177       }
178 #ifdef HAVE_DRISW_KMS
179       char* drm_driver_name = loader_get_driver_for_fd(drm_info->fd);
180       if(drm_driver_name) {
181          if (strcmp(drm_driver_name, "vgem") == 0)
182             drv->vscreen = vl_vgem_drm_screen_create(drm_info->fd);
183          FREE(drm_driver_name);
184       }
185 #endif
186       if(!drv->vscreen) {
187          /* VA_DISPLAY_WAYLAND uses the compositor's fd, like VA_DISPLAY_X11 does.
188           * In this case, tell vl_drm_screen_create to consider the DRI_PRIME env
189           * variable to let the user select a different device.
190           * The other display types receive a fd explicitely picked by the application,
191           * so don't try to override them.
192           */
193          bool honor_dri_prime = ctx->display_type == VA_DISPLAY_WAYLAND;
194          drv->vscreen = vl_drm_screen_create(drm_info->fd, honor_dri_prime);
195       }
196       break;
197    }
198 #endif
199    default:
200       FREE(drv);
201       return VA_STATUS_ERROR_INVALID_DISPLAY;
202    }
203 
204    if (!drv->vscreen)
205       goto error_screen;
206 
207    /* video cannot work if these are not supported */
208    if (!drv->vscreen->pscreen->get_video_param || !drv->vscreen->pscreen->is_video_format_supported)
209       goto error_pipe;
210 
211    bool compute_only = drv->vscreen->pscreen->caps.prefer_compute_for_multimedia;
212    drv->pipe = pipe_create_multimedia_context(drv->vscreen->pscreen, compute_only);
213    if (!drv->pipe)
214       goto error_pipe;
215 
216    drv->htab = handle_table_create();
217    if (!drv->htab)
218       goto error_htab;
219 
220    bool can_init_compositor = drv->vscreen->pscreen->caps.graphics ||
221                               drv->vscreen->pscreen->caps.compute;
222 
223    if (can_init_compositor) {
224       if (!vl_compositor_init(&drv->compositor, drv->pipe, compute_only))
225          goto error_compositor;
226       if (!vl_compositor_init_state(&drv->cstate, drv->pipe))
227          goto error_compositor_state;
228 
229       vl_csc_get_matrix(VL_CSC_COLOR_STANDARD_BT_601, NULL, true, &drv->csc);
230       if (!vl_compositor_set_csc_matrix(&drv->cstate, (const vl_csc_matrix *)&drv->csc, 1.0f, 0.0f))
231          goto error_csc_matrix;
232    }
233 
234    (void) mtx_init(&drv->mutex, mtx_plain);
235 
236    ctx->pDriverData = (void *)drv;
237    ctx->version_major = 0;
238    ctx->version_minor = 1;
239    *ctx->vtable = vtable;
240    *ctx->vtable_vpp = vtable_vpp;
241    ctx->max_profiles = PIPE_VIDEO_PROFILE_MAX - PIPE_VIDEO_PROFILE_UNKNOWN - 1;
242    ctx->max_entrypoints = 2;
243    ctx->max_attributes = 1;
244    ctx->max_image_formats = VL_VA_MAX_IMAGE_FORMATS;
245    ctx->max_subpic_formats = 1;
246 #if VA_CHECK_VERSION(1, 15, 0)
247    ctx->max_display_attributes = 1; /* VADisplayPCIID */
248 #else
249    ctx->max_display_attributes = 0;
250 #endif
251 
252    snprintf(drv->vendor_string, sizeof(drv->vendor_string),
253             "Mesa Gallium driver " PACKAGE_VERSION " for %s",
254             drv->vscreen->pscreen->get_name(drv->vscreen->pscreen));
255    ctx->str_vendor = drv->vendor_string;
256 
257    return VA_STATUS_SUCCESS;
258 
259 error_csc_matrix:
260    if (can_init_compositor)
261       vl_compositor_cleanup_state(&drv->cstate);
262 
263 error_compositor_state:
264    if (can_init_compositor)
265       vl_compositor_cleanup(&drv->compositor);
266 
267 error_compositor:
268    handle_table_destroy(drv->htab);
269 
270 error_htab:
271    drv->pipe->destroy(drv->pipe);
272 
273 error_pipe:
274    drv->vscreen->destroy(drv->vscreen);
275 
276 error_screen:
277    FREE(drv);
278    return VA_STATUS_ERROR_ALLOCATION_FAILED;
279 }
280 
281 VAStatus
vlVaCreateContext(VADriverContextP ctx,VAConfigID config_id,int picture_width,int picture_height,int flag,VASurfaceID * render_targets,int num_render_targets,VAContextID * context_id)282 vlVaCreateContext(VADriverContextP ctx, VAConfigID config_id, int picture_width,
283                   int picture_height, int flag, VASurfaceID *render_targets,
284                   int num_render_targets, VAContextID *context_id)
285 {
286    vlVaDriver *drv;
287    vlVaContext *context;
288    vlVaConfig *config;
289    int is_vpp;
290    int min_supported_width, min_supported_height;
291    int max_supported_width, max_supported_height;
292 
293    if (!ctx)
294       return VA_STATUS_ERROR_INVALID_CONTEXT;
295 
296    drv = VL_VA_DRIVER(ctx);
297    mtx_lock(&drv->mutex);
298    config = handle_table_get(drv->htab, config_id);
299    mtx_unlock(&drv->mutex);
300 
301    if (!config)
302       return VA_STATUS_ERROR_INVALID_CONFIG;
303 
304    is_vpp = config->profile == PIPE_VIDEO_PROFILE_UNKNOWN && !picture_width &&
305             !picture_height && !flag && !render_targets && !num_render_targets;
306 
307    if (!(picture_width && picture_height) && !is_vpp)
308       return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT;
309 
310    context = CALLOC(1, sizeof(vlVaContext));
311    if (!context)
312       return VA_STATUS_ERROR_ALLOCATION_FAILED;
313 
314    if (is_vpp && !drv->vscreen->pscreen->get_video_param(drv->vscreen->pscreen,
315                                                          PIPE_VIDEO_PROFILE_UNKNOWN,
316                                                          PIPE_VIDEO_ENTRYPOINT_PROCESSING,
317                                                          PIPE_VIDEO_CAP_SUPPORTED)) {
318       context->decoder = NULL;
319    } else {
320       if (config->entrypoint != PIPE_VIDEO_ENTRYPOINT_PROCESSING) {
321          min_supported_width = drv->vscreen->pscreen->get_video_param(drv->vscreen->pscreen,
322                         config->profile, config->entrypoint,
323                         PIPE_VIDEO_CAP_MIN_WIDTH);
324          min_supported_height = drv->vscreen->pscreen->get_video_param(drv->vscreen->pscreen,
325                         config->profile, config->entrypoint,
326                         PIPE_VIDEO_CAP_MIN_HEIGHT);
327          max_supported_width = drv->vscreen->pscreen->get_video_param(drv->vscreen->pscreen,
328                         config->profile, config->entrypoint,
329                         PIPE_VIDEO_CAP_MAX_WIDTH);
330          max_supported_height = drv->vscreen->pscreen->get_video_param(drv->vscreen->pscreen,
331                         config->profile, config->entrypoint,
332                         PIPE_VIDEO_CAP_MAX_HEIGHT);
333 
334          if (picture_width < min_supported_width || picture_height < min_supported_height ||
335              picture_width > max_supported_width || picture_height > max_supported_height) {
336             FREE(context);
337             return VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED;
338          }
339       }
340       context->templat.profile = config->profile;
341       context->templat.entrypoint = config->entrypoint;
342       context->templat.chroma_format = PIPE_VIDEO_CHROMA_FORMAT_420;
343       context->templat.width = picture_width;
344       context->templat.height = picture_height;
345       context->templat.expect_chunked_decode = true;
346 
347       switch (u_reduce_video_profile(context->templat.profile)) {
348       case PIPE_VIDEO_FORMAT_MPEG12:
349       case PIPE_VIDEO_FORMAT_VC1:
350       case PIPE_VIDEO_FORMAT_MPEG4:
351          context->templat.max_references = 2;
352          break;
353 
354       case PIPE_VIDEO_FORMAT_MPEG4_AVC:
355          context->templat.max_references = 0;
356          if (config->entrypoint != PIPE_VIDEO_ENTRYPOINT_ENCODE) {
357             context->desc.h264.pps = CALLOC_STRUCT(pipe_h264_pps);
358             if (!context->desc.h264.pps) {
359                FREE(context);
360                return VA_STATUS_ERROR_ALLOCATION_FAILED;
361             }
362             context->desc.h264.pps->sps = CALLOC_STRUCT(pipe_h264_sps);
363             if (!context->desc.h264.pps->sps) {
364                FREE(context->desc.h264.pps);
365                FREE(context);
366                return VA_STATUS_ERROR_ALLOCATION_FAILED;
367             }
368          }
369          break;
370 
371      case PIPE_VIDEO_FORMAT_HEVC:
372          if (config->entrypoint != PIPE_VIDEO_ENTRYPOINT_ENCODE) {
373             context->desc.h265.pps = CALLOC_STRUCT(pipe_h265_pps);
374             if (!context->desc.h265.pps) {
375                FREE(context);
376                return VA_STATUS_ERROR_ALLOCATION_FAILED;
377             }
378             context->desc.h265.pps->sps = CALLOC_STRUCT(pipe_h265_sps);
379             if (!context->desc.h265.pps->sps) {
380                FREE(context->desc.h265.pps);
381                FREE(context);
382                return VA_STATUS_ERROR_ALLOCATION_FAILED;
383             }
384          }
385          break;
386 
387       case PIPE_VIDEO_FORMAT_VP9:
388          break;
389 
390       default:
391          break;
392       }
393    }
394 
395    context->desc.base.profile = config->profile;
396    context->desc.base.entry_point = config->entrypoint;
397    if (config->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) {
398       switch (u_reduce_video_profile(context->templat.profile)) {
399       case PIPE_VIDEO_FORMAT_MPEG4_AVC:
400          context->templat.max_references = PIPE_H264_MAX_REFERENCES;
401          for (unsigned i = 0; i < ARRAY_SIZE(context->desc.h264enc.rate_ctrl); i++) {
402             context->desc.h264enc.rate_ctrl[i].rate_ctrl_method = config->rc;
403             context->desc.h264enc.rate_ctrl[i].vbv_buffer_size = 20000000;
404             context->desc.h264enc.rate_ctrl[i].vbv_buf_lv = 64;
405             context->desc.h264enc.rate_ctrl[i].fill_data_enable = 1;
406             context->desc.h264enc.rate_ctrl[i].enforce_hrd = 1;
407             context->desc.h264enc.rate_ctrl[i].max_qp = 51;
408             context->desc.h264enc.rate_ctrl[i].frame_rate_num = 30;
409             context->desc.h264enc.rate_ctrl[i].frame_rate_den = 1;
410          }
411          context->desc.h264enc.frame_idx = util_hash_table_create_ptr_keys();
412          util_dynarray_init(&context->desc.h264enc.raw_headers, NULL);
413          break;
414       case PIPE_VIDEO_FORMAT_HEVC:
415          context->templat.max_references = PIPE_H265_MAX_REFERENCES;
416          for (unsigned i = 0; i < ARRAY_SIZE(context->desc.h265enc.rc); i++) {
417             context->desc.h265enc.rc[i].rate_ctrl_method = config->rc;
418             context->desc.h265enc.rc[i].vbv_buffer_size = 20000000;
419             context->desc.h265enc.rc[i].vbv_buf_lv = 64;
420             context->desc.h265enc.rc[i].fill_data_enable = 1;
421             context->desc.h265enc.rc[i].enforce_hrd = 1;
422             context->desc.h265enc.rc[i].max_qp = 51;
423             context->desc.h265enc.rc[i].frame_rate_num = 30;
424             context->desc.h265enc.rc[i].frame_rate_den = 1;
425          }
426          context->desc.h265enc.frame_idx = util_hash_table_create_ptr_keys();
427          util_dynarray_init(&context->desc.h265enc.raw_headers, NULL);
428          break;
429       case PIPE_VIDEO_FORMAT_AV1:
430          context->templat.max_references = PIPE_AV1_MAX_REFERENCES;
431          for (unsigned i = 0; i < ARRAY_SIZE(context->desc.av1enc.rc); i++) {
432             context->desc.av1enc.rc[i].rate_ctrl_method = config->rc;
433             context->desc.av1enc.rc[i].vbv_buffer_size = 20000000;
434             context->desc.av1enc.rc[i].vbv_buf_lv = 64;
435             context->desc.av1enc.rc[i].fill_data_enable = 1;
436             context->desc.av1enc.rc[i].enforce_hrd = 1;
437             context->desc.av1enc.rc[i].max_qp = 255;
438             context->desc.av1enc.rc[i].min_qp = 1;
439             context->desc.av1enc.rc[i].frame_rate_num = 30;
440             context->desc.av1enc.rc[i].frame_rate_den = 1;
441          }
442          break;
443       default:
444          break;
445       }
446 
447       mtx_lock(&drv->mutex);
448       context->decoder = drv->pipe->create_video_codec(drv->pipe, &context->templat);
449       mtx_unlock(&drv->mutex);
450       if (!context->decoder)
451          return VA_STATUS_ERROR_ALLOCATION_FAILED;
452    }
453 
454    context->surfaces = _mesa_set_create(NULL, _mesa_hash_pointer, _mesa_key_pointer_equal);
455    context->buffers = _mesa_set_create(NULL, _mesa_hash_pointer, _mesa_key_pointer_equal);
456 
457    mtx_lock(&drv->mutex);
458    *context_id = handle_table_add(drv->htab, context);
459    mtx_unlock(&drv->mutex);
460 
461    return VA_STATUS_SUCCESS;
462 }
463 
464 VAStatus
vlVaDestroyContext(VADriverContextP ctx,VAContextID context_id)465 vlVaDestroyContext(VADriverContextP ctx, VAContextID context_id)
466 {
467    vlVaDriver *drv;
468    vlVaContext *context;
469 
470    if (!ctx)
471       return VA_STATUS_ERROR_INVALID_CONTEXT;
472 
473    if (context_id == 0)
474       return VA_STATUS_ERROR_INVALID_CONTEXT;
475 
476    drv = VL_VA_DRIVER(ctx);
477    mtx_lock(&drv->mutex);
478    context = handle_table_get(drv->htab, context_id);
479    if (!context) {
480       mtx_unlock(&drv->mutex);
481       return VA_STATUS_ERROR_INVALID_CONTEXT;
482    }
483 
484    set_foreach(context->surfaces, entry) {
485       vlVaSurface *surf = (vlVaSurface *)entry->key;
486       assert(surf->ctx == context);
487       surf->ctx = NULL;
488       if (surf->fence && context->decoder && context->decoder->destroy_fence) {
489          context->decoder->destroy_fence(context->decoder, surf->fence);
490          surf->fence = NULL;
491       }
492    }
493    _mesa_set_destroy(context->surfaces, NULL);
494 
495    set_foreach(context->buffers, entry) {
496       vlVaBuffer *buf = (vlVaBuffer *)entry->key;
497       assert(buf->ctx == context);
498       vlVaGetBufferFeedback(buf);
499       buf->ctx = NULL;
500       if (buf->fence && context->decoder && context->decoder->destroy_fence) {
501          context->decoder->destroy_fence(context->decoder, buf->fence);
502          buf->fence = NULL;
503       }
504    }
505    _mesa_set_destroy(context->buffers, NULL);
506 
507    if (context->decoder) {
508       if (context->desc.base.entry_point == PIPE_VIDEO_ENTRYPOINT_ENCODE) {
509          if (u_reduce_video_profile(context->decoder->profile) ==
510              PIPE_VIDEO_FORMAT_MPEG4_AVC) {
511             if (context->desc.h264enc.frame_idx)
512                _mesa_hash_table_destroy(context->desc.h264enc.frame_idx, NULL);
513             for (uint32_t i = 0; i < ARRAY_SIZE(context->desc.h264enc.dpb); i++) {
514                struct pipe_video_buffer *buf = context->desc.h264enc.dpb[i].buffer;
515                if (buf && !context->desc.h264enc.dpb[i].id)
516                   buf->destroy(buf);
517             }
518             util_dynarray_fini(&context->desc.h264enc.raw_headers);
519          }
520          if (u_reduce_video_profile(context->decoder->profile) ==
521              PIPE_VIDEO_FORMAT_HEVC) {
522             if (context->desc.h265enc.frame_idx)
523                _mesa_hash_table_destroy(context->desc.h265enc.frame_idx, NULL);
524             for (uint32_t i = 0; i < ARRAY_SIZE(context->desc.h265enc.dpb); i++) {
525                struct pipe_video_buffer *buf = context->desc.h265enc.dpb[i].buffer;
526                if (buf && !context->desc.h265enc.dpb[i].id)
527                   buf->destroy(buf);
528             }
529             util_dynarray_fini(&context->desc.h265enc.raw_headers);
530          }
531          if (u_reduce_video_profile(context->decoder->profile) ==
532              PIPE_VIDEO_FORMAT_AV1) {
533             for (uint32_t i = 0; i < ARRAY_SIZE(context->desc.av1enc.dpb); i++) {
534                struct pipe_video_buffer *buf = context->desc.av1enc.dpb[i].buffer;
535                if (buf && !context->desc.av1enc.dpb[i].id)
536                   buf->destroy(buf);
537             }
538             util_dynarray_fini(&context->desc.av1enc.raw_headers);
539          }
540       } else {
541          if (u_reduce_video_profile(context->decoder->profile) ==
542                PIPE_VIDEO_FORMAT_MPEG4_AVC) {
543             FREE(context->desc.h264.pps->sps);
544             FREE(context->desc.h264.pps);
545          }
546          if (u_reduce_video_profile(context->decoder->profile) ==
547                PIPE_VIDEO_FORMAT_HEVC) {
548             FREE(context->desc.h265.pps->sps);
549             FREE(context->desc.h265.pps);
550          }
551       }
552       context->decoder->destroy(context->decoder);
553    }
554    if (context->blit_cs)
555       drv->pipe->delete_compute_state(drv->pipe, context->blit_cs);
556    if (context->deint) {
557       vl_deint_filter_cleanup(context->deint);
558       FREE(context->deint);
559    }
560    FREE(context->desc.base.decrypt_key);
561    FREE(context->bs.buffers);
562    FREE(context->bs.sizes);
563    FREE(context);
564    handle_table_remove(drv->htab, context_id);
565    mtx_unlock(&drv->mutex);
566 
567    return VA_STATUS_SUCCESS;
568 }
569 
570 VAStatus
vlVaTerminate(VADriverContextP ctx)571 vlVaTerminate(VADriverContextP ctx)
572 {
573    vlVaDriver *drv;
574 
575    if (!ctx)
576       return VA_STATUS_ERROR_INVALID_CONTEXT;
577 
578    drv = ctx->pDriverData;
579    vl_compositor_cleanup_state(&drv->cstate);
580    vl_compositor_cleanup(&drv->compositor);
581    if (drv->pipe_gfx)
582       drv->pipe_gfx->destroy(drv->pipe_gfx);
583    drv->pipe->destroy(drv->pipe);
584    drv->vscreen->destroy(drv->vscreen);
585    handle_table_destroy(drv->htab);
586    mtx_destroy(&drv->mutex);
587    FREE(drv);
588 
589    return VA_STATUS_SUCCESS;
590 }
591