mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-03 13:02:29 +00:00
merge back from release
Original commit message from CVS: merge back from release
This commit is contained in:
parent
13377326ca
commit
96c2a15318
4 changed files with 35 additions and 114 deletions
|
@ -1,3 +1,12 @@
|
|||
2004-06-23 Thomas Vander Stichele <thomas at apestaart dot org>
|
||||
|
||||
* ext/alsa/gstalsa.c: (gst_alsa_init), (gst_alsa_dispose),
|
||||
(gst_alsa_change_state), (gst_alsa_update_avail),
|
||||
(gst_alsa_xrun_recovery):
|
||||
* ext/alsa/gstalsa.h:
|
||||
* ext/alsa/gstalsasink.c: (gst_alsa_sink_check_event):
|
||||
merge back changes from release
|
||||
|
||||
2004-06-23 Wim Taymans <wim@fluendo.com>
|
||||
|
||||
* gst/audiorate/gstaudiorate.c: (gst_audiorate_class_init),
|
||||
|
|
|
@ -203,12 +203,6 @@ static void
|
|||
gst_alsa_init (GstAlsa * this)
|
||||
{
|
||||
this->device = g_strdup ("default");
|
||||
g_assert (snd_pcm_status_malloc (&(this->status)) == 0);
|
||||
|
||||
this->clock = gst_alsa_clock_new ("alsaclock", gst_alsa_get_time, this);
|
||||
/* we hold a ref to our clock until we're disposed */
|
||||
gst_object_ref (GST_OBJECT (this->clock));
|
||||
gst_object_sink (GST_OBJECT (this->clock));
|
||||
|
||||
GST_FLAG_SET (this, GST_ELEMENT_EVENT_AWARE);
|
||||
GST_FLAG_SET (this, GST_ELEMENT_THREAD_SUGGESTED);
|
||||
|
@ -220,9 +214,6 @@ gst_alsa_dispose (GObject * object)
|
|||
GstAlsa *this = GST_ALSA (object);
|
||||
|
||||
g_free (this->device);
|
||||
this->device = NULL;
|
||||
snd_pcm_status_free (this->status);
|
||||
this->status = NULL;
|
||||
|
||||
if (this->clock)
|
||||
gst_object_unparent (GST_OBJECT (this->clock));
|
||||
|
@ -319,63 +310,6 @@ gst_alsa_get_property (GObject * object, guint prop_id, GValue * value,
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ask ALSA for current time using htstamp
|
||||
* FIXME: This is not very accurate, should use alsa timers instead.
|
||||
* htstamp seems to use the system clock instead of the hw clock.
|
||||
* We also use an ugly hack for now to substract the number of queued
|
||||
* samples in the device from the system time, this makes sure that other
|
||||
* plugins timestamp their samples with the right time but makes the
|
||||
* clock a little unstable. A good way to fix this is to get the exact amount
|
||||
* of samples that were produced by ALSA but I can't find a way to get that
|
||||
* information.. oh well.. ALSA has enough methods, there is bound to be at
|
||||
* least 1 way of getting the info...
|
||||
*/
|
||||
GstClockTime
|
||||
gst_alsa_get_time (GstAlsa * this)
|
||||
{
|
||||
int err;
|
||||
snd_htimestamp_t timestamp;
|
||||
GstClockTime time, ideal;
|
||||
GstClockTime availtime;
|
||||
snd_pcm_sframes_t avail;
|
||||
|
||||
if ((err = snd_pcm_status (this->handle, this->status)) < 0) {
|
||||
GST_WARNING_OBJECT (this, "could not get snd_pcm_status");
|
||||
}
|
||||
|
||||
/* see how many samples are still in the buffer */
|
||||
avail = snd_pcm_status_get_avail (this->status);
|
||||
availtime = gst_alsa_samples_to_timestamp (this, avail);
|
||||
|
||||
/* get the clock time */
|
||||
snd_pcm_status_get_htstamp (this->status, ×tamp);
|
||||
|
||||
/* time = GST_TIMESPEC_TO_TIME (timestamp); */
|
||||
/* we have to compensate the time for the number of queued samples
|
||||
* in the buffer */
|
||||
time =
|
||||
timestamp.tv_sec * GST_SECOND + timestamp.tv_nsec * GST_NSECOND -
|
||||
availtime;
|
||||
ideal =
|
||||
this->clock_base + gst_alsa_samples_to_timestamp (this,
|
||||
this->transmitted) - availtime;
|
||||
|
||||
GST_DEBUG_OBJECT (this, "clock time %lld, diff to ideal %lld\n", time,
|
||||
time - ideal);
|
||||
|
||||
GST_LOG_OBJECT (this, "ALSA reports time of %" GST_TIME_FORMAT,
|
||||
GST_TIME_ARGS (time));
|
||||
|
||||
return time;
|
||||
}
|
||||
|
||||
void
|
||||
gst_alsa_clock_update (GstAlsa * this, GstClockTime ideal)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static const GList *
|
||||
gst_alsa_probe_get_properties (GstPropertyProbe * probe)
|
||||
{
|
||||
|
@ -1152,7 +1086,6 @@ gst_alsa_change_state (GstElement * element)
|
|||
gst_alsa_start_audio (this)))
|
||||
return GST_STATE_FAILURE;
|
||||
this->transmitted = 0;
|
||||
this->clock_base = GST_CLOCK_TIME_NONE;
|
||||
break;
|
||||
case GST_STATE_PAUSED_TO_PLAYING:
|
||||
if (snd_pcm_state (this->handle) == SND_PCM_STATE_PAUSED) {
|
||||
|
@ -1222,10 +1155,8 @@ gst_alsa_set_clock (GstElement * element, GstClock * clock)
|
|||
inline snd_pcm_sframes_t
|
||||
gst_alsa_update_avail (GstAlsa * this)
|
||||
{
|
||||
snd_pcm_sframes_t avail = -1;
|
||||
snd_pcm_sframes_t avail = snd_pcm_avail_update (this->handle);
|
||||
|
||||
while (avail < 0) {
|
||||
avail = snd_pcm_avail_update (this->handle);
|
||||
if (avail < 0) {
|
||||
if (avail == -EPIPE) {
|
||||
gst_alsa_xrun_recovery (this);
|
||||
|
@ -1234,12 +1165,6 @@ gst_alsa_update_avail (GstAlsa * this)
|
|||
(int) avail);
|
||||
}
|
||||
}
|
||||
if (snd_pcm_state (this->handle) != SND_PCM_STATE_RUNNING) {
|
||||
if (!gst_alsa_start (this)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return avail;
|
||||
}
|
||||
|
||||
|
@ -1319,7 +1244,13 @@ gst_alsa_xrun_recovery (GstAlsa * this)
|
|||
GST_ERROR_OBJECT (this, "status error: %s", snd_strerror (err));
|
||||
|
||||
if (snd_pcm_status_get_state (status) == SND_PCM_STATE_XRUN) {
|
||||
GstClockTime elemnow;
|
||||
struct timeval now, diff, tstamp;
|
||||
|
||||
gettimeofday (&now, 0);
|
||||
snd_pcm_status_get_trigger_tstamp (status, &tstamp);
|
||||
timersub (&now, &tstamp, &diff);
|
||||
GST_INFO_OBJECT (this, "alsa: xrun of at least %.3f msecs",
|
||||
diff.tv_sec * 1000 + diff.tv_usec / 1000.0);
|
||||
|
||||
/* if we're allowed to recover, ... */
|
||||
if (this->autorecover) {
|
||||
|
@ -1333,28 +1264,13 @@ gst_alsa_xrun_recovery (GstAlsa * this)
|
|||
this->period_count *= 2;
|
||||
}
|
||||
}
|
||||
|
||||
if ((err = snd_pcm_prepare (this->handle)) < 0) {
|
||||
GST_ERROR_OBJECT (this, "prepare error: %s", snd_strerror (err));
|
||||
return FALSE;
|
||||
}
|
||||
/* The strategy to recover the timestamps from the xrun is to take the
|
||||
* current element time and pretend we just sent all the samples up to
|
||||
* that time. This will result in an offset discontinuity in the next
|
||||
* buffer along with the correct timestamp on that buffer */
|
||||
elemnow = gst_element_get_time (GST_ELEMENT (this));
|
||||
this->transmitted = gst_alsa_timestamp_to_samples (this, elemnow);
|
||||
GST_DEBUG_OBJECT (this, "XRun!!!! pretending we transmitted %lld samples",
|
||||
this->transmitted);
|
||||
|
||||
} else {
|
||||
/* something else happened, reset the device */
|
||||
if (!(gst_alsa_stop_audio (this) && gst_alsa_start_audio (this))) {
|
||||
GST_ELEMENT_ERROR (this, RESOURCE, FAILED, (NULL),
|
||||
("Error restarting audio after xrun"));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -156,7 +156,6 @@ struct _GstAlsa {
|
|||
|
||||
/* clocking */
|
||||
GstAlsaClock * clock; /* our provided clock */
|
||||
GstClockTime clock_base; /* adjusted clock base time */
|
||||
snd_pcm_uframes_t transmitted; /* samples transmitted since last sync
|
||||
This thing actually is our master clock.
|
||||
We will event insert silent samples or
|
||||
|
@ -165,7 +164,6 @@ struct _GstAlsa {
|
|||
GstClockTime max_discont; /* max difference between current
|
||||
playback timestamp and buffers timestamps
|
||||
*/
|
||||
snd_pcm_status_t *status;
|
||||
};
|
||||
|
||||
struct _GstAlsaClass {
|
||||
|
@ -193,10 +191,6 @@ GstCaps * gst_alsa_caps (snd_pcm_format_t format,
|
|||
gint rate,
|
||||
gint channels);
|
||||
|
||||
GstClockTime gst_alsa_get_time (GstAlsa * this);
|
||||
void gst_alsa_clock_update (GstAlsa * this, GstClockTime ideal);
|
||||
|
||||
|
||||
/* audio processing functions */
|
||||
inline snd_pcm_sframes_t gst_alsa_update_avail (GstAlsa * this);
|
||||
inline gboolean gst_alsa_pcm_wait (GstAlsa * this);
|
||||
|
|
|
@ -220,13 +220,15 @@ gst_alsa_sink_check_event (GstAlsaSink * sink, gint pad_nr)
|
|||
GST_SECOND * this->transmitted / this->format->rate -
|
||||
gst_alsa_sink_get_time (this);
|
||||
if (gst_event_discont_get_value (event, GST_FORMAT_TIME, &value)) {
|
||||
gst_element_set_time_delay (GST_ELEMENT (this), value, delay);
|
||||
} else if (this->format &&
|
||||
(gst_event_discont_get_value (event, GST_FORMAT_DEFAULT, &value) ||
|
||||
gst_event_discont_get_value (event, GST_FORMAT_BYTES,
|
||||
gst_element_set_time_delay (GST_ELEMENT (this), MIN (value, delay),
|
||||
delay);
|
||||
} else if (this->format
|
||||
&& (gst_event_discont_get_value (event, GST_FORMAT_DEFAULT, &value)
|
||||
|| gst_event_discont_get_value (event, GST_FORMAT_BYTES,
|
||||
&value))) {
|
||||
value = gst_alsa_samples_to_timestamp (this, value);
|
||||
gst_element_set_time_delay (GST_ELEMENT (this), value, delay);
|
||||
gst_element_set_time_delay (GST_ELEMENT (this), MIN (value, delay),
|
||||
delay);
|
||||
} else {
|
||||
GST_WARNING_OBJECT (this,
|
||||
"couldn't extract time from discont event. Bad things might happen!");
|
||||
|
|
Loading…
Reference in a new issue