gst-libs/gst/audio/gstaudioclock.c: This clock can be slaved to a master clock now.

Original commit message from CVS:
* gst-libs/gst/audio/gstaudioclock.c: (gst_audio_clock_init):
This clock can be slaved to a master clock now.

* gst-libs/gst/audio/gstbaseaudiosink.c:
(gst_base_audio_sink_class_init), (gst_base_audio_sink_init),
(gst_base_audio_sink_dispose), (gst_base_audio_sink_provide_clock),
(gst_base_audio_sink_set_clock),
(gst_base_audio_sink_set_property),
(gst_base_audio_sink_get_property), (gst_base_audio_sink_preroll),
(gst_base_audio_sink_render), (gst_base_audio_sink_change_state):
* gst-libs/gst/audio/gstbaseaudiosink.h:
Handle slaving the internal clock to the clock selected in the
pipeline.
Add property to make the basesink not provide a clock.

* gst-libs/gst/rtp/gstbasertpdepayload.c:
(gst_base_rtp_depayload_class_init), (gst_base_rtp_depayload_init),
(gst_base_rtp_depayload_wait):
* gst-libs/gst/rtp/gstbasertpdepayload.h:
We can use the clock in GstElement, no need to store it ourselves.
This commit is contained in:
Wim Taymans 2005-11-22 18:32:09 +00:00
parent c0759093eb
commit a3cb4d4937
6 changed files with 78 additions and 42 deletions

View file

@ -1,3 +1,26 @@
2005-11-22 Wim Taymans <wim@fluendo.com>
* gst-libs/gst/audio/gstaudioclock.c: (gst_audio_clock_init):
This clock can be slaved to a master clock now.
* gst-libs/gst/audio/gstbaseaudiosink.c:
(gst_base_audio_sink_class_init), (gst_base_audio_sink_init),
(gst_base_audio_sink_dispose), (gst_base_audio_sink_provide_clock),
(gst_base_audio_sink_set_clock),
(gst_base_audio_sink_set_property),
(gst_base_audio_sink_get_property), (gst_base_audio_sink_preroll),
(gst_base_audio_sink_render), (gst_base_audio_sink_change_state):
* gst-libs/gst/audio/gstbaseaudiosink.h:
Handle slaving the internal clock to the clock selected in the
pipeline.
Add property to make the basesink not provide a clock.
* gst-libs/gst/rtp/gstbasertpdepayload.c:
(gst_base_rtp_depayload_class_init), (gst_base_rtp_depayload_init),
(gst_base_rtp_depayload_wait):
* gst-libs/gst/rtp/gstbasertpdepayload.h:
We can use the clock in GstElement, no need to store it ourselves.
2005-11-22 Thomas Vander Stichele <thomas at apestaart dot org>
* docs/libs/tmpl/gstaudio.sgml:

View file

@ -83,6 +83,7 @@ gst_audio_clock_init (GstAudioClock * clock)
gst_object_set_name (GST_OBJECT (clock), "GstAudioClock");
clock->last_time = 0;
GST_OBJECT_FLAG_SET (clock, GST_CLOCK_FLAG_CAN_SET_MASTER);
}
GstClock *

View file

@ -41,11 +41,15 @@ enum
#define DEFAULT_BUFFER_TIME 500 * GST_USECOND
#define DEFAULT_LATENCY_TIME 10 * GST_USECOND
//#define DEFAULT_PROVIDE_CLOCK TRUE
#define DEFAULT_PROVIDE_CLOCK FALSE
enum
{
PROP_0,
PROP_BUFFER_TIME,
PROP_LATENCY_TIME,
PROP_PROVIDE_CLOCK,
};
#define _do_init(bla) \
@ -65,7 +69,8 @@ static GstStateChangeReturn gst_base_audio_sink_change_state (GstElement *
element, GstStateChange transition);
static GstClock *gst_base_audio_sink_provide_clock (GstElement * elem);
static void gst_base_audio_sink_set_clock (GstElement * elem, GstClock * clock);
static gboolean gst_base_audio_sink_set_clock (GstElement * elem,
GstClock * clock);
static GstClockTime gst_base_audio_sink_get_time (GstClock * clock,
GstBaseAudioSink * sink);
static void gst_base_audio_sink_callback (GstRingBuffer * rbuf, guint8 * data,
@ -114,6 +119,10 @@ gst_base_audio_sink_class_init (GstBaseAudioSinkClass * klass)
g_param_spec_int64 ("latency-time", "Latency Time",
"Audio latency in milliseconds (-1 = default)",
-1, G_MAXINT64, DEFAULT_LATENCY_TIME, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_PROVIDE_CLOCK,
g_param_spec_boolean ("provide-clock", "Provide Clock",
"Provide a clock to be used as the global pipeline clock",
DEFAULT_PROVIDE_CLOCK, G_PARAM_READWRITE));
gstelement_class->change_state =
GST_DEBUG_FUNCPTR (gst_base_audio_sink_change_state);
@ -136,8 +145,9 @@ gst_base_audio_sink_init (GstBaseAudioSink * baseaudiosink,
{
baseaudiosink->buffer_time = DEFAULT_BUFFER_TIME;
baseaudiosink->latency_time = DEFAULT_LATENCY_TIME;
baseaudiosink->provide_clock = DEFAULT_PROVIDE_CLOCK;
baseaudiosink->clock = gst_audio_clock_new ("clock",
baseaudiosink->provided_clock = gst_audio_clock_new ("clock",
(GstAudioClockGetTimeFunc) gst_base_audio_sink_get_time, baseaudiosink);
}
@ -148,9 +158,9 @@ gst_base_audio_sink_dispose (GObject * object)
sink = GST_BASE_AUDIO_SINK (object);
if (sink->clock)
gst_object_unref (sink->clock);
sink->clock = NULL;
if (sink->provided_clock)
gst_object_unref (sink->provided_clock);
sink->provided_clock = NULL;
if (sink->ringbuffer)
gst_object_unref (sink->ringbuffer);
@ -167,25 +177,31 @@ gst_base_audio_sink_provide_clock (GstElement * elem)
sink = GST_BASE_AUDIO_SINK (elem);
clock = GST_CLOCK_CAST (gst_object_ref (sink->clock));
if (sink->provide_clock)
clock = GST_CLOCK_CAST (gst_object_ref (sink->provided_clock));
else
clock = NULL;
return clock;
}
static void
static gboolean
gst_base_audio_sink_set_clock (GstElement * elem, GstClock * clock)
{
GstBaseAudioSink *sink;
gboolean ret;
sink = GST_BASE_AUDIO_SINK (elem);
GST_OBJECT_LOCK (sink);
if (clock != sink->clock) {
gst_clock_set_master (sink->clock, clock);
if (clock != sink->provided_clock) {
ret = gst_clock_set_master (sink->provided_clock, clock);
} else {
gst_clock_set_master (sink->clock, NULL);
ret = gst_clock_set_master (sink->provided_clock, NULL);
}
GST_OBJECT_UNLOCK (sink);
return ret;
}
static GstClockTime
@ -220,6 +236,9 @@ gst_base_audio_sink_set_property (GObject * object, guint prop_id,
case PROP_LATENCY_TIME:
sink->latency_time = g_value_get_int64 (value);
break;
case PROP_PROVIDE_CLOCK:
sink->provide_clock = g_value_get_boolean (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -241,6 +260,9 @@ gst_base_audio_sink_get_property (GObject * object, guint prop_id,
case PROP_LATENCY_TIME:
g_value_set_int64 (value, sink->latency_time);
break;
case PROP_PROVIDE_CLOCK:
g_value_set_boolean (value, sink->provide_clock);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -350,8 +372,8 @@ wrong_state:
{
GST_DEBUG ("ringbuffer in wrong state");
GST_ELEMENT_ERROR (sink, RESOURCE, NOT_FOUND,
("sink not negotiated."), (NULL));
return GST_FLOW_ERROR;
("sink not negotiated."), ("sink not negotiated."));
return GST_FLOW_NOT_NEGOTIATED;
}
}
@ -441,7 +463,8 @@ gst_base_audio_sink_render (GstBaseSink * bsink, GstBuffer * buf)
if (render_diff < 0)
goto out_of_segment;
gst_clock_get_calibration (sink->clock, &cinternal, &cexternal, &crate);
gst_clock_get_calibration (sink->provided_clock, &cinternal, &cexternal,
&crate);
GST_DEBUG_OBJECT (sink,
"internal %" G_GUINT64_FORMAT ", %" G_GUINT64_FORMAT ", rate %g",
cinternal, cexternal, crate);
@ -567,18 +590,23 @@ gst_base_audio_sink_change_state (GstElement * element,
break;
case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
{
GstClockTime time;
gdouble rate;
/* if we are slaved to a clock, we need to set the initial
* calibration */
/* FIXME, this is not yet accurate enough for smooth playback */
if (gst_clock_get_master (sink->provided_clock)) {
GstClockTime time;
gdouble rate;
time = gst_clock_get_internal_time (sink->clock);
time = gst_clock_get_internal_time (sink->provided_clock);
GST_DEBUG_OBJECT (sink, "time: %" GST_TIME_FORMAT, GST_TIME_ARGS (time));
GST_DEBUG_OBJECT (sink, "time: %" GST_TIME_FORMAT,
GST_TIME_ARGS (time));
gst_clock_get_calibration (sink->clock, NULL, NULL, &rate);
/* Does not work yet.
gst_clock_set_calibration (sink->clock,
time, element->base_time, rate);
*/
gst_clock_get_calibration (sink->provided_clock, NULL, NULL, &rate);
/* Does not work yet. */
gst_clock_set_calibration (sink->provided_clock,
time, element->base_time, rate);
}
break;
}
case GST_STATE_CHANGE_PAUSED_TO_READY:

View file

@ -84,7 +84,8 @@ struct _GstBaseAudioSink {
guint64 next_sample;
/* clock */
GstClock *clock;
gboolean provide_clock;
GstClock *provided_clock;
/*< private >*/
gpointer _gst_reserved[GST_PADDING];

View file

@ -80,8 +80,6 @@ static gboolean gst_base_rtp_depayload_setcaps (GstPad * pad, GstCaps * caps);
static GstFlowReturn gst_base_rtp_depayload_chain (GstPad * pad,
GstBuffer * in);
static void gst_base_rtp_depayload_set_clock (GstElement * element,
GstClock * clock);
static GstStateChangeReturn gst_base_rtp_depayload_change_state (GstElement *
element, GstStateChange transition);
static GstFlowReturn gst_base_rtp_depayload_add_to_queue (GstBaseRTPDepayload *
@ -118,8 +116,6 @@ gst_base_rtp_depayload_class_init (GstBaseRTPDepayloadClass * klass)
gobject_class->finalize = gst_base_rtp_depayload_finalize;
gstelement_class->set_clock =
GST_DEBUG_FUNCPTR (gst_base_rtp_depayload_set_clock);
gstelement_class->change_state = gst_base_rtp_depayload_change_state;
klass->add_to_queue = gst_base_rtp_depayload_add_to_queue;
@ -158,7 +154,6 @@ gst_base_rtp_depayload_init (GstBaseRTPDepayload * filter, gpointer g_class)
/* this one needs to be overwritten by child */
filter->clock_rate = 0;
filter->clock = NULL;
}
static void
@ -399,27 +394,17 @@ gst_base_rtp_depayload_wait (GstBaseRTPDepayload * filter, GstClockTime time)
GstClockID id;
g_return_if_fail (GST_CLOCK_TIME_IS_VALID (time));
if (filter->clock == NULL) {
if (GST_ELEMENT_CLOCK (filter) == NULL) {
GST_DEBUG_OBJECT (filter, "No clock given yet");
return;
}
id = gst_clock_new_single_shot_id (filter->clock, time);
id = gst_clock_new_single_shot_id (GST_ELEMENT_CLOCK (filter), time);
gst_clock_id_wait (id, NULL);
gst_clock_id_unref (id);
}
static void
gst_base_rtp_depayload_set_clock (GstElement * element, GstClock * clock)
{
GstBaseRTPDepayload *sink;
sink = GST_BASE_RTP_DEPAYLOAD (element);
sink->clock = clock;
}
static GstStateChangeReturn
gst_base_rtp_depayload_change_state (GstElement * element,
GstStateChange transition)

View file

@ -78,8 +78,6 @@ struct _GstBaseRTPDepayload
*/
GQueue *queue;
GstClock *clock;
/*< private >*/
union {
gboolean need_newsegment;