[pulseaudio-commits] r1478 - in /branches/lennart/src/pulsecore: sink-input.c sink-input.h source-output.c source-output.h

svnmailer-noreply at 0pointer.de svnmailer-noreply at 0pointer.de
Thu Jun 14 10:12:41 PDT 2007


Author: lennart
Date: Thu Jun 14 19:12:40 2007
New Revision: 1478

URL: http://0pointer.de/cgi-bin/viewcvs.cgi?rev=3D1478&root=3Dpulseaudio&vi=
ew=3Drev
Log:
rework sink input/source output state machine

Modified:
    branches/lennart/src/pulsecore/sink-input.c
    branches/lennart/src/pulsecore/sink-input.h
    branches/lennart/src/pulsecore/source-output.c
    branches/lennart/src/pulsecore/source-output.h

Modified: branches/lennart/src/pulsecore/sink-input.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/branches/lennart/src/pulsecore/=
sink-input.c?rev=3D1478&root=3Dpulseaudio&r1=3D1477&r2=3D1478&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-input.c (original)
+++ branches/lennart/src/pulsecore/sink-input.c Thu Jun 14 19:12:40 2007
@@ -166,7 +166,7 @@
     i->parent.process_msg =3D pa_sink_input_process_msg;
 =

     i->core =3D core;
-    pa_atomic_store(&i->state, PA_SINK_INPUT_DRAINED);
+    i->state =3D PA_SINK_INPUT_RUNNING;
     i->flags =3D flags;
     i->name =3D pa_xstrdup(data->name);
     i->driver =3D pa_xstrdup(data->driver);
@@ -181,7 +181,6 @@
     i->volume =3D data->volume;
     i->muted =3D data->muted;
 =

-    i->process_msg =3D NULL;
     i->peek =3D NULL;
     i->drop =3D NULL;
     i->kill =3D NULL;
@@ -189,6 +188,9 @@
     i->underrun =3D NULL;
     i->userdata =3D NULL;
 =

+    i->thread_info.state =3D i->state;
+    pa_atomic_store(&i->thread_info.drained, 1);
+    i->thread_info.sample_spec =3D i->sample_spec;
     i->thread_info.silence_memblock =3D NULL;
 /*     i->thread_info.move_silence =3D 0; */
     pa_memchunk_reset(&i->thread_info.resampled_chunk);
@@ -210,28 +212,41 @@
     return i;
 }
 =

+static int sink_input_set_state(pa_sink_input *i, pa_sink_input_state_t st=
ate) {
+    pa_assert(i);
+
+    if (state =3D=3D PA_SINK_INPUT_DRAINED)
+        state =3D PA_SINK_INPUT_RUNNING;
+
+    if (i->state =3D=3D state)
+        return 0;
+
+    if (pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INP=
UT_MESSAGE_SET_STATE, PA_UINT_TO_PTR(state), NULL) < 0)
+        return -1;
+
+    i->state =3D state;
+    return 0;
+}
+
 void pa_sink_input_disconnect(pa_sink_input *i) {
     pa_assert(i);
-    pa_return_if_fail(pa_sink_input_get_state(i) !=3D PA_SINK_INPUT_DISCON=
NECTED);
+    pa_return_if_fail(i->state !=3D PA_SINK_INPUT_DISCONNECTED);
 =

     pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_M=
ESSAGE_REMOVE_INPUT, i, NULL);
-
     pa_idxset_remove_by_data(i->sink->core->sink_inputs, i, NULL);
     pa_idxset_remove_by_data(i->sink->inputs, i, NULL);
 =

     pa_subscription_post(i->sink->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|P=
A_SUBSCRIPTION_EVENT_REMOVE, i->index);
 =

+    sink_input_set_state(i, PA_SINK_INPUT_DISCONNECTED);
     pa_sink_update_status(i->sink);
-
+    =

     i->sink =3D NULL;
-    i->process_msg =3D NULL;
     i->peek =3D NULL;
     i->drop =3D NULL;
     i->kill =3D NULL;
     i->get_latency =3D NULL;
     i->underrun =3D NULL;
