mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-24 16:18:16 +00:00
vdpau: add error reporting to device creation
This commit is contained in:
parent
57e05fdc76
commit
b37869c315
6 changed files with 102 additions and 99 deletions
|
@ -186,9 +186,11 @@ gst_vdp_decoder_start (GstBaseVideoDecoder * base_video_decoder)
|
|||
{
|
||||
GstVdpDecoder *vdp_decoder = GST_VDP_DECODER (base_video_decoder);
|
||||
|
||||
GError *err;
|
||||
GstVdpVideoSrcPad *vdp_pad;
|
||||
|
||||
vdp_decoder->device = gst_vdp_get_device (vdp_decoder->display);
|
||||
err = NULL;
|
||||
vdp_decoder->device = gst_vdp_get_device (vdp_decoder->display, &err);
|
||||
if (G_UNLIKELY (!vdp_decoder->device))
|
||||
goto device_error;
|
||||
|
||||
|
@ -201,8 +203,7 @@ gst_vdp_decoder_start (GstBaseVideoDecoder * base_video_decoder)
|
|||
return TRUE;
|
||||
|
||||
device_error:
|
||||
GST_ELEMENT_ERROR (vdp_decoder, RESOURCE, OPEN_READ,
|
||||
("Couldn't create GstVdpDevice"), (NULL));
|
||||
gst_vdp_decoder_post_error (vdp_decoder, err);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
|
@ -37,39 +37,9 @@ enum
|
|||
G_DEFINE_TYPE_WITH_CODE (GstVdpDevice, gst_vdp_device, G_TYPE_OBJECT,
|
||||
DEBUG_INIT ());
|
||||
|
||||
static void
|
||||
gst_vdp_device_init (GstVdpDevice * device)
|
||||
static gboolean
|
||||
gst_vdp_device_open (GstVdpDevice * device, GError ** error)
|
||||
{
|
||||
device->display_name = NULL;
|
||||
device->display = NULL;
|
||||
device->device = VDP_INVALID_HANDLE;
|
||||
|
||||
device->constructed = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vdp_device_finalize (GObject * object)
|
||||
{
|
||||
GstVdpDevice *device = (GstVdpDevice *) object;
|
||||
|
||||
if (device->device != VDP_INVALID_HANDLE) {
|
||||
device->vdp_device_destroy (device->device);
|
||||
device->device = VDP_INVALID_HANDLE;
|
||||
}
|
||||
if (device->display) {
|
||||
XCloseDisplay (device->display);
|
||||
device->display = NULL;
|
||||
}
|
||||
g_free (device->display_name);
|
||||
device->display_name = NULL;
|
||||
|
||||
G_OBJECT_CLASS (gst_vdp_device_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vdp_device_constructed (GObject * object)
|
||||
{
|
||||
GstVdpDevice *device = (GstVdpDevice *) object;
|
||||
gint screen;
|
||||
VdpStatus status;
|
||||
gint i;
|
||||
|
@ -135,55 +105,96 @@ gst_vdp_device_constructed (GObject * object)
|
|||
};
|
||||
|
||||
device->display = XOpenDisplay (device->display_name);
|
||||
if (!device->display) {
|
||||
GST_ERROR_OBJECT (device, "Could not open X display with name: %s",
|
||||
device->display_name);
|
||||
return;
|
||||
}
|
||||
if (!device->display)
|
||||
goto create_display_error;
|
||||
|
||||
screen = DefaultScreen (device->display);
|
||||
status =
|
||||
vdp_device_create_x11 (device->display, screen, &device->device,
|
||||
&device->vdp_get_proc_address);
|
||||
if (status != VDP_STATUS_OK) {
|
||||
GST_ERROR_OBJECT (device, "Could not create VDPAU device");
|
||||
device->device = VDP_INVALID_HANDLE;
|
||||
XCloseDisplay (device->display);
|
||||
device->display = NULL;
|
||||
|
||||
return;
|
||||
}
|
||||
if (status != VDP_STATUS_OK)
|
||||
goto create_device_error;
|
||||
|
||||
status = device->vdp_get_proc_address (device->device,
|
||||
VDP_FUNC_ID_GET_ERROR_STRING, (void **) &device->vdp_get_error_string);
|
||||
if (status != VDP_STATUS_OK) {
|
||||
GST_ERROR_OBJECT (device,
|
||||
"Could not get vdp_get_error_string function pointer from VDPAU");
|
||||
goto error;
|
||||
}
|
||||
if (status != VDP_STATUS_OK)
|
||||
goto get_error_string_error;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (vdp_function); i++) {
|
||||
status = device->vdp_get_proc_address (device->device,
|
||||
vdp_function[i].id, vdp_function[i].func);
|
||||
|
||||
if (status != VDP_STATUS_OK) {
|
||||
GST_ERROR_OBJECT (device, "Could not get function pointer from VDPAU,"
|
||||
" error returned was: %s", device->vdp_get_error_string (status));
|
||||
goto error;
|
||||
}
|
||||
if (status != VDP_STATUS_OK)
|
||||
goto function_error;
|
||||
}
|
||||
|
||||
device->constructed = TRUE;
|
||||
return;
|
||||
return TRUE;
|
||||
|
||||
error:
|
||||
create_display_error:
|
||||
g_set_error (error, GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_OPEN_READ,
|
||||
"Could not open X display with name: %s", device->display_name);
|
||||
return FALSE;
|
||||
|
||||
create_device_error:
|
||||
XCloseDisplay (device->display);
|
||||
g_set_error (error, GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_OPEN_READ,
|
||||
"Could not create VDPAU device for display: %s", device->display_name);
|
||||
return FALSE;
|
||||
|
||||
get_error_string_error:
|
||||
XCloseDisplay (device->display);
|
||||
g_set_error (error, GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_OPEN_READ,
|
||||
"Could not get vdp_get_error_string function pointer from VDPAU");
|
||||
return FALSE;
|
||||
|
||||
function_error:
|
||||
XCloseDisplay (device->display);
|
||||
g_set_error (error, GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_OPEN_READ,
|
||||
"Could not get function pointer from VDPAU, error returned was: %s",
|
||||
device->vdp_get_error_string (status));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static GstVdpDevice *
|
||||
gst_vdp_device_new (const gchar * display_name, GError ** error)
|
||||
{
|
||||
GstVdpDevice *device;
|
||||
|
||||
device = g_object_new (GST_TYPE_VDP_DEVICE, "display", display_name, NULL);
|
||||
|
||||
if (!gst_vdp_device_open (device, error)) {
|
||||
g_object_unref (device);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vdp_device_init (GstVdpDevice * device)
|
||||
{
|
||||
device->display_name = NULL;
|
||||
device->display = NULL;
|
||||
device->device = VDP_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vdp_device_finalize (GObject * object)
|
||||
{
|
||||
GstVdpDevice *device = (GstVdpDevice *) object;
|
||||
|
||||
if (device->device != VDP_INVALID_HANDLE) {
|
||||
device->vdp_device_destroy (device->device);
|
||||
device->device = VDP_INVALID_HANDLE;
|
||||
}
|
||||
if (device->display) {
|
||||
XCloseDisplay (device->display);
|
||||
device->display = NULL;
|
||||
}
|
||||
g_free (device->display_name);
|
||||
device->display_name = NULL;
|
||||
|
||||
G_OBJECT_CLASS (gst_vdp_device_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -231,7 +242,6 @@ gst_vdp_device_class_init (GstVdpDeviceClass * klass)
|
|||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->constructed = gst_vdp_device_constructed;
|
||||
object_class->finalize = gst_vdp_device_finalize;
|
||||
object_class->get_property = gst_vdp_device_get_property;
|
||||
object_class->set_property = gst_vdp_device_set_property;
|
||||
|
@ -244,21 +254,6 @@ gst_vdp_device_class_init (GstVdpDeviceClass * klass)
|
|||
"", G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
|
||||
}
|
||||
|
||||
static GstVdpDevice *
|
||||
gst_vdp_device_new (const gchar * display_name)
|
||||
{
|
||||
GstVdpDevice *device;
|
||||
|
||||
device = g_object_new (GST_TYPE_VDP_DEVICE, "display", display_name, NULL);
|
||||
|
||||
if (!device->constructed) {
|
||||
g_object_unref (device);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GHashTable *hash_table;
|
||||
|
@ -288,7 +283,7 @@ device_destroyed_cb (gpointer data, GObject * object)
|
|||
}
|
||||
|
||||
GstVdpDevice *
|
||||
gst_vdp_get_device (const gchar * display_name)
|
||||
gst_vdp_get_device (const gchar * display_name, GError ** error)
|
||||
{
|
||||
static gsize once = 0;
|
||||
static GstVdpDeviceCache device_cache;
|
||||
|
@ -310,7 +305,7 @@ gst_vdp_get_device (const gchar * display_name)
|
|||
device = g_hash_table_lookup (device_cache.hash_table, "");
|
||||
|
||||
if (!device) {
|
||||
device = gst_vdp_device_new (display_name);
|
||||
device = gst_vdp_device_new (display_name, error);
|
||||
if (device) {
|
||||
g_object_weak_ref (G_OBJECT (device), device_destroyed_cb, &device_cache);
|
||||
if (display_name)
|
||||
|
|
|
@ -96,7 +96,7 @@ struct _GstVdpDevice
|
|||
|
||||
GType gst_vdp_device_get_type (void);
|
||||
|
||||
GstVdpDevice *gst_vdp_get_device (const gchar *display_name);
|
||||
GstVdpDevice *gst_vdp_get_device (const gchar *display_name, GError **error);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
|
|
@ -22,11 +22,11 @@ vdpau_init (GstPlugin * vdpau_plugin)
|
|||
gst_element_register (vdpau_plugin, "vdpaumpegdec",
|
||||
GST_RANK_NONE, GST_TYPE_VDP_MPEG_DEC);
|
||||
gst_element_register (vdpau_plugin, "vdpauh264dec",
|
||||
GST_RANK_NONE, GST_TYPE_VDP_H264_DEC);
|
||||
GST_RANK_PRIMARY, GST_TYPE_VDP_H264_DEC);
|
||||
gst_element_register (vdpau_plugin, "vdpauvideopostprocess",
|
||||
GST_RANK_MARGINAL, GST_TYPE_VDP_VIDEO_POST_PROCESS);
|
||||
GST_RANK_PRIMARY, GST_TYPE_VDP_VIDEO_POST_PROCESS);
|
||||
gst_element_register (vdpau_plugin, "vdpausink",
|
||||
GST_RANK_NONE, GST_TYPE_VDP_SINK);
|
||||
GST_RANK_PRIMARY, GST_TYPE_VDP_SINK);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -569,14 +569,26 @@ gst_vdp_sink_get_allowed_caps (GstVdpDevice * device, GValue * par)
|
|||
return caps;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vdp_sink_post_error (VdpSink * vdp_sink, GError * error)
|
||||
{
|
||||
GstMessage *message;
|
||||
|
||||
message = gst_message_new_error (GST_OBJECT (vdp_sink), error, NULL);
|
||||
gst_element_post_message (GST_ELEMENT (vdp_sink), message);
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_vdp_sink_open_device (VdpSink * vdp_sink)
|
||||
{
|
||||
GstVdpDevice *device;
|
||||
GError *err;
|
||||
|
||||
vdp_sink->device = device = gst_vdp_get_device (vdp_sink->display_name);
|
||||
if (!vdp_sink->device)
|
||||
return FALSE;
|
||||
err = NULL;
|
||||
vdp_sink->device = device = gst_vdp_get_device (vdp_sink->display_name, &err);
|
||||
if (!device)
|
||||
goto device_error;
|
||||
|
||||
vdp_sink->bpool = gst_vdp_output_buffer_pool_new (device);
|
||||
|
||||
|
@ -594,6 +606,10 @@ gst_vdp_sink_open_device (VdpSink * vdp_sink)
|
|||
(GThreadFunc) gst_vdp_sink_event_thread, vdp_sink, TRUE, NULL);
|
||||
|
||||
return TRUE;
|
||||
|
||||
device_error:
|
||||
gst_vdp_sink_post_error (vdp_sink, err);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -898,16 +914,6 @@ gst_vdp_sink_event (GstBaseSink * sink, GstEvent * event)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vdp_sink_post_error (VdpSink * vdp_sink, GError * error)
|
||||
{
|
||||
GstMessage *message;
|
||||
|
||||
message = gst_message_new_error (GST_OBJECT (vdp_sink), error, NULL);
|
||||
gst_element_post_message (GST_ELEMENT (vdp_sink), message);
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
/* Buffer management
|
||||
*
|
||||
* The buffer_alloc function must either return a buffer with given size and
|
||||
|
|
|
@ -596,6 +596,7 @@ static gboolean
|
|||
gst_vdp_vpp_start (GstVdpVideoPostProcess * vpp)
|
||||
{
|
||||
gint i;
|
||||
GError *err;
|
||||
|
||||
vpp->interlaced = FALSE;
|
||||
vpp->field_duration = GST_CLOCK_TIME_NONE;
|
||||
|
@ -613,7 +614,8 @@ gst_vdp_vpp_start (GstVdpVideoPostProcess * vpp)
|
|||
vpp->n_future_pictures = 0;
|
||||
vpp->n_past_pictures = 0;
|
||||
|
||||
vpp->device = gst_vdp_get_device (vpp->display);
|
||||
err = NULL;
|
||||
vpp->device = gst_vdp_get_device (vpp->display, &err);
|
||||
if (G_UNLIKELY (!vpp->device))
|
||||
goto device_error;
|
||||
|
||||
|
@ -622,8 +624,7 @@ gst_vdp_vpp_start (GstVdpVideoPostProcess * vpp)
|
|||
return TRUE;
|
||||
|
||||
device_error:
|
||||
GST_ELEMENT_ERROR (vpp, RESOURCE, OPEN_READ,
|
||||
("Couldn't create GstVdpDevice"), (NULL));
|
||||
gst_vdp_vpp_post_error (vpp, err);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue