[pulseaudio-commits] r1529 - in /branches/lennart/src: modules/ modules/rtp/ pulse/ pulsecore/ tests/

svnmailer-noreply at 0pointer.de svnmailer-noreply at 0pointer.de
Wed Jul 25 07:46:41 PDT 2007


Author: lennart
Date: Wed Jul 25 16:46:40 2007
New Revision: 1529

URL: http://0pointer.de/cgi-bin/viewcvs.cgi?rev=3D1529&root=3Dpulseaudio&vi=
ew=3Drev
Log:
drop chunk argument from various drop() functions, since it doesn't make an=
y sense if we want to guarantee always monotonously increasing read pointer=
s; a couple of other fixes

Modified:
    branches/lennart/src/modules/module-sine.c
    branches/lennart/src/modules/rtp/rtp.c
    branches/lennart/src/pulse/stream.c
    branches/lennart/src/pulsecore/memblock.c
    branches/lennart/src/pulsecore/memblockq.c
    branches/lennart/src/pulsecore/memblockq.h
    branches/lennart/src/pulsecore/play-memblockq.c
    branches/lennart/src/pulsecore/play-memchunk.c
    branches/lennart/src/pulsecore/protocol-simple.c
    branches/lennart/src/pulsecore/sink-input.c
    branches/lennart/src/pulsecore/sink-input.h
    branches/lennart/src/pulsecore/sink.c
    branches/lennart/src/pulsecore/sound-file-stream.c
    branches/lennart/src/tests/memblockq-test.c

Modified: branches/lennart/src/modules/module-sine.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/branches/lennart/src/modules/mo=
dule-sine.c?rev=3D1529&root=3Dpulseaudio&r1=3D1528&r2=3D1529&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/modules/module-sine.c (original)
+++ branches/lennart/src/modules/module-sine.c Wed Jul 25 16:46:40 2007
@@ -73,14 +73,13 @@
     return 0;
 }
 =

