vdpau: change gst_vdp_video_src_pad_get_device behaviour

it now creates the device if it's not available
This commit is contained in:
Carl-Anton Ingmarsson 2010-06-17 15:20:03 +02:00
parent f8846a463d
commit 80749da166
3 changed files with 82 additions and 10 deletions

View file

@ -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 *

View file

@ -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 ();

View file

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