mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-20 23:36:38 +00:00
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.
This commit is contained in:
parent
ea364d7a5a
commit
9c1b87aaa6
3 changed files with 26 additions and 25 deletions
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
device = vdp_sink->device;
|
||||
|
||||
if (vdp_sink->cur_image) {
|
||||
prev_image = GST_VDP_OUTPUT_BUFFER (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);
|
||||
|
|
Loading…
Reference in a new issue