nvcodec: Move common methods to nvdecoder
authorSeungha Yang <seungha@centricular.com>
Thu, 18 Jun 2020 19:50:26 +0000 (04:50 +0900)
committerGStreamer Merge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Wed, 24 Jun 2020 16:25:58 +0000 (16:25 +0000)
... and remove all #ifdef from nvh264sldec implementation.
New helper methods will take care of OpenGL specific ones.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1357>

sys/nvcodec/gstnvdecoder.c
sys/nvcodec/gstnvdecoder.h
sys/nvcodec/gstnvh264dec.c

index b7efcc0..4a2c909 100644 (file)
 #include "gstnvdecoder.h"
 #include <string.h>
 
-
 GST_DEBUG_CATEGORY_EXTERN (gst_nv_decoder_debug);
 #define GST_CAT_DEFAULT gst_nv_decoder_debug
 
+#ifdef HAVE_NVCODEC_GST_GL
+#define SUPPORTED_GL_APIS (GST_GL_API_OPENGL | GST_GL_API_OPENGL3)
+#endif
+
 typedef struct _GstNvDecoderFrameInfo
 {
   gboolean available;
@@ -1100,3 +1103,301 @@ gst_cuda_video_codec_to_string (cudaVideoCodec codec)
 
   return "unknown";
 }
