summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl-Anton Ingmarsson <ca.ingmarsson@gmail.com>2010-06-17 15:20:03 +0200
committerCarl-Anton Ingmarsson <ca.ingmarsson@gmail.com>2010-06-23 21:51:53 +0200
commit80749da1668bf93b73fdb4c54b7b2834ff4fa19b (patch)
treeae39e545ff156fe63290bbd3c471bdfb11a3ac84
parentf8846a463d86c7bf8290c4aadc258835e863212f (diff)
downloadgstreamer-plugins-bad-80749da1668bf93b73fdb4c54b7b2834ff4fa19b.tar.gz
vdpau: change gst_vdp_video_src_pad_get_device behaviour
it now creates the device if it's not available
-rw-r--r--sys/vdpau/gstvdp/gstvdpvideosrcpad.c78
-rw-r--r--sys/vdpau/gstvdp/gstvdpvideosrcpad.h2
-rw-r--r--sys/vdpau/mpeg/gstvdpmpegdec.c12
3 files changed, 82 insertions, 10 deletions
diff --git a/sys/vdpau/gstvdp/gstvdpvideosrcpad.c b/sys/vdpau/gstvdp/gstvdpvideosrcpad.c
index 1ce4aad2c..167c4d790 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 1a32c6235..427658b81 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 b2d77706f..f31870432 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);