mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-09 13:29:59 -05:00
When in PA_STREAM_AUTO_TIMING_UPDATE mode, delay completion of initialization until we have the first timing data
git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1762 fefdeb5f-60dc-0310-8127-8f9354f1896f
This commit is contained in:
parent
c029038164
commit
65ac0ea99a
1 changed files with 45 additions and 20 deletions
|
|
@ -38,6 +38,7 @@
|
||||||
#include <pulsecore/pstream-util.h>
|
#include <pulsecore/pstream-util.h>
|
||||||
#include <pulsecore/log.h>
|
#include <pulsecore/log.h>
|
||||||
#include <pulsecore/hashmap.h>
|
#include <pulsecore/hashmap.h>
|
||||||
|
#include <pulsecore/macro.h>
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
|
|
@ -218,6 +219,13 @@ void pa_stream_set_state(pa_stream *s, pa_stream_state_t st) {
|
||||||
s->channel_valid = 0;
|
s->channel_valid = 0;
|
||||||
|
|
||||||
s->context = NULL;
|
s->context = NULL;
|
||||||
|
|
||||||
|
s->read_callback = NULL;
|
||||||
|
s->write_callback = NULL;
|
||||||
|
s->state_callback = NULL;
|
||||||
|
s->overflow_callback = NULL;
|
||||||
|
s->underflow_callback = NULL;
|
||||||
|
s->latency_update_callback = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pa_stream_unref(s);
|
pa_stream_unref(s);
|
||||||
|
|
@ -321,7 +329,6 @@ void pa_command_overflow_or_underflow(pa_pdispatch *pd, uint32_t command, PA_GCC
|
||||||
}
|
}
|
||||||
|
|
||||||
static void request_auto_timing_update(pa_stream *s, int force) {
|
static void request_auto_timing_update(pa_stream *s, int force) {
|
||||||
struct timeval next;
|
|
||||||
assert(s);
|
assert(s);
|
||||||
|
|
||||||
if (!(s->flags & PA_STREAM_AUTO_TIMING_UPDATE))
|
if (!(s->flags & PA_STREAM_AUTO_TIMING_UPDATE))
|
||||||
|
|
@ -339,9 +346,12 @@ static void request_auto_timing_update(pa_stream *s, int force) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pa_gettimeofday(&next);
|
if (s->auto_timing_update_event) {
|
||||||
pa_timeval_add(&next, LATENCY_IPOL_INTERVAL_USEC);
|
struct timeval next;
|
||||||
s->mainloop->time_restart(s->auto_timing_update_event, &next);
|
pa_gettimeofday(&next);
|
||||||
|
pa_timeval_add(&next, LATENCY_IPOL_INTERVAL_USEC);
|
||||||
|
s->mainloop->time_restart(s->auto_timing_update_event, &next);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void invalidate_indexes(pa_stream *s, int r, int w) {
|
static void invalidate_indexes(pa_stream *s, int r, int w) {
|
||||||
|
|
@ -387,6 +397,24 @@ static void auto_timing_update_callback(PA_GCC_UNUSED pa_mainloop_api *m, PA_GCC
|
||||||
pa_stream_unref(s);
|
pa_stream_unref(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void create_stream_complete(pa_stream *s) {
|
||||||
|
pa_assert(s);
|
||||||
|
pa_assert(s->state == PA_STREAM_CREATING);
|
||||||
|
|
||||||
|
pa_stream_set_state(s, PA_STREAM_READY);
|
||||||
|
|
||||||
|
if (s->requested_bytes > 0 && s->write_callback)
|
||||||
|
s->write_callback(s, s->requested_bytes, s->write_userdata);
|
||||||
|
|
||||||
|
if (s->flags & PA_STREAM_AUTO_TIMING_UPDATE) {
|
||||||
|
struct timeval tv;
|
||||||
|
pa_gettimeofday(&tv);
|
||||||
|
tv.tv_usec += LATENCY_IPOL_INTERVAL_USEC; /* every 100 ms */
|
||||||
|
assert(!s->auto_timing_update_event);
|
||||||
|
s->auto_timing_update_event = s->mainloop->time_new(s->mainloop, &tv, &auto_timing_update_callback, s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void pa_create_stream_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
|
void pa_create_stream_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
|
||||||
pa_stream *s = userdata;
|
pa_stream *s = userdata;
|
||||||
|
|
||||||
|
|
@ -450,23 +478,16 @@ void pa_create_stream_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED
|
||||||
s->channel_valid = 1;
|
s->channel_valid = 1;
|
||||||
pa_dynarray_put((s->direction == PA_STREAM_RECORD) ? s->context->record_streams : s->context->playback_streams, s->channel, s);
|
pa_dynarray_put((s->direction == PA_STREAM_RECORD) ? s->context->record_streams : s->context->playback_streams, s->channel, s);
|
||||||
|
|
||||||
pa_stream_set_state(s, PA_STREAM_READY);
|
if (s->direction != PA_STREAM_UPLOAD && s->flags & PA_STREAM_AUTO_TIMING_UPDATE) {
|
||||||
|
/* If automatic timing updates are active, we wait for the
|
||||||
if (s->direction != PA_STREAM_UPLOAD &&
|
* first timing update before going to PA_STREAM_READY
|
||||||
s->flags & PA_STREAM_AUTO_TIMING_UPDATE) {
|
* state */
|
||||||
struct timeval tv;
|
s->state = PA_STREAM_READY;
|
||||||
|
|
||||||
pa_gettimeofday(&tv);
|
|
||||||
tv.tv_usec += LATENCY_IPOL_INTERVAL_USEC; /* every 100 ms */
|
|
||||||
|
|
||||||
assert(!s->auto_timing_update_event);
|
|
||||||
s->auto_timing_update_event = s->mainloop->time_new(s->mainloop, &tv, &auto_timing_update_callback, s);
|
|
||||||
|
|
||||||
request_auto_timing_update(s, 1);
|
request_auto_timing_update(s, 1);
|
||||||
}
|
s->state = PA_STREAM_CREATING;
|
||||||
|
|
||||||
if (s->requested_bytes > 0 && s->ref > 1 && s->write_callback)
|
} else
|
||||||
s->write_callback(s, s->requested_bytes, s->write_userdata);
|
create_stream_complete(s);
|
||||||
|
|
||||||
finish:
|
finish:
|
||||||
pa_stream_unref(s);
|
pa_stream_unref(s);
|
||||||
|
|
@ -886,6 +907,10 @@ static void stream_get_timing_info_callback(pa_pdispatch *pd, uint32_t command,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* First, let's complete the initialization, if necessary. */
|
||||||
|
if (o->stream->state == PA_STREAM_CREATING)
|
||||||
|
create_stream_complete(o->stream);
|
||||||
|
|
||||||
if (o->stream->latency_update_callback)
|
if (o->stream->latency_update_callback)
|
||||||
o->stream->latency_update_callback(o->stream, o->stream->latency_update_userdata);
|
o->stream->latency_update_callback(o->stream, o->stream->latency_update_userdata);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue