From 80749da1668bf93b73fdb4c54b7b2834ff4fa19b Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Thu, 17 Jun 2010 15:20:03 +0200 Subject: [PATCH] vdpau: change gst_vdp_video_src_pad_get_device behaviour it now creates the device if it's not available --- sys/vdpau/gstvdp/gstvdpvideosrcpad.c | 78 ++++++++++++++++++++++++++-- sys/vdpau/gstvdp/gstvdpvideosrcpad.h | 2 +- sys/vdpau/mpeg/gstvdpmpegdec.c | 12 +++-- 3 files changed, 82 insertions(+), 10 deletions(-) diff --git a/sys/vdpau/gstvdp/gstvdpvideosrcpad.c b/sys/vdpau/gstvdp/gstvdpvideosrcpad.c index 1ce4aad2c6..167c4d7903 100644 --- a/sys/vdpau/gstvdp/gstvdpvideosrcpad.c +++ b/sys/vdpau/gstvdp/gstvdpvideosrcpad.c @@ -142,6 +142,23 @@ gst_vdp_video_src_pad_update_caps (GstVdpVideoSrcPad * vdp_pad) 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; +} + GstFlowReturn gst_vdp_video_src_pad_alloc_buffer (GstVdpVideoSrcPad * vdp_pad, GstVdpVideoBuffer ** video_buf) @@ -159,8 +176,7 @@ gst_vdp_video_src_pad_alloc_buffer (GstVdpVideoSrcPad * vdp_pad, GstVdpDevice *device; if (G_UNLIKELY (!vdp_pad->device)) { - vdp_pad->device = gst_vdp_get_device (vdp_pad->display); - if (G_UNLIKELY (!vdp_pad->device)) + if (!gst_vdp_video_src_pad_open_device (vdp_pad, NULL)) goto device_error; gst_vdp_video_src_pad_update_caps (vdp_pad); @@ -233,12 +249,64 @@ gst_vdp_video_src_pad_setcaps (GstPad * pad, GstCaps * caps) return TRUE; } -GstVdpDevice * -gst_vdp_video_src_pad_get_device (GstVdpVideoSrcPad * vdp_pad) +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); - return vdp_pad->device; + 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; + GstBuffer *buf; + + ret = gst_pad_alloc_buffer (GST_PAD (vdp_pad), 0, 0, + GST_PAD_CAPS (vdp_pad), &buf); + if (ret != GST_FLOW_OK) + goto alloc_failed; + + if (!gst_caps_is_equal_fixed (GST_PAD_CAPS (vdp_pad), + GST_BUFFER_CAPS (buf))) { + gst_buffer_unref (buf); + goto wrong_caps; + } + if (!GST_IS_VDP_VIDEO_BUFFER (buf)) { + gst_buffer_unref (buf); + goto invalid_buffer; + } + + vdp_pad->device = g_object_ref (GST_VDP_VIDEO_BUFFER (buf)->device); + } + + gst_vdp_video_src_pad_update_caps (vdp_pad); + } + + *device = vdp_pad->device; + return GST_FLOW_OK; + +alloc_failed: + g_set_error (error, GST_STREAM_ERROR, GST_STREAM_ERROR_FAILED, + "Couldn't allocate buffer"); + return GST_FLOW_ERROR; + +wrong_caps: + g_set_error (error, GST_STREAM_ERROR, GST_STREAM_ERROR_FAILED, + "Sink element returned buffer with wrong caps"); + return GST_FLOW_ERROR; + +invalid_buffer: + g_set_error (error, GST_STREAM_ERROR, GST_STREAM_ERROR_FAILED, + "Sink element returned invalid buffer type"); + return GST_FLOW_ERROR; } static GstCaps * diff --git a/sys/vdpau/gstvdp/gstvdpvideosrcpad.h b/sys/vdpau/gstvdp/gstvdpvideosrcpad.h index 1a32c62351..427658b81a 100644 --- a/sys/vdpau/gstvdp/gstvdpvideosrcpad.h +++ b/sys/vdpau/gstvdp/gstvdpvideosrcpad.h @@ -41,7 +41,7 @@ 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); -GstVdpDevice *gst_vdp_video_src_pad_get_device (GstVdpVideoSrcPad *vdp_pad); +GstFlowReturn gst_vdp_video_src_pad_get_device (GstVdpVideoSrcPad * vdp_pad, GstVdpDevice ** device, GError ** error); GstCaps *gst_vdp_video_src_pad_get_template_caps (); diff --git a/sys/vdpau/mpeg/gstvdpmpegdec.c b/sys/vdpau/mpeg/gstvdpmpegdec.c index b2d77706fa..f318704329 100644 --- a/sys/vdpau/mpeg/gstvdpmpegdec.c +++ b/sys/vdpau/mpeg/gstvdpmpegdec.c @@ -245,12 +245,14 @@ gst_vdp_mpeg_dec_handle_quant_matrix (GstVdpMpegDec * mpeg_dec, static gboolean gst_vdp_mpeg_dec_create_decoder (GstVdpMpegDec * mpeg_dec) { + GstFlowReturn ret; GstVdpDevice *device; - device = gst_vdp_video_src_pad_get_device - (GST_VDP_VIDEO_SRC_PAD (GST_BASE_VIDEO_DECODER_SRC_PAD (mpeg_dec))); + ret = gst_vdp_video_src_pad_get_device + (GST_VDP_VIDEO_SRC_PAD (GST_BASE_VIDEO_DECODER_SRC_PAD (mpeg_dec)), + &device, NULL); - if (device) { + if (ret == GST_FLOW_OK) { VdpStatus status; GstVdpMpegStreamInfo *stream_info; @@ -722,13 +724,15 @@ gst_vdp_mpeg_dec_stop (GstBaseVideoDecoder * base_video_decoder) GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (base_video_decoder); GstVdpVideoSrcPad *vdp_pad; + GstFlowReturn ret; GstVdpDevice *device; vdp_pad = GST_VDP_VIDEO_SRC_PAD (GST_BASE_VIDEO_DECODER_SRC_PAD (base_video_decoder)); - if ((device = gst_vdp_video_src_pad_get_device (vdp_pad))) { + ret = gst_vdp_video_src_pad_get_device (vdp_pad, &device, NULL); + if (ret == GST_FLOW_OK) { if (mpeg_dec->decoder != VDP_INVALID_HANDLE) device->vdp_decoder_destroy (mpeg_dec->decoder);