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.
This commit is contained in:
Carl-Anton Ingmarsson 2010-07-27 23:24:43 +02:00
parent d564e1bf19
commit 00ad3c8aeb
6 changed files with 135 additions and 156 deletions

View 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;

View file

@ -43,7 +43,11 @@ typedef struct _GstVdpDecoderClass GstVdpDecoderClass;
struct _GstVdpDecoder {
GstBaseVideoDecoder base_video_decoder;
GstVdpDevice *device;
VdpDecoder decoder;
/* properties */
gchar *display;
};
struct _GstVdpDecoderClass {

View 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));
}

View 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);

View 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

View 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