MSDK: Add _context_query() and avoid compile error on Windows
authorWu Tong <tong1.wu@intel.com>
Mon, 14 Feb 2022 08:15:46 +0000 (16:15 +0800)
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Mon, 28 Feb 2022 12:54:23 +0000 (12:54 +0000)
To avoid compile error on Windows, macro definitions are added to suppress va
variables. In the meantime, add function _context_query() to query
context on Windows.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1693>

subprojects/gst-plugins-bad/sys/msdk/gstmsdkcontextutil.c
subprojects/gst-plugins-bad/sys/msdk/gstmsdkenc.c

index 1aa7654..a852b31 100644 (file)
@@ -49,6 +49,95 @@ _init_context_debug (void)
 #endif
 }
 
+#ifdef _WIN32
+static gboolean
+_pad_query (const GValue * item, GValue * value, gpointer user_data)
+{
+  GstPad *pad = g_value_get_object (item);
+  GstQuery *query = user_data;
+  gboolean res;
+
+  res = gst_pad_peer_query (pad, query);
+
+  if (res) {
+    g_value_set_boolean (value, TRUE);
+    return FALSE;
+  }
+
+  GST_CAT_INFO_OBJECT (GST_CAT_CONTEXT, pad, "pad peer query failed");
+  return TRUE;
+}
+
+static gboolean
+_run_query (GstElement * element, GstQuery * query, GstPadDirection direction)
+{
+  GstIterator *it;
+  GstIteratorFoldFunction func = _pad_query;
+  GValue res = G_VALUE_INIT;
+
+  g_value_init (&res, G_TYPE_BOOLEAN);
+  g_value_set_boolean (&res, FALSE);
+
+  if (direction == GST_PAD_SRC)
+    it = gst_element_iterate_src_pads (element);
+  else
+    it = gst_element_iterate_sink_pads (element);
+
+  while (gst_iterator_fold (it, func, &res, query) == GST_ITERATOR_RESYNC)
+    gst_iterator_resync (it);
+
+  gst_iterator_free (it);
+
+  return g_value_get_boolean (&res);
+}
+
+static void
+_context_query (GstElement * element, const gchar * context_type)
+{
+  GstQuery *query;
+  GstContext *ctxt = NULL;
+
+  /*  2a) Query downstream with GST_QUERY_CONTEXT for the context and
+   *      check if downstream already has a context of the specific type
+   *  2b) Query upstream as above.
+   */
+  query = gst_query_new_context (context_type);
+  if (_run_query (element, query, GST_PAD_SRC)) {
+    gst_query_parse_context (query, &ctxt);
+    GST_CAT_INFO_OBJECT (GST_CAT_CONTEXT, element,
+        "found context (%p) in downstream query", ctxt);
+    gst_element_set_context (element, ctxt);
+  } else if (_run_query (element, query, GST_PAD_SINK)) {
+    gst_query_parse_context (query, &ctxt);
+    GST_CAT_INFO_OBJECT (GST_CAT_CONTEXT, element,
+        "found context (%p) in upstream query", ctxt);
+    gst_element_set_context (element, ctxt);
+  } else {
+    /* 3) Post a GST_MESSAGE_NEED_CONTEXT message on the bus with
+     *    the required context type and afterwards check if a
+     *    usable context was set now as in 1). The message could
+     *    be handled by the parent bins of the element and the
+     *    application.
+     */
+    GstMessage *msg;
+
+    GST_CAT_INFO_OBJECT (GST_CAT_CONTEXT, element,
+        "posting need context message");
+    msg = gst_message_new_need_context (GST_OBJECT_CAST (element),
+        context_type);
+    gst_element_post_message (element, msg);
+  }
+
+  /*
+   * Whomever responds to the need-context message performs a
+   * GstElement::set_context() with the required context in which the element
+   * is required to update the display_ptr or call gst_va_handle_set_context().
+   */
+
+  gst_query_unref (query);
+}
+#endif
+
 /* Find whether the other elements already have a msdk context. */
 gboolean
 gst_msdk_context_find (GstElement * element, GstMsdkContext ** context_ptr)
@@ -66,7 +155,11 @@ gst_msdk_context_find (GstElement * element, GstMsdkContext ** context_ptr)
   }
 
   /* This may indirectly set *context_ptr, see function body */
+#ifndef _WIN32
   gst_va_context_query (element, GST_MSDK_CONTEXT_TYPE_NAME);
+#else
+  _context_query (element, GST_MSDK_CONTEXT_TYPE_NAME);
+#endif
 
   if (*context_ptr) {
     GST_LOG_OBJECT (element, "found a context %" GST_PTR_FORMAT, *context_ptr);
index f25ae4a..07c21f0 100644 (file)
@@ -120,7 +120,9 @@ typedef struct
   mfxFrameSurface1 *surface;
   GstBuffer *buf;
   GstBuffer *buf_external;
+#ifndef _WIN32
   VASurfaceID cache_surface;
+#endif
 } MsdkSurface;
 
 void
@@ -964,7 +966,9 @@ gst_msdkenc_free_surface (MsdkSurface * surface)
 
     mfx_surface = surface->surface;
     msdk_mid = (GstMsdkMemoryID *) mfx_surface->Data.MemId;
+#ifndef _WIN32
     *msdk_mid->surface = surface->cache_surface;
+#endif
 
     gst_buffer_unref (surface->buf_external);
   }