1 /* GStreamer Intel MSDK plugin
2 * Copyright (c) 2018, Intel Corporation
3 * Copyright (c) 2018, Igalia S.L.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
9 * 1. Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright notice,
13 * this list of conditions and the following disclaimer in the documentation
14 * and/or other materials provided with the distribution.
16 * 3. Neither the name of the copyright holder nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGDECE
29 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 #include "gstmsdkcontext.h"
38 #include <va/va_drm.h>
39 #include <gudev/gudev.h>
40 #include <gst/va/gstvadisplay_drm.h>
42 #include <gst/d3d11/gstd3d11.h>
45 GST_DEBUG_CATEGORY_STATIC (gst_debug_msdkcontext);
46 #define GST_CAT_DEFAULT gst_debug_msdkcontext
48 struct _GstMsdkContextPrivate
51 GList *cached_alloc_responses;
53 gboolean has_frame_allocator;
54 GstMsdkContextJobType job_type;
55 gint shared_async_depth;
57 GList *child_session_list;
58 GstMsdkContext *parent_context;
60 GstVaDisplay *display;
62 GstD3D11Device *device;
66 #define gst_msdk_context_parent_class parent_class
67 G_DEFINE_TYPE_WITH_CODE (GstMsdkContext, gst_msdk_context, GST_TYPE_OBJECT,
68 G_ADD_PRIVATE (GstMsdkContext)
69 GST_DEBUG_CATEGORY_INIT (gst_debug_msdkcontext, "msdkcontext", 0,
75 get_device_path (void)
77 GUdevClient *client = NULL;
78 GUdevEnumerator *e = NULL;
80 GUdevDevice *dev, *parent;
81 const gchar *devnode_path;
82 const gchar *devnode_files[2] = { "renderD[0-9]*", "card[0-9]*" };
84 const gchar *user_choice = g_getenv ("GST_MSDK_DRM_DEVICE");
85 gchar *ret_path = NULL;
88 if (g_str_has_prefix (user_choice, "/dev/dri/"))
89 fd = open (user_choice, O_RDWR | O_CLOEXEC);
92 drmVersionPtr drm_version = drmGetVersion (fd);
94 if (!drm_version || strncmp (drm_version->name, "i915", 4)) {
95 GST_ERROR ("The specified device isn't an Intel device");
96 drmFreeVersion (drm_version);
100 GST_DEBUG ("Opened the specified drm device %s", user_choice);
101 drmFreeVersion (drm_version);
104 GST_ERROR ("The specified device isn't a valid drm device");
108 ret_path = g_strdup (user_choice);
115 client = g_udev_client_new (NULL);
119 e = g_udev_enumerator_new (client);
123 g_udev_enumerator_add_match_subsystem (e, "drm");
124 for (i = 0; i < 2; i++) {
125 g_udev_enumerator_add_match_name (e, devnode_files[i]);
126 devices = g_udev_enumerator_execute (e);
128 for (l = devices; l != NULL; l = l->next) {
129 dev = (GUdevDevice *) l->data;
131 parent = g_udev_device_get_parent (dev);
132 if (strcmp (g_udev_device_get_subsystem (parent), "pci") != 0 ||
133 strcmp (g_udev_device_get_driver (parent), "i915") != 0) {
134 g_object_unref (parent);
137 g_object_unref (parent);
139 devnode_path = g_udev_device_get_device_file (dev);
140 fd = open (devnode_path, O_RDWR | O_CLOEXEC);
143 GST_DEBUG ("Opened the drm device node %s", devnode_path);
144 ret_path = g_strdup (devnode_path);
148 g_list_foreach (devices, (GFunc) gst_object_unref, NULL);
149 g_list_free (devices);
161 g_object_unref (client);
167 gst_msdk_context_use_vaapi (GstMsdkContext * context)
170 VADisplay va_dpy = NULL;
171 GstVaDisplay *display_drm = NULL;
173 GstMsdkContextPrivate *priv = context->priv;
175 path = get_device_path ();
177 GST_WARNING ("Couldn't find a drm device node to open");
181 display_drm = gst_va_display_drm_new_from_path (path);
183 GST_ERROR ("Couldn't create a VA DRM display");
188 va_dpy = gst_va_display_get_va_dpy (display_drm);
190 status = MFXVideoCORE_SetHandle (priv->session.session, MFX_HANDLE_VA_DISPLAY,
192 if (status != MFX_ERR_NONE) {
193 GST_ERROR ("Setting VAAPI handle failed (%s)",
194 msdk_status_to_string (status));
198 priv->display = display_drm;
204 gst_object_unref (display_drm);
209 static GstD3D11Device *
210 get_device_by_index (IDXGIFactory1 * factory, guint idx)
213 IDXGIAdapter1 *adapter;
214 ID3D11Device *device_handle;
215 ID3D10Multithread *multi_thread;
216 DXGI_ADAPTER_DESC desc;
217 GstD3D11Device *device = NULL;
220 hr = IDXGIFactory1_EnumAdapters1 (factory, idx, &adapter);
225 hr = IDXGIAdapter1_GetDesc (adapter, &desc);
227 IDXGIAdapter1_Release (adapter);
231 if (desc.VendorId != 0x8086) {
232 IDXGIAdapter1_Release (adapter);
236 luid = gst_d3d11_luid_to_int64 (&desc.AdapterLuid);
237 device = gst_d3d11_device_new_for_adapter_luid (luid,
238 D3D11_CREATE_DEVICE_BGRA_SUPPORT);
239 IDXGIAdapter1_Release (adapter);
241 device_handle = gst_d3d11_device_get_device_handle (device);
242 hr = ID3D11Device_QueryInterface (device_handle,
243 &IID_ID3D10Multithread, (void **) &multi_thread);
245 gst_object_unref (device);
249 hr = ID3D10Multithread_SetMultithreadProtected (multi_thread, TRUE);
250 ID3D10Multithread_Release (multi_thread);
256 gst_msdk_context_use_d3d11 (GstMsdkContext * context)
259 IDXGIFactory1 *factory = NULL;
260 GstD3D11Device *device = NULL;
261 ID3D11Device *device_handle;
262 GstMsdkContextPrivate *priv = context->priv;
266 const gchar *user_choice = g_getenv ("GST_MSDK_DEVICE");
268 hr = CreateDXGIFactory1 (&IID_IDXGIFactory1, (void **) &factory);
270 GST_ERROR ("Couldn't create DXGI factory");
275 user_idx = atoi (user_choice);
276 if (!(device = get_device_by_index (factory, user_idx)))
278 ("Failed to get device by user index, try to pick the first available device");
281 /* Pick the first available device */
283 device = get_device_by_index (factory, idx++);
286 IDXGIFactory1_Release (factory);
287 device_handle = gst_d3d11_device_get_device_handle (device);
290 MFXVideoCORE_SetHandle (priv->session.session, MFX_HANDLE_D3D11_DEVICE,
291 gst_d3d11_device_get_device_handle (device));
292 if (status != MFX_ERR_NONE) {
293 GST_ERROR ("Setting D3D11VA handle failed (%s)",
294 msdk_status_to_string (status));
295 gst_object_unref (device);
299 priv->device = device;
306 gst_msdk_context_open (GstMsdkContext * context, gboolean hardware,
307 GstMsdkContextJobType job_type)
310 GstMsdkContextPrivate *priv = context->priv;
311 MsdkSession msdk_session;
314 priv->job_type = job_type;
315 priv->hardware = hardware;
317 impl = hardware ? MFX_IMPL_HARDWARE_ANY : MFX_IMPL_SOFTWARE;
320 impl |= MFX_IMPL_VIA_D3D11;
323 msdk_session = msdk_open_session (impl);
324 priv->session = msdk_session;
325 if (!priv->session.session)
330 if (!gst_msdk_context_use_vaapi (context))
335 if (!gst_msdk_context_use_d3d11 (context))
340 codename = msdk_get_platform_codename (priv->session.session);
342 if (codename != MFX_PLATFORM_UNKNOWN)
343 GST_INFO ("Detected MFX platform with device code %d", codename);
345 GST_WARNING ("Unknown MFX platform");
354 gst_msdk_context_init (GstMsdkContext * context)
356 GstMsdkContextPrivate *priv = gst_msdk_context_get_instance_private (context);
358 context->priv = priv;
360 g_mutex_init (&priv->mutex);
364 release_child_session (gpointer session)
368 mfxSession _session = session;
369 status = MFXDisjoinSession (_session);
370 if (status != MFX_ERR_NONE)
371 GST_WARNING ("failed to disjoin (%s)", msdk_status_to_string (status));
372 msdk_close_mfx_session (_session);
376 gst_msdk_context_finalize (GObject * obj)
378 GstMsdkContext *context = GST_MSDK_CONTEXT_CAST (obj);
379 GstMsdkContextPrivate *priv = context->priv;
381 /* child sessions will be closed when the parent session is closed */
382 if (priv->parent_context) {
383 gst_object_unref (priv->parent_context);
386 g_list_free_full (priv->child_session_list, release_child_session);
388 msdk_close_session (&priv->session);
389 g_mutex_clear (&priv->mutex);
393 gst_object_unref (priv->display);
396 gst_object_unref (priv->device);
400 G_OBJECT_CLASS (parent_class)->finalize (obj);
404 gst_msdk_context_class_init (GstMsdkContextClass * klass)
406 GObjectClass *const g_object_class = G_OBJECT_CLASS (klass);
408 g_object_class->finalize = gst_msdk_context_finalize;
412 gst_msdk_context_new (gboolean hardware, GstMsdkContextJobType job_type)
414 GstMsdkContext *obj = g_object_new (GST_TYPE_MSDK_CONTEXT, NULL);
416 if (obj && !gst_msdk_context_open (obj, hardware, job_type)) {
418 gst_object_unref (obj);
426 gst_msdk_context_new_with_parent (GstMsdkContext * parent)
429 GstMsdkContext *obj = g_object_new (GST_TYPE_MSDK_CONTEXT, NULL);
430 GstMsdkContextPrivate *priv = obj->priv;
431 GstMsdkContextPrivate *parent_priv = parent->priv;
434 MsdkSession child_msdk_session;
435 mfxHandleType handle_type = 0;
436 mfxHDL handle = NULL;
438 status = MFXQueryIMPL (parent_priv->session.session, &impl);
440 if (status == MFX_ERR_NONE)
441 status = MFXQueryVersion (parent_priv->session.session, &version);
443 if (status != MFX_ERR_NONE) {
444 GST_ERROR ("Failed to query the session attributes (%s)",
445 msdk_status_to_string (status));
446 gst_object_unref (obj);
450 if (MFX_IMPL_VIA_VAAPI == (0x0f00 & (impl)))
451 handle_type = MFX_HANDLE_VA_DISPLAY;
452 else if (MFX_IMPL_VIA_D3D11 == (0x0f00 & (impl)))
453 handle_type = MFX_HANDLE_D3D11_DEVICE;
457 MFXVideoCORE_GetHandle (parent_priv->session.session, handle_type,
460 if (status != MFX_ERR_NONE || !handle) {
461 GST_ERROR ("Failed to get session handle (%s)",
462 msdk_status_to_string (status));
463 gst_object_unref (obj);
468 child_msdk_session.loader = parent_priv->session.loader;
469 child_msdk_session.session = NULL;
470 status = msdk_init_msdk_session (impl, &version, &child_msdk_session);
472 if (status != MFX_ERR_NONE) {
473 GST_ERROR ("Failed to create a child mfx session (%s)",
474 msdk_status_to_string (status));
475 gst_object_unref (obj);
481 MFXVideoCORE_SetHandle (child_msdk_session.session, handle_type,
484 if (status != MFX_ERR_NONE) {
485 GST_ERROR ("Failed to set a HW handle (%s)",
486 msdk_status_to_string (status));
487 MFXClose (child_msdk_session.session);
488 gst_object_unref (obj);
492 #if (MFX_VERSION >= 1025)
494 MFXJoinSession (parent_priv->session.session, child_msdk_session.session);
496 if (status != MFX_ERR_NONE) {
497 GST_ERROR ("Failed to join two sessions (%s)",
498 msdk_status_to_string (status));
499 MFXClose (child_msdk_session.session);
500 gst_object_unref (obj);
505 /* Set loader to NULL for child session */
506 priv->session.loader = NULL;
507 priv->session.session = child_msdk_session.session;
508 priv->hardware = parent_priv->hardware;
509 priv->job_type = parent_priv->job_type;
510 parent_priv->child_session_list =
511 g_list_prepend (parent_priv->child_session_list, priv->session.session);
513 priv->display = parent_priv->display;
515 priv->device = parent_priv->device;
517 priv->parent_context = gst_object_ref (parent);
524 gst_msdk_context_new_with_va_display (GstObject * display_obj,
525 gboolean hardware, GstMsdkContextJobType job_type)
527 GstMsdkContext *obj = NULL;
529 GstMsdkContextPrivate *priv;
532 GstVaDisplay *va_display;
534 va_display = GST_VA_DISPLAY (display_obj);
538 obj = g_object_new (GST_TYPE_MSDK_CONTEXT, NULL);
541 priv->display = gst_object_ref (va_display);
543 priv->job_type = job_type;
544 priv->hardware = hardware;
546 msdk_open_session (hardware ? MFX_IMPL_HARDWARE_ANY : MFX_IMPL_SOFTWARE);
547 if (!priv->session.session) {
548 gst_object_unref (obj);
554 MFXVideoCORE_SetHandle (priv->session.session, MFX_HANDLE_VA_DISPLAY,
555 (mfxHDL) gst_va_display_get_va_dpy (priv->display));
556 if (status != MFX_ERR_NONE) {
557 GST_ERROR ("Setting VAAPI handle failed (%s)",
558 msdk_status_to_string (status));
559 gst_object_unref (obj);
564 codename = msdk_get_platform_codename (priv->session.session);
566 if (codename != MFX_PLATFORM_UNKNOWN)
567 GST_INFO ("Detected MFX platform with device code %d", codename);
569 GST_WARNING ("Unknown MFX platform");
575 gst_msdk_context_new_with_d3d11_device (GstD3D11Device * device,
576 gboolean hardware, GstMsdkContextJobType job_type)
578 GstMsdkContext *obj = NULL;
579 GstMsdkContextPrivate *priv;
582 ID3D10Multithread *multi_thread;
583 ID3D11Device *device_handle;
586 obj = g_object_new (GST_TYPE_MSDK_CONTEXT, NULL);
589 priv->device = gst_object_ref (device);
591 priv->job_type = job_type;
592 priv->hardware = hardware;
594 msdk_open_session (hardware ? MFX_IMPL_HARDWARE_ANY : MFX_IMPL_SOFTWARE);
595 if (!priv->session.session) {
599 device_handle = gst_d3d11_device_get_device_handle (device);
600 hr = ID3D11Device_QueryInterface (device_handle,
601 &IID_ID3D10Multithread, (void **) &multi_thread);
603 GST_ERROR ("ID3D10Multithread interface is unavailable");
607 hr = ID3D10Multithread_SetMultithreadProtected (multi_thread, TRUE);
608 ID3D10Multithread_Release (multi_thread);
612 MFXVideoCORE_SetHandle (priv->session.session, MFX_HANDLE_D3D11_DEVICE,
614 if (status != MFX_ERR_NONE) {
615 GST_ERROR ("Setting D3D11VA handle failed (%s)",
616 msdk_status_to_string (status));
621 codename = msdk_get_platform_codename (priv->session.session);
623 if (codename != MFX_PLATFORM_UNKNOWN)
624 GST_INFO ("Detected MFX platform with device code %d", codename);
626 GST_WARNING ("Unknown MFX platform");
631 gst_object_unref (obj);
632 gst_object_unref (device);
638 gst_msdk_context_get_session (GstMsdkContext * context)
640 return context->priv->session.session;
644 gst_msdk_context_get_handle (GstMsdkContext * context)
647 return gst_va_display_get_va_dpy (context->priv->display);
655 gst_msdk_context_get_va_display (GstMsdkContext * context)
657 if (context->priv->display)
658 return gst_object_ref (GST_OBJECT_CAST (context->priv->display));
663 gst_msdk_context_get_d3d11_device (GstMsdkContext * context)
665 if (context->priv->device)
666 return gst_object_ref (context->priv->device);
672 _find_response (gconstpointer resp, gconstpointer comp_resp)
674 GstMsdkAllocResponse *cached_resp = (GstMsdkAllocResponse *) resp;
675 mfxFrameAllocResponse *_resp = (mfxFrameAllocResponse *) comp_resp;
677 return cached_resp ? cached_resp->response.mids != _resp->mids : -1;
680 static inline gboolean
681 _requested_frame_size_is_equal_or_lower (mfxFrameAllocRequest * _req,
682 GstMsdkAllocResponse * cached_resp)
684 if (((_req->Type & MFX_MEMTYPE_EXPORT_FRAME) &&
685 _req->Info.Width == cached_resp->request.Info.Width &&
686 _req->Info.Height == cached_resp->request.Info.Height) ||
687 (!(_req->Type & MFX_MEMTYPE_EXPORT_FRAME) &&
688 _req->Info.Width <= cached_resp->request.Info.Width &&
689 _req->Info.Height <= cached_resp->request.Info.Height))
696 _find_request (gconstpointer resp, gconstpointer req)
698 GstMsdkAllocResponse *cached_resp = (GstMsdkAllocResponse *) resp;
699 mfxFrameAllocRequest *_req = (mfxFrameAllocRequest *) req;
701 /* Confirm if it's under the size of the cached response */
702 if (_req->NumFrameSuggested <= cached_resp->request.NumFrameSuggested &&
703 _requested_frame_size_is_equal_or_lower (_req, cached_resp))
704 return _req->Type & cached_resp->
705 request.Type & MFX_MEMTYPE_FROM_DECODE ? 0 : -1;
710 GstMsdkAllocResponse *
711 gst_msdk_context_get_cached_alloc_responses (GstMsdkContext * context,
712 mfxFrameAllocResponse * resp)
714 GstMsdkContextPrivate *priv = context->priv;
716 g_list_find_custom (priv->cached_alloc_responses, resp, _find_response);
724 GstMsdkAllocResponse *
725 gst_msdk_context_get_cached_alloc_responses_by_request (GstMsdkContext *
726 context, mfxFrameAllocRequest * req)
728 GstMsdkContextPrivate *priv = context->priv;
730 g_list_find_custom (priv->cached_alloc_responses, req, _find_request);
739 create_surfaces (GstMsdkContext * context, GstMsdkAllocResponse * resp)
743 mfxFrameSurface1 *surface;
745 for (i = 0; i < resp->response.NumFrameActual; i++) {
746 mem_id = resp->response.mids[i];
747 surface = (mfxFrameSurface1 *) g_slice_new0 (mfxFrameSurface1);
749 GST_ERROR ("failed to allocate surface");
752 surface->Data.MemId = mem_id;
753 resp->surfaces_avail = g_list_prepend (resp->surfaces_avail, surface);
758 free_surface (gpointer surface)
760 g_slice_free1 (sizeof (mfxFrameSurface1), surface);
764 remove_surfaces (GstMsdkContext * context, GstMsdkAllocResponse * resp)
766 g_list_free_full (resp->surfaces_used, free_surface);
767 g_list_free_full (resp->surfaces_avail, free_surface);
768 g_list_free_full (resp->surfaces_locked, free_surface);
772 gst_msdk_context_add_alloc_response (GstMsdkContext * context,
773 GstMsdkAllocResponse * resp)
775 context->priv->cached_alloc_responses =
776 g_list_prepend (context->priv->cached_alloc_responses, resp);
778 create_surfaces (context, resp);
782 gst_msdk_context_remove_alloc_response (GstMsdkContext * context,
783 mfxFrameAllocResponse * resp)
785 GstMsdkAllocResponse *msdk_resp;
786 GstMsdkContextPrivate *priv = context->priv;
788 g_list_find_custom (priv->cached_alloc_responses, resp, _find_response);
795 remove_surfaces (context, msdk_resp);
797 g_slice_free1 (sizeof (GstMsdkAllocResponse), msdk_resp);
798 priv->cached_alloc_responses =
799 g_list_delete_link (priv->cached_alloc_responses, l);
805 check_surfaces_available (GstMsdkContext * context, GstMsdkAllocResponse * resp)
808 mfxFrameSurface1 *surface = NULL;
809 GstMsdkContextPrivate *priv = context->priv;
810 gboolean ret = FALSE;
812 g_mutex_lock (&priv->mutex);
813 for (l = resp->surfaces_locked; l;) {
816 if (!surface->Data.Locked) {
817 resp->surfaces_locked = g_list_remove (resp->surfaces_locked, surface);
818 resp->surfaces_avail = g_list_prepend (resp->surfaces_avail, surface);
822 g_mutex_unlock (&priv->mutex);
828 * There are 3 lists here in GstMsdkContext as the following:
829 * 1. surfaces_avail : surfaces which are free and unused anywhere
830 * 2. surfaces_used : surfaces coupled with a gst buffer and being used now.
831 * 3. surfaces_locked : surfaces still locked even after the gst buffer is released.
833 * Note that they need to be protected by mutex to be thread-safe.
837 gst_msdk_context_get_surface_available (GstMsdkContext * context,
838 mfxFrameAllocResponse * resp)
841 mfxFrameSurface1 *surface = NULL;
842 GstMsdkAllocResponse *msdk_resp =
843 gst_msdk_context_get_cached_alloc_responses (context, resp);
845 GstMsdkContextPrivate *priv = context->priv;
848 g_mutex_lock (&priv->mutex);
849 for (l = msdk_resp->surfaces_avail; l;) {
852 if (!surface->Data.Locked) {
853 msdk_resp->surfaces_avail =
854 g_list_remove (msdk_resp->surfaces_avail, surface);
855 msdk_resp->surfaces_used =
856 g_list_prepend (msdk_resp->surfaces_used, surface);
860 g_mutex_unlock (&priv->mutex);
863 * If a msdk context is shared by multiple msdk elements,
864 * upstream msdk element sometimes needs to wait for a gst buffer
865 * to be released in downstream.
867 * Poll the pool for a maximum of 20 millisecond.
869 * FIXME: Is there any better way to handle this case?
871 if (!surface && retry < 20) {
872 /* If there's no surface available, find unlocked surfaces in the locked list,
873 * take it back to the available list and then search again.
875 check_surfaces_available (context, msdk_resp);
885 gst_msdk_context_put_surface_locked (GstMsdkContext * context,
886 mfxFrameAllocResponse * resp, mfxFrameSurface1 * surface)
888 GstMsdkContextPrivate *priv = context->priv;
889 GstMsdkAllocResponse *msdk_resp =
890 gst_msdk_context_get_cached_alloc_responses (context, resp);
892 g_mutex_lock (&priv->mutex);
893 if (!g_list_find (msdk_resp->surfaces_locked, surface)) {
894 msdk_resp->surfaces_used =
895 g_list_remove (msdk_resp->surfaces_used, surface);
896 msdk_resp->surfaces_locked =
897 g_list_prepend (msdk_resp->surfaces_locked, surface);
899 g_mutex_unlock (&priv->mutex);
903 gst_msdk_context_put_surface_available (GstMsdkContext * context,
904 mfxFrameAllocResponse * resp, mfxFrameSurface1 * surface)
906 GstMsdkContextPrivate *priv = context->priv;
907 GstMsdkAllocResponse *msdk_resp =
908 gst_msdk_context_get_cached_alloc_responses (context, resp);
910 g_mutex_lock (&priv->mutex);
911 if (!g_list_find (msdk_resp->surfaces_avail, surface)) {
912 msdk_resp->surfaces_used =
913 g_list_remove (msdk_resp->surfaces_used, surface);
914 msdk_resp->surfaces_avail =
915 g_list_prepend (msdk_resp->surfaces_avail, surface);
917 g_mutex_unlock (&priv->mutex);
920 GstMsdkContextJobType
921 gst_msdk_context_get_job_type (GstMsdkContext * context)
923 return context->priv->job_type;
927 gst_msdk_context_add_job_type (GstMsdkContext * context,
928 GstMsdkContextJobType job_type)
930 context->priv->job_type |= job_type;
934 gst_msdk_context_get_shared_async_depth (GstMsdkContext * context)
936 return context->priv->shared_async_depth;
940 gst_msdk_context_add_shared_async_depth (GstMsdkContext * context,
943 context->priv->shared_async_depth += async_depth;
947 gst_msdk_context_set_frame_allocator (GstMsdkContext * context,
948 mfxFrameAllocator * allocator)
950 GstMsdkContextPrivate *priv = context->priv;
952 g_mutex_lock (&priv->mutex);
954 if (!priv->has_frame_allocator) {
957 status = MFXVideoCORE_SetFrameAllocator (priv->session.session, allocator);
959 if (status != MFX_ERR_NONE)
960 GST_ERROR ("Failed to set frame allocator");
962 priv->has_frame_allocator = 1;
965 g_mutex_unlock (&priv->mutex);