Re: [PATCHv4 12/12] android/audio: Add write to SCO

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

 



Hi Andrei,

On Thu, May 8, 2014 at 3:25 PM, Andrei Emeltchenko
<Andrei.Emeltchenko.news@xxxxxxxxx> wrote:
> From: Andrei Emeltchenko <andrei.emeltchenko@xxxxxxxxx>
>
> For synchronization interleave read() and write().
> ---
>  android/hal-sco.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 73 insertions(+)
>
> diff --git a/android/hal-sco.c b/android/hal-sco.c
> index 7b6608b..5ec56ce 100644
> --- a/android/hal-sco.c
> +++ b/android/hal-sco.c
> @@ -41,6 +41,8 @@
>  #define OUT_BUFFER_SIZE                        2560
>  #define OUT_STREAM_FRAMES              2560
>
> +#define SOCKET_POLL_TIMEOUT_MS         500
> +
>  static int listen_sk = -1;
>  static int audio_sk = -1;
>
> @@ -275,6 +277,74 @@ static void downmix_to_mono(struct sco_stream_out *out, const uint8_t *buffer,
>         }
>  }
>
> +static bool write_data(struct sco_stream_out *out, const uint8_t *buffer,
> +                                                               size_t bytes)
> +{
> +       struct pollfd pfd;
> +       size_t len, written = 0;
> +       int ret;
> +       uint16_t mtu = /* out->cfg.mtu */ 48;
> +       uint8_t read_buf[mtu];
> +       bool do_write = false;
> +
> +       pfd.fd = out->fd;
> +       pfd.events = POLLOUT | POLLIN | POLLHUP | POLLNVAL;
> +
> +       while (bytes > written) {
> +
> +               /* poll for sending */
> +               if (poll(&pfd, 1, SOCKET_POLL_TIMEOUT_MS) == 0) {
> +                       DBG("timeout fd %d", out->fd);
> +                       return false;
> +               }
> +
> +               if (pfd.revents & (POLLHUP | POLLNVAL)) {
> +                       error("error fd %d, events 0x%x", out->fd, pfd.revents);
> +                       return false;
> +               }
> +
> +               if (pfd.revents & POLLIN) {
> +                       ret = read(out->fd, read_buf, mtu);
> +                       if (ret < 0) {
> +                               error("Error reading fd %d (%s)", out->fd,
> +                                                       strerror(errno));
> +                               return false;
> +                       }
> +
> +                       do_write = true;

You probably gonna have store the read data in a buffer to be read by
upper layer after remixed to 44.1 KHz, to safe space you can probably
leave the remixing to be done on the read callback. Im fine to do this
in a separate patch but we should at least add a comment about it.

> +               }
> +
> +               if (!do_write)
> +                       continue;
> +
> +               len = bytes - written > mtu ? mtu : bytes - written;
> +
> +               ret = write(out->fd, buffer + written, len);
> +               if (ret > 0) {
> +                       written += ret;
> +                       do_write = false;
> +                       continue;
> +               }
> +
> +               if (errno == EAGAIN) {
> +                       ret = errno;
> +                       warn("write failed (%d)", ret);
> +                       continue;
> +               }
> +
> +               if (errno != EINTR) {
> +                       ret = errno;
> +                       error("write failed (%d) fd %d bytes %zd", ret, out->fd,
> +                                                                       bytes);
> +                       return false;
> +               }
> +       }
> +
> +       DBG("written %zd bytes", bytes);
> +
> +       return true;
> +}
> +
>  static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
>                                                                 size_t bytes)
>  {
> @@ -320,6 +390,9 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
>
>         DBG("total %zd", total);
>
> +       if (!write_data(out, send_buf, total))
> +               return -1;
> +
>         return bytes;
>  }
>
> --
> 1.8.3.2
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html



-- 
Luiz Augusto von Dentz
--
To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[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