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)
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);
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)
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;
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)
{
}
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
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;
enum
{
PROP_0,
- PROP_DISPLAY
+ PROP_DEVICE
};
struct _GstVdpVideoSrcPad
GstPad pad;
GstCaps *caps;
- GstVdpDevice *device;
gboolean yuv_output;
gint width, height;
guint32 fourcc;
/* properties */
- gchar *display;
+ GstVdpDevice *device;
};
struct _GstVdpVideoSrcPadClass
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)
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)
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;
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)
{
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
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;
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)
{
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,
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));
}