[MPlayer-dev-eng] Patch: ao_jack for smoother playback

Reimar Döffinger Reimar.Doeffinger at stud.uni-karlsruhe.de
Sat Jul 9 22:15:43 CEST 2005


Hi,
On Sat, Jul 09, 2005 at 08:04:54PM +0100, Ed W wrote:
> I did send this message to you a couple of times offlist, but either you 
> didn't get it, or didn't think it was even worth commenting on...  Just 
> in case it was the former I am resending it to the list in the hope that 
> it might catch your eye.

I wanted it to merge with my local changes (attached), but didn't get
around to it...
The merging would essentially consist of replacing my estimation code in
the callback with yours (or maybe even keeping both, whatever).

Greetings,
Reimar Döffinger
-------------- next part --------------
Index: libao2/ao_jack.c
===================================================================
RCS file: /cvsroot/mplayer/main/libao2/ao_jack.c,v
retrieving revision 1.12
diff -u -r1.12 ao_jack.c
--- libao2/ao_jack.c	30 Jun 2005 13:25:08 -0000	1.12
+++ libao2/ao_jack.c	9 Jul 2005 20:12:29 -0000
@@ -11,6 +11,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <math.h>
 #include <unistd.h>
 
 #include "config.h"
@@ -43,15 +44,12 @@
 static int num_ports; ///< Number of used ports == number of channels
 static jack_client_t *client;
 static float jack_latency;
+static int estimate;
 static volatile int paused = 0; ///< set if paused
 static volatile int underrun = 0; ///< signals if an underrun occured
 
-//! If this is defined try to make a more precise delay estimation. Will be slower.
-#undef JACK_ESTIMATE_DELAY
-#ifdef JACK_ESTIMATE_DELAY
-static volatile int callback_samples = 0;
-static volatile unsigned int callback_time = 0;
-#endif
+static volatile float callback_interval = 0;
+static volatile float callback_time = 0;
 
 //! size of one chunk, if this is too small MPlayer will start to "stutter"
 //! after a short time of playback
@@ -168,6 +166,9 @@
       bufs[j][i] = 0;
 }
 
+//! experimental value for estimation code (squared)
+#define TIME_BASE (0.003 * 0.003)
+
 /**
  * \brief JACK Callback function
  * \param nframes number of frames to fill into buffers
@@ -186,10 +187,15 @@
       underrun = 1;
   if (paused || underrun)
     silence(bufs, nframes, num_ports);
-#ifdef JACK_ESTIMATE_DELAY
-  callback_samples = nframes;
-  callback_time = GetTimer();
-#endif
+  if (estimate) {
+    float now = (float)GetTimer() / 1000000.0;
+    if (callback_interval > 0) {
+      float diff = callback_time + callback_interval - now;
+      callback_time = now + exp(-diff*diff / TIME_BASE) * diff;
+    } else
+     callback_time = now;
+    callback_interval = (float)nframes / (float)ao_data.samplerate;
+  }
   return 0;
 }
 
@@ -204,7 +210,9 @@
            "  connects MPlayer to the jack ports named myout\n"
            "\nOptions:\n"
            "  port=<port name>\n"
-           "    Connects to the given ports instead of the default physical ones\n");
+           "    Connects to the given ports instead of the default physical ones\n"
+           "  estimate\n"
+           "    Estimates the amount of data in buffers (experimental)\n");
 }
 
 static int init(int rate, int channels, int format, int flags) {
@@ -213,10 +221,12 @@
   char client_name[40];
   opt_t subopts[] = {
     {"port", OPT_ARG_MSTRZ, &port_name, NULL},
+    {"estimate", OPT_ARG_BOOL, &estimate, NULL},
     {NULL}
   };
   int port_flags = JackPortIsInput;
   int i;
+  estimate = 0;
   if (subopt_parse(ao_subdevice, subopts) != 0) {
     print_help();
     return 0;
@@ -269,6 +279,7 @@
   rate = jack_get_sample_rate(client);
   jack_latency = (float)(jack_port_get_total_latency(client, ports[0]) +
                          jack_get_buffer_size(client)) / (float)rate;
+  callback_interval = 0;
   buffer = (unsigned char *) malloc(BUFFSIZE);
 
   ao_data.channels = channels;
@@ -343,11 +354,11 @@
 static float get_delay() {
   int buffered = BUFFSIZE - CHUNK_SIZE - buf_free(); // could be less
   float in_jack = jack_latency;
-#ifdef JACK_ESTIMATE_DELAY
-  unsigned int elapsed = GetTimer() - callback_time;
-  in_jack += (float)callback_samples / (float)ao_data.samplerate - (float)elapsed / 1000.0 / 1000.0;
-  if (in_jack < 0) in_jack = 0;
-#endif
+  if (estimate && callback_interval > 0) {
+    float elapsed = (float)GetTimer() / 1000000.0 - callback_time;
+    in_jack += callback_interval - elapsed;
+    if (in_jack < 0) in_jack = 0;
+  }
   return (float)buffered / (float)ao_data.bps + in_jack;
 }
 


More information about the MPlayer-dev-eng mailing list