-
-    pa_atomic_store(&i->state, PA_SINK_INPUT_DISCONNECTED);
 }
 =

 static void sink_input_free(pa_object *o) {
@@ -240,7 +255,8 @@
     pa_assert(i);
     pa_assert(pa_sink_input_refcnt(i) =3D=3D 0);
 =

-    pa_sink_input_disconnect(i);
+    if (i->state !=3D PA_SINK_INPUT_DISCONNECTED)
+        pa_sink_input_disconnect(i);
 =

     pa_log_info("Freeing output %u \"%s\"", i->index, i->name);
 =

@@ -295,21 +311,15 @@
     int ret =3D -1;
     int do_volume_adj_here;
     int volume_is_norm;
-    pa_sink_input_state_t state;
 =

     pa_sink_input_assert_ref(i);
     pa_assert(chunk);
     pa_assert(volume);
 =

-    state =3D pa_sink_input_get_state(i);
-
-    if (state =3D=3D PA_SINK_INPUT_DISCONNECTED)
-        return -1;
-
-    if (!i->peek || !i->drop || state =3D=3D PA_SINK_INPUT_CORKED)
+    if (!i->peek || !i->drop || i->thread_info.state =3D=3D PA_SINK_INPUT_=
DISCONNECTED || i->thread_info.state =3D=3D PA_SINK_INPUT_CORKED)
         goto finish;
 =

-    pa_assert(state =3D=3D PA_SINK_INPUT_RUNNING || state =3D=3D PA_SINK_I=
NPUT_DRAINED);
+    pa_assert(i->thread_info.state =3D=3D PA_SINK_INPUT_RUNNING || i->thre=
ad_info.state =3D=3D PA_SINK_INPUT_DRAINED);
 =

 /*     if (i->thread_info.move_silence > 0) { */
 /*         size_t l; */
@@ -359,7 +369,7 @@
         /* It might be necessary to adjust the volume here */
         if (do_volume_adj_here && !volume_is_norm) {
             pa_memchunk_make_writable(&tchunk, 0);
-            pa_volume_memchunk(&tchunk, &i->sample_spec, &i->thread_info.v=
olume);
+            pa_volume_memchunk(&tchunk, &i->thread_info.sample_spec, &i->t=
hread_info.volume);
         }
 =

         pa_resampler_run(i->thread_info.resampler, &tchunk, &i->thread_inf=
o.resampled_chunk);
@@ -376,13 +386,13 @@
 =

 finish:
 =

-    if (ret < 0 && state =3D=3D PA_SINK_INPUT_RUNNING && i->underrun)
+    if (ret < 0 && !pa_atomic_load(&i->thread_info.drained) && i->underrun)
         i->underrun(i);
 =

     if (ret >=3D 0)
-        pa_atomic_cmpxchg(&i->state, state, PA_SINK_INPUT_RUNNING);
-    else if (ret < 0 && state =3D=3D PA_SINK_INPUT_RUNNING)
-        pa_atomic_cmpxchg(&i->state, state, PA_SINK_INPUT_DRAINED);
+        pa_atomic_store(&i->thread_info.drained, 0);
+    else if (ret < 0)
+        pa_atomic_store(&i->thread_info.drained, 1);
 =

     if (ret >=3D 0) {
         /* Let's see if we had to apply the volume adjustment
@@ -487,17 +497,9 @@
 }
 =

 void pa_sink_input_cork(pa_sink_input *i, int b) {
-    pa_sink_input_state_t state;
-
-    pa_sink_input_assert_ref(i);
-
-    state =3D pa_sink_input_get_state(i);
-    pa_assert(state !=3D PA_SINK_INPUT_DISCONNECTED);
-
-    if (b && state !=3D PA_SINK_INPUT_CORKED)
-        pa_atomic_store(&i->state, PA_SINK_INPUT_CORKED);
-    else if (!b && state =3D=3D PA_SINK_INPUT_CORKED)
-        pa_atomic_cmpxchg(&i->state, state, PA_SINK_INPUT_DRAINED);
+    pa_sink_input_assert_ref(i);
+
+    sink_input_set_state(i, b ? PA_SINK_INPUT_CORKED : PA_SINK_INPUT_RUNNI=
NG);
 }
 =

 int pa_sink_input_set_rate(pa_sink_input *i, uint32_t rate) {
@@ -730,7 +732,26 @@
 =

             return 0;
         }
+
+        case PA_SINK_INPUT_MESSAGE_SET_STATE: {
+            if ((PA_PTR_TO_UINT(userdata) =3D=3D PA_SINK_INPUT_DRAINED || =
PA_PTR_TO_UINT(userdata) =3D=3D PA_SINK_INPUT_RUNNING) &&
+                (i->thread_info.state !=3D PA_SINK_INPUT_DRAINED) && (i->t=
hread_info.state !=3D PA_SINK_INPUT_RUNNING))
+                pa_atomic_store(&i->thread_info.drained, 1);
+            =

+            i->thread_info.state =3D PA_PTR_TO_UINT(userdata);
+
+            return 0;
+        }
     }
 =

     return -1;
 }
+
+pa_sink_input_state_t pa_sink_input_get_state(pa_sink_input *i) {
+    pa_sink_input_assert_ref(i);
+
+    if (i->state =3D=3D PA_SINK_INPUT_RUNNING || i->state =3D=3D PA_SINK_I=
NPUT_DRAINED)
+        return pa_atomic_load(&i->thread_info.drained) ? PA_SINK_INPUT_DRA=
INED : PA_SINK_INPUT_RUNNING;
+
+    return i->state;
+}

Modified: branches/lennart/src/pulsecore/sink-input.h
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/branches/lennart/src/pulsecore/=
sink-input.h?rev=3D1478&root=3Dpulseaudio&r1=3D1477&r2=3D1478&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-input.h (original)
+++ branches/lennart/src/pulsecore/sink-input.h Thu Jun 14 19:12:40 2007
@@ -39,8 +39,8 @@
 #include <pulsecore/core.h>
 =

 typedef enum pa_sink_input_state {
+    PA_SINK_INPUT_DRAINED,      /*< The stream stopped playing because the=
re was no data to play */
     PA_SINK_INPUT_RUNNING,      /*< The stream is alive and kicking */
-    PA_SINK_INPUT_DRAINED,      /*< The stream stopped playing because the=
re was no data to play */
     PA_SINK_INPUT_CORKED,       /*< The stream was corked on user request =
*/
     PA_SINK_INPUT_DISCONNECTED  /*< The stream is dead */
 } pa_sink_input_state_t;
@@ -55,7 +55,11 @@
 =

     uint32_t index;
     pa_core *core;
-    pa_atomic_t state;
+
+    /* Please note that this state should only be read with
+     * pa_sink_input_get_state(). That function will transparently
+     * merge the thread_info.drained value in. */
+    pa_sink_input_state_t state; =

     pa_sink_input_flags_t flags;
 =

     char *name, *driver;                /* may be NULL */
@@ -70,7 +74,6 @@
     pa_cvolume volume;
     int muted;
 =

-    int (*process_msg)(pa_sink_input *i, int code, void *userdata);
     int (*peek) (pa_sink_input *i, pa_memchunk *chunk);
     void (*drop) (pa_sink_input *i, const pa_memchunk *chunk, size_t lengt=
h);
     void (*kill) (pa_sink_input *i);             /* may be NULL */
@@ -80,6 +83,9 @@
     pa_resample_method_t resample_method;
 =

     struct {
+        pa_sink_input_state_t state;
+        pa_atomic_t drained;
+        =

         pa_sample_spec sample_spec;
 =

         pa_memchunk resampled_chunk;
@@ -106,6 +112,7 @@
     PA_SINK_INPUT_MESSAGE_SET_MUTE,
     PA_SINK_INPUT_MESSAGE_GET_LATENCY,
     PA_SINK_INPUT_MESSAGE_SET_RATE,
+    PA_SINK_INPUT_MESSAGE_SET_STATE,
     PA_SINK_INPUT_MESSAGE_MAX
 };
 =

@@ -166,7 +173,7 @@
 =

 int pa_sink_input_move_to(pa_sink_input *i, pa_sink *dest, int immediately=
);
 =

-#define pa_sink_input_get_state(i) ((pa_sink_input_state_t) pa_atomic_load=
(&i->state))
+pa_sink_input_state_t pa_sink_input_get_state(pa_sink_input *i);
 =

 /* To be used exclusively by the sink driver thread */
 =


