Re: [PATCH BlueZ] client: fix ISO send data rate

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Pauli,

On Sat, May 11, 2024 at 7:34 AM Pauli Virtanen <pav@xxxxxx> 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
>
>


-- 
Luiz Augusto von Dentz





[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux