From 00ad3c8aebcc3a0cd901970973e3cec59653f9a2 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Tue, 27 Jul 2010 23:24:43 +0200 Subject: [PATCH] vdpau: cleanup GstVdpDecoder opening of it's GstVdpDevice 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 | 100 ++++++++++----- sys/vdpau/gstvdp/gstvdpdecoder.h | 4 + sys/vdpau/gstvdp/gstvdpvideosrcpad.c | 175 +++++++++------------------ sys/vdpau/gstvdp/gstvdpvideosrcpad.h | 2 - sys/vdpau/h264/gstvdph264dec.c | 5 +- sys/vdpau/mpeg/gstvdpmpegdec.c | 5 +- 6 files changed, 135 insertions(+), 156 deletions(-) diff --git a/sys/vdpau/gstvdp/gstvdpdecoder.c b/sys/vdpau/gstvdp/gstvdpdecoder.c index a87ea6a3cc..8870398b20 100644 --- a/sys/vdpau/gstvdp/gstvdpdecoder.c +++ b/sys/vdpau/gstvdp/gstvdpdecoder.c @@ -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; diff --git a/sys/vdpau/gstvdp/gstvdpdecoder.h b/sys/vdpau/gstvdp/gstvdpdecoder.h index a8ef888db6..9ccf24379e 100644 --- a/sys/vdpau/gstvdp/gstvdpdecoder.h +++ b/sys/vdpau/gstvdp/gstvdpdecoder.h @@ -43,7 +43,11 @@ typedef struct _GstVdpDecoderClass GstVdpDecoderClass; struct _GstVdpDecoder { GstBaseVideoDecoder base_video_decoder; + GstVdpDevice *device; VdpDecoder decoder; + + /* properties */ + gchar *display; }; struct _GstVdpDecoderClass { diff --git a/sys/vdpau/gstvdp/gstvdpvideosrcpad.c b/sys/vdpau/gstvdp/gstvdpvideosrcpad.c index 59c6d5f65c..d2cc9bed82 100644 --- a/sys/vdpau/gstvdp/gstvdpvideosrcpad.c +++ b/sys/vdpau/gstvdp/gstvdpvideosrcpad.c @@ -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)); } diff --git a/sys/vdpau/gstvdp/gstvdpvideosrcpad.h b/sys/vdpau/gstvdp/gstvdpvideosrcpad.h index 135f18c227..e8ba3312b9 100644 --- a/sys/vdpau/gstvdp/gstvdpvideosrcpad.h +++ b/sys/vdpau/gstvdp/gstvdpvideosrcpad.h @@ -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); diff --git a/sys/vdpau/h264/gstvdph264dec.c b/sys/vdpau/h264/gstvdph264dec.c index d95a25bdd3..a3310a3549 100644 --- a/sys/vdpau/h264/gstvdph264dec.c +++ b/sys/vdpau/h264/gstvdph264dec.c @@ -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 diff --git a/sys/vdpau/mpeg/gstvdpmpegdec.c b/sys/vdpau/mpeg/gstvdpmpegdec.c index 72bda52cf6..16fb4dc2e3 100644 --- a/sys/vdpau/mpeg/gstvdpmpegdec.c +++ b/sys/vdpau/mpeg/gstvdpmpegdec.c @@ -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 -- 2.34.1