vdpau: add error parameter to gst_vdp_video_src_pad_get_device

This commit is contained in:
Carl-Anton Ingmarsson 2010-06-27 00:35:11 +02:00
parent 159b43d17c
commit 8e59521efa
6 changed files with 82 additions and 59 deletions

View file

@ -65,14 +65,27 @@ gst_vdp_decoder_create_srcpad (GstBaseVideoDecoder * base_video_decoder,
return GST_PAD (vdp_pad);
}
void
gst_vdp_decoder_post_error (GstVdpDecoder * decoder, GError * error)
{
GstMessage *message;
g_return_if_fail (GST_IS_VDP_DECODER (decoder));
g_return_if_fail (decoder != NULL);
message = gst_message_new_error (GST_OBJECT (decoder), error, NULL);
gst_element_post_message (GST_ELEMENT (decoder), message);
g_error_free (error);
}
GstFlowReturn
gst_vdp_decoder_alloc_buffer (GstVdpDecoder * vdp_decoder,
GstVdpVideoBuffer ** video_buf)
GstVdpVideoBuffer ** video_buf, GError ** error)
{
GstVdpVideoSrcPad *vdp_pad;
vdp_pad = (GstVdpVideoSrcPad *) GST_BASE_VIDEO_DECODER_SRC_PAD (vdp_decoder);
return gst_vdp_video_src_pad_alloc_buffer (vdp_pad, video_buf);
return gst_vdp_video_src_pad_alloc_buffer (vdp_pad, video_buf, error);
}
GstFlowReturn

View file

@ -47,8 +47,13 @@ struct _GstVdpDecoderClass {
GstBaseVideoDecoderClass base_video_decoder_class;
};
GstFlowReturn gst_vdp_decoder_alloc_buffer (GstVdpDecoder * vdp_decoder, GstVdpVideoBuffer **video_buf);
GstFlowReturn gst_vdp_decoder_get_device (GstVdpDecoder * vdp_decoder, GstVdpDevice ** device, GError ** error);
void gst_vdp_decoder_post_error (GstVdpDecoder * decoder, GError * error);
GstFlowReturn gst_vdp_decoder_alloc_buffer (GstVdpDecoder * vdp_decoder,
GstVdpVideoBuffer **video_buf, GError ** error);
GstFlowReturn gst_vdp_decoder_get_device (GstVdpDecoder * vdp_decoder,
GstVdpDevice ** device, GError ** error);
GType gst_vdp_decoder_get_type (void);

View file

