diff mbox series

[BlueZ] client: fix ISO send data rate

Message ID 9b88a0238679d24aa5d68a4c473483943a8ea2b6.1715427163.git.pav@iki.fi
State New
Headers show
Series [BlueZ] client: fix ISO send data rate | expand

Commit Message

Pauli Virtanen May 11, 2024, 11:34 a.m. UTC
We are sending data to controller at wrong average rate not equal to
1 packet / SDU interval, if Transport_Latency is not an integer multiple
of SDU_Interval.  The calculation currently may also give zero, so no
data gets sent.

We are sending data in bursts of num ~= Transport_Latency/SDU_Interval
packets, in hopes that possibly larger timer interval makes things more
efficient.

Fix the data rate by sending num packets every num*SDU_Interval, so that
the average data rate is correct.

Also fix use of itimerspect.it_value with TFD_TIMER_ABSTIME.  The value
set previously is going to always be in the past in CLOCK_MONOTONIC so
just set it to 1, and leave sending the initial packets to the main
loop.
---

Notes:
    This assumes kernel shall set qos.interval to SDU_Interval and not
    ISO_Interval.

 client/player.c | 20 ++++++++++++++------
 1 file changed, 14 insertions(+), 6 deletions(-)

Comments

Luiz Augusto von Dentz May 11, 2024, 3:22 p.m. UTC | #1
Hi Pauli,

On Sat, May 11, 2024 at 7:34 AM Pauli Virtanen <pav@iki.fi> wrote:
>
> We are sending data to controller at wrong average rate not equal to
> 1 packet / SDU interval, if Transport_Latency is not an integer multiple
> of SDU_Interval.  The calculation currently may also give zero, so no
> data gets sent.
>
> We are sending data in bursts of num ~= Transport_Latency/SDU_Interval
> packets, in hopes that possibly larger timer interval makes things more
> efficient.
>
> Fix the data rate by sending num packets every num*SDU_Interval, so that
> the average data rate is correct.
>
> Also fix use of itimerspect.it_value with TFD_TIMER_ABSTIME.  The value
> set previously is going to always be in the past in CLOCK_MONOTONIC so
> just set it to 1, and leave sending the initial packets to the main
> loop.
> ---
>
> Notes:
>     This assumes kernel shall set qos.interval to SDU_Interval and not
>     ISO_Interval.
>
>  client/player.c | 20 ++++++++++++++------
>  1 file changed, 14 insertions(+), 6 deletions(-)
>
> diff --git a/client/player.c b/client/player.c
> index 7f67425aa..8d17022de 100644
> --- a/client/player.c
> +++ b/client/player.c
> @@ -5066,22 +5066,30 @@ static int transport_send(struct transport *transport, int fd,
>         if (timer_fd < 0)
>                 return -errno;
>
> +       /* Send data in bursts of
> +        * num = ROUND_CLOSEST(Transport_Latency (ms) / SDU_Interval (us))
> +        * with average data rate = 1 packet / SDU_Interval
> +        */
> +       transport->num = ROUND_CLOSEST(qos->latency * 1000, qos->interval);
> +       if (!transport->num)
> +               transport->num = 1;
> +
>         memset(&ts, 0, sizeof(ts));
> -       ts.it_value.tv_nsec = qos->latency * 1000000;
> -       ts.it_interval.tv_nsec = qos->latency * 1000000;
> +       ts.it_value.tv_nsec = 1;
> +       ts.it_interval.tv_nsec = transport->num * qos->interval * 1000;
>
> -       if (timerfd_settime(timer_fd, TFD_TIMER_ABSTIME, &ts, NULL) < 0)
> +       if (timerfd_settime(timer_fd, TFD_TIMER_ABSTIME, &ts, NULL) < 0) {
> +               close(timer_fd);
>                 return -errno;
> +       }
>
>         transport->fd = fd;
> -       /* num of packets = ROUND_CLOSEST(latency (ms) / interval (us)) */
> -       transport->num = ROUND_CLOSEST(qos->latency * 1000, qos->interval);
>         transport->timer_io = io_new(timer_fd);
>
>         io_set_read_handler(transport->timer_io, transport_timer_read,
>                                                 transport, NULL);
>
> -       return transport_send_seq(transport, fd, 1);

The above was actually done on purpose so we are always one interval
ahead to keep controller buffer full as much as possible.

> +       return 0;
>  }
>
>  static void cmd_send_transport(int argc, char *argv[])
> --
> 2.45.0
>
>
diff mbox series

Patch

diff --git a/client/player.c b/client/player.c
index 7f67425aa..8d17022de 100644
--- a/client/player.c
+++ b/client/player.c
@@ -5066,22 +5066,30 @@  static int transport_send(struct transport *transport, int fd,
 	if (timer_fd < 0)
 		return -errno;
 
+	/* Send data in bursts of
+	 * num = ROUND_CLOSEST(Transport_Latency (ms) / SDU_Interval (us))
+	 * with average data rate = 1 packet / SDU_Interval
+	 */
+	transport->num = ROUND_CLOSEST(qos->latency * 1000, qos->interval);
+	if (!transport->num)
+		transport->num = 1;
+
 	memset(&ts, 0, sizeof(ts));
-	ts.it_value.tv_nsec = qos->latency * 1000000;
-	ts.it_interval.tv_nsec = qos->latency * 1000000;
+	ts.it_value.tv_nsec = 1;
+	ts.it_interval.tv_nsec = transport->num * qos->interval * 1000;
 
-	if (timerfd_settime(timer_fd, TFD_TIMER_ABSTIME, &ts, NULL) < 0)
+	if (timerfd_settime(timer_fd, TFD_TIMER_ABSTIME, &ts, NULL) < 0) {
+		close(timer_fd);
 		return -errno;
+	}
 
 	transport->fd = fd;
-	/* num of packets = ROUND_CLOSEST(latency (ms) / interval (us)) */
-	transport->num = ROUND_CLOSEST(qos->latency * 1000, qos->interval);
 	transport->timer_io = io_new(timer_fd);
 
 	io_set_read_handler(transport->timer_io, transport_timer_read,
 						transport, NULL);
 
-	return transport_send_seq(transport, fd, 1);
+	return 0;
 }
 
 static void cmd_send_transport(int argc, char *argv[])