+
+gboolean
+gst_nv_decoder_ensure_element_data (GstElement * decoder, guint cuda_device_id,
+    GstCudaContext ** cuda_context, CUstream * cuda_stream,
+    GstObject ** gl_display, GstObject ** other_gl_context)
+{
+  CUresult cuda_ret;
+
+  g_return_val_if_fail (GST_IS_ELEMENT (decoder), FALSE);
+  g_return_val_if_fail (cuda_context, FALSE);
+  g_return_val_if_fail (cuda_stream, FALSE);
+  g_return_val_if_fail (gl_display, FALSE);
+  g_return_val_if_fail (other_gl_context, FALSE);
+
+  if (!gst_cuda_ensure_element_context (decoder, cuda_device_id, cuda_context)) {
+    GST_ERROR_OBJECT (decoder, "failed to create CUDA context");
+    return FALSE;
+  }
+
+  if (gst_cuda_context_push (*cuda_context)) {
+    CUstream stream;
+    cuda_ret = CuStreamCreate (&stream, CU_STREAM_DEFAULT);
+    if (!gst_cuda_result (cuda_ret)) {
+      GST_WARNING_OBJECT (decoder,
+          "Could not create CUDA stream, will use default stream");
+      *cuda_stream = NULL;
+    } else {
+      *cuda_stream = stream;
+    }
+
+    gst_cuda_context_pop (NULL);
+  }
+#if HAVE_NVCODEC_GST_GL
+  gst_gl_ensure_element_data (decoder,
+      (GstGLDisplay **) gl_display, (GstGLContext **) other_gl_context);
+  if (*gl_display)
+    gst_gl_display_filter_gl_api (GST_GL_DISPLAY (*gl_display),
+        SUPPORTED_GL_APIS);
+#endif
+
+  return TRUE;
+}
+
+void
+gst_nv_decoder_set_context (GstElement * decoder, GstContext * context,
+    guint cuda_device_id, GstCudaContext ** cuda_context,
+    GstObject ** gl_display, GstObject ** other_gl_context)
+{
+  g_return_if_fail (GST_IS_ELEMENT (decoder));
+  g_return_if_fail (GST_IS_CONTEXT (context));
+  g_return_if_fail (cuda_context != NULL);
+  g_return_if_fail (gl_display != NULL);
+  g_return_if_fail (other_gl_context != NULL);
+
+  if (gst_cuda_handle_set_context (decoder, context, cuda_device_id,
+          cuda_context)) {
+    return;
+  }
+#ifdef HAVE_NVCODEC_GST_GL
+  gst_gl_handle_set_context (decoder, context,
+      (GstGLDisplay **) gl_display, (GstGLContext **) other_gl_context);
+#endif
+}
+
+gboolean
+gst_nv_decoder_handle_context_query (GstElement * decoder, GstQuery * query,
+    GstCudaContext * cuda_context, GstObject * gl_display,
+    GstObject * gl_context, GstObject * other_gl_context)
+{
+  g_return_val_if_fail (GST_IS_ELEMENT (decoder), FALSE);
+
+  if (gst_cuda_handle_context_query (decoder, query, cuda_context)) {
+    return TRUE;
+  }
+#ifdef HAVE_NVCODEC_GST_GL
+  if (gst_gl_handle_context_query (GST_ELEMENT (decoder), query,
+          (GstGLDisplay *) gl_display,
+          (GstGLContext *) gl_context, (GstGLContext *) other_gl_context)) {
+    if (gl_display)
+      gst_gl_display_filter_gl_api (GST_GL_DISPLAY (gl_display),
+          SUPPORTED_GL_APIS);
+    return TRUE;
+  }
+#endif
+
+  return FALSE;
+}
+
+#ifdef HAVE_NVCODEC_GST_GL
+static void
+gst_nv_decoder_check_cuda_device_from_context (GstGLContext * context,
+    gboolean * ret)
+{
+  guint device_count = 0;
+  CUdevice device_list[1] = { 0, };
+  CUresult cuda_ret;
+
+  *ret = FALSE;
+
+  cuda_ret = CuGLGetDevices (&device_count,
+      device_list, 1, CU_GL_DEVICE_LIST_ALL);
+
+  if (!gst_cuda_result (cuda_ret) || device_count == 0)
+    return;
+
+  *ret = TRUE;
+
+  return;
+}
+
+static gboolean
+gst_nv_decoder_ensure_gl_context (GstElement * decoder, GstObject * gl_display,
+    GstObject * other_gl_context, GstObject ** gl_context)
+{
+  gboolean ret;
+  GstGLDisplay *display;
+  GstGLContext *context;
+
+  if (!gl_display) {
+    GST_DEBUG_OBJECT (decoder, "No available OpenGL display");
+    return FALSE;
+  }
+
+  display = GST_GL_DISPLAY (gl_display);
+
+  if (!gst_gl_query_local_gl_context (decoder, GST_PAD_SRC,
+          (GstGLContext **) gl_context)) {
+    GST_INFO_OBJECT (decoder, "failed to query local OpenGL context");
+
+    gst_clear_object (gl_context);
+    *gl_context =
+        (GstObject *) gst_gl_display_get_gl_context_for_thread (display, NULL);
+    if (*gl_context == NULL
+        || !gst_gl_display_add_context (display,
+            GST_GL_CONTEXT (*gl_context))) {
+      gst_clear_object (gl_context);
+      if (!gst_gl_display_create_context (display,
+              (GstGLContext *) other_gl_context,
+              (GstGLContext **) gl_context, NULL)) {
+        GST_WARNING_OBJECT (decoder, "failed to create OpenGL context");
+        return FALSE;
+      }
+
+      if (!gst_gl_display_add_context (display, (GstGLContext *) * gl_context)) {
+        GST_WARNING_OBJECT (decoder,
+            "failed to add the OpenGL context to the display");
+        return FALSE;
+      }
+    }
+  }
+
+  context = GST_GL_CONTEXT (*gl_context);
+
+  if (!gst_gl_context_check_gl_version (context, SUPPORTED_GL_APIS, 3, 0)) {
+    GST_WARNING_OBJECT (decoder,
+        "OpenGL context could not support PBO download");
+    return FALSE;
+  }
+
+  gst_gl_context_thread_add (context,
+      (GstGLContextThreadFunc) gst_nv_decoder_check_cuda_device_from_context,
+      &ret);
+
+  if (!ret) {
+    GST_WARNING_OBJECT (decoder,
+        "Current OpenGL context is not CUDA-compatible");
+    return FALSE;
+  }
+
+  return TRUE;
+}
+#endif
+
+gboolean
+gst_nv_decoder_negotiate (GstVideoDecoder * decoder,
+    GstVideoCodecState * input_state, GstVideoFormat format, guint width,
+    guint height, GstObject * gl_display, GstObject * other_gl_context,
+    GstObject ** gl_context, GstVideoCodecState ** output_state,
+    GstNvDecoderOutputType * output_type)
+{
+  GstVideoCodecState *state;
+
+  g_return_val_if_fail (GST_IS_VIDEO_DECODER (decoder), FALSE);
+  g_return_val_if_fail (input_state != NULL, FALSE);
+  g_return_val_if_fail (format != GST_VIDEO_FORMAT_UNKNOWN, FALSE);
+  g_return_val_if_fail (width > 0, FALSE);
+  g_return_val_if_fail (height > 0, FALSE);
+  g_return_val_if_fail (output_state != NULL, FALSE);
+  g_return_val_if_fail (gl_context != NULL, FALSE);
+  g_return_val_if_fail (output_type != NULL, FALSE);
+
+  state = gst_video_decoder_set_output_state (decoder,
+      format, width, height, input_state);
+  state->caps = gst_video_info_to_caps (&state->info);
+
+  if (*output_state)
+    gst_video_codec_state_unref (*output_state);
+  *output_state = state;
+
+  *output_type = GST_NV_DECOCER_OUTPUT_TYPE_SYSTEM;
+
+#ifdef HAVE_NVCODEC_GST_GL
+  {
+    GstCaps *caps;
+    caps = gst_pad_get_allowed_caps (GST_VIDEO_DECODER_SRC_PAD (decoder));
+    GST_DEBUG_OBJECT (decoder, "Allowed caps %" GST_PTR_FORMAT, caps);
+
+    if (!caps || gst_caps_is_any (caps)) {
+      GST_DEBUG_OBJECT (decoder,
+          "cannot determine output format, using system memory");
+    } else if (gl_display) {
+      GstCapsFeatures *features;
+      guint size = gst_caps_get_size (caps);
+      guint i;
+
+      for (i = 0; i < size; i++) {
+        features = gst_caps_get_features (caps, i);
+        if (features && gst_caps_features_contains (features,
+                GST_CAPS_FEATURE_MEMORY_GL_MEMORY)) {
+          GST_DEBUG_OBJECT (decoder, "found GL memory feature, using gl");
+          *output_type = GST_NV_DECOCER_OUTPUT_TYPE_GL;
+          break;
+        }
+      }
+    }
+    gst_clear_caps (&caps);
+  }
+
+  if (*output_type == GST_NV_DECOCER_OUTPUT_TYPE_GL &&
+      !gst_nv_decoder_ensure_gl_context (GST_ELEMENT (decoder),
+          gl_display, other_gl_context, gl_context)) {
+    GST_WARNING_OBJECT (decoder,
+        "OpenGL context is not CUDA-compatible, fallback to system memory");
+    *output_type = GST_NV_DECOCER_OUTPUT_TYPE_SYSTEM;
+  }
+
+  if (*output_type == GST_NV_DECOCER_OUTPUT_TYPE_GL) {
+    gst_caps_set_features (state->caps, 0,
+        gst_caps_features_new (GST_CAPS_FEATURE_MEMORY_GL_MEMORY, NULL));
+    gst_caps_set_simple (state->caps, "texture-target", G_TYPE_STRING,
+        "2D", NULL);
+  } else {
+    GST_DEBUG_OBJECT (decoder, "using system memory");
+  }
+#endif
+
+  return TRUE;
+}
+
+gboolean
+gst_nv_decoder_decide_allocation (GstVideoDecoder * decocer, GstQuery * query,
+    GstObject * gl_context, GstNvDecoderOutputType output_type)
+{
+#ifdef HAVE_NVCODEC_GST_GL
+  GstCaps *outcaps;
+  GstBufferPool *pool = NULL;
+  guint n, size, min, max;
+  GstVideoInfo vinfo = { 0, };
+  GstStructure *config;
+
+  GST_DEBUG_OBJECT (decocer, "decide allocation");
+
+  /* GstVideoDecoder will take care this case */
+  if (output_type == GST_NV_DECOCER_OUTPUT_TYPE_SYSTEM)
+    return TRUE;
+
+  gst_query_parse_allocation (query, &outcaps, NULL);
+  n = gst_query_get_n_allocation_pools (query);
+  if (n > 0)
+    gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max);
+
+  if (pool && !GST_IS_GL_BUFFER_POOL (pool)) {
+    gst_object_unref (pool);
+    pool = NULL;
+  }
+
+  if (!pool) {
+    pool = gst_gl_buffer_pool_new (GST_GL_CONTEXT (gl_context));
+
+    if (outcaps)
+      gst_video_info_from_caps (&vinfo, outcaps);
+    size = (guint) vinfo.size;
+    min = max = 0;
+  }
+
+  config = gst_buffer_pool_get_config (pool);
+  gst_buffer_pool_config_set_params (config, outcaps, size, min, max);
+  gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META);
+  gst_buffer_pool_set_config (pool, config);
+  if (n > 0)
+    gst_query_set_nth_allocation_pool (query, 0, pool, size, min, max);
+  else
+    gst_query_add_allocation_pool (query, pool, size, min, max);
+  gst_object_unref (pool);
+#endif
+
+  return TRUE;
+}
index e0bf968..d3fc085 100644 (file)
@@ -84,6 +84,49 @@ gboolean gst_nv_decoder_check_device_caps (CUcontext cuda_ctx,
 G_GNUC_INTERNAL
 const gchar * gst_cuda_video_codec_to_string (cudaVideoCodec codec);
 
+/* helper methods */
+G_GNUC_INTERNAL
+gboolean gst_nv_decoder_ensure_element_data  (GstElement * decoder,
+                                              guint cuda_device_id,
+                                              GstCudaContext ** cuda_context,
+                                              CUstream * cuda_stream,
+                                              GstObject ** gl_display,
+                                              GstObject ** other_gl_context);
+
+G_GNUC_INTERNAL
+void     gst_nv_decoder_set_context          (GstElement * decoder,
+                                              GstContext * context,
+                                              guint cuda_device_id,
+                                              GstCudaContext ** cuda_context,
+                                              GstObject ** gl_display,
+                                              GstObject ** other_gl_context);
+
+G_GNUC_INTERNAL
+gboolean gst_nv_decoder_handle_context_query (GstElement * decoder,
+                                              GstQuery * query,
+                                              GstCudaContext * cuda_context,
+                                              GstObject * gl_display,
+                                              GstObject * gl_context,
+                                              GstObject * other_gl_context);
+
+G_GNUC_INTERNAL
+gboolean gst_nv_decoder_negotiate            (GstVideoDecoder * decoder,
+                                              GstVideoCodecState * input_state,
+                                              GstVideoFormat format,
+                                              guint width,
+                                              guint height,
+                                              GstObject * gl_display,
+                                              GstObject * other_gl_context,
+                                              GstObject ** gl_context,
+                                              GstVideoCodecState ** output_state,
+                                              GstNvDecoderOutputType * output_type);
+
+G_GNUC_INTERNAL
+gboolean gst_nv_decoder_decide_allocation (GstVideoDecoder * decocer,
+                                           GstQuery * query,
+                                           GstObject * gl_context,
+                                           GstNvDecoderOutputType output_type);
+
 G_END_DECLS
 
 #endif /* __GST_NV_DECODER_H__ */
index ea4f788..9c3cc0a 100644 (file)
 #include "config.h"
 #endif
 
-#ifdef HAVE_NVCODEC_GST_GL
-#include <gst/gl/gl.h>
-#include <gst/gl/gstglfuncs.h>
-#endif
-
 #include "gstnvh264dec.h"
 #include "gstcudautils.h"
 #include "gstnvdecoder.h"
 GST_DEBUG_CATEGORY_STATIC (gst_nv_h264_dec_debug);
 #define GST_CAT_DEFAULT gst_nv_h264_dec_debug
 
-#ifdef HAVE_NVCODEC_GST_GL
-#define SUPPORTED_GL_APIS (GST_GL_API_OPENGL | GST_GL_API_OPENGL3 | GST_GL_API_GLES2)
-#endif
-
 struct _GstNvH264Dec
 {
   GstH264Decoder parent;
@@ -229,17 +220,9 @@ gst_nv_h264_dec_set_context (GstElement * element, GstContext * context)
   GST_DEBUG_OBJECT (self, "set context %s",
       gst_context_get_context_type (context));
 
-  if (gst_cuda_handle_set_context (element, context, klass->cuda_device_id,
-          &self->context)) {
-    goto done;
-  }
-#ifdef HAVE_NVCODEC_GST_GL
-  gst_gl_handle_set_context (element, context,
-      (GstGLDisplay **) & self->gl_display,
-      (GstGLContext **) & self->other_gl_context);
-#endif
+  gst_nv_decoder_set_context (element, context, klass->cuda_device_id,
+      &self->context, &self->gl_display, &self->other_gl_context);
 
-done:
   GST_ELEMENT_CLASS (parent_class)->set_context (element, context);
 }
 
@@ -248,32 +231,14 @@ gst_nv_h264_dec_open (GstVideoDecoder * decoder)
 {
   GstNvH264Dec *self = GST_NV_H264_DEC (decoder);
   GstNvH264DecClass *klass = GST_NV_H264_DEC_GET_CLASS (self);
-  CUresult cuda_ret;
 
-  if (!gst_cuda_ensure_element_context (GST_ELEMENT_CAST (decoder),
-          klass->cuda_device_id, &self->context)) {
-    GST_ERROR_OBJECT (self, "failed to create CUDA context");
+  if (!gst_nv_decoder_ensure_element_data (GST_ELEMENT (self),
+          klass->cuda_device_id, &self->context, &self->cuda_stream,
+          &self->gl_display, &self->other_gl_context)) {
+    GST_ERROR_OBJECT (self, "Required element data is unavailable");
     return FALSE;
   }
 
-  if (gst_cuda_context_push (self->context)) {
-    cuda_ret = CuStreamCreate (&self->cuda_stream, CU_STREAM_DEFAULT);
-    if (!gst_cuda_result (cuda_ret)) {
-      GST_WARNING_OBJECT (self,
-          "Could not create CUDA stream, will use default stream");
-      self->cuda_stream = NULL;
-    }
-    gst_cuda_context_pop (NULL);
-  }
-#if HAVE_NVCODEC_GST_GL
-  gst_gl_ensure_element_data (GST_ELEMENT (self),
-      (GstGLDisplay **) & self->gl_display,
-      (GstGLContext **) & self->other_gl_context);
-  if (self->gl_display)
-    gst_gl_display_filter_gl_api (GST_GL_DISPLAY (self->gl_display),
-        SUPPORTED_GL_APIS);
-#endif
-
   return TRUE;
 }
 
@@ -301,153 +266,17 @@ gst_nv_h264_dec_close (GstVideoDecoder * decoder)
   return TRUE;
 }
 
-#ifdef HAVE_NVCODEC_GST_GL
-static void
-gst_nv_h264_dec_check_cuda_device_from_context (GstGLContext * context,
-    gboolean * ret)
-{
-  guint device_count = 0;
-  CUdevice device_list[1] = { 0, };
-  CUresult cuda_ret;
-
-  *ret = FALSE;
-
-  cuda_ret = CuGLGetDevices (&device_count,
-      device_list, 1, CU_GL_DEVICE_LIST_ALL);
-
-  if (!gst_cuda_result (cuda_ret) || device_count == 0)
-    return;
-
-  *ret = TRUE;
-
-  return;
-}
-
-static gboolean
-gst_nv_h264_dec_ensure_gl_context (GstNvH264Dec * self)
-{
-  gboolean ret;
-  GstGLDisplay *display;
-  GstGLContext *context;
-
-  if (!self->gl_display) {
-    GST_DEBUG_OBJECT (self, "No available OpenGL display");
-    return FALSE;
-  }
-
-  display = GST_GL_DISPLAY (self->gl_display);
-
-  if (!gst_gl_query_local_gl_context (GST_ELEMENT (self), GST_PAD_SRC,
-          (GstGLContext **) & self->gl_context)) {
-    GST_INFO_OBJECT (self, "failed to query local OpenGL context");
-
-    gst_clear_object (&self->gl_context);
-    self->gl_context =
-        (GstObject *) gst_gl_display_get_gl_context_for_thread (display, NULL);
-    if (!self->gl_context
-        || !gst_gl_display_add_context (display,
-            GST_GL_CONTEXT (self->gl_context))) {
-      gst_clear_object (&self->gl_context);
-      if (!gst_gl_display_create_context (display,
-              (GstGLContext *) self->other_gl_context,
-              (GstGLContext **) & self->gl_context, NULL)) {
-        GST_ERROR_OBJECT (self, "failed to create OpenGL context");
-        return FALSE;
-      }
-
-      if (!gst_gl_display_add_context (display,
-              (GstGLContext *) self->gl_context)) {
-        GST_ERROR_OBJECT (self,
-            "failed to add the OpenGL context to the display");
-        return FALSE;
-      }
-    }
-  }
-
-  context = GST_GL_CONTEXT (self->gl_context);
-
-  if (!gst_gl_context_check_gl_version (context, SUPPORTED_GL_APIS, 3, 0)) {
-    GST_WARNING_OBJECT (self, "OpenGL context could not support PBO download");
-    return FALSE;
-  }
-
-  gst_gl_context_thread_add (context,
-      (GstGLContextThreadFunc) gst_nv_h264_dec_check_cuda_device_from_context,
-      &ret);
-
-  if (!ret) {
-    GST_WARNING_OBJECT (self, "Current OpenGL context is not CUDA-compatible");
-    return FALSE;
-  }
-
-  return TRUE;
-}
-#endif
-
 static gboolean
 gst_nv_h264_dec_negotiate (GstVideoDecoder * decoder)
 {
   GstNvH264Dec *self = GST_NV_H264_DEC (decoder);
   GstH264Decoder *h264dec = GST_H264_DECODER (decoder);
-  GstVideoCodecState *state;
 
   GST_DEBUG_OBJECT (self, "negotiate");
 
-  state = gst_video_decoder_set_output_state (GST_VIDEO_DECODER (self),
-      self->out_format, self->width, self->height, h264dec->input_state);
-
-  state->caps = gst_video_info_to_caps (&state->info);
-
-  self->output_type = GST_NV_DECOCER_OUTPUT_TYPE_SYSTEM;
-
-#ifdef HAVE_NVCODEC_GST_GL
-  {
-    GstCaps *caps;
-    caps = gst_pad_get_allowed_caps (GST_VIDEO_DECODER_SRC_PAD (self));
-    GST_DEBUG_OBJECT (self, "Allowed caps %" GST_PTR_FORMAT, caps);
-
-    if (!caps || gst_caps_is_any (caps)) {
-      GST_DEBUG_OBJECT (self,
-          "cannot determine output format, use system memory");
-    } else if (self->gl_display) {
-      GstCapsFeatures *features;
-      guint size = gst_caps_get_size (caps);
-      guint i;
-
-      for (i = 0; i < size; i++) {
-        features = gst_caps_get_features (caps, i);
-        if (features && gst_caps_features_contains (features,
-                GST_CAPS_FEATURE_MEMORY_GL_MEMORY)) {
-          GST_DEBUG_OBJECT (self, "found GL memory feature, use gl");
-          self->output_type = GST_NV_DECOCER_OUTPUT_TYPE_GL;
-          break;
-        }
-      }
-    }
-    gst_clear_caps (&caps);
-  }
-
-  if (self->output_type == GST_NV_DECOCER_OUTPUT_TYPE_GL &&
-      !gst_nv_h264_dec_ensure_gl_context (self)) {
-    GST_WARNING_OBJECT (self,
-        "OpenGL context is not CUDA-compatible, fallback to system memory");
-    self->output_type = GST_NV_DECOCER_OUTPUT_TYPE_SYSTEM;
-  }
-
-  if (self->output_type == GST_NV_DECOCER_OUTPUT_TYPE_GL) {
-    gst_caps_set_features (state->caps, 0,
-        gst_caps_features_new (GST_CAPS_FEATURE_MEMORY_GL_MEMORY, NULL));
-    gst_caps_set_simple (state->caps, "texture-target", G_TYPE_STRING,
-        "2D", NULL);
-  } else {
-    GST_DEBUG_OBJECT (self, "use system memory");
-  }
-#endif
-
-  if (self->output_state)
-    gst_video_codec_state_unref (self->output_state);
-
-  self->output_state = state;
+  gst_nv_decoder_negotiate (decoder, h264dec->input_state, self->out_format,
+      self->width, self->height, self->gl_display, self->other_gl_context,
+      &self->gl_context, &self->output_state, &self->output_type);
 
   /* TODO: add support D3D11 memory */
 
@@ -457,49 +286,10 @@ gst_nv_h264_dec_negotiate (GstVideoDecoder * decoder)
 static gboolean
 gst_nv_h264_dec_decide_allocation (GstVideoDecoder * decoder, GstQuery * query)
 {
-#ifdef HAVE_NVCODEC_GST_GL
   GstNvH264Dec *self = GST_NV_H264_DEC (decoder);
-  GstCaps *outcaps;
-  GstBufferPool *pool = NULL;
-  guint n, size, min, max;
-  GstVideoInfo vinfo = { 0, };
-  GstStructure *config;
-
-  GST_DEBUG_OBJECT (self, "decide allocation");
-
-  if (self->output_type == GST_NV_DECOCER_OUTPUT_TYPE_SYSTEM)
-    return GST_VIDEO_DECODER_CLASS (parent_class)->decide_allocation
-        (decoder, query);
-
-  gst_query_parse_allocation (query, &outcaps, NULL);
-  n = gst_query_get_n_allocation_pools (query);
-  if (n > 0)
-    gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max);
-
-  if (pool && !GST_IS_GL_BUFFER_POOL (pool)) {
-    gst_object_unref (pool);
-    pool = NULL;
-  }
 
-  if (!pool) {
-    pool = gst_gl_buffer_pool_new (GST_GL_CONTEXT (self->gl_context));
-
-    if (outcaps)
-      gst_video_info_from_caps (&vinfo, outcaps);
-    size = (guint) vinfo.size;
-    min = max = 0;
-  }
-
-  config = gst_buffer_pool_get_config (pool);
-  gst_buffer_pool_config_set_params (config, outcaps, size, min, max);
-  gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META);
-  gst_buffer_pool_set_config (pool, config);
-  if (n > 0)
-    gst_query_set_nth_allocation_pool (query, 0, pool, size, min, max);
-  else
-    gst_query_add_allocation_pool (query, pool, size, min, max);
-  gst_object_unref (pool);
-#endif
+  gst_nv_decoder_decide_allocation (decoder, query,
+      self->gl_context, self->output_type);
 
   return GST_VIDEO_DECODER_CLASS (parent_class)->decide_allocation
       (decoder, query);
@@ -512,21 +302,11 @@ gst_nv_h264_dec_src_query (GstVideoDecoder * decoder, GstQuery * query)
 
   switch (GST_QUERY_TYPE (query)) {
     case GST_QUERY_CONTEXT:
-      if (gst_cuda_handle_context_query (GST_ELEMENT (decoder),
-              query, self->context)) {
-        return TRUE;
-      }
-#ifdef HAVE_NVCODEC_GST_GL
-      if (gst_gl_handle_context_query (GST_ELEMENT (decoder), query,
-              (GstGLDisplay *) self->gl_display,
-              (GstGLContext *) self->gl_context,
-              (GstGLContext *) self->other_gl_context)) {
-        if (self->gl_display)
-          gst_gl_display_filter_gl_api (GST_GL_DISPLAY (self->gl_display),
-              SUPPORTED_GL_APIS);
+      if (gst_nv_decoder_handle_context_query (GST_ELEMENT (self), query,
+              self->context, self->gl_display, self->gl_context,
+              self->other_gl_context)) {
         return TRUE;
       }
-#endif
       break;
     default:
       break;
@@ -680,10 +460,9 @@ gst_nv_h264_dec_output_picture (GstH264Decoder * decoder,
       gst_video_decoder_allocate_output_buffer (GST_VIDEO_DECODER (self));
   frame->output_buffer = output_buffer;
 
-#ifdef HAVE_NVCODEC_GST_GL
   if (self->output_type == GST_NV_DECOCER_OUTPUT_TYPE_GL) {
     ret = gst_nv_decoder_finish_frame (self->decoder,
-        GST_NV_DECOCER_OUTPUT_TYPE_GL, GST_OBJECT (self->gl_context),
+        GST_NV_DECOCER_OUTPUT_TYPE_GL, self->gl_context,
         decoder_frame, output_buffer);
 
     /* FIXME: This is the case where OpenGL context of downstream glbufferpool
@@ -697,9 +476,7 @@ gst_nv_h264_dec_output_picture (GstH264Decoder * decoder,
     }
   }
 
-  if (!ret)
-#endif
-  {
+  if (!ret) {
     if (!gst_nv_decoder_finish_frame (self->decoder,
             GST_NV_DECOCER_OUTPUT_TYPE_SYSTEM, NULL, decoder_frame,
             output_buffer)) {