Modified: branches/lennart/src/pulsecore/source-output.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/branches/lennart/src/pulsecore/=
source-output.c?rev=3D1478&root=3Dpulseaudio&r1=3D1477&r2=3D1478&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/source-output.c (original)
+++ branches/lennart/src/pulsecore/source-output.c Thu Jun 14 19:12:40 2007
@@ -135,7 +135,7 @@
     o->parent.process_msg =3D pa_source_output_process_msg;
 =

     o->core =3D core;
-    pa_atomic_store(&o->state, PA_SOURCE_OUTPUT_RUNNING);
+    o->state =3D PA_SOURCE_OUTPUT_RUNNING;
     o->flags =3D flags;
     o->name =3D pa_xstrdup(data->name);
     o->driver =3D pa_xstrdup(data->driver);
@@ -147,12 +147,13 @@
     o->sample_spec =3D data->sample_spec;
     o->channel_map =3D data->channel_map;
 =

-    o->process_msg =3D NULL;
     o->push =3D NULL;
     o->kill =3D NULL;
     o->get_latency =3D NULL;
     o->userdata =3D NULL;
 =

+    o->thread_info.state =3D o->state;
+    o->thread_info.sample_spec =3D o->sample_spec;
     o->thread_info.resampler =3D resampler;
 =

     pa_assert_se(pa_idxset_put(core->source_outputs, o, &o->index) =3D=3D =
0);
@@ -169,11 +170,22 @@
     return o;
 }
 =

