mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-11 09:55:36 +00:00
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:
parent
c0759093eb
commit
a3cb4d4937
6 changed files with 78 additions and 42 deletions
23
ChangeLog
23
ChangeLog
|
@ -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:
|
||||
|
|
|
@ -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 *
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -84,7 +84,8 @@ struct _GstBaseAudioSink {
|
|||
guint64 next_sample;
|
||||
|
||||
/* clock */
|
||||
GstClock *clock;
|
||||
gboolean provide_clock;
|
||||
GstClock *provided_clock;
|
||||
|
||||
/*< private >*/
|
||||
gpointer _gst_reserved[GST_PADDING];
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -78,8 +78,6 @@ struct _GstBaseRTPDepayload
|
|||
*/
|
||||
GQueue *queue;
|
||||
|
||||
GstClock *clock;
|
||||
|
||||
/*< private >*/
|
||||
union {
|
||||
gboolean need_newsegment;
|
||||
|
|
Loading…
Reference in a new issue