Re: [PATCH 5/9] android/hal-audio: Calculate SBC stream parameters

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

 



Hi Marcel,

On 17 January 2014 19:25, Marcel Holtmann <marcel@xxxxxxxxxxxx> wrote:
> Hi Andrzej,
>
>> This patch adds necessary calculations for SBC stream parameters.
>>
>> Both input and output buffers are expected to have exact amount of
>> data to fill single media packet (based on transport channel MTU).
>>
>> Frame duration will be used to synchronize input and output streams.
>> ---
>> android/hal-audio.c | 50 ++++++++++++++++++++++++++++++-----
>> android/rtp.h       | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++
>> 2 files changed, 120 insertions(+), 6 deletions(-)
>> create mode 100644 android/rtp.h
>>
>> diff --git a/android/hal-audio.c b/android/hal-audio.c
>> index e5c646c..3f53295 100644
>> --- a/android/hal-audio.c
>> +++ b/android/hal-audio.c
>> @@ -33,6 +33,7 @@
>> #include "hal-msg.h"
>> #include "../profiles/audio/a2dp-codecs.h"
>> #include <sbc/sbc.h>
>> +#include "rtp.h"
>>
>> static const uint8_t a2dp_src_uuid[] = {
>>               0x00, 0x00, 0x11, 0x0a, 0x00, 0x00, 0x10, 0x00,
>> @@ -46,6 +47,12 @@ static pthread_t ipc_th = 0;
>> static pthread_mutex_t close_mutex = PTHREAD_MUTEX_INITIALIZER;
>> static pthread_mutex_t sk_mutex = PTHREAD_MUTEX_INITIALIZER;
>>
>> +struct media_packet {
>> +     struct rtp_header hdr;
>> +     struct rtp_payload payload;
>> +     uint8_t data[0];
>> +};
>> +
>> struct audio_input_config {
>>       uint32_t rate;
>>       uint32_t channels;
>> @@ -56,10 +63,19 @@ struct sbc_data {
>>       a2dp_sbc_t sbc;
>>
>>       sbc_t enc;
>> +
>> +     size_t in_frame_len;
>> +     size_t in_buf_size;
>> +
>> +     size_t out_buf_size;
>> +     uint8_t *out_buf;
>> +
>> +     unsigned frame_duration;
>> };
>>
>> static int sbc_get_presets(struct audio_preset *preset, size_t *len);
>> -static int sbc_codec_init(struct audio_preset *preset, void **codec_data);
>> +static int sbc_codec_init(struct audio_preset *preset, uint16_t mtu,
>> +                             void **codec_data);
>> static int sbc_cleanup(void *codec_data);
>> static int sbc_get_config(void *codec_data,
>>                                       struct audio_input_config *config);
>> @@ -69,7 +85,8 @@ struct audio_codec {
>>
>>       int (*get_presets) (struct audio_preset *preset, size_t *len);
>>
>> -     int (*init) (struct audio_preset *preset, void **codec_data);
>> +     int (*init) (struct audio_preset *preset, uint16_t mtu,
>> +                             void **codec_data);
>>       int (*cleanup) (void *codec_data);
>>       int (*get_config) (void *codec_data,
>>                                       struct audio_input_config *config);
>> @@ -251,9 +268,14 @@ static void sbc_init_encoder(struct sbc_data *sbc_data)
>>       }
>> }
>>
>> -static int sbc_codec_init(struct audio_preset *preset, void **codec_data)
>> +static int sbc_codec_init(struct audio_preset *preset, uint16_t mtu,
>> +                             void **codec_data)
>> {
>>       struct sbc_data *sbc_data;
>> +     size_t hdr_len = sizeof(struct media_packet);
>> +     size_t in_frame_len;
>> +     size_t out_frame_len;
>> +     size_t num_frames;
>>
>>       DBG("");
>>
>> @@ -268,6 +290,18 @@ static int sbc_codec_init(struct audio_preset *preset, void **codec_data)
>>
>>       sbc_init_encoder(sbc_data);
>>
>> +     in_frame_len = sbc_get_codesize(&sbc_data->enc);
>> +     out_frame_len = sbc_get_frame_length(&sbc_data->enc);
>> +     num_frames = (mtu - hdr_len) / out_frame_len;
>> +
>> +     sbc_data->in_frame_len = in_frame_len;
>> +     sbc_data->in_buf_size = num_frames * in_frame_len;
>> +
>> +     sbc_data->out_buf_size = hdr_len + num_frames * out_frame_len;
>> +     sbc_data->out_buf = calloc(1, sbc_data->out_buf_size);
>> +
>> +     sbc_data->frame_duration = sbc_get_frame_duration(&sbc_data->enc);
>> +
>>       *codec_data = sbc_data;
>>
>>       return AUDIO_STATUS_SUCCESS;
>> @@ -280,6 +314,7 @@ static int sbc_cleanup(void *codec_data)
>>       DBG("");
>>
>>       sbc_finish(&sbc_data->enc);
>> +     free(sbc_data->out_buf);
>>       free(codec_data);
>>
>>       return AUDIO_STATUS_SUCCESS;
>> @@ -511,7 +546,7 @@ static int ipc_close_cmd(uint8_t endpoint_id)
>>       return result;
>> }
>>
>> -static int ipc_open_stream_cmd(uint8_t endpoint_id,
>> +static int ipc_open_stream_cmd(uint8_t endpoint_id, uint16_t *mtu,
>>                                       struct audio_preset **caps)
>> {
>>       char buf[BLUEZ_AUDIO_MTU];
>> @@ -534,6 +569,7 @@ static int ipc_open_stream_cmd(uint8_t endpoint_id,
>>       if (result == AUDIO_STATUS_SUCCESS) {
>>               size_t buf_len = sizeof(struct audio_preset) +
>>                                       rsp->preset[0].len;
>> +             *mtu = rsp->mtu;
>>               *caps = malloc(buf_len);
>>               memcpy(*caps, &rsp->preset, buf_len);
>>       } else {
>> @@ -919,6 +955,7 @@ static int audio_open_output_stream(struct audio_hw_device *dev,
>>       struct a2dp_stream_out *out;
>>       struct audio_preset *preset;
>>       const struct audio_codec *codec;
>> +     uint16_t mtu;
>>
>>       out = calloc(1, sizeof(struct a2dp_stream_out));
>>       if (!out)
>> @@ -946,7 +983,8 @@ static int audio_open_output_stream(struct audio_hw_device *dev,
>>       /* TODO: for now we always use endpoint 0 */
>>       out->ep = &audio_endpoints[0];
>>
>> -     if (ipc_open_stream_cmd(out->ep->id, &preset) != AUDIO_STATUS_SUCCESS)
>> +     if (ipc_open_stream_cmd(out->ep->id, &mtu, &preset) !=
>> +                     AUDIO_STATUS_SUCCESS)
>>               goto fail;
>>
>>       if (!preset)
>> @@ -954,7 +992,7 @@ static int audio_open_output_stream(struct audio_hw_device *dev,
>>
>>       codec = out->ep->codec;
>>
>> -     codec->init(preset, &out->ep->codec_data);
>> +     codec->init(preset, mtu, &out->ep->codec_data);
>>       codec->get_config(out->ep->codec_data, &out->cfg);
>>
>>       DBG("rate=%d channels=%d format=%d", out->cfg.rate,
>> diff --git a/android/rtp.h b/android/rtp.h
>> new file mode 100644
>> index 0000000..45fddcf
>> --- /dev/null
>> +++ b/android/rtp.h
>> @@ -0,0 +1,76 @@
>> +/*
>> + *
>> + *  BlueZ - Bluetooth protocol stack for Linux
>> + *
>> + *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@xxxxxxxxxxxx>
>> + *
>> + *
>> + *  This library is free software; you can redistribute it and/or
>> + *  modify it under the terms of the GNU Lesser General Public
>> + *  License as published by the Free Software Foundation; either
>> + *  version 2.1 of the License, or (at your option) any later version.
>> + *
>> + *  This library is distributed in the hope that it will be useful,
>> + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
>> + *  Lesser General Public License for more details.
>> + *
>> + *  You should have received a copy of the GNU Lesser General Public
>> + *  License along with this library; if not, write to the Free Software
>> + *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
>> + *
>> + */
>
> where is this file coming from? Why do we need a copy of it?

>From BlueZ but it was removed (was used in pcm_bluetooth.c) so I just
added it again since we need RTP header structures. Or should these
just be added inline to hal-audio.c?


BR,
Andrzej
--
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