[pulseaudio-commits] r1490 - in /branches/lennart/src/pulsecore: sink.c sink.h
svnmailer-noreply at 0pointer.de
svnmailer-noreply at 0pointer.de
Sat Jun 23 13:04:48 PDT 2007
Author: lennart
Date: Sat Jun 23 22:04:47 2007
New Revision: 1490
URL: http://0pointer.de/cgi-bin/viewcvs.cgi?rev=3D1490&root=3Dpulseaudio&vi=
ew=3Drev
Log:
remove underrun condition in pa_sinks. Instead return silence in pa_sink_re=
nder() when necessary. This is required to guarantee that the time function=
s in connected sink inputs stays linear
Modified:
branches/lennart/src/pulsecore/sink.c
branches/lennart/src/pulsecore/sink.h
Modified: branches/lennart/src/pulsecore/sink.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/branches/lennart/src/pulsecore/=
sink.c?rev=3D1490&root=3Dpulseaudio&r1=3D1489&r2=3D1490&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- branches/lennart/src/pulsecore/sink.c (original)
+++ branches/lennart/src/pulsecore/sink.c Sat Jun 23 22:04:47 2007
@@ -116,6 +116,7 @@
s->userdata =3D NULL;
=
s->asyncmsgq =3D NULL;
+ s->silence =3D NULL;
=
r =3D pa_idxset_put(core->sinks, s, &s->index);
pa_assert(s->index !=3D PA_IDXSET_INVALID && r >=3D 0);
@@ -222,6 +223,9 @@
=
pa_hashmap_free(s->thread_info.inputs, NULL, NULL);
=
+ if (s->silence)
+ pa_memblock_unref(s->silence);
+ =
pa_xfree(s->name);
pa_xfree(s->description);
pa_xfree(s->driver);
@@ -270,53 +274,85 @@
pa_sink_assert_ref(s);
pa_assert(info);
=
+ while ((i =3D pa_hashmap_iterate(s->thread_info.inputs, &state, NULL))=
&& maxinfo > 0) {
+ pa_sink_input_assert_ref(i);
+
+ if (pa_sink_input_peek(i, &info->chunk, &info->volume) < 0)
+ continue;
+
+ info->userdata =3D pa_sink_input_ref(i);
+
+ pa_assert(info->chunk.memblock);
+ pa_assert(info->chunk.length > 0);
+
+ info++;
+ n++;
+ maxinfo--;
+ }
+
+ return n;
+}
+
+static void inputs_drop(pa_sink *s, pa_mix_info *info, unsigned n, size_t =
length) {
+ pa_sink_input *i;
+ void *state =3D NULL;
+ unsigned p =3D 0;
+ unsigned n_unreffed =3D 0;
+
+ pa_sink_assert_ref(s);
+
+ /* We optimize for the case where the order of the inputs has not chan=
ged */
+
while ((i =3D pa_hashmap_iterate(s->thread_info.inputs, &state, NULL))=
) {
- /* Increase ref counter, to make sure that this input doesn't
- * vanish while we still need it */
- pa_sink_input_ref(i);
-
- if (pa_sink_input_peek(i, &info->chunk, &info->volume) < 0) {
- pa_sink_input_unref(i);
- continue;
+ unsigned j;
+ pa_mix_info* m;
+
+ pa_sink_input_assert_ref(i);
+
+ m =3D NULL;
+
+ /* Let's try to find the matching entry info the pa_mix_info array=
*/
+ for (j =3D 0; j < n; j ++) {
+
+ if (info[p].userdata =3D=3D i) {
+ m =3D info + p;
+ break;
+ }
+
+ if (++p > n)
+ p =3D 0;
}
=
- info->userdata =3D i;
-
- pa_assert(info->chunk.memblock);
- pa_assert(info->chunk.length);
-
- info++;
- maxinfo--;
- n++;
- }
-
- return n;
-}
-
-static void inputs_drop(pa_sink *s, pa_mix_info *info, unsigned maxinfo, s=
ize_t length) {
- pa_sink_assert_ref(s);
- pa_assert(info);
-
- for (; maxinfo > 0; maxinfo--, info++) {
- pa_sink_input *i =3D info->userdata;
-
- pa_assert(i);
- pa_assert(info->chunk.memblock);
-
/* Drop read data */
- pa_sink_input_drop(i, &info->chunk, length);
- pa_memblock_unref(info->chunk.memblock);
-
- /* Decrease ref counter */
- pa_sink_input_unref(i);
- info->userdata =3D NULL;
- }
-}
-
-int pa_sink_render(pa_sink*s, size_t length, pa_memchunk *result) {
+ pa_sink_input_drop(i, m ? &m->chunk : NULL, length);
+
+ if (m) {
+ pa_sink_input_unref(m->userdata);
+ m->userdata =3D NULL;
+ if (m->chunk.memblock)
+ pa_memblock_unref(m->chunk.memblock);
+ pa_memchunk_reset(&m->chunk);
+
+ n_unreffed +=3D 1;
+ }
+ }
+
+ /* Now drop references to entries that are included in the
+ * pa_mix_info array but don't exist anymore */
+
+ if (n_unreffed < n) {
+ for (; n > 0; info++, n--) {
+ if (info->userdata)
+ pa_sink_input_unref(info->userdata);
+ if (info->chunk.memblock)
+ pa_memblock_unref(info->chunk.memblock);
+ }
+ }
+}
+
+void pa_sink_render(pa_sink*s, size_t length, pa_memchunk *result) {
pa_mix_info info[MAX_MIX_CHANNELS];
unsigned n;
- int r =3D -1;
=
pa_sink_assert_ref(s);
pa_assert(length);
@@ -326,10 +362,19 @@
=
n =3D fill_mix_info(s, info, MAX_MIX_CHANNELS);
=
- if (n <=3D 0)
- goto finish;
-
- if (n =3D=3D 1) {
+ if (n =3D=3D 0) {
+
+ if (!s->silence || pa_memblock_get_length(s->silence) < length) {
+ if (s->silence)
+ pa_memblock_unref(s->silence);
+ s->silence =3D pa_silence_memblock_new(s->core->mempool, &s->s=
ample_spec, length);
+ }
+
+ result->memblock =3D pa_memblock_ref(s->silence);
+ result->length =3D length;
+ result->index =3D 0;
+
+ } else if (n =3D=3D 1) {
pa_cvolume volume;
=
*result =3D info[0].chunk;
@@ -363,18 +408,12 @@
if (s->monitor_source)
pa_source_post(s->monitor_source, result);
=
- r =3D 0;
-
-finish:
pa_sink_unref(s);
-
- return r;
-}
-
-int pa_sink_render_into(pa_sink*s, pa_memchunk *target) {
+}
+
+void pa_sink_render_into(pa_sink*s, pa_memchunk *target) {
pa_mix_info info[MAX_MIX_CHANNELS];
unsigned n;
- int r =3D -1;
=
pa_sink_assert_ref(s);
pa_assert(target);
@@ -385,11 +424,9 @@
=
n =3D fill_mix_info(s, info, MAX_MIX_CHANNELS);
=
- if (n <=3D 0)
- goto finish;
-
-
- if (n =3D=3D 1) {
+ if (n =3D=3D 0) {
+ pa_silence_memchunk(target, &s->sample_spec);
+ } else if (n =3D=3D 1) {
if (target->length > info[0].chunk.length)
target->length =3D info[0].chunk.length;
=
@@ -435,12 +472,7 @@
if (s->monitor_source)
pa_source_post(s->monitor_source, target);
=
- r =3D 0;
-
-finish:
pa_sink_unref(s);
-
- return r;
}
=
void pa_sink_render_into_full(pa_sink *s, pa_memchunk *target) {
@@ -461,18 +493,10 @@
chunk.index +=3D d;
chunk.length -=3D d;
=
- if (pa_sink_render_into(s, &chunk) < 0)
- break;
+ pa_sink_render_into(s, &chunk);
=
d +=3D chunk.length;
l -=3D chunk.length;
- }
-
- if (l > 0) {
- chunk =3D *target;
- chunk.index +=3D d;
- chunk.length -=3D d;
- pa_silence_memchunk(&chunk, &s->sample_spec);
}
=
pa_sink_unref(s);
@@ -668,7 +692,7 @@
case PA_SINK_MESSAGE_SET_STATE:
s->thread_info.state =3D PA_PTR_TO_UINT(userdata);
return 0;
- =
+
case PA_SINK_MESSAGE_GET_LATENCY:
case PA_SINK_MESSAGE_MAX:
;
Modified: branches/lennart/src/pulsecore/sink.h
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/branches/lennart/src/pulsecore/=
sink.h?rev=3D1490&root=3Dpulseaudio&r1=3D1489&r2=3D1490&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- branches/lennart/src/pulsecore/sink.h (original)
+++ branches/lennart/src/pulsecore/sink.h Sat Jun 23 22:04:47 2007
@@ -92,6 +92,8 @@
int soft_muted;
} thread_info;
=
+ pa_memblock *silence;
+
void *userdata;
};
=
@@ -149,9 +151,9 @@
=
/* To be used exclusively by the sink driver thread */
=
-int pa_sink_render(pa_sink*s, size_t length, pa_memchunk *result);
+void pa_sink_render(pa_sink*s, size_t length, pa_memchunk *result);
void pa_sink_render_full(pa_sink *s, size_t length, pa_memchunk *result);
-int pa_sink_render_into(pa_sink*s, pa_memchunk *target);
+void pa_sink_render_into(pa_sink*s, pa_memchunk *target);
void pa_sink_render_into_full(pa_sink *s, pa_memchunk *target);
=
int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, pa_memc=
hunk *chunk);
More information about the pulseaudio-commits
mailing list