vdpau: cleanup GstVdpDecoder opening of it's GstVdpDevice
authorCarl-Anton Ingmarsson <ca.ingmarsson@gmail.com>
Tue, 27 Jul 2010 21:24:43 +0000 (23:24 +0200)
committerCarl-Anton Ingmarsson <ca.ingmarsson@gmail.com>
Fri, 30 Jul 2010 09:31:59 +0000 (11:31 +0200)
we now no longer try to get the GstVdpDevice from downstream since it in
practice didn't give us anything and complicates the code alot. Nevertheless if device
distribution should be done there's probably a lot better ways to do it.

sys/vdpau/gstvdp/gstvdpdecoder.c
sys/vdpau/gstvdp/gstvdpdecoder.h
sys/vdpau/gstvdp/gstvdpvideosrcpad.c
sys/vdpau/gstvdp/gstvdpvideosrcpad.h
sys/vdpau/h264/gstvdph264dec.c
sys/vdpau/mpeg/gstvdpmpegdec.c

index a87ea6a3cc1d9a68d9ca141944767bdad4d42186..8870398b205b687f2540bac8386cc8e75e74737d 100644 (file)
@@ -102,23 +102,6 @@ gst_vdp_decoder_alloc_buffer (GstVdpDecoder * vdp_decoder,
   return ret;
 }
 
-static GstFlowReturn
-gst_vdp_decoder_get_device (GstVdpDecoder * vdp_decoder, GstVdpDevice ** device)
-{
-  GstVdpVideoSrcPad *vdp_pad;
-
-  GstFlowReturn ret;
-  GError *err = NULL;
-
-  vdp_pad = (GstVdpVideoSrcPad *) GST_BASE_VIDEO_DECODER_SRC_PAD (vdp_decoder);
-
-  ret = gst_vdp_video_src_pad_get_device (vdp_pad, device, &err);
-  if (ret == GST_FLOW_ERROR)
-    gst_vdp_decoder_post_error (vdp_decoder, err);
-
-  return ret;
-}
-
 GstFlowReturn
 gst_vdp_decoder_render (GstVdpDecoder * vdp_decoder, VdpPictureInfo * info,
     guint n_bufs, VdpBitstreamBuffer * bufs, GstVdpVideoBuffer ** video_buf)
@@ -158,15 +141,12 @@ GstFlowReturn
 gst_vdp_decoder_init_decoder (GstVdpDecoder * vdp_decoder,
     VdpDecoderProfile profile, guint32 max_references)
 {
-  GstFlowReturn ret;
   GstVdpDevice *device;
 
   VdpStatus status;
   GstVideoState state;
 
-  ret = gst_vdp_decoder_get_device (vdp_decoder, &device);
-  if (ret != GST_FLOW_OK)
-    return ret;
+  device = vdp_decoder->device;
 
   if (vdp_decoder->decoder != VDP_INVALID_HANDLE) {
     status = device->vdp_decoder_destroy (vdp_decoder->decoder);
@@ -201,6 +181,55 @@ create_decoder_error:
   return GST_FLOW_ERROR;
 }
 
+static gboolean
+gst_vdp_decoder_start (GstBaseVideoDecoder * base_video_decoder)
+{
+  GstVdpDecoder *vdp_decoder = GST_VDP_DECODER (base_video_decoder);
+
+  GstVdpVideoSrcPad *vdp_pad;
+
+  vdp_decoder->device = gst_vdp_get_device (vdp_decoder->display);
+  if (G_UNLIKELY (!vdp_decoder->device))
+    goto device_error;
+
+  vdp_pad =
+      (GstVdpVideoSrcPad *) GST_BASE_VIDEO_DECODER_SRC_PAD (base_video_decoder);
+  g_object_set (G_OBJECT (vdp_pad), "device", vdp_decoder->device, NULL);
+
+  vdp_decoder->decoder = VDP_INVALID_HANDLE;
+
+  return TRUE;
+
+device_error:
+  GST_ELEMENT_ERROR (vdp_decoder, RESOURCE, OPEN_READ,
+      ("Couldn't create GstVdpDevice"), (NULL));
+  return FALSE;
+}
+
+static gboolean
+gst_vdp_decoder_stop (GstBaseVideoDecoder * base_video_decoder)
+{
+  GstVdpDecoder *vdp_decoder = GST_VDP_DECODER (base_video_decoder);
+
+  if (vdp_decoder->decoder != VDP_INVALID_HANDLE) {
+    GstVdpDevice *device = vdp_decoder->device;
+    VdpStatus status;
+
+    status = device->vdp_decoder_destroy (vdp_decoder->decoder);
+    if (status != VDP_STATUS_OK) {
+      GST_ELEMENT_ERROR (vdp_decoder, RESOURCE, READ,
+          ("Could not destroy vdpau decoder"),
+          ("Error returned from vdpau was: %s",
+              device->vdp_get_error_string (status)));
+      return FALSE;
+    }
+  }
+
+  g_object_unref (vdp_decoder->device);
+
+  return TRUE;
+}
+
 static void
 gst_vdp_decoder_get_property (GObject * object, guint prop_id,
     GValue * value, GParamSpec * pspec)
@@ -209,10 +238,9 @@ gst_vdp_decoder_get_property (GObject * object, guint prop_id,
 
   switch (prop_id) {
     case PROP_DISPLAY:
-      g_object_get_property
-          (G_OBJECT (GST_BASE_VIDEO_DECODER_SRC_PAD (vdp_decoder)), "display",
-          value);
+      g_value_set_string (value, vdp_decoder->display);
       break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -227,16 +255,26 @@ gst_vdp_decoder_set_property (GObject * object, guint prop_id,
 
   switch (prop_id) {
     case PROP_DISPLAY:
-      g_object_set_property
-          (G_OBJECT (GST_BASE_VIDEO_DECODER_SRC_PAD (vdp_decoder)), "display",
-          value);
+      g_free (vdp_decoder->display);
+      vdp_decoder->display = g_value_dup_string (value);
       break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
   }
 }
 
+static void
+gst_vdp_decoder_finalize (GObject * object)
+{
+  GstVdpDecoder *vdp_decoder = GST_VDP_DECODER (object);
+
+  g_free (vdp_decoder->display);
+
+  G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
 static void
 gst_vdp_decoder_base_init (gpointer g_class)
 {
@@ -253,9 +291,9 @@ gst_vdp_decoder_base_init (gpointer g_class)
 }
 
 static void
-gst_vdp_decoder_init (GstVdpDecoder * decoder, GstVdpDecoderClass * klass)
+gst_vdp_decoder_init (GstVdpDecoder * vdp_decoder, GstVdpDecoderClass * klass)
 {
-  decoder->decoder = VDP_INVALID_HANDLE;
+  vdp_decoder->display = NULL;
 }
 
 static void
@@ -269,6 +307,10 @@ gst_vdp_decoder_class_init (GstVdpDecoderClass * klass)
 
   object_class->get_property = gst_vdp_decoder_get_property;
   object_class->set_property = gst_vdp_decoder_set_property;
+  object_class->finalize = gst_vdp_decoder_finalize;
+
+  base_video_decoder_class->start = gst_vdp_decoder_start;
+  base_video_decoder_class->stop = gst_vdp_decoder_stop;
 
   base_video_decoder_class->create_srcpad = gst_vdp_decoder_create_srcpad;
   base_video_decoder_class->shape_output = gst_vdp_decoder_shape_output;
index a8ef888db6dca16e15abc6722fe16379867bd298..9ccf24379e11e186adfb3e228871cea0167deb2f 100644 (file)
@@ -43,7 +43,11 @@ typedef struct _GstVdpDecoderClass GstVdpDecoderClass;
 struct _GstVdpDecoder {
   GstBaseVideoDecoder base_video_decoder;
 
+  GstVdpDevice *device;
   VdpDecoder decoder;
+
+  /* properties */
+  gchar *display;
 };
 
 struct _GstVdpDecoderClass {
index 59c6d5f65cfc01a4acf12f1cde88a6beb9ecede5..d2cc9bed827722e50a8232ffa2e505d0c585b082 100644 (file)
@@ -28,7 +28,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_vdp_video_src_pad_debug);
 enum
 {
   PROP_0,
-  PROP_DISPLAY
+  PROP_DEVICE
 };
 
 struct _GstVdpVideoSrcPad
@@ -36,14 +36,13 @@ struct _GstVdpVideoSrcPad
   GstPad pad;
 
   GstCaps *caps;
-  GstVdpDevice *device;
 
   gboolean yuv_output;
   gint width, height;
   guint32 fourcc;
 
   /* properties */
-  gchar *display;
+  GstVdpDevice *device;
 };
 
 struct _GstVdpVideoSrcPadClass
@@ -57,6 +56,16 @@ GST_DEBUG_CATEGORY_INIT (gst_vdp_video_src_pad_debug, "vdpvideosrcpad", 0, "GstV
 G_DEFINE_TYPE_WITH_CODE (GstVdpVideoSrcPad, gst_vdp_video_src_pad, GST_TYPE_PAD,
     DEBUG_INIT ());
 
+GstVdpVideoSrcPad *
+gst_vdp_video_src_pad_new (GstPadTemplate * templ, const gchar * name)
+{
+  g_return_val_if_fail (GST_IS_PAD_TEMPLATE (templ), NULL);
+  g_return_val_if_fail ((templ->direction == GST_PAD_SRC), NULL);
+
+  return g_object_new (GST_TYPE_VDP_VIDEO_SRC_PAD,
+      "name", name, "direction", templ->direction, "template", templ, NULL);
+}
+
 GstFlowReturn
 gst_vdp_video_src_pad_push (GstVdpVideoSrcPad * vdp_pad,
     GstVdpVideoBuffer * video_buf)
@@ -124,41 +133,6 @@ gst_vdp_video_src_pad_push (GstVdpVideoSrcPad * vdp_pad,
   return gst_pad_push (pad, out_buf);
 }
 
-static void
-gst_vdp_video_src_pad_update_caps (GstVdpVideoSrcPad * vdp_pad)
-{
-  GstCaps *caps;
-  const GstCaps *templ_caps;
-
-  if (vdp_pad->caps)
-    gst_caps_unref (vdp_pad->caps);
-
-  caps = gst_vdp_video_buffer_get_allowed_caps (vdp_pad->device);
-
-  if ((templ_caps = gst_pad_get_pad_template_caps (GST_PAD (vdp_pad)))) {
-    vdp_pad->caps = gst_caps_intersect (caps, templ_caps);
-    gst_caps_unref (caps);
-  } else
-    vdp_pad->caps = caps;
-}
-
-static gboolean
-gst_vdp_video_src_pad_open_device (GstVdpVideoSrcPad * vdp_pad, GError ** error)
-{
-  GstVdpDevice *device;
-
-  vdp_pad->device = device = gst_vdp_get_device (vdp_pad->display);
-  if (G_UNLIKELY (!vdp_pad->device))
-    goto device_error;
-
-  return TRUE;
-
-device_error:
-  g_set_error (error, GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_OPEN_READ,
-      "Couldn't create GstVdpDevice");
-  return FALSE;
-}
-
 static GstFlowReturn
 gst_vdp_video_src_pad_alloc_with_caps (GstVdpVideoSrcPad * vdp_pad,
     GstCaps * caps, GstVdpVideoBuffer ** video_buf, GError ** error)
@@ -205,32 +179,18 @@ gst_vdp_video_src_pad_alloc_buffer (GstVdpVideoSrcPad * vdp_pad,
     return GST_FLOW_NOT_NEGOTIATED;
 
   if (vdp_pad->yuv_output) {
-    GstVdpDevice *device;
-
-    if (G_UNLIKELY (!vdp_pad->device)) {
-      if (!gst_vdp_video_src_pad_open_device (vdp_pad, error))
-        return GST_FLOW_ERROR;
-
-      gst_vdp_video_src_pad_update_caps (vdp_pad);
-    }
-    device = vdp_pad->device;
+    GstVdpDevice *device = vdp_pad->device;
 
     *video_buf = gst_vdp_video_buffer_new (device, VDP_CHROMA_TYPE_420,
         vdp_pad->width, vdp_pad->height);
     if (!*video_buf)
       goto video_buf_error;
+
   } else {
     ret = gst_vdp_video_src_pad_alloc_with_caps (vdp_pad, caps, video_buf,
         error);
     if (ret != GST_FLOW_OK)
       return ret;
-
-    if (G_UNLIKELY (!vdp_pad->device)) {
-      vdp_pad->device =
-          g_object_ref (GST_VDP_VIDEO_BUFFER (*video_buf)->device);
-
-      gst_vdp_video_src_pad_update_caps (vdp_pad);
-    }
   }
 
   return GST_FLOW_OK;
@@ -270,42 +230,6 @@ gst_vdp_video_src_pad_setcaps (GstPad * pad, GstCaps * caps)
   return TRUE;
 }
 
-GstFlowReturn
-gst_vdp_video_src_pad_get_device (GstVdpVideoSrcPad * vdp_pad,
-    GstVdpDevice ** device, GError ** error)
-{
-  g_return_val_if_fail (GST_IS_VDP_VIDEO_SRC_PAD (vdp_pad), FALSE);
-
-  if (!GST_PAD_CAPS (vdp_pad))
-    return GST_FLOW_NOT_NEGOTIATED;
-
-  if (G_UNLIKELY (!vdp_pad->device)) {
-
-    if (vdp_pad->yuv_output) {
-      if (!gst_vdp_video_src_pad_open_device (vdp_pad, error))
-        return GST_FLOW_ERROR;
-    }
-
-    else {
-      GstFlowReturn ret;
-      GstVdpVideoBuffer *buf;
-
-      ret = gst_vdp_video_src_pad_alloc_with_caps (vdp_pad,
-          GST_PAD_CAPS (vdp_pad), &buf, error);
-      if (ret != GST_FLOW_OK)
-        return ret;
-
-      vdp_pad->device = g_object_ref (buf->device);
-      gst_buffer_unref (GST_BUFFER (buf));
-    }
-
-    gst_vdp_video_src_pad_update_caps (vdp_pad);
-  }
-
-  *device = vdp_pad->device;
-  return GST_FLOW_OK;
-}
-
 static GstCaps *
 gst_vdp_video_src_pad_getcaps (GstPad * pad)
 {
@@ -325,29 +249,37 @@ gst_vdp_video_src_pad_getcaps (GstPad * pad)
 static gboolean
 gst_vdp_video_src_pad_activate_push (GstPad * pad, gboolean active)
 {
-  GstVdpVideoSrcPad *vdp_pad = GST_VDP_VIDEO_SRC_PAD (pad);
+  GstVdpVideoSrcPad *vdp_pad = (GstVdpVideoSrcPad *) pad;
 
   if (!active) {
-    if (vdp_pad->device)
-      g_object_unref (vdp_pad->device);
-    vdp_pad->device = NULL;
-
     if (vdp_pad->caps)
       gst_caps_unref (vdp_pad->caps);
     vdp_pad->caps = NULL;
+
+    if (vdp_pad->device)
+      gst_object_unref (vdp_pad->device);
+    vdp_pad->device = NULL;
   }
 
   return TRUE;
 }
 
-GstVdpVideoSrcPad *
-gst_vdp_video_src_pad_new (GstPadTemplate * templ, const gchar * name)
+static void
+gst_vdp_video_src_pad_update_caps (GstVdpVideoSrcPad * vdp_pad)
 {
-  g_return_val_if_fail (GST_IS_PAD_TEMPLATE (templ), NULL);
-  g_return_val_if_fail ((templ->direction == GST_PAD_SRC), NULL);
+  GstCaps *caps;
+  const GstCaps *templ_caps;
 
-  return g_object_new (GST_TYPE_VDP_VIDEO_SRC_PAD,
-      "name", name, "direction", templ->direction, "template", templ, NULL);
+  if (vdp_pad->caps)
+    gst_caps_unref (vdp_pad->caps);
+
+  caps = gst_vdp_video_buffer_get_allowed_caps (vdp_pad->device);
+
+  if ((templ_caps = gst_pad_get_pad_template_caps (GST_PAD (vdp_pad)))) {
+    vdp_pad->caps = gst_caps_intersect (caps, templ_caps);
+    gst_caps_unref (caps);
+  } else
+    vdp_pad->caps = caps;
 }
 
 static void
@@ -357,9 +289,10 @@ gst_vdp_video_src_pad_get_property (GObject * object, guint prop_id,
   GstVdpVideoSrcPad *vdp_pad = (GstVdpVideoSrcPad *) object;
 
   switch (prop_id) {
-    case PROP_DISPLAY:
-      g_value_set_string (value, vdp_pad->display);
+    case PROP_DEVICE:
+      g_value_set_object (value, vdp_pad->device);
       break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -373,25 +306,19 @@ gst_vdp_video_src_pad_set_property (GObject * object, guint prop_id,
   GstVdpVideoSrcPad *vdp_pad = (GstVdpVideoSrcPad *) object;
 
   switch (prop_id) {
-    case PROP_DISPLAY:
-      vdp_pad->display = g_value_dup_string (value);
+    case PROP_DEVICE:
+      if (vdp_pad->device)
+        g_object_unref (vdp_pad->device);
+      vdp_pad->device = g_value_dup_object (value);
+      gst_vdp_video_src_pad_update_caps (vdp_pad);
       break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
   }
 }
 
-static void
-gst_vdp_video_src_pad_finalize (GObject * object)
-{
-  GstVdpVideoSrcPad *vdp_pad = (GstVdpVideoSrcPad *) object;
-
-  g_free (vdp_pad->display);
-
-  G_OBJECT_CLASS (gst_vdp_video_src_pad_parent_class)->finalize (object);
-}
-
 static void
 gst_vdp_video_src_pad_init (GstVdpVideoSrcPad * vdp_pad)
 {
@@ -400,8 +327,6 @@ gst_vdp_video_src_pad_init (GstVdpVideoSrcPad * vdp_pad)
   vdp_pad->device = NULL;
   vdp_pad->caps = NULL;
 
-  vdp_pad->display = NULL;
-
   gst_pad_set_getcaps_function (pad,
       GST_DEBUG_FUNCPTR (gst_vdp_video_src_pad_getcaps));
   gst_pad_set_setcaps_function (pad,
@@ -417,9 +342,17 @@ gst_vdp_video_src_pad_class_init (GstVdpVideoSrcPadClass * klass)
 
   object_class->get_property = gst_vdp_video_src_pad_get_property;
   object_class->set_property = gst_vdp_video_src_pad_set_property;
-  object_class->finalize = gst_vdp_video_src_pad_finalize;
 
-  g_object_class_install_property (object_class, PROP_DISPLAY,
-      g_param_spec_string ("display", "Display", "X Display name",
-          NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+  /**
+   * GstVdpVideoSrcPad:device:
+   *
+   * The #GstVdpDevice this pool is bound to.
+   */
+  g_object_class_install_property
+      (object_class,
+      PROP_DEVICE,
+      g_param_spec_object ("device",
+          "Device",
+          "The GstVdpDevice the pad should use",
+          GST_TYPE_VDP_DEVICE, G_PARAM_READWRITE));
 }
index 135f18c227db633a11558363f1f07a9ddc55d86c..e8ba3312b932c32aeaeb9c45c22910bf4621be96 100644 (file)
@@ -41,8 +41,6 @@ typedef struct _GstVdpVideoSrcPadClass GstVdpVideoSrcPadClass;
 GstFlowReturn gst_vdp_video_src_pad_push (GstVdpVideoSrcPad *vdp_pad, GstVdpVideoBuffer *video_buf);
 GstFlowReturn gst_vdp_video_src_pad_alloc_buffer (GstVdpVideoSrcPad *vdp_pad, GstVdpVideoBuffer **video_buf, GError ** error);
 
-GstFlowReturn gst_vdp_video_src_pad_get_device (GstVdpVideoSrcPad * vdp_pad, GstVdpDevice ** device, GError ** error);
-
 GstCaps *gst_vdp_video_src_pad_get_template_caps ();
 
 GstVdpVideoSrcPad * gst_vdp_video_src_pad_new (GstPadTemplate * templ, const gchar * name);
index d95a25bdd369717ed91b788f4935878657548f66..a3310a35497d561bbd76a572f55e60144f8f17cf 100644 (file)
@@ -821,7 +821,8 @@ gst_vdp_h264_dec_start (GstBaseVideoDecoder * base_video_decoder)
   gst_h264_dpb_set_output_func (h264_dec->dpb, gst_vdp_h264_dec_output,
       h264_dec);
 
-  return TRUE;
+  return GST_BASE_VIDEO_DECODER_CLASS
+      (parent_class)->start (base_video_decoder);
 }
 
 static gboolean
@@ -832,7 +833,7 @@ gst_vdp_h264_dec_stop (GstBaseVideoDecoder * base_video_decoder)
   g_object_unref (h264_dec->parser);
   g_object_unref (h264_dec->dpb);
 
-  return TRUE;
+  return GST_BASE_VIDEO_DECODER_CLASS (parent_class)->stop (base_video_decoder);
 }
 
 static void
index 72bda52cf69210418a464690f48f1ca65b9061aa..16fb4dc2e37516ebb89fcd4b1cdb86d58e047269 100644 (file)
@@ -589,7 +589,8 @@ gst_vdp_mpeg_dec_start (GstBaseVideoDecoder * base_video_decoder)
 
   memset (&mpeg_dec->stream_info, 0, sizeof (GstVdpMpegStreamInfo));
 
-  return TRUE;
+  return GST_BASE_VIDEO_DECODER_CLASS
+      (parent_class)->start (base_video_decoder);
 }
 
 static gboolean
@@ -604,7 +605,7 @@ gst_vdp_mpeg_dec_stop (GstBaseVideoDecoder * base_video_decoder)
 
   mpeg_dec->state = GST_VDP_MPEG_DEC_STATE_NEED_SEQUENCE;
 
-  return TRUE;
+  return GST_BASE_VIDEO_DECODER_CLASS (parent_class)->stop (base_video_decoder);
 }
 
 static void