gst/base/: Implement clock sync in base class.

Original commit message from CVS:
* gst/base/gstbasesink.c: (gst_base_sink_do_sync):
* gst/base/gstbasesrc.c: (gst_base_src_wait),
(gst_base_src_do_sync), (gst_base_src_get_range):
Implement clock sync in base class.
This commit is contained in:
Wim Taymans 2005-11-10 14:45:27 +00:00
parent a144ca207c
commit d5a2005e0c
5 changed files with 215 additions and 2 deletions

View file

@ -1,3 +1,10 @@
2005-11-10 Wim Taymans <wim@fluendo.com>
* gst/base/gstbasesink.c: (gst_base_sink_do_sync):
* gst/base/gstbasesrc.c: (gst_base_src_wait),
(gst_base_src_do_sync), (gst_base_src_get_range):
Implement clock sync in base class.
2005-11-10 Thomas Vander Stichele <thomas at apestaart dot org>
patch by: Tim-Philipp Müller <tim at centricular dot net>

View file

@ -1063,8 +1063,13 @@ gst_base_sink_do_sync (GstBaseSink * basesink, GstBuffer * buffer)
if (end_valid)
stream_end += basesink->segment_accum;
if (!basesink->sync) {
GST_DEBUG_OBJECT (basesink, "no need to sync");
goto done;
}
/* now do clocking */
if (basesink->clock && basesink->sync) {
if (basesink->clock) {
GstClockTime base_time;
GST_LOCK (basesink);

View file

@ -782,6 +782,84 @@ gst_base_src_get_property (GObject * object, guint prop_id, GValue * value,
}
}
/* with STREAM_LOCK and LOCK*/
static GstClockReturn
gst_base_src_wait (GstBaseSrc * basesrc, GstClockTime time)
{
GstClockReturn ret;
GstClockID id;
GstClock *clock;
if ((clock = GST_ELEMENT_CLOCK (basesrc)) == NULL)
return GST_CLOCK_OK;
/* clock_id should be NULL outside of this function */
g_assert (basesrc->clock_id == NULL);
g_assert (GST_CLOCK_TIME_IS_VALID (time));
id = gst_clock_new_single_shot_id (clock, time);
basesrc->clock_id = id;
/* release the object lock while waiting */
GST_UNLOCK (basesrc);
ret = gst_clock_id_wait (id, NULL);
GST_LOCK (basesrc);
gst_clock_id_unref (id);
basesrc->clock_id = NULL;
return ret;
}
/* perform synchronisation on a buffer
*/
static GstClockReturn
gst_base_src_do_sync (GstBaseSrc * basesrc, GstBuffer * buffer)
{
GstClockReturn result = GST_CLOCK_OK;
GstClockTime start, end;
GstBaseSrcClass *bclass;
gboolean start_valid;
GstClockTime base_time;
bclass = GST_BASE_SRC_GET_CLASS (basesrc);
start = end = -1;
if (bclass->get_times)
bclass->get_times (basesrc, buffer, &start, &end);
start_valid = GST_CLOCK_TIME_IS_VALID (start);
/* if we don't have a timestamp, we don't sync */
if (!start_valid) {
GST_DEBUG_OBJECT (basesrc, "get_times returned invalid start");
goto done;
}
GST_DEBUG_OBJECT (basesrc, "got times start: %" GST_TIME_FORMAT
", end: %" GST_TIME_FORMAT, GST_TIME_ARGS (start), GST_TIME_ARGS (end));
/* now do clocking */
GST_LOCK (basesrc);
base_time = GST_ELEMENT_CAST (basesrc)->base_time;
GST_LOG_OBJECT (basesrc,
"waiting for clock, base time %" GST_TIME_FORMAT
", stream_start %" GST_TIME_FORMAT,
GST_TIME_ARGS (base_time), GST_TIME_ARGS (start));
result = gst_base_src_wait (basesrc, start + base_time);
GST_UNLOCK (basesrc);
GST_LOG_OBJECT (basesrc, "clock entry done: %d", result);
done:
return result;
}
static GstFlowReturn
gst_base_src_get_range (GstBaseSrc * src, guint64 offset, guint length,
GstBuffer ** buf)
@ -789,6 +867,7 @@ gst_base_src_get_range (GstBaseSrc * src, guint64 offset, guint length,
GstFlowReturn ret;
GstBaseSrcClass *bclass;
gint64 maxsize;
GstClockReturn status;
bclass = GST_BASE_SRC_GET_CLASS (src);
@ -858,7 +937,26 @@ gst_base_src_get_range (GstBaseSrc * src, guint64 offset, guint length,
}
ret = bclass->create (src, offset, length, buf);
if (ret != GST_FLOW_OK)
goto done;
/* now sync before pushing the buffer */
status = gst_base_src_do_sync (src, *buf);
switch (status) {
case GST_CLOCK_EARLY:
GST_DEBUG_OBJECT (src, "buffer too late!, returning anyway");
break;
case GST_CLOCK_OK:
GST_DEBUG_OBJECT (src, "buffer ok");
break;
default:
GST_DEBUG_OBJECT (src, "clock returned %d, not returning", status);
gst_buffer_unref (*buf);
*buf = NULL;
ret = GST_FLOW_WRONG_STATE;
break;
}
done:
return ret;
/* ERROR */

View file

@ -1063,8 +1063,13 @@ gst_base_sink_do_sync (GstBaseSink * basesink, GstBuffer * buffer)
if (end_valid)
stream_end += basesink->segment_accum;
if (!basesink->sync) {
GST_DEBUG_OBJECT (basesink, "no need to sync");
goto done;
}
/* now do clocking */
if (basesink->clock && basesink->sync) {
if (basesink->clock) {
GstClockTime base_time;
GST_LOCK (basesink);

View file

@ -782,6 +782,84 @@ gst_base_src_get_property (GObject * object, guint prop_id, GValue * value,
}
}
/* with STREAM_LOCK and LOCK*/
static GstClockReturn
gst_base_src_wait (GstBaseSrc * basesrc, GstClockTime time)
{
GstClockReturn ret;
GstClockID id;
GstClock *clock;
if ((clock = GST_ELEMENT_CLOCK (basesrc)) == NULL)
return GST_CLOCK_OK;
/* clock_id should be NULL outside of this function */
g_assert (basesrc->clock_id == NULL);
g_assert (GST_CLOCK_TIME_IS_VALID (time));
id = gst_clock_new_single_shot_id (clock, time);
basesrc->clock_id = id;
/* release the object lock while waiting */
GST_UNLOCK (basesrc);
ret = gst_clock_id_wait (id, NULL);
GST_LOCK (basesrc);
gst_clock_id_unref (id);
basesrc->clock_id = NULL;
return ret;
}
/* perform synchronisation on a buffer
*/
static GstClockReturn
gst_base_src_do_sync (GstBaseSrc * basesrc, GstBuffer * buffer)
{
GstClockReturn result = GST_CLOCK_OK;
GstClockTime start, end;
GstBaseSrcClass *bclass;
gboolean start_valid;
GstClockTime base_time;
bclass = GST_BASE_SRC_GET_CLASS (basesrc);
start = end = -1;
if (bclass->get_times)
bclass->get_times (basesrc, buffer, &start, &end);
start_valid = GST_CLOCK_TIME_IS_VALID (start);
/* if we don't have a timestamp, we don't sync */
if (!start_valid) {
GST_DEBUG_OBJECT (basesrc, "get_times returned invalid start");
goto done;
}
GST_DEBUG_OBJECT (basesrc, "got times start: %" GST_TIME_FORMAT
", end: %" GST_TIME_FORMAT, GST_TIME_ARGS (start), GST_TIME_ARGS (end));
/* now do clocking */
GST_LOCK (basesrc);
base_time = GST_ELEMENT_CAST (basesrc)->base_time;
GST_LOG_OBJECT (basesrc,
"waiting for clock, base time %" GST_TIME_FORMAT
", stream_start %" GST_TIME_FORMAT,
GST_TIME_ARGS (base_time), GST_TIME_ARGS (start));
result = gst_base_src_wait (basesrc, start + base_time);
GST_UNLOCK (basesrc);
GST_LOG_OBJECT (basesrc, "clock entry done: %d", result);
done:
return result;
}
static GstFlowReturn
gst_base_src_get_range (GstBaseSrc * src, guint64 offset, guint length,
GstBuffer ** buf)
@ -789,6 +867,7 @@ gst_base_src_get_range (GstBaseSrc * src, guint64 offset, guint length,
GstFlowReturn ret;
GstBaseSrcClass *bclass;
gint64 maxsize;
GstClockReturn status;
bclass = GST_BASE_SRC_GET_CLASS (src);
@ -858,7 +937,26 @@ gst_base_src_get_range (GstBaseSrc * src, guint64 offset, guint length,
}
ret = bclass->create (src, offset, length, buf);
if (ret != GST_FLOW_OK)
goto done;
/* now sync before pushing the buffer */
status = gst_base_src_do_sync (src, *buf);
switch (status) {
case GST_CLOCK_EARLY:
GST_DEBUG_OBJECT (src, "buffer too late!, returning anyway");
break;
case GST_CLOCK_OK:
GST_DEBUG_OBJECT (src, "buffer ok");
break;
default:
GST_DEBUG_OBJECT (src, "clock returned %d, not returning", status);
gst_buffer_unref (*buf);
*buf = NULL;
ret = GST_FLOW_WRONG_STATE;
break;
}
done:
return ret;
/* ERROR */