chiark / gitweb /
drop 0s at end of rtp packets
[disorder] / server / speaker.c
index b3d62ab800718db677423e189e149fd755b70eec..acbc9bf05e4261f95240af79cc6b563d23e681c8 100644 (file)
@@ -553,9 +553,9 @@ static void fork_cmd(void) {
 }
 
 static void play(size_t frames) {
-  size_t avail_bytes, written_frames;
+  size_t avail_bytes, write_bytes, written_frames;
   ssize_t written_bytes;
-  struct rtp header;
+  struct rtp_header header;
   struct iovec vec[2];
 
   if(activate()) {
@@ -648,9 +648,14 @@ static void play(size_t frames) {
       struct timeval now;
       xgettimeofday(&now, 0);
       /* There's been a gap.  Fix up the RTP time accordingly. */
-      rtp_time += (((now.tv_sec + now.tv_usec /1000000.0)
-                    - (rtp_time_real.tv_sec + rtp_time_real.tv_usec / 1000000.0)) 
-                   * playing->format.rate * playing->format.channels);
+      const long offset =  (((now.tv_sec + now.tv_usec /1000000.0)
+                             - (rtp_time_real.tv_sec + rtp_time_real.tv_usec / 1000000.0)) 
+                            * playing->format.rate * playing->format.channels);
+      if(offset >= 0) {
+        info("offset RTP timestamp by %ld", offset);
+        rtp_time += offset;
+      }
+      rtp_time_real = now;
     }
     header.vpxcc = 2 << 6;              /* V=2, P=0, X=0, CC=0 */
     header.seq = htons(rtp_seq++);
@@ -674,33 +679,40 @@ static void play(size_t frames) {
      * generated per second is then the sampling rate times the channel
      * count.)"
      */
-    vec[0].iov_base = (void *)&header;
-    vec[0].iov_len = sizeof header;
-    vec[1].iov_base = playing->buffer + playing->start;
-    vec[1].iov_len = avail_bytes;
+    write_bytes = avail_bytes;
 #if 0
-    {
-      char buffer[3 * sizeof header + 1];
-      size_t n;
-      const uint8_t *ptr = (void *)&header;
-      
-      for(n = 0; n < sizeof header; ++n)
-        sprintf(&buffer[3 * n], "%02x ", *ptr++);
-      info(buffer);
-    }
+    while(write_bytes > 0 && (uint32_t)(playing->buffer + playing->start + write_bytes - 4) == 0)
+      write_bytes -= 4;
 #endif
-    do {
-      written_bytes = writev(bfd,
-                             vec,
-                             2);
-    } while(written_bytes < 0 && errno == EINTR);
-    if(written_bytes < 0) {
-      error(errno, "error transmitting audio data");
-      ++audio_errors;
-      if(audio_errors == 10)
-        fatal(0, "too many audio errors");
+    if(write_bytes) {
+      vec[0].iov_base = (void *)&header;
+      vec[0].iov_len = sizeof header;
+      vec[1].iov_base = playing->buffer + playing->start;
+      vec[1].iov_len = avail_bytes;
+#if 0
+      {
+        char buffer[3 * sizeof header + 1];
+        size_t n;
+        const uint8_t *ptr = (void *)&header;
+        
+        for(n = 0; n < sizeof header; ++n)
+          sprintf(&buffer[3 * n], "%02x ", *ptr++);
+        info(buffer);
+      }
+#endif
+      do {
+        written_bytes = writev(bfd,
+                               vec,
+                               2);
+      } while(written_bytes < 0 && errno == EINTR);
+      if(written_bytes < 0) {
+        error(errno, "error transmitting audio data");
+        ++audio_errors;
+        if(audio_errors == 10)
+          fatal(0, "too many audio errors");
       return;
-    }
+      }
+    } else
     audio_errors /= 2;
     written_bytes = avail_bytes;
     written_frames = written_bytes / bpf;
@@ -713,6 +725,7 @@ static void play(size_t frames) {
       ++rtp_time_real.tv_sec;
       rtp_time_real.tv_usec -= 1000000;
     }
+    assert(rtp_time_real.tv_usec < 1000000);
     break;
   default:
     assert(!"reached");