@ -159,9 +159,41 @@ device_error:
return FALSE;
}
static GstFlowReturn
gst_vdp_video_src_pad_alloc_with_caps (GstVdpVideoSrcPad * vdp_pad,
GstCaps * caps, GstVdpVideoBuffer ** video_buf, GError ** error)
{
GstFlowReturn ret;
ret = gst_pad_alloc_buffer ((GstPad *) vdp_pad, 0, 0, caps,
(GstBuffer **) video_buf);
if (ret != GST_FLOW_OK)
return ret;
if (!gst_caps_is_equal_fixed (caps, GST_BUFFER_CAPS (*video_buf)))
goto wrong_caps;
if (!GST_IS_VDP_VIDEO_BUFFER (*video_buf))
goto invalid_buf;
return GST_FLOW_OK;
wrong_caps:
gst_buffer_unref (GST_BUFFER (*video_buf));
g_set_error (error, GST_STREAM_ERROR, GST_STREAM_ERROR_FAILED,
"Sink element returned buffer with wrong caps");
return GST_FLOW_ERROR;
invalid_buf:
gst_buffer_unref (GST_BUFFER (*video_buf));
g_set_error (error, GST_STREAM_ERROR, GST_STREAM_ERROR_FAILED,
"Sink element returned buffer of wrong type");
return GST_FLOW_ERROR;
}
GstFlowReturn
gst_vdp_video_src_pad_alloc_buffer (GstVdpVideoSrcPad * vdp_pad,
GstVdpVideoBuffer ** video_buf)
GstVdpVideoBuffer ** video_buf, GError ** error)
{
GstCaps *caps;
GstFlowReturn ret;
@ -176,8 +208,8 @@ gst_vdp_video_src_pad_alloc_buffer (GstVdpVideoSrcPad * vdp_pad,
GstVdpDevice *device;
if (G_UNLIKELY (!vdp_pad->device)) {
if (!gst_vdp_video_src_pad_open_device (vdp_pad, NULL))
goto device_error;
if (!gst_vdp_video_src_pad_open_device (vdp_pad, error))
return GST_FLOW_ERROR;
gst_vdp_video_src_pad_update_caps (vdp_pad);
}
@ -186,16 +218,13 @@ gst_vdp_video_src_pad_alloc_buffer (GstVdpVideoSrcPad * vdp_pad,
*video_buf = gst_vdp_video_buffer_new (device, VDP_CHROMA_TYPE_420,
vdp_pad->width, vdp_pad->height);
if (!*video_buf)
goto video_buffer_error;
goto video_buf_error;
} else {
ret = gst_pad_alloc_buffer ((GstPad *) vdp_pad, 0, 0, caps,
(GstBuffer **) video_buf);
ret = gst_vdp_video_src_pad_alloc_with_caps (vdp_pad, caps, video_buf,
error);
if (ret != GST_FLOW_OK)
return ret;
if (!gst_caps_is_equal_fixed (caps, GST_BUFFER_CAPS (*video_buf)))
goto wrong_caps;
if (G_UNLIKELY (!vdp_pad->device)) {
vdp_pad->device =
g_object_ref (GST_VDP_VIDEO_BUFFER (*video_buf)->device);
@ -206,17 +235,9 @@ gst_vdp_video_src_pad_alloc_buffer (GstVdpVideoSrcPad * vdp_pad,
return GST_FLOW_OK;
device_error:
GST_ERROR_OBJECT (vdp_pad, "Couldn't create GstVdpDevice");
return GST_FLOW_ERROR;
video_buffer_error:
GST_ERROR_OBJECT (vdp_pad, "Couldn't create GstVdpVideoBuffer");
return GST_FLOW_ERROR;
wrong_caps:
GST_ERROR_OBJECT (vdp_pad, "Sink element returned buffer with wrong caps");
gst_buffer_unref (GST_BUFFER_CAST (*video_buf));
video_buf_error:
g_set_error (error, GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_READ,
"Couldn't create a GstVdpVideoBuffer");
return GST_FLOW_ERROR;
}
@ -267,24 +288,15 @@ gst_vdp_video_src_pad_get_device (GstVdpVideoSrcPad * vdp_pad,
else {
GstFlowReturn ret;
GstBuffer *buf;
GstVdpVideoBuffer *buf;
ret = gst_pad_alloc_buffer (GST_PAD (vdp_pad), 0, 0,
GST_PAD_CAPS (vdp_pad), &buf);
ret = gst_vdp_video_src_pad_alloc_with_caps (vdp_pad,
GST_PAD_CAPS (vdp_pad), &buf, error);
if (ret != GST_FLOW_OK)
goto alloc_failed;
return ret;
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);
vdp_pad->device = g_object_ref (buf->device);
gst_buffer_unref (GST_BUFFER (buf));
}
gst_vdp_video_src_pad_update_caps (vdp_pad);
@ -292,21 +304,6 @@ gst_vdp_video_src_pad_get_device (GstVdpVideoSrcPad * 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

@ -39,7 +39,7 @@ typedef struct _GstVdpVideoSrcPad GstVdpVideoSrcPad;
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);
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);

View file

@ -440,6 +440,7 @@ gst_vdp_h264_dec_handle_frame (GstBaseVideoDecoder * base_video_decoder,
GstH264Sequence *seq;
GstFlowReturn ret;
GError *err = NULL;
GstVdpVideoBuffer *outbuf;
VdpPictureInfoH264 info;
GstVdpDevice *device;
@ -479,8 +480,8 @@ gst_vdp_h264_dec_handle_frame (GstBaseVideoDecoder * base_video_decoder,
/* decoding */
if ((ret = gst_vdp_decoder_alloc_buffer (GST_VDP_DECODER (h264_dec), &outbuf)
!= GST_FLOW_OK))
if ((ret = gst_vdp_decoder_alloc_buffer (GST_VDP_DECODER (h264_dec), &outbuf,
&err) != GST_FLOW_OK))
goto alloc_error;
device = GST_VDP_VIDEO_BUFFER (outbuf)->device;
@ -566,6 +567,9 @@ gst_vdp_h264_dec_handle_frame (GstBaseVideoDecoder * base_video_decoder,
alloc_error:
gst_base_video_decoder_skip_frame (base_video_decoder, frame);
if (ret == GST_FLOW_ERROR)
gst_vdp_decoder_post_error (GST_VDP_DECODER (h264_dec), err);
return ret;
decode_error:

View file

@ -331,6 +331,7 @@ gst_vdp_mpeg_dec_handle_frame (GstBaseVideoDecoder * base_video_decoder,
GstVdpMpegFrame *mpeg_frame;
GstFlowReturn ret;
GError *err = NULL;
GstVdpVideoBuffer *outbuf;
VdpVideoSurface surface;
GstVdpDevice *device;
@ -402,8 +403,8 @@ gst_vdp_mpeg_dec_handle_frame (GstBaseVideoDecoder * base_video_decoder,
info->backward_reference = VDP_INVALID_HANDLE;
}
if ((ret = gst_vdp_decoder_alloc_buffer (GST_VDP_DECODER (mpeg_dec), &outbuf)
!= GST_FLOW_OK))
if ((ret = gst_vdp_decoder_alloc_buffer (GST_VDP_DECODER (mpeg_dec), &outbuf,
&err) != GST_FLOW_OK))
goto alloc_error;
/* create decoder */
@ -447,6 +448,9 @@ gst_vdp_mpeg_dec_handle_frame (GstBaseVideoDecoder * base_video_decoder,
alloc_error:
gst_base_video_decoder_skip_frame (base_video_decoder, frame);
if (ret == GST_FLOW_ERROR)
gst_vdp_decoder_post_error (GST_VDP_DECODER (mpeg_dec), err);
return ret;
decode_error: