summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl-Anton Ingmarsson <ca.ingmarsson@gmail.com>2010-07-27 23:24:43 +0200
committerCarl-Anton Ingmarsson <ca.ingmarsson@gmail.com>2010-07-30 11:31:59 +0200
commit00ad3c8aebcc3a0cd901970973e3cec59653f9a2 (patch)
tree36470b95db5d2ee072cd7db3e83669e2a5fe827b
parentd564e1bf19cbeb4bd5aae9cbf92b79445fde96c8 (diff)
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.
-rw-r--r--sys/vdpau/gstvdp/gstvdpdecoder.c100
-rw-r--r--sys/vdpau/gstvdp/gstvdpdecoder.h4
-rw-r--r--sys/vdpau/gstvdp/gstvdpvideosrcpad.c175
-rw-r--r--sys/vdpau/gstvdp/gstvdpvideosrcpad.h2
-rw-r--r--sys/vdpau/h264/gstvdph264dec.c5
-rw-r--r--sys/vdpau/mpeg/gstvdpmpegdec.c5
6 files changed, 135 insertions, 156 deletions
diff --git a/sys/vdpau/gstvdp/gstvdpdecoder.c b/sys/vdpau/gstvdp/gstvdpdecoder.c
index a87ea6a3c..8870398b2 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,10 +255,10 @@ 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;
@@ -238,6 +266,16 @@ gst_vdp_decoder_set_property (GObject * object, guint prop_id,
}
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)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (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 a8ef888db..9ccf24379 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 59c6d5f65..d2cc9bed8 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,9 +306,13 @@ 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;
@@ -383,16 +320,6 @@ gst_vdp_video_src_pad_set_property (GObject * object, guint prop_id,
}
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)
{
GstPad *pad = GST_PAD (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 135f18c22..e8ba3312b 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 d95a25bdd..a3310a354 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 72bda52cf..16fb4dc2e 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