mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-07-03 21:25:54 +00:00
fdsink: Block in preroll_wait on unlock
The correct behaviour of anything stuck in the ->render() function between ->unlock() and ->unlock_stop() is to call gst_base_sink_wait_preroll() and only return an error if this returns an error, otherwise, it must continue where it left off! https://bugzilla.gnome.org/show_bug.cgi?id=773912
This commit is contained in:
parent
2872ae21c3
commit
5216322d39
|
@ -193,7 +193,7 @@ fill_vectors (struct iovec *vecs, GstMapInfo * maps, guint n, GstBuffer * buf)
|
||||||
GstFlowReturn
|
GstFlowReturn
|
||||||
gst_writev_buffers (GstObject * sink, gint fd, GstPoll * fdset,
|
gst_writev_buffers (GstObject * sink, gint fd, GstPoll * fdset,
|
||||||
GstBuffer ** buffers, guint num_buffers, guint8 * mem_nums,
|
GstBuffer ** buffers, guint num_buffers, guint8 * mem_nums,
|
||||||
guint total_mem_num, guint64 * total_written, guint64 * cur_pos)
|
guint total_mem_num, guint64 * bytes_written, guint64 skip)
|
||||||
{
|
{
|
||||||
struct iovec *vecs;
|
struct iovec *vecs;
|
||||||
GstMapInfo *map_infos;
|
GstMapInfo *map_infos;
|
||||||
|
@ -218,6 +218,13 @@ gst_writev_buffers (GstObject * sink, gint fd, GstPoll * fdset,
|
||||||
guint n_vecs = total_mem_num;
|
guint n_vecs = total_mem_num;
|
||||||
|
|
||||||
left = size;
|
left = size;
|
||||||
|
|
||||||
|
if (skip) {
|
||||||
|
ret = skip;
|
||||||
|
errno = 0;
|
||||||
|
goto skip_first;
|
||||||
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
#ifndef HAVE_WIN32
|
#ifndef HAVE_WIN32
|
||||||
if (fdset != NULL) {
|
if (fdset != NULL) {
|
||||||
|
@ -239,12 +246,12 @@ gst_writev_buffers (GstObject * sink, gint fd, GstPoll * fdset,
|
||||||
ret = gst_writev (fd, vecs, n_vecs, left);
|
ret = gst_writev (fd, vecs, n_vecs, left);
|
||||||
|
|
||||||
if (ret > 0) {
|
if (ret > 0) {
|
||||||
if (total_written)
|
if (bytes_written)
|
||||||
*total_written += ret;
|
*bytes_written += ret;
|
||||||
if (cur_pos)
|
|
||||||
*cur_pos += ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
skip_first:
|
||||||
|
|
||||||
if (ret == left)
|
if (ret == left)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ G_GNUC_INTERNAL
|
||||||
GstFlowReturn gst_writev_buffers (GstObject * sink, gint fd, GstPoll * fdset,
|
GstFlowReturn gst_writev_buffers (GstObject * sink, gint fd, GstPoll * fdset,
|
||||||
GstBuffer ** buffers, guint num_buffers,
|
GstBuffer ** buffers, guint num_buffers,
|
||||||
guint8 * mem_nums, guint total_mem_num,
|
guint8 * mem_nums, guint total_mem_num,
|
||||||
guint64 * total_written, guint64 * cur_pos);
|
guint64 * bytes_written, guint64 skip);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
|
|
@ -243,9 +243,28 @@ static GstFlowReturn
|
||||||
gst_fd_sink_render_buffers (GstFdSink * sink, GstBuffer ** buffers,
|
gst_fd_sink_render_buffers (GstFdSink * sink, GstBuffer ** buffers,
|
||||||
guint num_buffers, guint8 * mem_nums, guint total_mems)
|
guint num_buffers, guint8 * mem_nums, guint total_mems)
|
||||||
{
|
{
|
||||||
return gst_writev_buffers (GST_OBJECT_CAST (sink), sink->fd, sink->fdset,
|
GstFlowReturn ret;
|
||||||
buffers, num_buffers, mem_nums, total_mems, &sink->bytes_written,
|
guint64 skip = 0;
|
||||||
&sink->current_pos);
|
|
||||||
|
for (;;) {
|
||||||
|
guint64 bytes_written = 0;
|
||||||
|
|
||||||
|
ret = gst_writev_buffers (GST_OBJECT_CAST (sink), sink->fd, sink->fdset,
|
||||||
|
buffers, num_buffers, mem_nums, total_mems, &bytes_written, skip);
|
||||||
|
|
||||||
|
sink->bytes_written += bytes_written;
|
||||||
|
sink->current_pos += bytes_written;
|
||||||
|
skip += bytes_written;
|
||||||
|
|
||||||
|
if (!sink->unlock)
|
||||||
|
break;
|
||||||
|
|
||||||
|
ret = gst_base_sink_wait_preroll (GST_BASE_SINK (sink));
|
||||||
|
if (ret != GST_FLOW_OK)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
|
@ -403,6 +422,7 @@ gst_fd_sink_unlock (GstBaseSink * basesink)
|
||||||
|
|
||||||
GST_LOG_OBJECT (fdsink, "Flushing");
|
GST_LOG_OBJECT (fdsink, "Flushing");
|
||||||
GST_OBJECT_LOCK (fdsink);
|
GST_OBJECT_LOCK (fdsink);
|
||||||
|
fdsink->unlock = TRUE;
|
||||||
gst_poll_set_flushing (fdsink->fdset, TRUE);
|
gst_poll_set_flushing (fdsink->fdset, TRUE);
|
||||||
GST_OBJECT_UNLOCK (fdsink);
|
GST_OBJECT_UNLOCK (fdsink);
|
||||||
|
|
||||||
|
@ -416,6 +436,7 @@ gst_fd_sink_unlock_stop (GstBaseSink * basesink)
|
||||||
|
|
||||||
GST_LOG_OBJECT (fdsink, "No longer flushing");
|
GST_LOG_OBJECT (fdsink, "No longer flushing");
|
||||||
GST_OBJECT_LOCK (fdsink);
|
GST_OBJECT_LOCK (fdsink);
|
||||||
|
fdsink->unlock = FALSE;
|
||||||
gst_poll_set_flushing (fdsink->fdset, FALSE);
|
gst_poll_set_flushing (fdsink->fdset, FALSE);
|
||||||
GST_OBJECT_UNLOCK (fdsink);
|
GST_OBJECT_UNLOCK (fdsink);
|
||||||
|
|
||||||
|
|
|
@ -62,6 +62,7 @@ struct _GstFdSink {
|
||||||
guint64 current_pos;
|
guint64 current_pos;
|
||||||
|
|
||||||
gboolean seekable;
|
gboolean seekable;
|
||||||
|
gboolean unlock; /* OBJECT LOCK */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstFdSinkClass {
|
struct _GstFdSinkClass {
|
||||||
|
|
|
@ -662,7 +662,7 @@ gst_file_sink_render_buffers (GstFileSink * sink, GstBuffer ** buffers,
|
||||||
num_buffers, total_mems, sink->current_pos);
|
num_buffers, total_mems, sink->current_pos);
|
||||||
|
|
||||||
return gst_writev_buffers (GST_OBJECT_CAST (sink), fileno (sink->file), NULL,
|
return gst_writev_buffers (GST_OBJECT_CAST (sink), fileno (sink->file), NULL,
|
||||||
buffers, num_buffers, mem_nums, total_mems, NULL, &sink->current_pos);
|
buffers, num_buffers, mem_nums, total_mems, &sink->current_pos, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
|
|
Loading…
Reference in a new issue