-static void sink_input_drop_cb(pa_sink_input *i, const pa_memchunk *chunk,=
 size_t length) {
+static void sink_input_drop_cb(pa_sink_input *i, size_t length) {
     struct userdata *u;
     size_t l;
     =

     pa_assert(i);
     u =3D i->userdata;
     pa_assert(u);
-    pa_assert(chunk);
     pa_assert(length > 0);
 =

     u->peek_index +=3D length;
@@ -93,8 +92,10 @@
 =

 static void sink_input_kill_cb(pa_sink_input *i) {
     struct userdata *u;
-    pa_assert(i && i->userdata);
+    =

+    pa_assert(i);
     u =3D i->userdata;
+    pa_assert(u);
 =

     pa_sink_input_disconnect(u->sink_input);
     pa_sink_input_unref(u->sink_input);

Modified: branches/lennart/src/modules/rtp/rtp.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/branches/lennart/src/modules/rt=
p/rtp.c?rev=3D1529&root=3Dpulseaudio&r1=3D1528&r2=3D1529&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/modules/rtp/rtp.c (original)
+++ branches/lennart/src/modules/rtp/rtp.c Wed Jul 25 16:46:40 2007
@@ -90,7 +90,7 @@
             }
 =

             skip +=3D k;
-            pa_memblockq_drop(q, &chunk, k);
+            pa_memblockq_drop(q, k);
         }
 =

         if (r < 0 || !chunk.memblock || n >=3D size || iov_idx >=3D MAX_IO=
VECS) {

Modified: branches/lennart/src/pulse/stream.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/branches/lennart/src/pulse/stre=
am.c?rev=3D1529&root=3Dpulseaudio&r1=3D1528&r2=3D1529&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/pulse/stream.c (original)
+++ branches/lennart/src/pulse/stream.c Wed Jul 25 16:46:40 2007
@@ -700,7 +700,7 @@
     PA_CHECK_VALIDITY(s->context, s->direction =3D=3D PA_STREAM_RECORD, PA=
_ERR_BADSTATE);
     PA_CHECK_VALIDITY(s->context, s->peek_memchunk.memblock, PA_ERR_BADSTA=
TE);
 =

-    pa_memblockq_drop(s->record_memblockq, &s->peek_memchunk, s->peek_memc=
hunk.length);
+    pa_memblockq_drop(s->record_memblockq, s->peek_memchunk.length);
 =

     /* Fix the simulated local read index */
     if (s->timing_info_valid && !s->timing_info.read_index_corrupt)

Modified: branches/lennart/src/pulsecore/memblock.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/branches/lennart/src/pulsecore/=
memblock.c?rev=3D1529&root=3Dpulseaudio&r1=3D1528&r2=3D1529&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/memblock.c (original)
+++ branches/lennart/src/pulsecore/memblock.c Wed Jul 25 16:46:40 2007
@@ -150,7 +150,7 @@
 =

 static void segment_detach(pa_memimport_segment *seg);
 =

-PA_STATIC_FLIST_DECLARE(unused_memblocks, 0);
+PA_STATIC_FLIST_DECLARE(unused_memblocks, 0, pa_xfree);
 =

 /* No lock necessary */
 static void stat_add(pa_memblock*b) {
@@ -670,8 +670,8 @@
     pa_mutex_unlock(p->mutex);
 =

     if (pa_atomic_load(&p->stat.n_allocated) > 0) {
-        raise(SIGTRAP);
-        pa_log_warn("WARNING! Memory pool destroyed but not all memory blo=
cks freed!");
+/*         raise(SIGTRAP);  */
+        pa_log_warn("WARNING! Memory pool destroyed but not all memory blo=
cks freed! %u remain.", pa_atomic_load(&p->stat.n_allocated));
     }
 =

     pa_flist_free(p->free_slots, NULL);

Modified: branches/lennart/src/pulsecore/memblockq.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/branches/lennart/src/pulsecore/=
memblockq.c?rev=3D1529&root=3Dpulseaudio&r1=3D1528&r2=3D1529&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/memblockq.c (original)
+++ branches/lennart/src/pulsecore/memblockq.c Wed Jul 25 16:46:40 2007
@@ -36,21 +36,24 @@
 #include <pulsecore/log.h>
 #include <pulsecore/mcalign.h>
 #include <pulsecore/macro.h>
+#include <pulsecore/flist.h>
 =

 #include "memblockq.h"
 =

-struct memblock_list {
-    struct memblock_list *next, *prev;
+struct list_item {
+    struct list_item *next, *prev;
     int64_t index;
     pa_memchunk chunk;
 };
 =

+PA_STATIC_FLIST_DECLARE(list_items, 0, pa_xfree);
+        =

 struct pa_memblockq {
-    struct memblock_list *blocks, *blocks_tail;
+    struct list_item *blocks, *blocks_tail;
     unsigned n_blocks;
     size_t maxlength, tlength, base, prebuf, minreq;
     int64_t read_index, write_index;
-    enum { PREBUF, RUNNING } state;
+    int in_prebuf;
     pa_memblock *silence;
     pa_mcalign *mcalign;
 };
@@ -77,13 +80,13 @@
     bq->read_index =3D bq->write_index =3D idx;
 =

     pa_log_debug("memblockq requested: maxlength=3D%lu, tlength=3D%lu, bas=
e=3D%lu, prebuf=3D%lu, minreq=3D%lu",
-        (unsigned long)maxlength, (unsigned long)tlength, (unsigned long)b=
ase, (unsigned long)prebuf, (unsigned long)minreq);
+        (unsigned long) maxlength, (unsigned long) tlength, (unsigned long=
) base, (unsigned long) prebuf, (unsigned long) minreq);
 =

     bq->maxlength =3D ((maxlength+base-1)/base)*base;
     pa_assert(bq->maxlength >=3D base);
 =

     bq->tlength =3D ((tlength+base-1)/base)*base;
-    if (!bq->tlength || bq->tlength >=3D bq->maxlength)
+    if (bq->tlength <=3D 0 || bq->tlength > bq->maxlength)
         bq->tlength =3D bq->maxlength;
 =

     bq->prebuf =3D (prebuf =3D=3D (size_t) -1) ? bq->tlength/2 : prebuf;
@@ -102,7 +105,7 @@
     pa_log_debug("memblockq sanitized: maxlength=3D%lu, tlength=3D%lu, bas=
e=3D%lu, prebuf=3D%lu, minreq=3D%lu",
         (unsigned long)bq->maxlength, (unsigned long)bq->tlength, (unsigne=
d long)bq->base, (unsigned long)bq->prebuf, (unsigned long)bq->minreq);
 =

-    bq->state =3D bq->prebuf ? PREBUF : RUNNING;
+    bq->in_prebuf =3D bq->prebuf > 0;
     bq->silence =3D silence ? pa_memblock_ref(silence) : NULL;
     bq->mcalign =3D NULL;
 =

@@ -113,7 +116,7 @@
     pa_assert(bq);
 =

     pa_memblockq_flush(bq);
-
+    =

     if (bq->silence)
         pa_memblock_unref(bq->silence);
 =

@@ -123,7 +126,7 @@
     pa_xfree(bq);
 }
 =

-static void drop_block(pa_memblockq *bq, struct memblock_list *q) {
+static void drop_block(pa_memblockq *bq, struct list_item *q) {
     pa_assert(bq);
     pa_assert(q);
 =

@@ -140,7 +143,9 @@
         bq->blocks_tail =3D q->prev;
 =

     pa_memblock_unref(q->chunk.memblock);
-    pa_xfree(q);
+
+    if (pa_flist_push(PA_STATIC_FLIST_GET(list_items), q) < 0)
+        pa_xfree(q);
 =

     bq->n_blocks--;
 }
@@ -171,7 +176,7 @@
 =

 int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *uchunk) {
 =

-    struct memblock_list *q, *n;
+    struct list_item *q, *n;
     pa_memchunk chunk;
 =

     pa_assert(bq);
@@ -198,7 +203,7 @@
         if (chunk.length > d) {
             chunk.index +=3D d;
             chunk.length -=3D d;
-            bq->write_index =3D bq->read_index;
+            bq->write_index +=3D d;
         } else {
             /* We drop the incoming data completely */
             bq->write_index +=3D chunk.length;
@@ -212,10 +217,10 @@
     q =3D bq->blocks_tail;
     while (q) {
 =

-        if (bq->write_index >=3D q->index + (int64_t)q->chunk.length)
+        if (bq->write_index >=3D q->index + (int64_t) q->chunk.length)
             /* We found the entry where we need to place the new entry imm=
ediately after */
             break;
-        else if (bq->write_index + (int64_t)chunk.length <=3D q->index) {
+        else if (bq->write_index + (int64_t) chunk.length <=3D q->index) {
             /* This entry isn't touched at all, let's skip it */
             q =3D q->prev;
         } else if (bq->write_index <=3D q->index &&
@@ -223,7 +228,7 @@
 =

             /* This entry is fully replaced by the new entry, so let's dro=
p it */
 =

-            struct memblock_list *p;
+            struct list_item *p;
             p =3D q;
             q =3D q->prev;
             drop_block(bq, p);
@@ -234,11 +239,13 @@
             if (bq->write_index + chunk.length < q->index + q->chunk.lengt=
h) {
 =

                 /* We need to save the end of this memchunk */
-                struct memblock_list *p;
+                struct list_item *p;
                 size_t d;
 =

                 /* Create a new list entry for the end of thie memchunk */
-                p =3D pa_xnew(struct memblock_list, 1);
+                if (!(p =3D pa_flist_pop(PA_STATIC_FLIST_GET(list_items))))
+                    p =3D pa_xnew(struct list_item, 1);
+                =

                 p->chunk =3D q->chunk;
                 pa_memblock_ref(p->chunk.memblock);
 =

@@ -263,7 +270,7 @@
 =

             /* Truncate the chunk */
             if (!(q->chunk.length =3D bq->write_index - q->index)) {
-                struct memblock_list *p;
+                struct list_item *p;
                 p =3D q;
                 q =3D q->prev;
                 drop_block(bq, p);
@@ -287,7 +294,6 @@
 =

             q =3D q->prev;
         }
-
     }
 =

     if (q) {
@@ -308,7 +314,9 @@
         pa_assert(!bq->blocks || (bq->write_index + (int64_t)chunk.length =
<=3D bq->blocks->index));
 =

 =

-    n =3D pa_xnew(struct memblock_list, 1);
+    if (!(n =3D pa_flist_pop(PA_STATIC_FLIST_GET(list_items))))
+        n =3D pa_xnew(struct list_item, 1);
+    =

     n->chunk =3D chunk;
     pa_memblock_ref(n->chunk.memblock);
     n->index =3D bq->write_index;
@@ -331,24 +339,34 @@
     return 0;
 }
 =

+static int memblockq_check_prebuf(pa_memblockq *bq) {
+    pa_assert(bq);
+    =

+    if (bq->in_prebuf) {
+        =

+        if (pa_memblockq_get_length(bq) < bq->prebuf)
+            return 1;
+
+        bq->in_prebuf =3D 0;
+        return 0;
+    } else {
+
+        if (bq->prebuf > 0 && bq->read_index >=3D bq->write_index) {
+            bq->in_prebuf =3D 1;
+            return 1;
+        }
+
+        return 0;
+    }
+}
+
 int pa_memblockq_peek(pa_memblockq* bq, pa_memchunk *chunk) {
     pa_assert(bq);
     pa_assert(chunk);
 =

-    if (bq->state =3D=3D PREBUF) {
-
-        /* We need to pre-buffer */
-        if (pa_memblockq_get_length(bq) < bq->prebuf)
-            return -1;
-
-        bq->state =3D RUNNING;
-
-    } else if (bq->prebuf > 0 && bq->read_index >=3D bq->write_index) {
-
-        /* Buffer underflow protection */
-        bq->state =3D PREBUF;
+    /* We need to pre-buffer */
+    if (memblockq_check_prebuf(bq))
         return -1;
-    }
 =

     /* Do we need to spit out silence? */
     if (!bq->blocks || bq->blocks->index > bq->read_index) {
@@ -390,43 +408,16 @@
     return 0;
 }
 =

-void pa_memblockq_drop(pa_memblockq *bq, const pa_memchunk *chunk, size_t =
length) {
+void pa_memblockq_drop(pa_memblockq *bq, size_t length) {
     pa_assert(bq);
     pa_assert(length % bq->base =3D=3D 0);
-    pa_assert(!chunk || length <=3D chunk->length);
-
-    if (chunk) {
-
-        if (bq->blocks && bq->blocks->index =3D=3D bq->read_index) {
-            /* The first item in queue is valid */
-
-            /* Does the chunk match with what the user supplied us? */
-            if (memcmp(chunk, &bq->blocks->chunk, sizeof(pa_memchunk)) !=
=3D 0)
-                return;
-
-        } else {
-            size_t l;
-
-            /* The first item in the queue is not yet relevant */
-
-            pa_assert(!bq->blocks || bq->blocks->index > bq->read_index);
-            l =3D bq->blocks ? bq->blocks->index - bq->read_index : 0;
-
-            if (bq->silence) {
-
-                if (!l || l > pa_memblock_get_length(bq->silence))
-                    l =3D pa_memblock_get_length(bq->silence);
-
-            }
-
-            /* Do the entries still match? */
-            if (chunk->index !=3D 0 || chunk->length !=3D l || chunk->memb=
lock !=3D bq->silence)
-                return;
-        }
-    }
-
+    =

     while (length > 0) {
 =

+        /* Do not drop any data when we are in prebuffering mode */
+        if (memblockq_check_prebuf(bq))
+            break;
+        =

         if (bq->blocks) {
             size_t d;
 =

@@ -476,15 +467,11 @@
 int pa_memblockq_is_readable(pa_memblockq *bq) {
     pa_assert(bq);
 =

-    if (bq->prebuf > 0) {
-        size_t l =3D pa_memblockq_get_length(bq);
-
-        if (bq->state =3D=3D PREBUF && l < bq->prebuf)
-            return 0;
-
-        if (l <=3D 0)
-            return 0;
-    }
+    if (memblockq_check_prebuf(bq))
+        return 0;
+
+    if (pa_memblockq_get_length(bq) <=3D 0)
+        return 0;
 =

     return 1;
 }
@@ -506,7 +493,7 @@
         return 0;
 =

     l =3D bq->tlength - l;
-    return (l >=3D bq->minreq) ? l : 0;
+    return l >=3D bq->minreq ? l : 0;
 }
 =

 size_t pa_memblockq_get_minreq(pa_memblockq *bq) {
@@ -529,7 +516,7 @@
             bq->write_index =3D bq->read_index + offset;
             return;
         case PA_SEEK_RELATIVE_END:
-            bq->write_index =3D (bq->blocks_tail ? bq->blocks_tail->index =
+ (int64_t)bq->blocks_tail->chunk.length : bq->read_index) + offset;
+            bq->write_index =3D (bq->blocks_tail ? bq->blocks_tail->index =
+ (int64_t) bq->blocks_tail->chunk.length : bq->read_index) + offset;
             return;
     }
 =

@@ -569,7 +556,7 @@
     pa_memchunk rchunk;
 =

     pa_assert(bq);
-    pa_assert(chunk && bq->base);
+    pa_assert(chunk);
 =

     if (bq->base =3D=3D 1)
         return pa_memblockq_push(bq, chunk);
@@ -601,21 +588,20 @@
     l =3D pa_memblockq_get_length(bq);
 =

     if (l > length)
-        pa_memblockq_drop(bq, NULL, l - length);
+        pa_memblockq_drop(bq, l - length);
 }
 =

 void pa_memblockq_prebuf_disable(pa_memblockq *bq) {
     pa_assert(bq);
 =

-    if (bq->state =3D=3D PREBUF)
-        bq->state =3D RUNNING;
+    bq->in_prebuf =3D 0;
 }
 =

 void pa_memblockq_prebuf_force(pa_memblockq *bq) {
     pa_assert(bq);
 =

-    if (bq->state =3D=3D RUNNING && bq->prebuf > 0)
-        bq->state =3D PREBUF;
+    if (!bq->in_prebuf && bq->prebuf > 0)
+        bq->in_prebuf =3D 1;
 }
 =

 size_t pa_memblockq_get_maxlength(pa_memblockq *bq) {

Modified: branches/lennart/src/pulsecore/memblockq.h
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/branches/lennart/src/pulsecore/=
memblockq.h?rev=3D1529&root=3Dpulseaudio&r1=3D1528&r2=3D1529&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/memblockq.h (original)
+++ branches/lennart/src/pulsecore/memblockq.h Wed Jul 25 16:46:40 2007
@@ -83,13 +83,16 @@
  * you know what you do. */
 int pa_memblockq_push_align(pa_memblockq* bq, const pa_memchunk *chunk);
 =

-/* Return a copy of the next memory chunk in the queue. It is not removed =
from the queue */
+/* Return a copy of the next memory chunk in the queue. It is not
+ * removed from the queue. There are two reasons this function might
+ * fail: 1. prebuffering is active, 2. queue is empty and no silence
+ * memblock was passed at initialization. If the queue is not empty,
+ * but we're currently at a hole in the queue and no silence memblock
+ * was passed we return the length of the hole in chunk->length. */
 int pa_memblockq_peek(pa_memblockq* bq, pa_memchunk *chunk);
 =

-/* Drop the specified bytes from the queue, but only if the first
- * chunk in the queue matches the one passed here. If NULL is passed,
- * this check isn't done. */
-void pa_memblockq_drop(pa_memblockq *bq, const pa_memchunk *chunk, size_t =
length);
+/* Drop the specified bytes from the queue. */
+void pa_memblockq_drop(pa_memblockq *bq, size_t length);
 =

 /* Test if the pa_memblockq is currently readable, that is, more data than=
 base */
 int pa_memblockq_is_readable(pa_memblockq *bq);

Modified: branches/lennart/src/pulsecore/play-memblockq.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/branches/lennart/src/pulsecore/=
play-memblockq.c?rev=3D1529&root=3Dpulseaudio&r1=3D1528&r2=3D1529&view=3Ddi=
ff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=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/play-memblockq.c (original)
+++ branches/lennart/src/pulsecore/play-memblockq.c Wed Jul 25 16:46:40 2007
@@ -37,7 +37,7 @@
 =

 #include "play-memblockq.h"
 =

-static void sink_input_kill(pa_sink_input *i) {
+static void sink_input_kill_cb(pa_sink_input *i) {
     pa_memblockq *q;
     assert(i);
     assert(i->userdata);
@@ -50,7 +50,7 @@
     pa_memblockq_free(q);
 }
 =

-static int sink_input_peek(pa_sink_input *i, pa_memchunk *chunk) {
+static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) {
     pa_memblockq *q;
     assert(i);
     assert(chunk);
@@ -61,11 +61,11 @@
     return pa_memblockq_peek(q, chunk);
 }
 =

-static void si_kill(PA_GCC_UNUSED pa_mainloop_api *m, void *i) {
-    sink_input_kill(i);
+static void si_kill_cb(PA_GCC_UNUSED pa_mainloop_api *m, void *i) {
+    sink_input_kill_cb(i);
 }
 =

-static void sink_input_drop(pa_sink_input *i, const pa_memchunk*chunk, siz=
e_t length) {
+static void sink_input_drop_cb(pa_sink_input *i, size_t length) {
     pa_memblockq *q;
 =

     assert(i);
@@ -74,10 +74,10 @@
 =

     q =3D i->userdata;
 =

-    pa_memblockq_drop(q, chunk, length);
+    pa_memblockq_drop(q, length);
 =

     if (pa_memblockq_get_length(q) <=3D 0)
-        pa_mainloop_api_once(i->sink->core->mainloop, si_kill, i);
+        pa_mainloop_api_once(i->sink->core->mainloop, si_kill_cb, i);
 }
 =

 int pa_play_memblockq(
@@ -116,9 +116,9 @@
     if (!(si =3D pa_sink_input_new(sink->core, &data, 0)))
         return -1;
 =

-    si->peek =3D sink_input_peek;
-    si->drop =3D sink_input_drop;
-    si->kill =3D sink_input_kill;
+    si->peek =3D sink_input_peek_cb;
+    si->drop =3D sink_input_drop_cb;
+    si->kill =3D sink_input_kill_cb;
 =

     si->userdata =3D q;
 =


Modified: branches/lennart/src/pulsecore/play-memchunk.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/branches/lennart/src/pulsecore/=
play-memchunk.c?rev=3D1529&root=3Dpulseaudio&r1=3D1528&r2=3D1529&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/play-memchunk.c (original)
+++ branches/lennart/src/pulsecore/play-memchunk.c Wed Jul 25 16:46:40 2007
@@ -37,7 +37,7 @@
 =

 #include "play-memchunk.h"
 =

-static void sink_input_kill(pa_sink_input *i) {
+static void sink_input_kill_cb(pa_sink_input *i) {
     pa_memchunk *c;
     assert(i && i->userdata);
     c =3D i->userdata;
@@ -49,7 +49,7 @@
     pa_xfree(c);
 }
 =

-static int sink_input_peek(pa_sink_input *i, pa_memchunk *chunk) {
+static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) {
     pa_memchunk *c;
     assert(i && chunk && i->userdata);
     c =3D i->userdata;
@@ -64,23 +64,24 @@
     return 0;
 }
 =

-static void si_kill(PA_GCC_UNUSED pa_mainloop_api *m, void *i) {
-    sink_input_kill(i);
+static void si_kill_cb(PA_GCC_UNUSED pa_mainloop_api *m, void *i) {
+    sink_input_kill_cb(i);
 }
 =

-static void sink_input_drop(pa_sink_input *i, const pa_memchunk*chunk, siz=
e_t length) {
+static void sink_input_drop_cb(pa_sink_input *i, size_t length) {
     pa_memchunk *c;
     assert(i && length && i->userdata);
     c =3D i->userdata;
 =

-    assert(!memcmp(chunk, c, sizeof(chunk)));
-    assert(length <=3D c->length);
+    if (length >=3D c->length) {
+        c->length -=3D length;
+        c->index +=3D length;
+    } else {
 =

-    c->length -=3D length;
-    c->index +=3D length;
+        c->length =3D 0;
 =

-    if (c->length <=3D 0)
-        pa_mainloop_api_once(i->sink->core->mainloop, si_kill, i);
+        pa_mainloop_api_once(i->sink->core->mainloop, si_kill_cb, i);
+    }
 }
 =

 int pa_play_memchunk(
@@ -113,9 +114,9 @@
     if (!(si =3D pa_sink_input_new(sink->core, &data, 0)))
         return -1;
 =

-    si->peek =3D sink_input_peek;
-    si->drop =3D sink_input_drop;
-    si->kill =3D sink_input_kill;
+    si->peek =3D sink_input_peek_cb;
+    si->drop =3D sink_input_drop_cb;
+    si->kill =3D sink_input_kill_cb;
 =

     si->userdata =3D nchunk =3D pa_xnew(pa_memchunk, 1);
     *nchunk =3D *chunk;

Modified: branches/lennart/src/pulsecore/protocol-simple.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/branches/lennart/src/pulsecore/=
protocol-simple.c?rev=3D1529&root=3Dpulseaudio&r1=3D1528&r2=3D1529&view=3Dd=
iff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=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/protocol-simple.c (original)
+++ branches/lennart/src/pulsecore/protocol-simple.c Wed Jul 25 16:46:40 20=
07
@@ -67,7 +67,6 @@
 =

 PA_DECLARE_CLASS(connection);
 #define CONNECTION(o) (connection_cast(o))
-
 static PA_DEFINE_CHECK_TYPE(connection, connection_check_type, pa_msgobjec=
t_check_type);
                      =

 struct pa_protocol_simple {
@@ -230,7 +229,7 @@
         return -1;
     }
 =

-    pa_memblockq_drop(c->output_memblockq, &chunk, r);
+    pa_memblockq_drop(c->output_memblockq, r);
 =

     return 0;
 }
@@ -271,7 +270,6 @@
 =

 static int connection_process_msg(pa_msgobject *o, int code, void*userdata=
, pa_memchunk *chunk) {
     connection *c =3D CONNECTION(o);
-    =

     connection_assert_ref(c);
 =

     switch (code) {
@@ -351,13 +349,13 @@
 /*     pa_log("peeked %u %i", r >=3D 0 ? chunk->length: 0, r); */
 =

     if (c->dead && r < 0)
-        pa_asyncmsgq_post(c->protocol->core->asyncmsgq, PA_MSGOBJECT(c), M=
ESSAGE_DROP_CONNECTION, c, NULL, NULL);
+        pa_asyncmsgq_post(c->protocol->core->asyncmsgq, PA_MSGOBJECT(c), M=
ESSAGE_DROP_CONNECTION, NULL, NULL, NULL);
 =

     return r;
 }
 =

 /* Called from thread context */
-static void sink_input_drop_cb(pa_sink_input *i, const pa_memchunk *chunk,=
 size_t length) {
+static void sink_input_drop_cb(pa_sink_input *i, size_t length) {
     connection*c =3D i->userdata;
     size_t old, new;
 =

@@ -366,7 +364,7 @@
     pa_assert(length);
 =

     old =3D pa_memblockq_missing(c->input_memblockq);
-    pa_memblockq_drop(c->input_memblockq, chunk, length);
+    pa_memblockq_drop(c->input_memblockq, length);
     new =3D pa_memblockq_missing(c->input_memblockq);
 =

     if (new > old) {
@@ -378,9 +376,8 @@
 /* Called from main context */
 static void sink_input_kill_cb(pa_sink_input *i) {
     pa_assert(i);
-    pa_assert(i->userdata);
-
-    connection_drop((connection *) i->userdata);
+
+    connection_drop(CONNECTION(i->userdata));
 }
 =

 /*** source_output callbacks ***/

Modified: branches/lennart/src/pulsecore/sink-input.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/branches/lennart/src/pulsecore/=
sink-input.c?rev=3D1529&root=3Dpulseaudio&r1=3D1528&r2=3D1529&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 Wed Jul 25 16:46:40 2007
@@ -341,7 +341,7 @@
 /*     } */
 =

     if (!i->thread_info.resampler) {
-        do_volume_adj_here =3D 0;
+        do_volume_adj_here =3D 0; /* FIXME??? */
         ret =3D i->peek(i, chunk);
         goto finish;
     }
@@ -356,15 +356,14 @@
         if ((ret =3D i->peek(i, &tchunk)) < 0)
             goto finish;
 =

-        pa_assert(tchunk.length);
+        pa_assert(tchunk.length > 0);
 =

         l =3D pa_resampler_request(i->thread_info.resampler, CONVERT_BUFFE=
R_LENGTH);
 =

-        if (l > tchunk.length)
-            l =3D tchunk.length;
-
-        i->drop(i, &tchunk, l);
-        tchunk.length =3D l;
+        if (tchunk.length > l)
+            tchunk.length =3D l;
+
+        i->drop(i, tchunk.length);
 =

         /* It might be necessary to adjust the volume here */
         if (do_volume_adj_here && !volume_is_norm) {
@@ -377,7 +376,7 @@
     }
 =

     pa_assert(i->thread_info.resampled_chunk.memblock);
-    pa_assert(i->thread_info.resampled_chunk.length);
+    pa_assert(i->thread_info.resampled_chunk.length > 0);
 =

     *chunk =3D i->thread_info.resampled_chunk;
     pa_memblock_ref(i->thread_info.resampled_chunk.memblock);
@@ -409,7 +408,7 @@
     return ret;
 }
 =

-void pa_sink_input_drop(pa_sink_input *i, const pa_memchunk *chunk, size_t=
 length) {
+void pa_sink_input_drop(pa_sink_input *i, size_t length) {
     pa_sink_input_assert_ref(i);
     pa_assert(length > 0);
 =

@@ -440,22 +439,67 @@
 /*         return; */
 /*     } */
 =

-    if (!i->thread_info.resampler) {
-        if (i->drop)
-            i->drop(i, chunk, length);
-        return;
+    pa_log("dropping %u", length);
+    =

+    if (i->thread_info.resampled_chunk.memblock) {
+        size_t l =3D length;
+
+        if (l > i->thread_info.resampled_chunk.length)
+            l =3D i->thread_info.resampled_chunk.length;
+
+        pa_log("really dropping %u", l);
+        =

+        i->thread_info.resampled_chunk.index +=3D l;
+        i->thread_info.resampled_chunk.length -=3D l;
+        =

+        if (i->thread_info.resampled_chunk.length <=3D 0) {
+            pa_memblock_unref(i->thread_info.resampled_chunk.memblock);
+            pa_memchunk_reset(&i->thread_info.resampled_chunk);
+        }
+
+        length -=3D l;
     }
 =

-    pa_assert(i->thread_info.resampled_chunk.memblock);
-    pa_assert(i->thread_info.resampled_chunk.length >=3D length);
-
-    i->thread_info.resampled_chunk.index +=3D length;
-    i->thread_info.resampled_chunk.length -=3D length;
-
-    if (i->thread_info.resampled_chunk.length <=3D 0) {
-        pa_memblock_unref(i->thread_info.resampled_chunk.memblock);
-        i->thread_info.resampled_chunk.memblock =3D NULL;
-        i->thread_info.resampled_chunk.index =3D i->thread_info.resampled_=
chunk.length =3D 0;
+    pa_log("really remaining %u", length);
+    =

+    if (length > 0) {
+        =

+        if (i->thread_info.resampler) {
+            /* So, we have a resampler. To avoid discontinuities we
+             * have to actually read all data that could be read and
+             * pass it through the resampler. */
+
+            while (length > 0) {
+                pa_memchunk chunk;
+                pa_cvolume volume;
+                =

+                if (pa_sink_input_peek(i, &chunk, &volume) >=3D 0) {
+                    size_t l =3D chunk.length;
+
+                    if (l > length)
+                        l =3D length;
+                    =

+                    pa_sink_input_drop(i, l);
+                    length -=3D l;
+                    =

+                } else {
+                    /* Hmmm, peeking failed, so let's at least drop
+                     * the right amount of data */
+                    =

+                    if (i->drop)
+                        i->drop(i, pa_resampler_request(i->thread_info.res=
ampler, length));
+                            =

+                    break;
+                }
+            }
+
+        } else {
+
+            /* We have no resampler, hence let's just drop the data */
+
+            if (i->drop)
+                i->drop(i, length);
+        }
     }
 }
 =


Modified: branches/lennart/src/pulsecore/sink-input.h
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/branches/lennart/src/pulsecore/=
sink-input.h?rev=3D1529&root=3Dpulseaudio&r1=3D1528&r2=3D1529&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 Wed Jul 25 16:46:40 2007
@@ -75,7 +75,7 @@
     int muted;
 =

     int (*peek) (pa_sink_input *i, pa_memchunk *chunk);
-    void (*drop) (pa_sink_input *i, const pa_memchunk *chunk, size_t lengt=
h);
+    void (*drop) (pa_sink_input *i, size_t length);
     void (*kill) (pa_sink_input *i);             /* may be NULL */
     pa_usec_t (*get_latency) (pa_sink_input *i); /* may be NULL */
     void (*underrun) (pa_sink_input *i);         /* may be NULL */
@@ -178,7 +178,7 @@
 /* To be used exclusively by the sink driver thread */
 =

 int pa_sink_input_peek(pa_sink_input *i, pa_memchunk *chunk, pa_cvolume *v=
olume);
-void pa_sink_input_drop(pa_sink_input *i, const pa_memchunk *chunk, size_t=
 length);
+void pa_sink_input_drop(pa_sink_input *i, size_t length);
 int pa_sink_input_process_msg(pa_msgobject *o, int code, void *userdata, p=
a_memchunk *chunk);
 =

 #endif

Modified: branches/lennart/src/pulsecore/sink.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/branches/lennart/src/pulsecore/=
sink.c?rev=3D1529&root=3Dpulseaudio&r1=3D1528&r2=3D1529&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 Wed Jul 25 16:46:40 2007
@@ -326,7 +326,7 @@
         }
 =

         /* Drop read data */
-        pa_sink_input_drop(i, m ? &m->chunk : NULL, length);
+        pa_sink_input_drop(i, length);
 =

         if (m) {
             pa_sink_input_unref(m->userdata);

Modified: branches/lennart/src/pulsecore/sound-file-stream.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/branches/lennart/src/pulsecore/=
sound-file-stream.c?rev=3D1529&root=3Dpulseaudio&r1=3D1528&r2=3D1529&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/sound-file-stream.c (original)
+++ branches/lennart/src/pulsecore/sound-file-stream.c Wed Jul 25 16:46:40 =
2007
@@ -26,7 +26,6 @@
 #endif
 =

 #include <stdlib.h>
-#include <assert.h>
 #include <stdio.h>
 #include <string.h>
 =

@@ -41,89 +40,177 @@
 =

 #define BUF_SIZE (1024*10)
 =

-struct userdata {
+typedef struct file_stream {
+    pa_msgobject parent;
+    pa_core *core;
     SNDFILE *sndfile;
     pa_sink_input *sink_input;
     pa_memchunk memchunk;
     sf_count_t (*readf_function)(SNDFILE *sndfile, void *ptr, sf_count_t f=
rames);
+    size_t drop;
+} file_stream;
+
+enum {
+    MESSAGE_DROP_FILE_STREAM
 };
 =

-static void free_userdata(struct userdata *u) {
-    assert(u);
+PA_DECLARE_CLASS(file_stream);
+#define FILE_STREAM(o) (file_stream_cast(o))
+static PA_DEFINE_CHECK_TYPE(file_stream, file_stream_check_type, pa_msgobj=
ect_check_type);
+
+static void file_stream_free(pa_object *o) {
+    file_stream *u =3D FILE_STREAM(o);
+    pa_assert(u);
+
+    pa_log("xxxx ffreee");
+    =

+    if (u->memchunk.memblock)
+        pa_memblock_unref(u->memchunk.memblock);
+
+    if (u->sndfile)
+        sf_close(u->sndfile);
+
+    pa_xfree(u);
+}
+
+static void file_stream_drop(file_stream *u) {
+    file_stream_assert_ref(u);
+
+    pa_log("xxxx drop");
+    =

+    =

     if (u->sink_input) {
         pa_sink_input_disconnect(u->sink_input);
         pa_sink_input_unref(u->sink_input);
-    }
-
-    if (u->memchunk.memblock)
+        u->sink_input =3D NULL;
+
+        /* Make sure we don't decrease the ref count twice. */
+        file_stream_unref(u);
+    }
+}
+
+static int file_stream_process_msg(pa_msgobject *o, int code, void*userdat=
a, pa_memchunk *chunk) {
+    file_stream *u =3D FILE_STREAM(o);
+    file_stream_assert_ref(u);
+    =

+    switch (code) {
+        case MESSAGE_DROP_FILE_STREAM:
+            file_stream_drop(u);
+            break;
+    }
+
+    return 0;
+}
+
+static void sink_input_kill_cb(pa_sink_input *i) {
+    pa_assert(i);
+    =

+    file_stream_drop(FILE_STREAM(i->userdata));
+}
+
+static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) {
+    file_stream *u;
+    =

+    pa_assert(i);
+    pa_assert(chunk);
+    u =3D FILE_STREAM(i->userdata);
+    file_stream_assert_ref(u);
+
+    for (;;) {
+        =

+        if (!u->memchunk.memblock) {
+            =

+            u->memchunk.memblock =3D pa_memblock_new(i->sink->core->mempoo=
l, BUF_SIZE);
+            u->memchunk.index =3D 0;
+            =

+            if (u->readf_function) {
+                sf_count_t n;
+                void *p;
+                size_t fs =3D pa_frame_size(&i->sample_spec);
+                =

+                p =3D pa_memblock_acquire(u->memchunk.memblock);
+                n =3D u->readf_function(u->sndfile, p, BUF_SIZE/fs);
+                pa_memblock_release(u->memchunk.memblock);
+
+                pa_log("%u/%u =3D data: %02x %02x %02x %02x %02x %02x %02x=
 %02x",
+                       (unsigned int) n, BUF_SIZE/fs,
+                       ((uint8_t*)p)[0], ((uint8_t*)p)[1], ((uint8_t*)p)[2=
], ((uint8_t*)p)[3],
+                       ((uint8_t*)p)[4], ((uint8_t*)p)[5], ((uint8_t*)p)[6=
], ((uint8_t*)p)[7]);
+                =

+                if (n <=3D 0)
+                    n =3D 0;
+                =

+                u->memchunk.length =3D n * fs;
+            } else {
+                sf_count_t n;
+                void *p;
+
+                p =3D pa_memblock_acquire(u->memchunk.memblock);
+                n =3D sf_read_raw(u->sndfile, p, BUF_SIZE);
+                pa_memblock_release(u->memchunk.memblock);
+                =

+                if (n <=3D 0)
+                    n =3D 0;
+                =

+                u->memchunk.length =3D n;
+            }
+            =

+            if (u->memchunk.length <=3D 0) {
+
+                pa_memblock_unref(u->memchunk.memblock);
+                pa_memchunk_reset(&u->memchunk);
+                =

+                pa_asyncmsgq_post(u->core->asyncmsgq, PA_MSGOBJECT(u), MES=
SAGE_DROP_FILE_STREAM, NULL, NULL, NULL);
+                return -1;
+            }
+        }
+
+        pa_assert(u->memchunk.memblock);
+        pa_assert(u->memchunk.length > 0);
+
+        if (u->drop < u->memchunk.length) {
+            u->memchunk.index +=3D u->drop;
+            u->memchunk.length -=3D u->drop;
+            u->drop =3D 0;
+            break;
+        }
+                =

+        u->drop -=3D u->memchunk.length;
         pa_memblock_unref(u->memchunk.memblock);
-    if (u->sndfile)
-        sf_close(u->sndfile);
-
-    pa_xfree(u);
-}
-
-static void sink_input_kill(pa_sink_input *i) {
-    assert(i && i->userdata);
-    free_userdata(i->userdata);
-}
-
-static int sink_input_peek(pa_sink_input *i, pa_memchunk *chunk) {
-    struct userdata *u;
-    assert(i && chunk && i->userdata);
-    u =3D i->userdata;
-
-    if (!u->memchunk.memblock) {
-        uint32_t fs =3D pa_frame_size(&i->sample_spec);
-        sf_count_t n;
-        void *p;
-
-        u->memchunk.memblock =3D pa_memblock_new(i->sink->core->mempool, B=
UF_SIZE);
-        u->memchunk.index =3D 0;
-
-        p =3D pa_memblock_acquire(u->memchunk.memblock);
-
-        if (u->readf_function) {
-            if ((n =3D u->readf_function(u->sndfile, p, BUF_SIZE/fs)) <=3D=
 0)
-                n =3D 0;
-
-            u->memchunk.length =3D n * fs;
-        } else {
-            if ((n =3D sf_read_raw(u->sndfile, p, BUF_SIZE)) <=3D 0)
-                n =3D 0;
-
-            u->memchunk.length =3D n;
-        }
-        pa_memblock_release(u->memchunk.memblock);
-
-        if (!u->memchunk.length) {
-            free_userdata(u);
-            return -1;
-        }
+        pa_memchunk_reset(&u->memchunk);
     }
 =

     *chunk =3D u->memchunk;
     pa_memblock_ref(chunk->memblock);
-    assert(chunk->length);
+    =

+    pa_assert(chunk->length > 0);
+    pa_assert(u->drop <=3D 0);
+    =

     return 0;
 }
 =

-static void sink_input_drop(pa_sink_input *i, const pa_memchunk*chunk, siz=
e_t length) {
-    struct userdata *u;
-    assert(i && chunk && length && i->userdata);
-    u =3D i->userdata;
-
-    assert(!memcmp(chunk, &u->memchunk, sizeof(chunk)));
-    assert(length <=3D u->memchunk.length);
-
-    u->memchunk.index +=3D length;
-    u->memchunk.length -=3D length;
-
-    if (u->memchunk.length <=3D 0) {
+static void sink_input_drop_cb(pa_sink_input *i, size_t length) {
+    file_stream *u;
+
+    pa_assert(i);
+    pa_assert(length > 0);
+    u =3D FILE_STREAM(i->userdata);
+    file_stream_assert_ref(u);
+    =

+    if (u->memchunk.memblock) {
+
+        if (length < u->memchunk.length) {
+            u->memchunk.index +=3D length;
+            u->memchunk.length -=3D length;
+            return;
+        }
+
+        length -=3D u->memchunk.length;
         pa_memblock_unref(u->memchunk.memblock);
-        u->memchunk.memblock =3D NULL;
-        u->memchunk.index =3D u->memchunk.length =3D 0;
-    }
+        pa_memchunk_reset(&u->memchunk);
+    }
+            =

+    u->drop +=3D length;
 }
 =

 int pa_play_file(
@@ -131,19 +218,23 @@
         const char *fname,
         const pa_cvolume *volume) {
 =

-    struct userdata *u =3D NULL;
+    file_stream *u =3D NULL;
     SF_INFO sfinfo;
     pa_sample_spec ss;
     pa_sink_input_new_data data;
 =

-    assert(sink);
-    assert(fname);
-
-    u =3D pa_xnew(struct userdata, 1);
+    pa_assert(sink);
+    pa_assert(fname);
+
+    u =3D pa_msgobject_new(file_stream, file_stream_check_type);
+    u->parent.parent.free =3D file_stream_free;
+    u->parent.process_msg =3D file_stream_process_msg;
+    u->core =3D sink->core;
     u->sink_input =3D NULL;
-    u->memchunk.memblock =3D NULL;
-    u->memchunk.index =3D u->memchunk.length =3D 0;
+    pa_memchunk_reset(&u->memchunk);
     u->sndfile =3D NULL;
+    u->readf_function =3D NULL;
+    u->drop =3D 0;
 =

     memset(&sfinfo, 0, sizeof(sfinfo));
 =

@@ -151,8 +242,6 @@
         pa_log("Failed to open file %s", fname);
         goto fail;
     }
-
-    u->readf_function =3D NULL;
 =

     switch (sfinfo.format & 0xFF) {
         case SF_FORMAT_PCM_16:
@@ -195,18 +284,21 @@
     if (!(u->sink_input =3D pa_sink_input_new(sink->core, &data, 0)))
         goto fail;
 =

-    u->sink_input->peek =3D sink_input_peek;
-    u->sink_input->drop =3D sink_input_drop;
-    u->sink_input->kill =3D sink_input_kill;
+    u->sink_input->peek =3D sink_input_peek_cb;
+    u->sink_input->drop =3D sink_input_drop_cb;
+    u->sink_input->kill =3D sink_input_kill_cb;
     u->sink_input->userdata =3D u;
 =

-/*     pa_sink_notify(u->sink_input->sink); */
+    pa_sink_input_put(u->sink_input);
+
+    /* The reference to u is dangling here, because we want to keep
+     * this stream around until it is fully played. */
 =

     return 0;
 =

 fail:
     if (u)
-        free_userdata(u);
+        file_stream_unref(u);
 =

     return -1;
 }

Modified: branches/lennart/src/tests/memblockq-test.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/branches/lennart/src/tests/memb=
lockq-test.c?rev=3D1529&root=3Dpulseaudio&r1=3D1528&r2=3D1529&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/tests/memblockq-test.c (original)
+++ branches/lennart/src/tests/memblockq-test.c Wed Jul 25 16:46:40 2007
@@ -26,6 +26,7 @@
 #include <stdlib.h>
 #include <assert.h>
 #include <stdio.h>
+#include <signal.h>
 =

 #include <pulsecore/memblockq.h>
 #include <pulsecore/log.h>
@@ -48,22 +49,22 @@
     bq =3D pa_memblockq_new(0, 40, 10, 2, 4, 4, silence);
     assert(bq);
 =

-    chunk1.memblock =3D pa_memblock_new_fixed(p, (char*) "AA", 2, 1);
+    chunk1.memblock =3D pa_memblock_new_fixed(p, (char*) "11", 2, 1);
     chunk1.index =3D 0;
     chunk1.length =3D 2;
     assert(chunk1.memblock);
 =

-    chunk2.memblock =3D pa_memblock_new_fixed(p, (char*) "TTBB", 4, 1);
+    chunk2.memblock =3D pa_memblock_new_fixed(p, (char*) "XX22", 4, 1);
     chunk2.index =3D 2;
     chunk2.length =3D 2;
     assert(chunk2.memblock);
 =

-    chunk3.memblock =3D pa_memblock_new_fixed(p, (char*) "ZZZZ", 4, 1);
+    chunk3.memblock =3D pa_memblock_new_fixed(p, (char*) "3333", 4, 1);
     chunk3.index =3D 0;
     chunk3.length =3D 4;
     assert(chunk3.memblock);
 =

-    chunk4.memblock =3D pa_memblock_new_fixed(p, (char*) "KKKKKKKK", 8, 1);
+    chunk4.memblock =3D pa_memblock_new_fixed(p, (char*) "44444444", 8, 1);
     chunk4.index =3D 0;
     chunk4.length =3D 8;
     assert(chunk4.memblock);
@@ -115,13 +116,12 @@
 =

     chunk3.index +=3D 2;
     chunk3.length -=3D 2;
-
     ret =3D pa_memblockq_push(bq, &chunk3);
     assert(ret =3D=3D 0);
 =

+    pa_memblockq_shorten(bq, pa_memblockq_get_length(bq)-2);
+
     printf(">");
-
-    pa_memblockq_shorten(bq, 6);
 =

     for (;;) {
         pa_memchunk out;
@@ -137,7 +137,7 @@
         pa_memblock_release(out.memblock);
 =

         pa_memblock_unref(out.memblock);
-        pa_memblockq_drop(bq, &out, out.length);
+        pa_memblockq_drop(bq, out.length);
     }
 =

     printf("<\n");




More information about the pulseaudio-commits mailing list