From 9c1b87aaa65d0d13264ea644b8094bd3a965107f Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Tue, 27 Oct 2009 22:04:10 +0100 Subject: [PATCH] vdpausink: rework presentation blocking a bit instead of blocking until the previous surface has been displayed, we new only add surfaces to the queue if it's idle. --- sys/vdpau/gstvdpdevice.c | 4 +++- sys/vdpau/gstvdpdevice.h | 1 + sys/vdpau/gstvdpsink.c | 46 +++++++++++++++++++--------------------- 3 files changed, 26 insertions(+), 25 deletions(-) diff --git a/sys/vdpau/gstvdpdevice.c b/sys/vdpau/gstvdpdevice.c index 906948d920..1aef9a34bf 100644 --- a/sys/vdpau/gstvdpdevice.c +++ b/sys/vdpau/gstvdpdevice.c @@ -123,7 +123,9 @@ gst_vdp_device_constructed (GObject * object) {VDP_FUNC_ID_PRESENTATION_QUEUE_BLOCK_UNTIL_SURFACE_IDLE, &device->vdp_presentation_queue_block_until_surface_idle}, {VDP_FUNC_ID_PRESENTATION_QUEUE_SET_BACKGROUND_COLOR, - &device->vdp_presentation_queue_set_background_color} + &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); diff --git a/sys/vdpau/gstvdpdevice.h b/sys/vdpau/gstvdpdevice.h index 4d73f09b26..2d14e6ab9e 100644 --- a/sys/vdpau/gstvdpdevice.h +++ b/sys/vdpau/gstvdpdevice.h @@ -88,6 +88,7 @@ struct _GstVdpDevice VdpPresentationQueueDisplay *vdp_presentation_queue_display; VdpPresentationQueueBlockUntilSurfaceIdle *vdp_presentation_queue_block_until_surface_idle; VdpPresentationQueueSetBackgroundColor *vdp_presentation_queue_set_background_color; + VdpPresentationQueueQuerySurfaceStatus *vdp_presentation_queue_query_surface_status; }; GType gst_vdp_device_get_type (void) G_GNUC_CONST; diff --git a/sys/vdpau/gstvdpsink.c b/sys/vdpau/gstvdpsink.c index 8529872489..0e0fb1321b 100644 --- a/sys/vdpau/gstvdpsink.c +++ b/sys/vdpau/gstvdpsink.c @@ -780,7 +780,6 @@ static GstFlowReturn gst_vdp_sink_show_frame (GstBaseSink * bsink, GstBuffer * outbuf) { VdpSink *vdp_sink = GST_VDP_SINK (bsink); - GstVdpOutputBuffer *prev_image = NULL; VdpStatus status; GstVdpDevice *device; @@ -795,13 +794,24 @@ gst_vdp_sink_show_frame (GstBaseSink * bsink, GstBuffer * outbuf) return GST_FLOW_ERROR; } - /* Store a reference to the last image we put, lose the previous one */ - if (outbuf && vdp_sink->cur_image != outbuf) { - if (vdp_sink->cur_image) { - prev_image = GST_VDP_OUTPUT_BUFFER (vdp_sink->cur_image); + device = vdp_sink->device; + + if (vdp_sink->cur_image) { + VdpOutputSurface surface = + GST_VDP_OUTPUT_BUFFER (vdp_sink->cur_image)->surface; + VdpPresentationQueueStatus queue_status; + VdpTime pres_time; + + g_mutex_lock (vdp_sink->x_lock); + status = + device->vdp_presentation_queue_query_surface_status (vdp_sink->window-> + queue, surface, &queue_status, &pres_time); + g_mutex_unlock (vdp_sink->x_lock); + + if (queue_status == VDP_PRESENTATION_QUEUE_STATUS_QUEUED) { + g_mutex_unlock (vdp_sink->flow_lock); + return GST_FLOW_OK; } - GST_LOG_OBJECT (vdp_sink, "reffing %p as our current image", outbuf); - vdp_sink->cur_image = gst_buffer_ref (outbuf); } /* Expose sends a NULL image, we take the latest frame */ @@ -818,7 +828,6 @@ gst_vdp_sink_show_frame (GstBaseSink * bsink, GstBuffer * outbuf) g_mutex_lock (vdp_sink->x_lock); - device = vdp_sink->device; status = device->vdp_presentation_queue_display (vdp_sink->window->queue, GST_VDP_OUTPUT_BUFFER (outbuf)->surface, 0, 0, 0); if (status != VDP_STATUS_OK) { @@ -832,24 +841,13 @@ gst_vdp_sink_show_frame (GstBaseSink * bsink, GstBuffer * outbuf) return GST_FLOW_ERROR; } - if (prev_image) { - VdpTime time; - /* block till the previous surface has been displayed */ - status = - device->vdp_presentation_queue_block_until_surface_idle (vdp_sink-> - window->queue, prev_image->surface, &time); - if (status != VDP_STATUS_OK) { - GST_ELEMENT_ERROR (vdp_sink, RESOURCE, READ, - ("Could not display frame"), - ("Error returned from vdpau was: %s", - device->vdp_get_error_string (status))); + if (!vdp_sink->cur_image) + vdp_sink->cur_image = gst_buffer_ref (outbuf); - g_mutex_unlock (vdp_sink->x_lock); - g_mutex_unlock (vdp_sink->flow_lock); - return GST_FLOW_ERROR; - } - gst_buffer_unref (GST_BUFFER (prev_image)); + else if (vdp_sink->cur_image != outbuf) { + gst_buffer_unref (vdp_sink->cur_image); + vdp_sink->cur_image = gst_buffer_ref (outbuf); } XSync (vdp_sink->device->display, FALSE);