summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/vdpau/gstvdp/gstvdpdecoder.c7
-rw-r--r--sys/vdpau/gstvdp/gstvdpdevice.c147
-rw-r--r--sys/vdpau/gstvdp/gstvdpdevice.h2
-rw-r--r--sys/vdpau/gstvdpau.c6
-rw-r--r--sys/vdpau/gstvdpsink.c32
-rw-r--r--sys/vdpau/gstvdpvideopostprocess.c7
6 files changed, 102 insertions, 99 deletions
diff --git a/sys/vdpau/gstvdp/gstvdpdecoder.c b/sys/vdpau/gstvdp/gstvdpdecoder.c
index 8870398b2..5e14fac44 100644
--- a/sys/vdpau/gstvdp/gstvdpdecoder.c
+++ b/sys/vdpau/gstvdp/gstvdpdecoder.c
@@ -183,29 +183,30 @@ create_decoder_error:
static gboolean
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;
vdp_pad =
(GstVdpVideoSrcPad *) GST_BASE_VIDEO_DECODER_SRC_PAD (base_video_decoder);
g_object_set (G_OBJECT (vdp_pad), "device", vdp_decoder->device, NULL);
vdp_decoder->decoder = VDP_INVALID_HANDLE;
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;
}
static gboolean
gst_vdp_decoder_stop (GstBaseVideoDecoder * base_video_decoder)
{
diff --git a/sys/vdpau/gstvdp/gstvdpdevice.c b/sys/vdpau/gstvdp/gstvdpdevice.c
index 8867e4e34..2e441b93c 100644
--- a/sys/vdpau/gstvdp/gstvdpdevice.c
+++ b/sys/vdpau/gstvdp/gstvdpdevice.c
@@ -34,45 +34,15 @@ enum
G_DEFINE_TYPE_WITH_CODE (GstVdpDevice, gst_vdp_device, G_TYPE_OBJECT,
DEBUG_INIT ());
-static void
-gst_vdp_device_init (GstVdpDevice * device)
-{
- device->display_name = NULL;
- device->display = NULL;
- device->device = VDP_INVALID_HANDLE;
-
- device->constructed = FALSE;
-}
-
-static void
-gst_vdp_device_finalize (GObject * object)
+static gboolean
+gst_vdp_device_open (GstVdpDevice * device, GError ** error)
{
- 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;
typedef struct
{
@@ -132,61 +102,102 @@ gst_vdp_device_constructed (GObject * object)
&device->vdp_presentation_queue_set_background_color},
{VDP_FUNC_ID_PRESENTATION_QUEUE_QUERY_SURFACE_STATUS,
&device->vdp_presentation_queue_query_surface_status}
};
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;
+
+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;
-error:
+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
gst_vdp_device_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
@@ -228,40 +239,24 @@ gst_vdp_device_get_property (GObject * object, guint prop_id, GValue * value,
static void
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;
g_object_class_install_property (object_class,
PROP_DISPLAY,
g_param_spec_string ("display",
"Display",
"X Display Name",
"", 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;
GMutex *mutex;
} GstVdpDeviceCache;
@@ -285,13 +280,13 @@ device_destroyed_cb (gpointer data, GObject * object)
}
g_mutex_unlock (device_cache->mutex);
}
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;
GstVdpDevice *device;
if (g_once_init_enter (&once)) {
@@ -307,13 +302,13 @@ gst_vdp_get_device (const gchar * display_name)
if (display_name)
device = g_hash_table_lookup (device_cache.hash_table, display_name);
else
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)
g_hash_table_insert (device_cache.hash_table, g_strdup (display_name),
device);
else
diff --git a/sys/vdpau/gstvdp/gstvdpdevice.h b/sys/vdpau/gstvdp/gstvdpdevice.h
index df1367524..6010e7554 100644
--- a/sys/vdpau/gstvdp/gstvdpdevice.h
+++ b/sys/vdpau/gstvdp/gstvdpdevice.h
@@ -93,11 +93,11 @@ struct _GstVdpDevice
VdpPresentationQueueSetBackgroundColor *vdp_presentation_queue_set_background_color;
VdpPresentationQueueQuerySurfaceStatus *vdp_presentation_queue_query_surface_status;
};
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
#endif /* _GST_VDP_DEVICE_H_ */
diff --git a/sys/vdpau/gstvdpau.c b/sys/vdpau/gstvdpau.c
index 7e47e85a1..2ec57afb4 100644
--- a/sys/vdpau/gstvdpau.c
+++ b/sys/vdpau/gstvdpau.c
@@ -19,17 +19,17 @@ vdpau_init (GstPlugin * vdpau_plugin)
/* Before giving these elements a rank again, make sure they pass at
* least the generic/states test when there's no device available */
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;
}
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
GST_VERSION_MINOR,
diff --git a/sys/vdpau/gstvdpsink.c b/sys/vdpau/gstvdpsink.c
index 70bcd6bfe..2f7c5d059 100644
--- a/sys/vdpau/gstvdpsink.c
+++ b/sys/vdpau/gstvdpsink.c
@@ -566,20 +566,32 @@ gst_vdp_sink_get_allowed_caps (GstVdpDevice * device, GValue * par)
gst_structure_set_value (structure, "pixel-aspect-ratio", 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);
vdp_sink->caps = gst_vdp_sink_get_allowed_caps (device, vdp_sink->par);
GST_DEBUG ("runtime calculated caps: %" GST_PTR_FORMAT, vdp_sink->caps);
@@ -591,12 +603,16 @@ gst_vdp_sink_open_device (VdpSink * vdp_sink)
/* Setup our event listening thread */
vdp_sink->running = TRUE;
vdp_sink->event_thread = g_thread_create (
(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
gst_vdp_sink_start (GstBaseSink * bsink)
{
VdpSink *vdp_sink = GST_VDP_SINK (bsink);
@@ -895,22 +911,12 @@ gst_vdp_sink_event (GstBaseSink * sink, GstEvent * event)
if (GST_BASE_SINK_CLASS (parent_class)->event)
return GST_BASE_SINK_CLASS (parent_class)->event (sink, event);
else
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
* caps or create a buffer with different caps attached to the buffer. This
* last option is called reverse negotiation, ie, where the sink suggests a
* different format from the upstream peer.
diff --git a/sys/vdpau/gstvdpvideopostprocess.c b/sys/vdpau/gstvdpvideopostprocess.c
index 4658f901d..adaabf4bc 100644
--- a/sys/vdpau/gstvdpvideopostprocess.c
+++ b/sys/vdpau/gstvdpvideopostprocess.c
@@ -593,12 +593,13 @@ gst_vdp_vpp_flush (GstVdpVideoPostProcess * vpp)
}
static gboolean
gst_vdp_vpp_start (GstVdpVideoPostProcess * vpp)
{
gint i;
+ GError *err;
vpp->interlaced = FALSE;
vpp->field_duration = GST_CLOCK_TIME_NONE;
vpp->earliest_time = GST_CLOCK_TIME_NONE;
vpp->discont = FALSE;
@@ -610,23 +611,23 @@ gst_vdp_vpp_start (GstVdpVideoPostProcess * vpp)
vpp->future_pictures[i].buf = NULL;
vpp->past_pictures[i].buf = NULL;
}
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;
g_object_set (G_OBJECT (vpp->srcpad), "device", vpp->device, NULL);
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;
}
static gboolean
gst_vdp_vpp_stop (GstVdpVideoPostProcess * vpp)
{