summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 a87ea6a..8870398 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 a8ef888..9ccf243 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 59c6d5f..d2cc9bed 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 135f18c..e8ba331 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 d95a25b..a3310a3 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 72bda52..16fb4dc 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