Hi Andrzej, On Fri, Jan 17, 2014 at 9:17 PM, Andrzej Kaczmarek <andrzej.kaczmarek@xxxxxxxxx> wrote: > 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? I would just add these to hal-audio.c, nothing else should need it. -- 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