+static int source_output_set_state(pa_source_output *o, pa_source_output_s=
tate_t state) {
+    pa_assert(o);
+
+    if (o->state =3D=3D state)
+        return 0;
+
+    if (pa_asyncmsgq_send(o->source->asyncmsgq, PA_MSGOBJECT(o), PA_SOURCE=
_OUTPUT_MESSAGE_SET_STATE, PA_UINT_TO_PTR(state), NULL) < 0)
+        return -1;
+
+    o->state =3D state;
+    return 0;
+}
+
 void pa_source_output_disconnect(pa_source_output*o) {
     pa_assert(o);
-    pa_return_if_fail(pa_source_output_get_state(o) !=3D PA_SOURCE_OUTPUT_=
DISCONNECTED);
-    pa_assert(o->source);
-    pa_assert(o->source->core);
+    pa_return_if_fail(o->state !=3D PA_SOURCE_OUTPUT_DISCONNECTED);
 =

     pa_asyncmsgq_send(o->source->asyncmsgq, PA_MSGOBJECT(o->source), PA_SO=
URCE_MESSAGE_REMOVE_OUTPUT, o, NULL);
 =

@@ -182,15 +194,13 @@
 =

     pa_subscription_post(o->source->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUT=
PUT|PA_SUBSCRIPTION_EVENT_REMOVE, o->index);
 =

+    source_output_set_state(o, PA_SOURCE_OUTPUT_DISCONNECTED);
     pa_source_update_status(o->source);
 =

     o->source =3D NULL;
-    o->process_msg =3D NULL;
     o->push =3D NULL;
     o->kill =3D NULL;
     o->get_latency =3D NULL;
-
-    pa_atomic_store(&o->state, PA_SOURCE_OUTPUT_DISCONNECTED);
 }
 =

 static void source_output_free(pa_object* mo) {
@@ -198,7 +208,8 @@
 =

     pa_assert(pa_source_output_refcnt(o) =3D=3D 0);
 =

-    pa_source_output_disconnect(o);
+    if (o->state !=3D PA_SOURCE_OUTPUT_DISCONNECTED)
+        pa_source_output_disconnect(o);
 =

     pa_log_info("Freeing output %u \"%s\"", o->index, o->name);
 =

@@ -242,18 +253,15 @@
 =

 void pa_source_output_push(pa_source_output *o, const pa_memchunk *chunk) {
     pa_memchunk rchunk;
-    pa_source_output_state_t state;
 =

     pa_source_output_assert_ref(o);
     pa_assert(chunk);
     pa_assert(chunk->length);
 =

-    state =3D pa_source_output_get_state(o);
-
-    if (!o->push || state =3D=3D PA_SOURCE_OUTPUT_DISCONNECTED || state =
=3D=3D PA_SOURCE_OUTPUT_CORKED)
+    if (!o->push || o->state =3D=3D PA_SOURCE_OUTPUT_DISCONNECTED || o->st=
ate =3D=3D PA_SOURCE_OUTPUT_CORKED)
         return;
 =

-    pa_assert(state =3D PA_SOURCE_OUTPUT_RUNNING);
+    pa_assert(o->state =3D PA_SOURCE_OUTPUT_RUNNING);
 =

     if (!o->thread_info.resampler) {
         o->push(o, chunk);
@@ -270,17 +278,9 @@
 }
 =

 void pa_source_output_cork(pa_source_output *o, int b) {
-    pa_source_output_state_t state;
-
-    pa_source_output_assert_ref(o);
-
-    state =3D pa_source_output_get_state(o);
-    pa_assert(state !=3D PA_SOURCE_OUTPUT_DISCONNECTED);
-
-    if (b && state !=3D PA_SOURCE_OUTPUT_CORKED)
-        pa_atomic_store(&o->state, PA_SOURCE_OUTPUT_CORKED);
-    else if (!b && state =3D=3D PA_SOURCE_OUTPUT_CORKED)
-        pa_atomic_cmpxchg(&o->state, state, PA_SOURCE_OUTPUT_RUNNING);
+    pa_source_output_assert_ref(o);
+
+    source_output_set_state(o, b ? PA_SOURCE_OUTPUT_CORKED : PA_SOURCE_OUT=
PUT_RUNNING);
 }
 =

 int pa_source_output_set_rate(pa_source_output *o, uint32_t rate) {
@@ -393,6 +393,13 @@
 =

             return 0;
         }
+
+        case PA_SOURCE_OUTPUT_MESSAGE_SET_STATE: {
+            o->thread_info.state =3D PA_PTR_TO_UINT(userdata);
+
+            return 0;
+        }
+            =

     }
 =

     return -1;

Modified: branches/lennart/src/pulsecore/source-output.h
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/branches/lennart/src/pulsecore/=
source-output.h?rev=3D1478&root=3Dpulseaudio&r1=3D1477&r2=3D1478&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/source-output.h (original)
+++ branches/lennart/src/pulsecore/source-output.h Thu Jun 14 19:12:40 2007
@@ -51,7 +51,7 @@
 =

     uint32_t index;
     pa_core *core;
-    pa_atomic_t state;
+    pa_source_output_state_t state;
     pa_source_output_flags_t flags;
 =

     char *name, *driver;                  /* may be NULL */
@@ -63,7 +63,6 @@
     pa_sample_spec sample_spec;
     pa_channel_map channel_map;
 =

-    int (*process_msg)(pa_sink_input *i, int code, void *userdata);
     void (*push)(pa_source_output *o, const pa_memchunk *chunk);
     void (*kill)(pa_source_output* o);              /* may be NULL */
     pa_usec_t (*get_latency) (pa_source_output *o); /* may be NULL */
@@ -71,6 +70,8 @@
     pa_resample_method_t resample_method;
 =

     struct {
+        pa_source_output_state_t state;
+        =

         pa_sample_spec sample_spec;
 =

         pa_resampler* resampler;              /* may be NULL */
@@ -85,6 +86,7 @@
 enum {
     PA_SOURCE_OUTPUT_MESSAGE_GET_LATENCY,
     PA_SOURCE_OUTPUT_MESSAGE_SET_RATE,
+    PA_SOURCE_OUTPUT_MESSAGE_SET_STATE,
     PA_SOURCE_OUTPUT_MESSAGE_MAX
 };
 =

@@ -135,7 +137,7 @@
 =

 int pa_source_output_move_to(pa_source_output *o, pa_source *dest);
 =

-#define pa_source_output_get_state(o) ((pa_source_output_state_t) pa_atomi=
c_load(&o->state))
+#define pa_source_output_get_state(o) ((o)->state)
 =

 /* To be used exclusively by the source driver thread */
 =





More information about the pulseaudio-commits mailing list