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,
|
{VDP_FUNC_ID_PRESENTATION_QUEUE_BLOCK_UNTIL_SURFACE_IDLE,
|
||||||
&device->vdp_presentation_queue_block_until_surface_idle},
|
&device->vdp_presentation_queue_block_until_surface_idle},
|
||||||
{VDP_FUNC_ID_PRESENTATION_QUEUE_SET_BACKGROUND_COLOR,
|
{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);
|
device->display = XOpenDisplay (device->display_name);
|
||||||
|
|
|
@ -88,6 +88,7 @@ struct _GstVdpDevice
|
||||||
VdpPresentationQueueDisplay *vdp_presentation_queue_display;
|
VdpPresentationQueueDisplay *vdp_presentation_queue_display;
|
||||||
VdpPresentationQueueBlockUntilSurfaceIdle *vdp_presentation_queue_block_until_surface_idle;
|
VdpPresentationQueueBlockUntilSurfaceIdle *vdp_presentation_queue_block_until_surface_idle;
|
||||||
VdpPresentationQueueSetBackgroundColor *vdp_presentation_queue_set_background_color;
|
VdpPresentationQueueSetBackgroundColor *vdp_presentation_queue_set_background_color;
|
||||||
|
VdpPresentationQueueQuerySurfaceStatus *vdp_presentation_queue_query_surface_status;
|
||||||
};
|
};
|
||||||
|
|
||||||
GType gst_vdp_device_get_type (void) G_GNUC_CONST;
|
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)
|
gst_vdp_sink_show_frame (GstBaseSink * bsink, GstBuffer * outbuf)
|
||||||
{
|
{
|
||||||
VdpSink *vdp_sink = GST_VDP_SINK (bsink);
|
VdpSink *vdp_sink = GST_VDP_SINK (bsink);
|
||||||
GstVdpOutputBuffer *prev_image = NULL;
|
|
||||||
VdpStatus status;
|
VdpStatus status;
|
||||||
GstVdpDevice *device;
|
GstVdpDevice *device;
|
||||||
|
|
||||||
|
@ -795,13 +794,24 @@ gst_vdp_sink_show_frame (GstBaseSink * bsink, GstBuffer * outbuf)
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Store a reference to the last image we put, lose the previous one */
|
device = vdp_sink->device;
|
||||||
if (outbuf && vdp_sink->cur_image != outbuf) {
|
|
||||||
if (vdp_sink->cur_image) {
|
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 */
|
/* 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);
|
g_mutex_lock (vdp_sink->x_lock);
|
||||||
|
|
||||||
device = vdp_sink->device;
|
|
||||||
status = device->vdp_presentation_queue_display (vdp_sink->window->queue,
|
status = device->vdp_presentation_queue_display (vdp_sink->window->queue,
|
||||||
GST_VDP_OUTPUT_BUFFER (outbuf)->surface, 0, 0, 0);
|
GST_VDP_OUTPUT_BUFFER (outbuf)->surface, 0, 0, 0);
|
||||||
if (status != VDP_STATUS_OK) {
|
if (status != VDP_STATUS_OK) {
|
||||||
|
@ -832,24 +841,13 @@ gst_vdp_sink_show_frame (GstBaseSink * bsink, GstBuffer * outbuf)
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prev_image) {
|
|
||||||
VdpTime time;
|
|
||||||
|
|
||||||
/* block till the previous surface has been displayed */
|
if (!vdp_sink->cur_image)
|
||||||
status =
|
vdp_sink->cur_image = gst_buffer_ref (outbuf);
|
||||||
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)));
|
|
||||||
|
|
||||||
g_mutex_unlock (vdp_sink->x_lock);
|
else if (vdp_sink->cur_image != outbuf) {
|
||||||
g_mutex_unlock (vdp_sink->flow_lock);
|
gst_buffer_unref (vdp_sink->cur_image);
|
||||||
return GST_FLOW_ERROR;
|
vdp_sink->cur_image = gst_buffer_ref (outbuf);
|
||||||
}
|
|
||||||
gst_buffer_unref (GST_BUFFER (prev_image));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
XSync (vdp_sink->device->display, FALSE);
|
XSync (vdp_sink->device->display, FALSE);
|
||||||
|
|
Loading…
Reference in a new issue