Hi all,

I've been working on bluetooth for the fun of it, using my pc as a media player for my phone. However one thing not handled well currently is underruns. They can occur because the phone is not in range, or some packets fail to decode. How should I respond to underruns? The delta calculations are probably calculating the correct byte offset despite packet loss, but still currently I'm doing nothing with that information.

Cheers,
Maarten

---
diff --git a/src/modules/bluetooth/module-bluetooth-device.c 
b/src/modules/bluetooth/module-bluetooth-device.c
index 8664001..1affd35 100644
--- a/src/modules/bluetooth/module-bluetooth-device.c
+++ b/src/modules/bluetooth/module-bluetooth-device.c
@@ -153,7 +153,8 @@ struct userdata {
     pa_rtpoll_item *rtpoll_item;
     pa_thread *thread;
 
-    uint64_t read_index, write_index;
+    pa_bool_t first_read;
+    int64_t read_timestamp, read_index, write_index;
     pa_usec_t started_at;
     pa_smoother *read_smoother;
 
@@ -920,6 +921,8 @@ static int bt_transport_acquire(struct userdata *u, 
pa_bool_t start)
     u->accesstype = pa_xstrdup(accesstype);
     pa_log_info("Transport %s acquired: fd %d", u->transport, u->stream_fd);
 
+    u->first_read = 1;
+
     if (!start)
         return 0;
 
@@ -1391,7 +1394,6 @@ static int a2dp_process_push(struct userdata *u) {
     memchunk.index = memchunk.length = 0;
 
     for (;;) {
-        pa_bool_t found_tstamp = FALSE;
         pa_usec_t tstamp;
         struct a2dp_info *a2dp;
         struct rtp_header *header;
@@ -1400,7 +1402,6 @@ static int a2dp_process_push(struct userdata *u) {
         void *d;
         ssize_t l;
         size_t to_write, to_decode;
-        unsigned frame_count;
 
         a2dp_prepare_buffer(u);
 
@@ -1427,12 +1428,23 @@ static int a2dp_process_push(struct userdata *u) {
 
         pa_assert((size_t) l <= a2dp->buffer_size);
 
-        u->read_index += (uint64_t) l;
+        tstamp = pa_rtclock_now();
 
-        /* TODO: get timestamp from rtp */
-        if (!found_tstamp) {
-            /* pa_log_warn("Couldn't find SO_TIMESTAMP data in auxiliary 
recvmsg() data!"); */
-            tstamp = pa_rtclock_now();
+        if (u->first_read) {
+            u->read_timestamp = ntohl(header->timestamp);
+            u->first_read = 0;
+        } else {
+            int64_t timestamp = ntohl(header->timestamp);
+            int64_t ofs = u->read_timestamp;
+            int64_t delta, k, j;
+            k = timestamp - ofs;
+            j = 0x100000000 + timestamp - ofs;
+
+            if ((k < 0 ? -k : k) < (j < 0 ? -j : j))
+                delta = k;
+            else
+                delta = j;
+            u->read_index += delta * a2dp->codesize;
         }
 
         pa_smoother_put(u->read_smoother, tstamp, 
pa_bytes_to_usec(u->read_index, &u->sample_spec));
@@ -1458,7 +1470,7 @@ static int a2dp_process_push(struct userdata *u) {
                 pa_log_error("SBC decoding error (%li)", (long) decoded);
                 pa_memblock_release(memchunk.memblock);
                 pa_memblock_unref(memchunk.memblock);
-                return -1;
+                return 0;
             }
 
 /*             pa_log_debug("SBC: decoded: %lu; written: %lu", (unsigned long) 
decoded, (unsigned long) written); */
@@ -1476,8 +1488,6 @@ static int a2dp_process_push(struct userdata *u) {
             d = (uint8_t*) d + written;
             to_write -= written;
             memchunk.length += written;
-
-            frame_count++;
         }
 
         if (to_decode)
_______________________________________________
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss

Reply via email to