mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 06:54:49 +00:00
make provided clock run in sync
Original commit message from CVS: make provided clock run in sync
This commit is contained in:
parent
078ad9c68b
commit
42d83d0474
2 changed files with 48 additions and 5 deletions
|
@ -1,3 +1,10 @@
|
||||||
|
2004-06-25 Thomas Vander Stichele <thomas at apestaart dot org>
|
||||||
|
|
||||||
|
* ext/alsa/gstalsasrc.c: (gst_alsa_src_init),
|
||||||
|
(gst_alsa_src_get_time), (gst_alsa_src_loop),
|
||||||
|
(gst_alsa_src_change_state):
|
||||||
|
return a time that is in sync with the element's processing
|
||||||
|
|
||||||
2004-06-25 Wim Taymans <wim@fluendo.com>
|
2004-06-25 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
* gst/tcp/gsttcpserversink.c: (gst_tcpserversink_class_init),
|
* gst/tcp/gsttcpserversink.c: (gst_tcpserversink_class_init),
|
||||||
|
|
|
@ -134,17 +134,51 @@ gst_alsa_src_init (GstAlsaSrc * src)
|
||||||
gst_object_ref (GST_OBJECT (this->clock));
|
gst_object_ref (GST_OBJECT (this->clock));
|
||||||
gst_object_sink (GST_OBJECT (this->clock));
|
gst_object_sink (GST_OBJECT (this->clock));
|
||||||
|
|
||||||
|
src->status = NULL;
|
||||||
gst_element_set_loop_function (GST_ELEMENT (this), gst_alsa_src_loop);
|
gst_element_set_loop_function (GST_ELEMENT (this), gst_alsa_src_loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* alsasrc provides a clock starting from the trigger tstamp
|
||||||
|
* (last play/pause/stop), and added to that the time for the currently
|
||||||
|
* processed samples, and the current fill state of the buffer */
|
||||||
static GstClockTime
|
static GstClockTime
|
||||||
gst_alsa_src_get_time (GstAlsa * this)
|
gst_alsa_src_get_time (GstAlsa * this)
|
||||||
{
|
{
|
||||||
|
struct timeval trigger;
|
||||||
|
snd_pcm_sframes_t delay;
|
||||||
|
GstClockTime gct_trigger, gct_captured, gct_delay, retval =
|
||||||
|
GST_CLOCK_TIME_NONE;
|
||||||
|
int err;
|
||||||
|
GstAlsaSrc *src = GST_ALSA_SRC (this);
|
||||||
|
|
||||||
GTimeVal now;
|
GTimeVal now;
|
||||||
|
|
||||||
g_get_current_time (&now);
|
g_get_current_time (&now);
|
||||||
|
|
||||||
return GST_TIMEVAL_TO_TIME (now);
|
return GST_TIMEVAL_TO_TIME (now);
|
||||||
|
|
||||||
|
if (src->status == NULL)
|
||||||
|
return GST_CLOCK_TIME_NONE;
|
||||||
|
|
||||||
|
if ((err = snd_pcm_status (this->handle, src->status)) < 0) {
|
||||||
|
GST_ERROR_OBJECT (this, "status error: %s", snd_strerror (err));
|
||||||
|
return GST_CLOCK_TIME_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* trigger tstamp is the last time the device got started/stopped/paused */
|
||||||
|
snd_pcm_status_get_trigger_tstamp (src->status, &trigger);
|
||||||
|
gct_trigger = GST_TIMEVAL_TO_TIME (trigger);
|
||||||
|
|
||||||
|
/* captured is the number of samples already sent out as buffers */
|
||||||
|
gct_captured = gst_alsa_samples_to_timestamp (this, this->captured);
|
||||||
|
|
||||||
|
/* delay is the number of samples in the buffer not yet processed */
|
||||||
|
delay = snd_pcm_status_get_delay (src->status);
|
||||||
|
gct_delay = gst_alsa_samples_to_timestamp (this, delay);
|
||||||
|
|
||||||
|
retval = gct_trigger + gct_captured + gct_delay;
|
||||||
|
GST_LOG_OBJECT (src, "returning clock time of %" GST_TIME_FORMAT,
|
||||||
|
GST_TIME_ARGS (retval));
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -388,13 +422,11 @@ gst_alsa_src_loop (GstElement * element)
|
||||||
gint outsize;
|
gint outsize;
|
||||||
GstClockTime outtime, outdur, outreal, outideal, startalsa, outalsa;
|
GstClockTime outtime, outdur, outreal, outideal, startalsa, outalsa;
|
||||||
gint64 diff, offset;
|
gint64 diff, offset;
|
||||||
snd_pcm_status_t *status;
|
|
||||||
struct timeval tstamp;
|
struct timeval tstamp;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
snd_pcm_status_alloca (&status);
|
|
||||||
|
|
||||||
if ((err = snd_pcm_status (this->handle, status)) < 0)
|
if ((err = snd_pcm_status (this->handle, src->status)) < 0)
|
||||||
GST_ERROR_OBJECT (this, "status error: %s", snd_strerror (err));
|
GST_ERROR_OBJECT (this, "status error: %s", snd_strerror (err));
|
||||||
|
|
||||||
offset = this->captured;
|
offset = this->captured;
|
||||||
|
@ -408,7 +440,7 @@ gst_alsa_src_loop (GstElement * element)
|
||||||
/* ideal time is counting samples */
|
/* ideal time is counting samples */
|
||||||
outideal = gst_alsa_samples_to_timestamp (this, offset);
|
outideal = gst_alsa_samples_to_timestamp (this, offset);
|
||||||
|
|
||||||
snd_pcm_status_get_trigger_tstamp (status, &tstamp);
|
snd_pcm_status_get_trigger_tstamp (src->status, &tstamp);
|
||||||
startalsa = GST_TIMEVAL_TO_TIME (tstamp) - element->base_time;
|
startalsa = GST_TIMEVAL_TO_TIME (tstamp) - element->base_time;
|
||||||
outalsa = startalsa + outideal;
|
outalsa = startalsa + outideal;
|
||||||
|
|
||||||
|
@ -473,13 +505,17 @@ gst_alsa_src_change_state (GstElement * element)
|
||||||
|
|
||||||
switch (GST_STATE_TRANSITION (element)) {
|
switch (GST_STATE_TRANSITION (element)) {
|
||||||
case GST_STATE_NULL_TO_READY:
|
case GST_STATE_NULL_TO_READY:
|
||||||
|
break;
|
||||||
case GST_STATE_READY_TO_PAUSED:
|
case GST_STATE_READY_TO_PAUSED:
|
||||||
|
snd_pcm_status_malloc (&src->status);
|
||||||
break;
|
break;
|
||||||
case GST_STATE_PAUSED_TO_PLAYING:
|
case GST_STATE_PAUSED_TO_PLAYING:
|
||||||
break;
|
break;
|
||||||
case GST_STATE_PLAYING_TO_PAUSED:
|
case GST_STATE_PLAYING_TO_PAUSED:
|
||||||
break;
|
break;
|
||||||
case GST_STATE_PAUSED_TO_READY:
|
case GST_STATE_PAUSED_TO_READY:
|
||||||
|
snd_pcm_status_free (src->status);
|
||||||
|
src->status = NULL;
|
||||||
gst_alsa_src_flush (src);
|
gst_alsa_src_flush (src);
|
||||||
break;
|
break;
|
||||||
case GST_STATE_READY_TO_NULL:
|
case GST_STATE_READY_TO_NULL:
|
||||||
|
|
Loading…
Reference in a new issue