From 9b397f1e281bff80d05fee7c2f5da89fa3e10252 Mon Sep 17 00:00:00 2001 From: wangmengyang Date: Mon, 5 Dec 2016 18:02:09 +0800 Subject: [PATCH] component/bt: A2DP clean-up 1. remove unused file audio_a2dp_hw.c 2. remove "BTIF_AV_SRC_INCLUDED" enclosed codes --- .../audio_a2dp_hw/audio_a2dp_hw.c | 1405 ----------------- .../bluedroid_demos/btif/btif_avk.c | 176 +-- .../bluedroid_demos/btif/btif_media_task.c | 1242 +-------------- .../bluedroid_demos/btif/include/btif_media.h | 2 +- 4 files changed, 6 insertions(+), 2819 deletions(-) delete mode 100644 examples/09_a2dp/components/bluedroid_demos/audio_a2dp_hw/audio_a2dp_hw.c diff --git a/examples/09_a2dp/components/bluedroid_demos/audio_a2dp_hw/audio_a2dp_hw.c b/examples/09_a2dp/components/bluedroid_demos/audio_a2dp_hw/audio_a2dp_hw.c deleted file mode 100644 index 3de97fe93c..0000000000 --- a/examples/09_a2dp/components/bluedroid_demos/audio_a2dp_hw/audio_a2dp_hw.c +++ /dev/null @@ -1,1405 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2009-2012 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/***************************************************************************** - * - * Filename: audio_a2dp_hw.c - * - * Description: Implements hal for bluedroid a2dp audio device - * - *****************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include "audio_a2dp_hw.h" -#include "bt_utils.h" - -#define LOG_TAG "bt_a2dp_hw" -#include "osi/include/log.h" - -/***************************************************************************** -** Constants & Macros -******************************************************************************/ - -#define CTRL_CHAN_RETRY_COUNT 3 -#define USEC_PER_SEC 1000000L - -#define CASE_RETURN_STR(const) case const: return #const; - -#define FNLOG() LOG_VERBOSE("%s", __FUNCTION__); -#define DEBUG(fmt, ...) LOG_VERBOSE("%s: " fmt,__FUNCTION__, ## __VA_ARGS__) -#define INFO(fmt, ...) LOG_INFO("%s: " fmt,__FUNCTION__, ## __VA_ARGS__) -#define ERROR(fmt, ...) LOG_ERROR("%s: " fmt,__FUNCTION__, ## __VA_ARGS__) - -#define ASSERTC(cond, msg, val) if (!(cond)) {ERROR("### ASSERT : %s line %d %s (%d) ###", __FILE__, __LINE__, msg, val);} - -/***************************************************************************** -** Local type definitions -******************************************************************************/ - -typedef enum { - AUDIO_A2DP_STATE_STARTING, - AUDIO_A2DP_STATE_STARTED, - AUDIO_A2DP_STATE_STOPPING, - AUDIO_A2DP_STATE_STOPPED, - AUDIO_A2DP_STATE_SUSPENDED, /* need explicit set param call to resume (suspend=false) */ - AUDIO_A2DP_STATE_STANDBY /* allows write to autoresume */ -} a2dp_state_t; - -struct a2dp_stream_in; -struct a2dp_stream_out; - -struct a2dp_audio_device { - struct audio_hw_device device; - struct a2dp_stream_in *input; - struct a2dp_stream_out *output; -}; - -struct a2dp_config { - uint32_t rate; - uint32_t channel_flags; - int format; -}; - -/* move ctrl_fd outside output stream and keep open until HAL unloaded ? */ - -struct a2dp_stream_common { - pthread_mutex_t lock; - int ctrl_fd; - int audio_fd; - size_t buffer_sz; - struct a2dp_config cfg; - a2dp_state_t state; -}; - -struct a2dp_stream_out { - struct audio_stream_out stream; - struct a2dp_stream_common common; - uint64_t frames_presented; // frames written, never reset - uint64_t frames_rendered; // frames written, reset on standby -}; - -struct a2dp_stream_in { - struct audio_stream_in stream; - struct a2dp_stream_common common; -}; - -/***************************************************************************** -** Static variables -******************************************************************************/ - -/***************************************************************************** -** Static functions -******************************************************************************/ - -static size_t out_get_buffer_size(const struct audio_stream *stream); - -/***************************************************************************** -** Externs -******************************************************************************/ - -/***************************************************************************** -** Functions -******************************************************************************/ - -/***************************************************************************** -** Miscellaneous helper functions -******************************************************************************/ - -static const char *dump_a2dp_ctrl_event(char event) -{ - switch (event) { - CASE_RETURN_STR(A2DP_CTRL_CMD_NONE) - CASE_RETURN_STR(A2DP_CTRL_CMD_CHECK_READY) - CASE_RETURN_STR(A2DP_CTRL_CMD_START) - CASE_RETURN_STR(A2DP_CTRL_CMD_STOP) - CASE_RETURN_STR(A2DP_CTRL_CMD_SUSPEND) - default: - return "UNKNOWN MSG ID"; - } -} - -/* logs timestamp with microsec precision - pprev is optional in case a dedicated diff is required */ -static void ts_log(char *tag, int val, struct timespec *pprev_opt) -{ - struct timespec now; - static struct timespec prev = {0, 0}; - unsigned long long now_us; - unsigned long long diff_us; - UNUSED(tag); - UNUSED(val); - - clock_gettime(CLOCK_MONOTONIC, &now); - - now_us = now.tv_sec * USEC_PER_SEC + now.tv_nsec / 1000; - - if (pprev_opt) { - diff_us = (now.tv_sec - prev.tv_sec) * USEC_PER_SEC + (now.tv_nsec - prev.tv_nsec) / 1000; - *pprev_opt = now; - DEBUG("[%s] ts %08lld, *diff %08lld, val %d", tag, now_us, diff_us, val); - } else { - diff_us = (now.tv_sec - prev.tv_sec) * USEC_PER_SEC + (now.tv_nsec - prev.tv_nsec) / 1000; - prev = now; - DEBUG("[%s] ts %08lld, diff %08lld, val %d", tag, now_us, diff_us, val); - } -} - -static int calc_audiotime(struct a2dp_config cfg, int bytes) -{ - int chan_count = popcount(cfg.channel_flags); - - ASSERTC(cfg.format == AUDIO_FORMAT_PCM_16_BIT, - "unsupported sample sz", cfg.format); - - return bytes * (1000000 / (chan_count * 2)) / cfg.rate; -} - -/***************************************************************************** -** -** bluedroid stack adaptation -** -*****************************************************************************/ - -static int skt_connect(char *path, size_t buffer_sz) -{ - int ret; - int skt_fd; - struct sockaddr_un remote; - int len; - - INFO("connect to %s (sz %zu)", path, buffer_sz); - - skt_fd = socket(AF_LOCAL, SOCK_STREAM, 0); - - if (socket_local_client_connect(skt_fd, path, - ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM) < 0) { - ERROR("failed to connect (%s)", strerror(errno)); - close(skt_fd); - return -1; - } - - len = buffer_sz; - ret = setsockopt(skt_fd, SOL_SOCKET, SO_SNDBUF, (char *)&len, (int)sizeof(len)); - - /* only issue warning if failed */ - if (ret < 0) { - ERROR("setsockopt failed (%s)", strerror(errno)); - } - - ret = setsockopt(skt_fd, SOL_SOCKET, SO_RCVBUF, (char *)&len, (int)sizeof(len)); - - /* only issue warning if failed */ - if (ret < 0) { - ERROR("setsockopt failed (%s)", strerror(errno)); - } - - INFO("connected to stack fd = %d", skt_fd); - - return skt_fd; -} - -static int skt_read(int fd, void *p, size_t len) -{ - int read; - struct pollfd pfd; - struct timespec ts; - - FNLOG(); - - ts_log("skt_read recv", len, NULL); - - if ((read = recv(fd, p, len, MSG_NOSIGNAL)) == -1) { - ERROR("write failed with errno=%d\n", errno); - return -1; - } - - return read; -} - -static int skt_write(int fd, const void *p, size_t len) -{ - int sent; - struct pollfd pfd; - - FNLOG(); - - pfd.fd = fd; - pfd.events = POLLOUT; - - /* poll for 500 ms */ - - /* send time out */ - if (poll(&pfd, 1, 500) == 0) { - return 0; - } - - ts_log("skt_write", len, NULL); - - if ((sent = send(fd, p, len, MSG_NOSIGNAL)) == -1) { - ERROR("write failed with errno=%d\n", errno); - return -1; - } - - return sent; -} - -static int skt_disconnect(int fd) -{ - INFO("fd %d", fd); - - if (fd != AUDIO_SKT_DISCONNECTED) { - shutdown(fd, SHUT_RDWR); - close(fd); - } - return 0; -} - - - -/***************************************************************************** -** -** AUDIO CONTROL PATH -** -*****************************************************************************/ - -static int a2dp_ctrl_receive(struct a2dp_stream_common *common, void *buffer, int length) -{ - int ret = recv(common->ctrl_fd, buffer, length, MSG_NOSIGNAL); - if (ret < 0) { - ERROR("ack failed (%s)", strerror(errno)); - if (errno == EINTR) { - /* retry again */ - ret = recv(common->ctrl_fd, buffer, length, MSG_NOSIGNAL); - if (ret < 0) { - ERROR("ack failed (%s)", strerror(errno)); - skt_disconnect(common->ctrl_fd); - common->ctrl_fd = AUDIO_SKT_DISCONNECTED; - return -1; - } - } else { - skt_disconnect(common->ctrl_fd); - common->ctrl_fd = AUDIO_SKT_DISCONNECTED; - return -1; - - } - } - return ret; -} - -static int a2dp_command(struct a2dp_stream_common *common, char cmd) -{ - char ack; - - DEBUG("A2DP COMMAND %s", dump_a2dp_ctrl_event(cmd)); - - /* send command */ - if (send(common->ctrl_fd, &cmd, 1, MSG_NOSIGNAL) == -1) { - ERROR("cmd failed (%s)", strerror(errno)); - skt_disconnect(common->ctrl_fd); - common->ctrl_fd = AUDIO_SKT_DISCONNECTED; - return -1; - } - - /* wait for ack byte */ - if (a2dp_ctrl_receive(common, &ack, 1) < 0) { - return -1; - } - - DEBUG("A2DP COMMAND %s DONE STATUS %d", dump_a2dp_ctrl_event(cmd), ack); - - if (ack == A2DP_CTRL_ACK_INCALL_FAILURE) { - return ack; - } - if (ack != A2DP_CTRL_ACK_SUCCESS) { - return -1; - } - - return 0; -} - -static int check_a2dp_ready(struct a2dp_stream_common *common) -{ - if (a2dp_command(common, A2DP_CTRL_CMD_CHECK_READY) < 0) { - ERROR("check a2dp ready failed"); - return -1; - } - return 0; -} - -static int a2dp_read_audio_config(struct a2dp_stream_common *common) -{ - char cmd = A2DP_CTRL_GET_AUDIO_CONFIG; - uint32_t sample_rate; - uint8_t channel_count; - - if (a2dp_command(common, A2DP_CTRL_GET_AUDIO_CONFIG) < 0) { - ERROR("check a2dp ready failed"); - return -1; - } - - if (a2dp_ctrl_receive(common, &sample_rate, 4) < 0) { - return -1; - } - if (a2dp_ctrl_receive(common, &channel_count, 1) < 0) { - return -1; - } - - common->cfg.channel_flags = (channel_count == 1 ? AUDIO_CHANNEL_IN_MONO : AUDIO_CHANNEL_IN_STEREO); - common->cfg.format = AUDIO_STREAM_DEFAULT_FORMAT; - common->cfg.rate = sample_rate; - - INFO("got config %d %d", common->cfg.format, common->cfg.rate); - - return 0; -} - -static void a2dp_open_ctrl_path(struct a2dp_stream_common *common) -{ - int i; - - /* retry logic to catch any timing variations on control channel */ - for (i = 0; i < CTRL_CHAN_RETRY_COUNT; i++) { - /* connect control channel if not already connected */ - if ((common->ctrl_fd = skt_connect(A2DP_CTRL_PATH, common->buffer_sz)) > 0) { - /* success, now check if stack is ready */ - if (check_a2dp_ready(common) == 0) { - break; - } - - ERROR("error : a2dp not ready, wait 250 ms and retry"); - usleep(250000); - skt_disconnect(common->ctrl_fd); - common->ctrl_fd = AUDIO_SKT_DISCONNECTED; - } - - /* ctrl channel not ready, wait a bit */ - usleep(250000); - } -} - -/***************************************************************************** -** -** AUDIO DATA PATH -** -*****************************************************************************/ - -static void a2dp_stream_common_init(struct a2dp_stream_common *common) -{ - pthread_mutexattr_t lock_attr; - - FNLOG(); - - pthread_mutexattr_init(&lock_attr); - pthread_mutexattr_settype(&lock_attr, PTHREAD_MUTEX_RECURSIVE); - pthread_mutex_init(&common->lock, &lock_attr); - - common->ctrl_fd = AUDIO_SKT_DISCONNECTED; - common->audio_fd = AUDIO_SKT_DISCONNECTED; - common->state = AUDIO_A2DP_STATE_STOPPED; - - /* manages max capacity of socket pipe */ - common->buffer_sz = AUDIO_STREAM_OUTPUT_BUFFER_SZ; -} - -static int start_audio_datapath(struct a2dp_stream_common *common) -{ - INFO("state %d", common->state); - - if (common->ctrl_fd == AUDIO_SKT_DISCONNECTED) { - INFO("%s AUDIO_SKT_DISCONNECTED", __func__); - return -1; - } - - int oldstate = common->state; - common->state = AUDIO_A2DP_STATE_STARTING; - - int a2dp_status = a2dp_command(common, A2DP_CTRL_CMD_START); - if (a2dp_status < 0) { - ERROR("%s Audiopath start failed (status %d)", __func__, a2dp_status); - - common->state = oldstate; - return -1; - } else if (a2dp_status == A2DP_CTRL_ACK_INCALL_FAILURE) { - ERROR("%s Audiopath start failed - in call, move to suspended", __func__); - common->state = oldstate; - return -1; - } - - /* connect socket if not yet connected */ - if (common->audio_fd == AUDIO_SKT_DISCONNECTED) { - common->audio_fd = skt_connect(A2DP_DATA_PATH, common->buffer_sz); - if (common->audio_fd < 0) { - common->state = oldstate; - return -1; - } - - common->state = AUDIO_A2DP_STATE_STARTED; - } - - return 0; -} - -static int stop_audio_datapath(struct a2dp_stream_common *common) -{ - int oldstate = common->state; - - INFO("state %d", common->state); - - if (common->ctrl_fd == AUDIO_SKT_DISCONNECTED) { - return -1; - } - - /* prevent any stray output writes from autostarting the stream - while stopping audiopath */ - common->state = AUDIO_A2DP_STATE_STOPPING; - - if (a2dp_command(common, A2DP_CTRL_CMD_STOP) < 0) { - ERROR("audiopath stop failed"); - common->state = oldstate; - return -1; - } - - common->state = AUDIO_A2DP_STATE_STOPPED; - - /* disconnect audio path */ - skt_disconnect(common->audio_fd); - common->audio_fd = AUDIO_SKT_DISCONNECTED; - - return 0; -} - -static int suspend_audio_datapath(struct a2dp_stream_common *common, bool standby) -{ - INFO("state %d", common->state); - - if (common->ctrl_fd == AUDIO_SKT_DISCONNECTED) { - return -1; - } - - if (common->state == AUDIO_A2DP_STATE_STOPPING) { - return -1; - } - - if (a2dp_command(common, A2DP_CTRL_CMD_SUSPEND) < 0) { - return -1; - } - - if (standby) { - common->state = AUDIO_A2DP_STATE_STANDBY; - } else { - common->state = AUDIO_A2DP_STATE_SUSPENDED; - } - - /* disconnect audio path */ - skt_disconnect(common->audio_fd); - - common->audio_fd = AUDIO_SKT_DISCONNECTED; - - return 0; -} - - -/***************************************************************************** -** -** audio output callbacks -** -*****************************************************************************/ - -static ssize_t out_write(struct audio_stream_out *stream, const void *buffer, - size_t bytes) -{ - struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream; - int sent; - - DEBUG("write %zu bytes (fd %d)", bytes, out->common.audio_fd); - - pthread_mutex_lock(&out->common.lock); - - if (out->common.state == AUDIO_A2DP_STATE_SUSPENDED) { - DEBUG("stream suspended"); - pthread_mutex_unlock(&out->common.lock); - return -1; - } - - /* only allow autostarting if we are in stopped or standby */ - if ((out->common.state == AUDIO_A2DP_STATE_STOPPED) || - (out->common.state == AUDIO_A2DP_STATE_STANDBY)) { - if (start_audio_datapath(&out->common) < 0) { - /* emulate time this write represents to avoid very fast write - failures during transition periods or remote suspend */ - - int us_delay = calc_audiotime(out->common.cfg, bytes); - - DEBUG("emulate a2dp write delay (%d us)", us_delay); - - usleep(us_delay); - pthread_mutex_unlock(&out->common.lock); - return -1; - } - } else if (out->common.state != AUDIO_A2DP_STATE_STARTED) { - ERROR("stream not in stopped or standby"); - pthread_mutex_unlock(&out->common.lock); - return -1; - } - - pthread_mutex_unlock(&out->common.lock); - sent = skt_write(out->common.audio_fd, buffer, bytes); - - if (sent == -1) { - skt_disconnect(out->common.audio_fd); - out->common.audio_fd = AUDIO_SKT_DISCONNECTED; - if (out->common.state != AUDIO_A2DP_STATE_SUSPENDED) { - out->common.state = AUDIO_A2DP_STATE_STOPPED; - } else { - ERROR("write failed : stream suspended, avoid resetting state"); - } - } else { - const size_t frames = bytes / audio_stream_out_frame_size(stream); - out->frames_rendered += frames; - out->frames_presented += frames; - } - - DEBUG("wrote %d bytes out of %zu bytes", sent, bytes); - return sent; -} - - -static uint32_t out_get_sample_rate(const struct audio_stream *stream) -{ - struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream; - - DEBUG("rate %" PRIu32, out->common.cfg.rate); - - return out->common.cfg.rate; -} - -static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate) -{ - struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream; - - DEBUG("out_set_sample_rate : %" PRIu32, rate); - - if (rate != AUDIO_STREAM_DEFAULT_RATE) { - ERROR("only rate %d supported", AUDIO_STREAM_DEFAULT_RATE); - return -1; - } - - out->common.cfg.rate = rate; - - return 0; -} - -static size_t out_get_buffer_size(const struct audio_stream *stream) -{ - struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream; - - DEBUG("buffer_size : %zu", out->common.buffer_sz); - - return out->common.buffer_sz; -} - -static uint32_t out_get_channels(const struct audio_stream *stream) -{ - struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream; - - DEBUG("channels 0x%" PRIx32, out->common.cfg.channel_flags); - - return out->common.cfg.channel_flags; -} - -static audio_format_t out_get_format(const struct audio_stream *stream) -{ - struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream; - DEBUG("format 0x%x", out->common.cfg.format); - return out->common.cfg.format; -} - -static int out_set_format(struct audio_stream *stream, audio_format_t format) -{ - UNUSED(format); - struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream; - DEBUG("setting format not yet supported (0x%x)", format); - return -ENOSYS; -} - -static int out_standby(struct audio_stream *stream) -{ - struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream; - int retVal = 0; - - FNLOG(); - - pthread_mutex_lock(&out->common.lock); - // Do nothing in SUSPENDED state. - if (out->common.state != AUDIO_A2DP_STATE_SUSPENDED) { - retVal = suspend_audio_datapath(&out->common, true); - } - out->frames_rendered = 0; // rendered is reset, presented is not - pthread_mutex_unlock (&out->common.lock); - - return retVal; -} - -static int out_dump(const struct audio_stream *stream, int fd) -{ - UNUSED(fd); - struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream; - FNLOG(); - return 0; -} - -static int out_set_parameters(struct audio_stream *stream, const char *kvpairs) -{ - struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream; - struct str_parms *parms; - char keyval[16]; - int retval; - int status = 0; - - INFO("state %d", out->common.state); - - parms = str_parms_create_str(kvpairs); - - /* dump params */ - str_parms_dump(parms); - - retval = str_parms_get_str(parms, "closing", keyval, sizeof(keyval)); - - if (retval >= 0) { - if (strcmp(keyval, "true") == 0) { - DEBUG("stream closing, disallow any writes"); - pthread_mutex_lock(&out->common.lock); - out->common.state = AUDIO_A2DP_STATE_STOPPING; - pthread_mutex_unlock(&out->common.lock); - } - } - - retval = str_parms_get_str(parms, "A2dpSuspended", keyval, sizeof(keyval)); - - if (retval >= 0) { - pthread_mutex_lock(&out->common.lock); - if (strcmp(keyval, "true") == 0) { - if (out->common.state == AUDIO_A2DP_STATE_STARTED) { - status = suspend_audio_datapath(&out->common, false); - } - } else { - /* Do not start the streaming automatically. If the phone was streaming - * prior to being suspended, the next out_write shall trigger the - * AVDTP start procedure */ - if (out->common.state == AUDIO_A2DP_STATE_SUSPENDED) { - out->common.state = AUDIO_A2DP_STATE_STANDBY; - } - /* Irrespective of the state, return 0 */ - } - pthread_mutex_unlock(&out->common.lock); - } - - str_parms_destroy(parms); - - return status; -} - -static char *out_get_parameters(const struct audio_stream *stream, const char *keys) -{ - UNUSED(keys); - struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream; - - FNLOG(); - - /* add populating param here */ - - return strdup(""); -} - -static uint32_t out_get_latency(const struct audio_stream_out *stream) -{ - int latency_us; - - struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream; - - FNLOG(); - - latency_us = ((out->common.buffer_sz * 1000 ) / - audio_stream_out_frame_size(&out->stream) / - out->common.cfg.rate) * 1000; - - - return (latency_us / 1000) + 200; -} - -static int out_set_volume(struct audio_stream_out *stream, float left, - float right) -{ - UNUSED(stream); - UNUSED(left); - UNUSED(right); - - FNLOG(); - - /* volume controlled in audioflinger mixer (digital) */ - - return -ENOSYS; -} - -static int out_get_presentation_position(const struct audio_stream_out *stream, - uint64_t *frames, struct timespec *timestamp) -{ - struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream; - - FNLOG(); - if (stream == NULL || frames == NULL || timestamp == NULL) { - return -EINVAL; - } - - int ret = -EWOULDBLOCK; - pthread_mutex_lock(&out->common.lock); - uint64_t latency_frames = (uint64_t)out_get_latency(stream) * out->common.cfg.rate / 1000; - if (out->frames_presented >= latency_frames) { - *frames = out->frames_presented - latency_frames; - clock_gettime(CLOCK_MONOTONIC, timestamp); // could also be associated with out_write(). - ret = 0; - } - pthread_mutex_unlock(&out->common.lock); - return ret; -} - -static int out_get_render_position(const struct audio_stream_out *stream, - uint32_t *dsp_frames) -{ - struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream; - - FNLOG(); - if (stream == NULL || dsp_frames == NULL) { - return -EINVAL; - } - - pthread_mutex_lock(&out->common.lock); - uint64_t latency_frames = (uint64_t)out_get_latency(stream) * out->common.cfg.rate / 1000; - if (out->frames_rendered >= latency_frames) { - *dsp_frames = (uint32_t)(out->frames_rendered - latency_frames); - } else { - *dsp_frames = 0; - } - pthread_mutex_unlock(&out->common.lock); - return 0; -} - -static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect) -{ - UNUSED(stream); - UNUSED(effect); - - FNLOG(); - return 0; -} - -static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect) -{ - UNUSED(stream); - UNUSED(effect); - - FNLOG(); - return 0; -} - -/* - * AUDIO INPUT STREAM - */ - -static uint32_t in_get_sample_rate(const struct audio_stream *stream) -{ - struct a2dp_stream_in *in = (struct a2dp_stream_in *)stream; - - FNLOG(); - return in->common.cfg.rate; -} - -static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate) -{ - struct a2dp_stream_in *in = (struct a2dp_stream_in *)stream; - - FNLOG(); - - if (in->common.cfg.rate > 0 && in->common.cfg.rate == rate) { - return 0; - } else { - return -1; - } -} - -static size_t in_get_buffer_size(const struct audio_stream *stream) -{ - UNUSED(stream); - - FNLOG(); - return 320; -} - -static uint32_t in_get_channels(const struct audio_stream *stream) -{ - struct a2dp_stream_in *in = (struct a2dp_stream_in *)stream; - - FNLOG(); - return in->common.cfg.channel_flags; -} - -static audio_format_t in_get_format(const struct audio_stream *stream) -{ - UNUSED(stream); - - FNLOG(); - return AUDIO_FORMAT_PCM_16_BIT; -} - -static int in_set_format(struct audio_stream *stream, audio_format_t format) -{ - UNUSED(stream); - UNUSED(format); - - FNLOG(); - if (format == AUDIO_FORMAT_PCM_16_BIT) { - return 0; - } else { - return -1; - } -} - -static int in_standby(struct audio_stream *stream) -{ - UNUSED(stream); - - FNLOG(); - return 0; -} - -static int in_dump(const struct audio_stream *stream, int fd) -{ - UNUSED(stream); - UNUSED(fd); - - FNLOG(); - return 0; -} - -static int in_set_parameters(struct audio_stream *stream, const char *kvpairs) -{ - UNUSED(stream); - UNUSED(kvpairs); - - FNLOG(); - return 0; -} - -static char *in_get_parameters(const struct audio_stream *stream, - const char *keys) -{ - UNUSED(stream); - UNUSED(keys); - - FNLOG(); - return strdup(""); -} - -static int in_set_gain(struct audio_stream_in *stream, float gain) -{ - UNUSED(stream); - UNUSED(gain); - - FNLOG(); - return 0; -} - -static ssize_t in_read(struct audio_stream_in *stream, void *buffer, - size_t bytes) -{ - struct a2dp_stream_in *in = (struct a2dp_stream_in *)stream; - int read; - - DEBUG("read %zu bytes, state: %d", bytes, in->common.state); - - if (in->common.state == AUDIO_A2DP_STATE_SUSPENDED) { - DEBUG("stream suspended"); - return -1; - } - - /* only allow autostarting if we are in stopped or standby */ - if ((in->common.state == AUDIO_A2DP_STATE_STOPPED) || - (in->common.state == AUDIO_A2DP_STATE_STANDBY)) { - pthread_mutex_lock(&in->common.lock); - - if (start_audio_datapath(&in->common) < 0) { - /* emulate time this write represents to avoid very fast write - failures during transition periods or remote suspend */ - - int us_delay = calc_audiotime(in->common.cfg, bytes); - - DEBUG("emulate a2dp read delay (%d us)", us_delay); - - usleep(us_delay); - pthread_mutex_unlock(&in->common.lock); - return -1; - } - - pthread_mutex_unlock(&in->common.lock); - } else if (in->common.state != AUDIO_A2DP_STATE_STARTED) { - ERROR("stream not in stopped or standby"); - return -1; - } - - read = skt_read(in->common.audio_fd, buffer, bytes); - - if (read == -1) { - skt_disconnect(in->common.audio_fd); - in->common.audio_fd = AUDIO_SKT_DISCONNECTED; - in->common.state = AUDIO_A2DP_STATE_STOPPED; - } else if (read == 0) { - DEBUG("read time out - return zeros"); - memset(buffer, 0, bytes); - read = bytes; - } - - DEBUG("read %d bytes out of %zu bytes", read, bytes); - return read; -} - -static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream) -{ - UNUSED(stream); - - FNLOG(); - return 0; -} - -static int in_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect) -{ - UNUSED(stream); - UNUSED(effect); - - FNLOG(); - return 0; -} - -static int in_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect) -{ - UNUSED(stream); - UNUSED(effect); - - FNLOG(); - - return 0; -} - -static int adev_open_output_stream(struct audio_hw_device *dev, - audio_io_handle_t handle, - audio_devices_t devices, - audio_output_flags_t flags, - struct audio_config *config, - struct audio_stream_out **stream_out, - const char *address) - -{ - struct a2dp_audio_device *a2dp_dev = (struct a2dp_audio_device *)dev; - struct a2dp_stream_out *out; - int ret = 0; - int i; - UNUSED(address); - UNUSED(handle); - UNUSED(devices); - UNUSED(flags); - - INFO("opening output"); - - out = (struct a2dp_stream_out *)calloc(1, sizeof(struct a2dp_stream_out)); - - if (!out) { - return -ENOMEM; - } - - out->stream.common.get_sample_rate = out_get_sample_rate; - out->stream.common.set_sample_rate = out_set_sample_rate; - out->stream.common.get_buffer_size = out_get_buffer_size; - out->stream.common.get_channels = out_get_channels; - out->stream.common.get_format = out_get_format; - out->stream.common.set_format = out_set_format; - out->stream.common.standby = out_standby; - out->stream.common.dump = out_dump; - out->stream.common.set_parameters = out_set_parameters; - out->stream.common.get_parameters = out_get_parameters; - out->stream.common.add_audio_effect = out_add_audio_effect; - out->stream.common.remove_audio_effect = out_remove_audio_effect; - out->stream.get_latency = out_get_latency; - out->stream.set_volume = out_set_volume; - out->stream.write = out_write; - out->stream.get_render_position = out_get_render_position; - out->stream.get_presentation_position = out_get_presentation_position; - - - /* initialize a2dp specifics */ - a2dp_stream_common_init(&out->common); - - out->common.cfg.channel_flags = AUDIO_STREAM_DEFAULT_CHANNEL_FLAG; - out->common.cfg.format = AUDIO_STREAM_DEFAULT_FORMAT; - out->common.cfg.rate = AUDIO_STREAM_DEFAULT_RATE; - - /* set output config values */ - if (config) { - config->format = out_get_format((const struct audio_stream *)&out->stream); - config->sample_rate = out_get_sample_rate((const struct audio_stream *)&out->stream); - config->channel_mask = out_get_channels((const struct audio_stream *)&out->stream); - } - *stream_out = &out->stream; - a2dp_dev->output = out; - - a2dp_open_ctrl_path(&out->common); - if (out->common.ctrl_fd == AUDIO_SKT_DISCONNECTED) { - ERROR("ctrl socket failed to connect (%s)", strerror(errno)); - ret = -1; - goto err_open; - } - - DEBUG("success"); - /* Delay to ensure Headset is in proper state when START is initiated - from DUT immediately after the connection due to ongoing music playback. */ - usleep(250000); - return 0; - -err_open: - free(out); - *stream_out = NULL; - a2dp_dev->output = NULL; - ERROR("failed"); - return ret; -} - -static void adev_close_output_stream(struct audio_hw_device *dev, - struct audio_stream_out *stream) -{ - struct a2dp_audio_device *a2dp_dev = (struct a2dp_audio_device *)dev; - struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream; - - INFO("closing output (state %d)", out->common.state); - - pthread_mutex_lock(&out->common.lock); - if ((out->common.state == AUDIO_A2DP_STATE_STARTED) || (out->common.state == AUDIO_A2DP_STATE_STOPPING)) { - stop_audio_datapath(&out->common); - } - - skt_disconnect(out->common.ctrl_fd); - free(stream); - a2dp_dev->output = NULL; - pthread_mutex_unlock(&out->common.lock); - - DEBUG("done"); -} - -static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs) -{ - struct a2dp_audio_device *a2dp_dev = (struct a2dp_audio_device *)dev; - struct a2dp_stream_out *out = a2dp_dev->output; - int retval = 0; - - if (out == NULL) { - return retval; - } - - INFO("state %d", out->common.state); - - retval = out->stream.common.set_parameters((struct audio_stream *)out, kvpairs); - - return retval; -} - -static char *adev_get_parameters(const struct audio_hw_device *dev, - const char *keys) -{ - struct str_parms *parms; - UNUSED(dev); - - FNLOG(); - - parms = str_parms_create_str(keys); - - str_parms_dump(parms); - - str_parms_destroy(parms); - - return strdup(""); -} - -static int adev_init_check(const struct audio_hw_device *dev) -{ - struct a2dp_audio_device *a2dp_dev = (struct a2dp_audio_device *)dev; - - FNLOG(); - - return 0; -} - -static int adev_set_voice_volume(struct audio_hw_device *dev, float volume) -{ - UNUSED(dev); - UNUSED(volume); - - FNLOG(); - - return -ENOSYS; -} - -static int adev_set_master_volume(struct audio_hw_device *dev, float volume) -{ - UNUSED(dev); - UNUSED(volume); - - FNLOG(); - - return -ENOSYS; -} - -static int adev_set_mode(struct audio_hw_device *dev, int mode) -{ - UNUSED(dev); - UNUSED(mode); - - FNLOG(); - - return 0; -} - -static int adev_set_mic_mute(struct audio_hw_device *dev, bool state) -{ - UNUSED(dev); - UNUSED(state); - - FNLOG(); - - return -ENOSYS; -} - -static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state) -{ - UNUSED(dev); - UNUSED(state); - - FNLOG(); - - return -ENOSYS; -} - -static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev, - const struct audio_config *config) -{ - UNUSED(dev); - UNUSED(config); - - FNLOG(); - - return 320; -} - -static int adev_open_input_stream(struct audio_hw_device *dev, - audio_io_handle_t handle, - audio_devices_t devices, - struct audio_config *config, - struct audio_stream_in **stream_in, - audio_input_flags_t flags, - const char *address, - audio_source_t source) -{ - struct a2dp_audio_device *a2dp_dev = (struct a2dp_audio_device *)dev; - struct a2dp_stream_in *in; - int ret; - UNUSED(address); - UNUSED(config); - UNUSED(devices); - UNUSED(flags); - UNUSED(handle); - UNUSED(source); - - FNLOG(); - - in = (struct a2dp_stream_in *)calloc(1, sizeof(struct a2dp_stream_in)); - - if (!in) { - return -ENOMEM; - } - - in->stream.common.get_sample_rate = in_get_sample_rate; - in->stream.common.set_sample_rate = in_set_sample_rate; - in->stream.common.get_buffer_size = in_get_buffer_size; - in->stream.common.get_channels = in_get_channels; - in->stream.common.get_format = in_get_format; - in->stream.common.set_format = in_set_format; - in->stream.common.standby = in_standby; - in->stream.common.dump = in_dump; - in->stream.common.set_parameters = in_set_parameters; - in->stream.common.get_parameters = in_get_parameters; - in->stream.common.add_audio_effect = in_add_audio_effect; - in->stream.common.remove_audio_effect = in_remove_audio_effect; - in->stream.set_gain = in_set_gain; - in->stream.read = in_read; - in->stream.get_input_frames_lost = in_get_input_frames_lost; - - /* initialize a2dp specifics */ - a2dp_stream_common_init(&in->common); - - *stream_in = &in->stream; - a2dp_dev->input = in; - - a2dp_open_ctrl_path(&in->common); - if (in->common.ctrl_fd == AUDIO_SKT_DISCONNECTED) { - ERROR("ctrl socket failed to connect (%s)", strerror(errno)); - ret = -1; - goto err_open; - } - - if (a2dp_read_audio_config(&in->common) < 0) { - ERROR("a2dp_read_audio_config failed (%s)", strerror(errno)); - ret = -1; - goto err_open; - } - - DEBUG("success"); - return 0; - -err_open: - free(in); - *stream_in = NULL; - a2dp_dev->input = NULL; - ERROR("failed"); - return ret; -} - -static void adev_close_input_stream(struct audio_hw_device *dev, - struct audio_stream_in *stream) -{ - struct a2dp_audio_device *a2dp_dev = (struct a2dp_audio_device *)dev; - struct a2dp_stream_in *in = (struct a2dp_stream_in *)stream; - a2dp_state_t state = in->common.state; - - INFO("closing input (state %d)", state); - - if ((state == AUDIO_A2DP_STATE_STARTED) || (state == AUDIO_A2DP_STATE_STOPPING)) { - stop_audio_datapath(&in->common); - } - - skt_disconnect(in->common.ctrl_fd); - free(stream); - a2dp_dev->input = NULL; - - DEBUG("done"); -} - -static int adev_dump(const audio_hw_device_t *device, int fd) -{ - UNUSED(device); - UNUSED(fd); - - FNLOG(); - - return 0; -} - -static int adev_close(hw_device_t *device) -{ - FNLOG(); - - free(device); - return 0; -} - -static int adev_open(const hw_module_t *module, const char *name, - hw_device_t **device) -{ - struct a2dp_audio_device *adev; - int ret; - - INFO(" adev_open in A2dp_hw module"); - FNLOG(); - - if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) { - ERROR("interface %s not matching [%s]", name, AUDIO_HARDWARE_INTERFACE); - return -EINVAL; - } - - adev = calloc(1, sizeof(struct a2dp_audio_device)); - - if (!adev) { - return -ENOMEM; - } - - adev->device.common.tag = HARDWARE_DEVICE_TAG; - adev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0; - adev->device.common.module = (struct hw_module_t *) module; - adev->device.common.close = adev_close; - - adev->device.init_check = adev_init_check; - adev->device.set_voice_volume = adev_set_voice_volume; - adev->device.set_master_volume = adev_set_master_volume; - adev->device.set_mode = adev_set_mode; - adev->device.set_mic_mute = adev_set_mic_mute; - adev->device.get_mic_mute = adev_get_mic_mute; - adev->device.set_parameters = adev_set_parameters; - adev->device.get_parameters = adev_get_parameters; - adev->device.get_input_buffer_size = adev_get_input_buffer_size; - adev->device.open_output_stream = adev_open_output_stream; - adev->device.close_output_stream = adev_close_output_stream; - adev->device.open_input_stream = adev_open_input_stream; - adev->device.close_input_stream = adev_close_input_stream; - adev->device.dump = adev_dump; - - adev->output = NULL; - - - *device = &adev->device.common; - - return 0; -} - -static struct hw_module_methods_t hal_module_methods = { - .open = adev_open, -}; - -struct audio_module HAL_MODULE_INFO_SYM = { - .common = { - .tag = HARDWARE_MODULE_TAG, - .version_major = 1, - .version_minor = 0, - .id = AUDIO_HARDWARE_MODULE_ID, - .name = "A2DP Audio HW HAL", - .author = "The Android Open Source Project", - .methods = &hal_module_methods, - }, -}; diff --git a/examples/09_a2dp/components/bluedroid_demos/btif/btif_avk.c b/examples/09_a2dp/components/bluedroid_demos/btif/btif_avk.c index a7b396d269..733936a879 100644 --- a/examples/09_a2dp/components/bluedroid_demos/btif/btif_avk.c +++ b/examples/09_a2dp/components/bluedroid_demos/btif/btif_avk.c @@ -25,14 +25,10 @@ * *****************************************************************************/ -// #include #include "bt_trace.h" #include -// #include #include "bt_defs.h" -// #include -// #include "bt_av.h" #include "esp_bt_defs.h" #include "esp_a2dp_api.h" #include "allocator.h" @@ -438,13 +434,6 @@ static BOOLEAN btif_av_state_closing_handler(btif_sm_event_t event, void *p_data switch (event) { case BTIF_SM_ENTER_EVT: -#if (BTIF_AV_SRC_INCLUDED == TRUE) - if (btif_av_cb.peer_sep == AVDT_TSEP_SNK) { - /* immediately stop transmission of frames */ - btif_a2dp_set_tx_flush(TRUE); - /* wait for audioflinger to stop a2dp */ - } -#endif /* (BTIF_AV_SRC_INCLUDED == TRUE) */ if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) { btif_a2dp_set_rx_flush(TRUE); } @@ -452,12 +441,6 @@ static BOOLEAN btif_av_state_closing_handler(btif_sm_event_t event, void *p_data case BTA_AV_STOP_EVT: case BTIF_AV_STOP_STREAM_REQ_EVT: -#if (BTIF_AV_SRC_INCLUDED == TRUE) - if (btif_av_cb.peer_sep == AVDT_TSEP_SNK) { - /* immediately flush any pending tx frames while suspend is pending */ - btif_a2dp_set_tx_flush(TRUE); - } -#endif if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) { btif_a2dp_set_rx_flush(TRUE); } @@ -525,11 +508,6 @@ static BOOLEAN btif_av_state_opened_handler(btif_sm_event_t event, void *p_data) break; case BTIF_AV_START_STREAM_REQ_EVT: -#if (BTIF_AV_SRC_INCLUDED == TRUE) - if (btif_av_cb.peer_sep != AVDT_TSEP_SRC) { - btif_a2dp_setup_codec(); - } -#endif BTA_AvStart(); btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_START; break; @@ -542,27 +520,6 @@ static BOOLEAN btif_av_state_opened_handler(btif_sm_event_t event, void *p_data) return TRUE; } -#if (BTIF_AV_SRC_INCLUDED == TRUE) - /* if remote tries to start a2dp when DUT is a2dp source - * then suspend. In case a2dp is sink and call is active - * then disconnect the AVDTP channel - */ - if (!(btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START)) { - if (btif_av_cb.peer_sep == AVDT_TSEP_SNK) { - BTIF_TRACE_EVENT("%s: trigger suspend as remote initiated!!\n", __FUNCTION__); - btif_dispatch_sm_event(BTIF_AV_SUSPEND_STREAM_REQ_EVT, NULL, 0); - } - } - - /* In case peer is A2DP SRC we do not want to ack commands on UIPC*/ - if (btif_av_cb.peer_sep == AVDT_TSEP_SNK) { - if (btif_a2dp_on_started(&p_av->start, - ((btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) != 0))) { - /* only clear pending flag after acknowledgement */ - btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START; - } - } -#endif /* remain in open state if status failed */ if (p_av->start.status != BTA_AV_SUCCESS) { return FALSE; @@ -574,11 +531,7 @@ static BOOLEAN btif_av_state_opened_handler(btif_sm_event_t event, void *p_data) /* change state to started, send acknowledgement if start is pending */ if (btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) { -#if (BTIF_AV_SRC_INCLUDED == TRUE) - if (btif_av_cb.peer_sep == AVDT_TSEP_SNK) { - btif_a2dp_on_started(NULL, TRUE); - } -#endif + /* pending start flag will be cleared when exit current state */ } btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_STARTED); @@ -679,12 +632,6 @@ static BOOLEAN btif_av_state_started_handler(btif_sm_event_t event, void *p_data break; case BTIF_AV_START_STREAM_REQ_EVT: -#if (BTIF_AV_SRC_INCLUDED == TRUE) - /* we were remotely started, just ack back the local request */ - if (btif_av_cb.peer_sep == AVDT_TSEP_SNK) { - btif_a2dp_on_started(NULL, TRUE); - } -#endif break; /* fixme -- use suspend = true always to work around issue with BTA AV */ @@ -698,12 +645,7 @@ static BOOLEAN btif_av_state_started_handler(btif_sm_event_t event, void *p_data /* if we were remotely suspended but suspend locally, local suspend always overrides */ btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND; -#if (BTIF_AV_SRC_INCLUDED == TRUE) - if (btif_av_cb.peer_sep == AVDT_TSEP_SNK) { - /* immediately stop transmission of frames while suspend is pending */ - btif_a2dp_set_tx_flush(TRUE); - } -#endif + if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) { btif_a2dp_set_rx_flush(TRUE); btif_a2dp_on_stopped(NULL); @@ -735,12 +677,7 @@ static BOOLEAN btif_av_state_started_handler(btif_sm_event_t event, void *p_data /* if not successful, remain in current state */ if (p_av->suspend.status != BTA_AV_SUCCESS) { btif_av_cb.flags &= ~BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING; -#if (BTIF_AV_SRC_INCLUDED == TRUE) - if (btif_av_cb.peer_sep == AVDT_TSEP_SNK) { - /* suspend failed, reset back tx flush state */ - btif_a2dp_set_tx_flush(FALSE); - } -#endif + return FALSE; } @@ -948,31 +885,6 @@ bt_status_t btif_av_init() return BT_STATUS_SUCCESS; } -#if (BTIF_AV_SRC_INCLUDED == TRUE) -/******************************************************************************* -** -** Function init_src -** -** Description Initializes the AV interface for source mode -** -** Returns bt_status_t -** -*******************************************************************************/ - -static bt_status_t init_src(btav_callbacks_t *callbacks) -{ - BTIF_TRACE_EVENT("%s()\n", __func__); - - bt_status_t status = btif_av_init(); - if (status == BT_STATUS_SUCCESS) { - bt_av_src_callbacks = callbacks; - } - - return status; -} - -#endif - /** * * Function register A2DP callback @@ -1028,18 +940,7 @@ static bt_status_t connect_int(bt_bdaddr_t *bd_addr, uint16_t uuid) return BT_STATUS_SUCCESS; } -#if (BTIF_AV_SRC_INCLUDED == TRUE) -static bt_status_t src_connect_sink(bt_bdaddr_t *bd_addr) -{ - BTIF_TRACE_EVENT("%s\n", __FUNCTION__); - CHECK_BTAV_INIT(); - - return btif_queue_connect(UUID_SERVCLASS_AUDIO_SOURCE, bd_addr, connect_int); -} -#endif - esp_err_t esp_a2d_sink_connect(esp_bd_addr_t *remote_bda) -// static bt_status_t sink_connect_src(bt_bdaddr_t *bd_addr) { BTIF_TRACE_EVENT("%s\n", __FUNCTION__); CHECK_BTAV_INIT(); @@ -1052,26 +953,6 @@ esp_err_t esp_a2d_sink_connect(esp_bd_addr_t *remote_bda) return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; } -/******************************************************************************* -** -** Function disconnect -** -** Description Tears down the AV signalling channel with the remote headset -** -** Returns bt_status_t -** -*******************************************************************************/ -static bt_status_t disconnect(bt_bdaddr_t *bd_addr) -{ - BTIF_TRACE_EVENT("%s\n", __FUNCTION__); - - CHECK_BTAV_INIT(); - - /* Switch to BTIF context */ - return btif_transfer_context(btif_av_handle_event, BTIF_AV_DISCONNECT_REQ_EVT, - (char *)bd_addr, sizeof(bt_bdaddr_t), NULL); -} - esp_err_t esp_a2d_sink_disconnect(esp_bd_addr_t *remote_bda) { bt_status_t stat; @@ -1109,20 +990,6 @@ static void cleanup(void) btif_av_cb.sm_handle = NULL; } -#if (BTIF_AV_SRC_INCLUDED == TRUE) -static void cleanup_src(void) -{ - BTIF_TRACE_EVENT("%s\n", __FUNCTION__); - - if (bt_av_src_callbacks) { - bt_av_src_callbacks = NULL; - if (bt_av_sink_callbacks == NULL) { - cleanup(); - } - } -} -#endif - void esp_a2d_sink_deinit(void) { BTIF_TRACE_EVENT("%s\n", __FUNCTION__); @@ -1133,25 +1000,6 @@ void esp_a2d_sink_deinit(void) } } -#if (BTIF_AV_SRC_INCLUDED == TRUE) -static const btav_interface_t bt_av_src_interface = { - sizeof(btav_interface_t), - init_src, - src_connect_sink, - disconnect, - cleanup_src, -}; -#endif - -/* -static const btav_interface_t bt_av_sink_interface = { - sizeof(btav_interface_t), - init_sink, - sink_connect_src, - disconnect, - cleanup_sink, -}; -*/ /******************************************************************************* ** ** Function btif_av_get_sm_handle @@ -1288,24 +1136,6 @@ bt_status_t btif_av_sink_execute_service(BOOLEAN b_enable) return BT_STATUS_SUCCESS; } -#if (BTIF_AV_SRC_INCLUDED == TRUE) -/******************************************************************************* -** -** Function btif_av_get_src_interface -** -** Description Get the AV callback interface for A2DP source profile -** -** Returns btav_interface_t -** -*******************************************************************************/ -const btav_interface_t *btif_av_get_src_interface(void) -{ - BTIF_TRACE_EVENT("%s\n", __FUNCTION__); - return &bt_av_src_interface; -} - -#endif - /******************************************************************************* ** ** Function btif_av_is_connected diff --git a/examples/09_a2dp/components/bluedroid_demos/btif/btif_media_task.c b/examples/09_a2dp/components/bluedroid_demos/btif/btif_media_task.c index 2115ba470c..21066a3f90 100644 --- a/examples/09_a2dp/components/bluedroid_demos/btif/btif_media_task.c +++ b/examples/09_a2dp/components/bluedroid_demos/btif/btif_media_task.c @@ -28,18 +28,10 @@ #define LOG_TAG "bt_btif_media" -// #include #include "bt_trace.h" #include #include -// #include -// #include -// #include -// #include -// #include #include -// #include -// #include #include "bt_target.h" #include "fixed_queue.h" @@ -61,7 +53,6 @@ #include "btif_media.h" #include "alarm.h" -// #include "ois/include/log.h" #include "bt_trace.h" #include "thread.h" @@ -69,7 +60,6 @@ #include "sbc_encoder.h" #endif -// #include #include "bt_defs.h" #include "audio_a2dp_hw.h" #include "btif_av.h" @@ -80,7 +70,7 @@ #include "oi_status.h" #endif #include "stdio.h" -// #include + #include "btif_media.h" #include "allocator.h" #include "bt_utils.h" @@ -274,16 +264,9 @@ typedef struct { long long ts_prev_us; } t_stat; -#if (BTIF_AV_SRC_INCLUDED == TRUE) -static UINT64 last_frame_us = 0; -#endif /* #if (BTIF_AV_SRC_INCLUDED == TRUE) */ - static void btif_a2dp_data_cb(tUIPC_CH_ID ch_id, tUIPC_EVENT event); static void btif_a2dp_ctrl_cb(tUIPC_CH_ID ch_id, tUIPC_EVENT event); -#if (BTIF_AV_SRC_INCLUDED == TRUE) -static void btif_a2dp_encoder_update(void); -#endif /* #if (BTIF_AV_SRC_INCLUDED == TRUE) */ #if (BTA_AV_SINK_INCLUDED == TRUE) extern OI_STATUS OI_CODEC_SBC_DecodeFrame(OI_CODEC_SBC_DECODER_CONTEXT *context, @@ -313,17 +296,6 @@ static void btif_media_task_handle_inc_media(tBT_SBC_HDR *p_msg); #endif #if (BTA_AV_INCLUDED == TRUE) -#if (BTIF_AV_SRC_INCLUDED == TRUE) -static void btif_media_send_aa_frame(void); -static void btif_media_task_feeding_state_reset(void); -static void btif_media_task_aa_start_tx(void); -static void btif_media_task_aa_stop_tx(void); -static void btif_media_task_enc_init(BT_HDR *p_msg); -static void btif_media_task_enc_update(BT_HDR *p_msg); -static void btif_media_task_audio_feeding_init(BT_HDR *p_msg); -static void btif_media_task_aa_tx_flush(BT_HDR *p_msg); -static void btif_media_aa_prep_2_send(UINT8 nb_frame); -#endif /* (BTIF_AV_SRC_INCLUDED == TRUE) */ #if (BTA_AV_SINK_INCLUDED == TRUE) static void btif_media_task_aa_handle_decoder_reset(BT_HDR *p_msg); static void btif_media_task_aa_handle_clear_track(void); @@ -332,9 +304,7 @@ static void btif_media_task_aa_handle_start_decoding(void); #endif BOOLEAN btif_media_task_clear_track(void); static void btif_media_task_handler(void *arg); -#if (BTIF_AV_SRC_INCLUDED == TRUE) -static void btif_media_task_aa_handle_timer(UNUSED_ATTR void *context); -#endif + static void btif_media_task_avk_handle_timer(UNUSED_ATTR void *context); static void btif_media_thread_init(UNUSED_ATTR void *context); static void btif_media_thread_cleanup(UNUSED_ATTR void *context); @@ -375,23 +345,6 @@ BOOLEAN btif_hf_is_call_idle(void) ** Misc helper functions *****************************************************************************/ -#if (BTIF_AV_SRC_INCLUDED == TRUE) -static UINT64 time_now_us() -{ - // TODO: implement this function - return 0; -} - -static void log_tstamps_us(char *comment) -{ - static UINT64 prev_us = 0; - const UINT64 now_us = time_now_us(); - APPL_TRACE_DEBUG("[%s] ts %08llu, diff : %08llu, queue sz %d\n", comment, now_us, now_us - prev_us, - GKI_queue_length(&btif_media_cb.TxAaQ)); - prev_us = now_us; -} -#endif /* #if (BTIF_AV_SRC_INCLUDED == TRUE) */ - UNUSED_ATTR static const char *dump_media_event(UINT16 event) { switch (event) { @@ -620,15 +573,6 @@ static void btif_a2dp_data_cb(tUIPC_CH_ID ch_id, tUIPC_EVENT event) UIPC_Ioctl(UIPC_CH_ID_AV_AUDIO, UIPC_SET_READ_POLL_TMO, (void *)A2DP_DATA_READ_POLL_MS); -#if (BTIF_AV_SRC_INCLUDED == TRUE) - if (btif_media_cb.peer_sep == AVDT_TSEP_SNK) { - /* Start the media task to encode SBC */ - btif_media_task_start_aa_req(); - - /* make sure we update any changed sbc encoder params */ - btif_a2dp_encoder_update(); - } -#endif /* BTIF_AV_SRC_INCLUDED == TRUE */ btif_media_cb.data_channel_open = TRUE; /* ack back when media task is fully started */ @@ -650,105 +594,6 @@ static void btif_a2dp_data_cb(tUIPC_CH_ID ch_id, tUIPC_EVENT event) /***************************************************************************** ** BTIF ADAPTATION *****************************************************************************/ -#if (BTIF_AV_SRC_INCLUDED == TRUE) -static UINT16 btif_media_task_get_sbc_rate(void) -{ - UINT16 rate = DEFAULT_SBC_BITRATE; - - /* restrict bitrate if a2dp link is non-edr */ - if (!btif_av_is_peer_edr()) { - rate = BTIF_A2DP_NON_EDR_MAX_RATE; - APPL_TRACE_DEBUG("non-edr a2dp sink detected, restrict rate to %d\n", rate); - } - - return rate; -} - -static void btif_a2dp_encoder_init(void) -{ - UINT16 minmtu; - tBTIF_MEDIA_INIT_AUDIO msg; - tA2D_SBC_CIE sbc_config; - - /* lookup table for converting channel mode */ - UINT16 codec_mode_tbl[5] = { SBC_JOINT_STEREO, SBC_STEREO, SBC_DUAL, 0, SBC_MONO }; - - /* lookup table for converting number of blocks */ - UINT16 codec_block_tbl[5] = { 16, 12, 8, 0, 4 }; - - /* lookup table to convert freq */ - UINT16 freq_block_tbl[5] = { SBC_sf48000, SBC_sf44100, SBC_sf32000, 0, SBC_sf16000 }; - - APPL_TRACE_DEBUG("btif_a2dp_encoder_init"); - - /* Retrieve the current SBC configuration (default if currently not used) */ - bta_av_co_audio_get_sbc_config(&sbc_config, &minmtu); - msg.NumOfSubBands = (sbc_config.num_subbands == A2D_SBC_IE_SUBBAND_4) ? 4 : 8; - msg.NumOfBlocks = codec_block_tbl[sbc_config.block_len >> 5]; - msg.AllocationMethod = (sbc_config.alloc_mthd == A2D_SBC_IE_ALLOC_MD_L) ? SBC_LOUDNESS : SBC_SNR; - msg.ChannelMode = codec_mode_tbl[sbc_config.ch_mode >> 1]; - msg.SamplingFreq = freq_block_tbl[sbc_config.samp_freq >> 5]; - msg.MtuSize = minmtu; - - APPL_TRACE_EVENT("msg.ChannelMode %x\n", msg.ChannelMode); - - /* Init the media task to encode SBC properly */ - btif_media_task_enc_init_req(&msg); -} - -static void btif_a2dp_encoder_update(void) -{ - UINT16 minmtu; - tA2D_SBC_CIE sbc_config; - tBTIF_MEDIA_UPDATE_AUDIO msg; - UINT8 pref_min; - UINT8 pref_max; - - APPL_TRACE_DEBUG("btif_a2dp_encoder_update"); - - /* Retrieve the current SBC configuration (default if currently not used) */ - bta_av_co_audio_get_sbc_config(&sbc_config, &minmtu); - - APPL_TRACE_DEBUG("btif_a2dp_encoder_update: Common min_bitpool:%d(0x%x) max_bitpool:%d(0x%x)\n", - sbc_config.min_bitpool, sbc_config.min_bitpool, - sbc_config.max_bitpool, sbc_config.max_bitpool); - - if (sbc_config.min_bitpool > sbc_config.max_bitpool) { - APPL_TRACE_ERROR("btif_a2dp_encoder_update: ERROR btif_a2dp_encoder_update min_bitpool > max_bitpool"); - } - - /* check if remote sink has a preferred bitpool range */ - if (bta_av_co_get_remote_bitpool_pref(&pref_min, &pref_max) == TRUE) { - /* adjust our preferred bitpool with the remote preference if within - our capable range */ - - if (pref_min < sbc_config.min_bitpool) { - pref_min = sbc_config.min_bitpool; - } - - if (pref_max > sbc_config.max_bitpool) { - pref_max = sbc_config.max_bitpool; - } - - msg.MinBitPool = pref_min; - msg.MaxBitPool = pref_max; - - if ((pref_min != sbc_config.min_bitpool) || (pref_max != sbc_config.max_bitpool)) { - APPL_TRACE_EVENT("## adjusted our bitpool range to peer pref [%d:%d] ##\n", - pref_min, pref_max); - } - } else { - msg.MinBitPool = sbc_config.min_bitpool; - msg.MaxBitPool = sbc_config.max_bitpool; - } - - msg.MinMtuSize = minmtu; - - /* Update the media task to encode SBC properly */ - btif_media_task_enc_update_req(&msg); -} - -#endif /* #if (BTIF_AV_SRC_INCLUDED == TRUE) */ static void btif_media_task_post(uint32_t sig) { @@ -775,11 +620,6 @@ static void btif_media_task_handler(void *arg) case SIG_MEDIA_TASK_AVK_ALARM_TO: btif_media_task_avk_handle_timer(NULL); break; -#if (BTIF_AV_SRC_INCLUDED == TRUE) - case SIG_MEDIA_TASK_AA_ALARM_TO: - btif_media_task_aa_handle_timer(NULL); -#endif - break; case SIG_MEDIA_TASK_CMD_READY: fixed_queue_process(btif_media_cmd_msg_queue); break; @@ -908,19 +748,6 @@ void btif_a2dp_setup_codec(void) media_feeding.format = BTIF_AV_CODEC_PCM; if (bta_av_co_audio_set_codec(&media_feeding, &status)) { -#if (BTIF_AV_SRC_INCLUDED == TRUE) - - tBTIF_MEDIA_INIT_AUDIO_FEEDING mfeed; - - /* Init the encoding task */ - btif_a2dp_encoder_init(); - - /* Build the media task configuration */ - mfeed.feeding = media_feeding; - mfeed.feeding_mode = BTIF_AV_FEEDING_ASYNCHRONOUS; - /* Send message to Media task to configure transcoding */ - btif_media_task_audio_feeding_init_req(&mfeed); -#endif /* #if (BTIF_AV_SRC_INCLUDED == TRUE) */ } GKI_enable(); @@ -940,12 +767,6 @@ void btif_a2dp_setup_codec(void) void btif_a2dp_on_idle(void) { APPL_TRACE_EVENT("## ON A2DP IDLE ##\n"); -#if (BTIF_AV_SRC_INCLUDED == TRUE) - if (btif_media_cb.peer_sep == AVDT_TSEP_SNK) { - /* Make sure media task is stopped */ - btif_media_task_stop_aa_req(); - } -#endif /* #if (BTIF_AV_SRC_INCLUDED == TRUE) */ bta_av_co_init(); #if (BTA_AV_SINK_INCLUDED == TRUE) @@ -1125,14 +946,6 @@ void btif_a2dp_on_stopped(tBTA_AV_SUSPEND *p_av) } } -#if (BTIF_AV_SRC_INCLUDED == TRUE) - /* ensure tx frames are immediately suspended */ - btif_media_cb.tx_flush = 1; - - /* request to stop media task */ - btif_media_task_aa_tx_flush_req(); - btif_media_task_stop_aa_req(); -#endif /* #if (BTIF_AV_SRC_INCLUDED == TRUE) */ /* once stream is fully stopped we will ack back */ } @@ -1165,13 +978,6 @@ void btif_a2dp_on_suspended(tBTA_AV_SUSPEND *p_av) } /* once stream is fully stopped we will ack back */ -#if (BTIF_AV_SRC_INCLUDED == TRUE) - /* ensure tx frames are immediately flushed */ - btif_media_cb.tx_flush = 1; - - /* stop timer tick */ - btif_media_task_stop_aa_req(); -#endif /* #if (BTIF_AV_SRC_INCLUDED == TRUE) */ } /* when true media task discards any rx frames */ @@ -1181,14 +987,6 @@ void btif_a2dp_set_rx_flush(BOOLEAN enable) btif_media_cb.rx_flush = enable; } -#if (BTIF_AV_SRC_INCLUDED == TRUE) -/* when true media task discards any tx frames */ -void btif_a2dp_set_tx_flush(BOOLEAN enable) -{ - APPL_TRACE_EVENT("## DROP TX %d ##\n", enable); - btif_media_cb.tx_flush = enable; -} -#endif /* #if (BTIF_AV_SRC_INCLUDED == TRUE) */ #if (BTA_AV_SINK_INCLUDED == TRUE) static void btif_media_task_avk_handle_timer(UNUSED_ATTR void *context) { @@ -1244,35 +1042,6 @@ static void btif_media_task_avk_handle_timer(UNUSED_ATTR void *context) static void btif_media_task_avk_handle_timer(UNUSED_ATTR void *context) {} #endif -#if (BTIF_AV_SRC_INCLUDED == TRUE) -static void btif_media_task_aa_handle_timer(UNUSED_ATTR void *context) -{ - log_tstamps_us("media task tx timer"); - -#if (BTA_AV_INCLUDED == TRUE) - if (btif_media_cb.is_tx_timer == TRUE) { - btif_media_send_aa_frame(); - } else { - APPL_TRACE_ERROR("ERROR Media task Scheduled after Suspend"); - } -#endif -} -#endif /* #if (BTIF_AV_SRC_INCLUDED == TRUE) */ - -#if (BTA_AV_INCLUDED == TRUE) -#if (BTIF_AV_SRC_INCLUDED == TRUE) -static void btif_media_task_aa_handle_uipc_rx_rdy(void) -{ - /* process all the UIPC data */ - btif_media_aa_prep_2_send(0xFF); - - /* send it */ - LOG_VERBOSE("btif_media_task_aa_handle_uipc_rx_rdy calls bta_av_ci_src_data_ready"); - bta_av_ci_src_data_ready(BTA_AV_CHNL_AUDIO); -} -#endif /* #if (BTIF_AV_SRC_INCLUDED == TRUE) */ -#endif - static void btif_media_thread_init(UNUSED_ATTR void *context) { memset(&btif_media_cb, 0, sizeof(btif_media_cb)); @@ -1348,29 +1117,6 @@ static void btif_media_thread_handle_cmd(fixed_queue_t *queue) switch (p_msg->event) { #if (BTA_AV_INCLUDED == TRUE) -#if (BTIF_AV_SRC_INCLUDED == TRUE) - case BTIF_MEDIA_START_AA_TX: - btif_media_task_aa_start_tx(); - break; - case BTIF_MEDIA_STOP_AA_TX: - btif_media_task_aa_stop_tx(); - break; - case BTIF_MEDIA_SBC_ENC_INIT: - btif_media_task_enc_init(p_msg); - break; - case BTIF_MEDIA_SBC_ENC_UPDATE: - btif_media_task_enc_update(p_msg); - break; - case BTIF_MEDIA_AUDIO_FEEDING_INIT: - btif_media_task_audio_feeding_init(p_msg); - break; - case BTIF_MEDIA_FLUSH_AA_TX: - btif_media_task_aa_tx_flush(p_msg); - break; - case BTIF_MEDIA_UIPC_RX_RDY: - btif_media_task_aa_handle_uipc_rx_rdy(); - break; -#endif /* #if (BTIF_AV_SRC_INCLUDED == TRUE) */ case BTIF_MEDIA_AUDIO_SINK_CFG_UPDATE: #if (BTA_AV_SINK_INCLUDED == TRUE) LOG_ERROR("SINK_CFG_UPDATE: xx\n"); @@ -1454,139 +1200,7 @@ static void btif_media_task_handle_inc_media(tBT_SBC_HDR *p_msg) #endif #if (BTA_AV_INCLUDED == TRUE) -#if (BTIF_AV_SRC_INCLUDED == TRUE) -/******************************************************************************* - ** - ** Function btif_media_task_enc_init_req - ** - ** Description - ** - ** Returns TRUE is success - ** - *******************************************************************************/ -BOOLEAN btif_media_task_enc_init_req(tBTIF_MEDIA_INIT_AUDIO *p_msg) -{ - tBTIF_MEDIA_INIT_AUDIO *p_buf; - if (NULL == (p_buf = GKI_getbuf(sizeof(tBTIF_MEDIA_INIT_AUDIO)))) { - return FALSE; - } - - memcpy(p_buf, p_msg, sizeof(tBTIF_MEDIA_INIT_AUDIO)); - p_buf->hdr.event = BTIF_MEDIA_SBC_ENC_INIT; - - fixed_queue_enqueue(btif_media_cmd_msg_queue, p_buf); - btif_media_task_post(SIG_MEDIA_TASK_CMD_READY); - return TRUE; -} - -/******************************************************************************* - ** - ** Function btif_media_task_enc_update_req - ** - ** Description - ** - ** Returns TRUE is success - ** - *******************************************************************************/ -BOOLEAN btif_media_task_enc_update_req(tBTIF_MEDIA_UPDATE_AUDIO *p_msg) -{ - tBTIF_MEDIA_UPDATE_AUDIO *p_buf; - if (NULL == (p_buf = GKI_getbuf(sizeof(tBTIF_MEDIA_UPDATE_AUDIO)))) { - return FALSE; - } - - memcpy(p_buf, p_msg, sizeof(tBTIF_MEDIA_UPDATE_AUDIO)); - p_buf->hdr.event = BTIF_MEDIA_SBC_ENC_UPDATE; - - fixed_queue_enqueue(btif_media_cmd_msg_queue, p_buf); - btif_media_task_post(SIG_MEDIA_TASK_CMD_READY); - return TRUE; -} - -/******************************************************************************* - ** - ** Function btif_media_task_audio_feeding_init_req - ** - ** Description - ** - ** Returns TRUE is success - ** - *******************************************************************************/ -BOOLEAN btif_media_task_audio_feeding_init_req(tBTIF_MEDIA_INIT_AUDIO_FEEDING *p_msg) -{ - tBTIF_MEDIA_INIT_AUDIO_FEEDING *p_buf; - if (NULL == (p_buf = GKI_getbuf(sizeof(tBTIF_MEDIA_INIT_AUDIO_FEEDING)))) { - return FALSE; - } - - memcpy(p_buf, p_msg, sizeof(tBTIF_MEDIA_INIT_AUDIO_FEEDING)); - p_buf->hdr.event = BTIF_MEDIA_AUDIO_FEEDING_INIT; - - fixed_queue_enqueue(btif_media_cmd_msg_queue, p_buf); - btif_media_task_post(SIG_MEDIA_TASK_CMD_READY); - return TRUE; -} - -/******************************************************************************* - ** - ** Function btif_media_task_start_aa_req - ** - ** Description - ** - ** Returns TRUE is success - ** - *******************************************************************************/ -BOOLEAN btif_media_task_start_aa_req(void) -{ - BT_HDR *p_buf; - if (NULL == (p_buf = GKI_getbuf(sizeof(BT_HDR)))) { - APPL_TRACE_EVENT("GKI failed"); - return FALSE; - } - - p_buf->event = BTIF_MEDIA_START_AA_TX; - - fixed_queue_enqueue(btif_media_cmd_msg_queue, p_buf); - btif_media_task_post(SIG_MEDIA_TASK_CMD_READY); - return TRUE; -} -/******************************************************************************* - ** - ** Function btif_media_task_stop_aa_req - ** - ** Description - ** - ** Returns TRUE is success - ** - *******************************************************************************/ -BOOLEAN btif_media_task_stop_aa_req(void) -{ - BT_HDR *p_buf; - if (NULL == (p_buf = GKI_getbuf(sizeof(BT_HDR)))) { - return FALSE; - } - - p_buf->event = BTIF_MEDIA_STOP_AA_TX; - - /* - * Explicitly check whether the btif_media_cmd_msg_queue is not NULL to - * avoid a race condition during shutdown of the Bluetooth stack. - * This race condition is triggered when A2DP audio is streaming on - * shutdown: - * "btif_a2dp_on_stopped() -> btif_media_task_stop_aa_req()" is called - * to stop the particular audio stream, and this happens right after - * the "cleanup() -> btif_a2dp_stop_media_task()" processing during - * the shutdown of the Bluetooth stack. - */ - if (btif_media_cmd_msg_queue != NULL) { - fixed_queue_enqueue(btif_media_cmd_msg_queue, p_buf); - btif_media_task_post(SIG_MEDIA_TASK_CMD_READY); - } - - return TRUE; -} -#endif /* #if (BTIF_AV_SRC_INCLUDED == TRUE) */ /******************************************************************************* ** ** Function btif_media_task_aa_rx_flush_req @@ -1615,45 +1229,6 @@ BOOLEAN btif_media_task_aa_rx_flush_req(void) return TRUE; } -#if (BTIF_AV_SRC_INCLUDED == TRUE) -/******************************************************************************* - ** - ** Function btif_media_task_aa_tx_flush_req - ** - ** Description - ** - ** Returns TRUE is success - ** - *******************************************************************************/ -BOOLEAN btif_media_task_aa_tx_flush_req(void) -{ - BT_HDR *p_buf = GKI_getbuf(sizeof(BT_HDR)); - - if (p_buf == NULL) { - return FALSE; - } - - p_buf->event = BTIF_MEDIA_FLUSH_AA_TX; - - /* - * Explicitly check whether the btif_media_cmd_msg_queue is not NULL to - * avoid a race condition during shutdown of the Bluetooth stack. - * This race condition is triggered when A2DP audio is streaming on - * shutdown: - * "btif_a2dp_on_stopped() -> btif_media_task_aa_tx_flush_req()" is called - * to stop the particular audio stream, and this happens right after - * the "cleanup() -> btif_a2dp_stop_media_task()" processing during - * the shutdown of the Bluetooth stack. - */ - if (btif_media_cmd_msg_queue != NULL) { - fixed_queue_enqueue(btif_media_cmd_msg_queue, p_buf); - btif_media_task_post(SIG_MEDIA_TASK_CMD_READY); - } - - return TRUE; -} -#endif /* #if (BTIF_AV_SRC_INCLUDED == TRUE) */ - /******************************************************************************* ** ** Function btif_media_task_aa_rx_flush @@ -1671,322 +1246,6 @@ static void btif_media_task_aa_rx_flush(void) btif_media_flush_q(&(btif_media_cb.RxSbcQ)); } -#if (BTIF_AV_SRC_INCLUDED == TRUE) -/******************************************************************************* - ** - ** Function btif_media_task_aa_tx_flush - ** - ** Description - ** - ** Returns void - ** - *******************************************************************************/ -static void btif_media_task_aa_tx_flush(BT_HDR *p_msg) -{ - UNUSED(p_msg); - - /* Flush all enqueued GKI music buffers (encoded) */ - APPL_TRACE_DEBUG("btif_media_task_aa_tx_flush"); - - btif_media_cb.media_feeding_state.pcm.counter = 0; - btif_media_cb.media_feeding_state.pcm.aa_feed_residue = 0; - - btif_media_flush_q(&(btif_media_cb.TxAaQ)); - - UIPC_Ioctl(UIPC_CH_ID_AV_AUDIO, UIPC_REQ_RX_FLUSH, NULL); -} - -/******************************************************************************* - ** - ** Function btif_media_task_enc_init - ** - ** Description Initialize encoding task - ** - ** Returns void - ** - *******************************************************************************/ -static void btif_media_task_enc_init(BT_HDR *p_msg) -{ - tBTIF_MEDIA_INIT_AUDIO *pInitAudio = (tBTIF_MEDIA_INIT_AUDIO *) p_msg; - - APPL_TRACE_DEBUG("btif_media_task_enc_init"); - - btif_media_cb.timestamp = 0; - - /* SBC encoder config (enforced even if not used) */ - btif_media_cb.encoder.s16ChannelMode = pInitAudio->ChannelMode; - btif_media_cb.encoder.s16NumOfSubBands = pInitAudio->NumOfSubBands; - btif_media_cb.encoder.s16NumOfBlocks = pInitAudio->NumOfBlocks; - btif_media_cb.encoder.s16AllocationMethod = pInitAudio->AllocationMethod; - btif_media_cb.encoder.s16SamplingFreq = pInitAudio->SamplingFreq; - - btif_media_cb.encoder.u16BitRate = btif_media_task_get_sbc_rate(); - - /* Default transcoding is PCM to SBC, modified by feeding configuration */ - btif_media_cb.TxTranscoding = BTIF_MEDIA_TRSCD_PCM_2_SBC; - btif_media_cb.TxAaMtuSize = ((BTIF_MEDIA_AA_BUF_SIZE - BTIF_MEDIA_AA_SBC_OFFSET - sizeof(BT_HDR)) - < pInitAudio->MtuSize) ? (BTIF_MEDIA_AA_BUF_SIZE - BTIF_MEDIA_AA_SBC_OFFSET - - sizeof(BT_HDR)) : pInitAudio->MtuSize; - - APPL_TRACE_EVENT("btif_media_task_enc_init busy %d, mtu %d, peer mtu %d\n", - btif_media_cb.busy_level, btif_media_cb.TxAaMtuSize, pInitAudio->MtuSize); - APPL_TRACE_EVENT(" ch mode %d, subnd %d, nb blk %d, alloc %d, rate %d, freq %d\n", - btif_media_cb.encoder.s16ChannelMode, btif_media_cb.encoder.s16NumOfSubBands, - btif_media_cb.encoder.s16NumOfBlocks, - btif_media_cb.encoder.s16AllocationMethod, btif_media_cb.encoder.u16BitRate, - btif_media_cb.encoder.s16SamplingFreq); - - /* Reset entirely the SBC encoder */ - SBC_Encoder_Init(&(btif_media_cb.encoder)); - APPL_TRACE_DEBUG("btif_media_task_enc_init bit pool %d\n", btif_media_cb.encoder.s16BitPool); -} - -/******************************************************************************* - ** - ** Function btif_media_task_enc_update - ** - ** Description Update encoding task - ** - ** Returns void - ** - *******************************************************************************/ -static void btif_media_task_enc_update(BT_HDR *p_msg) -{ - tBTIF_MEDIA_UPDATE_AUDIO *pUpdateAudio = (tBTIF_MEDIA_UPDATE_AUDIO *) p_msg; - SBC_ENC_PARAMS *pstrEncParams = &btif_media_cb.encoder; - UINT16 s16SamplingFreq; - SINT16 s16BitPool = 0; - SINT16 s16BitRate; - SINT16 s16FrameLen; - UINT8 protect = 0; - - APPL_TRACE_DEBUG("btif_media_task_enc_update : minmtu %d, maxbp %d minbp %d\n", - pUpdateAudio->MinMtuSize, pUpdateAudio->MaxBitPool, pUpdateAudio->MinBitPool); - - /* Only update the bitrate and MTU size while timer is running to make sure it has been initialized */ - //if (btif_media_cb.is_tx_timer) - { - btif_media_cb.TxAaMtuSize = ((BTIF_MEDIA_AA_BUF_SIZE - - BTIF_MEDIA_AA_SBC_OFFSET - sizeof(BT_HDR)) - < pUpdateAudio->MinMtuSize) ? (BTIF_MEDIA_AA_BUF_SIZE - BTIF_MEDIA_AA_SBC_OFFSET - - sizeof(BT_HDR)) : pUpdateAudio->MinMtuSize; - - /* Set the initial target bit rate */ - pstrEncParams->u16BitRate = btif_media_task_get_sbc_rate(); - - if (pstrEncParams->s16SamplingFreq == SBC_sf16000) { - s16SamplingFreq = 16000; - } else if (pstrEncParams->s16SamplingFreq == SBC_sf32000) { - s16SamplingFreq = 32000; - } else if (pstrEncParams->s16SamplingFreq == SBC_sf44100) { - s16SamplingFreq = 44100; - } else { - s16SamplingFreq = 48000; - } - - do { - if (pstrEncParams->s16NumOfBlocks == 0 || pstrEncParams->s16NumOfSubBands == 0 - || pstrEncParams->s16NumOfChannels == 0) { - APPL_TRACE_ERROR("btif_media_task_enc_update() - Avoiding division by zero..."); - APPL_TRACE_ERROR("btif_media_task_enc_update() - block=%d, subBands=%d, channels=%d\n", - pstrEncParams->s16NumOfBlocks, pstrEncParams->s16NumOfSubBands, - pstrEncParams->s16NumOfChannels); - break; - } - - if ((pstrEncParams->s16ChannelMode == SBC_JOINT_STEREO) || - (pstrEncParams->s16ChannelMode == SBC_STEREO) ) { - s16BitPool = (SINT16)( (pstrEncParams->u16BitRate * - pstrEncParams->s16NumOfSubBands * 1000 / s16SamplingFreq) - - ( (32 + (4 * pstrEncParams->s16NumOfSubBands * - pstrEncParams->s16NumOfChannels) - + ( (pstrEncParams->s16ChannelMode - 2) * - pstrEncParams->s16NumOfSubBands ) ) - / pstrEncParams->s16NumOfBlocks) ); - - s16FrameLen = 4 + (4 * pstrEncParams->s16NumOfSubBands * - pstrEncParams->s16NumOfChannels) / 8 - + ( ((pstrEncParams->s16ChannelMode - 2) * - pstrEncParams->s16NumOfSubBands) - + (pstrEncParams->s16NumOfBlocks * s16BitPool) ) / 8; - - s16BitRate = (8 * s16FrameLen * s16SamplingFreq) - / (pstrEncParams->s16NumOfSubBands * - pstrEncParams->s16NumOfBlocks * 1000); - - if (s16BitRate > pstrEncParams->u16BitRate) { - s16BitPool--; - } - - if (pstrEncParams->s16NumOfSubBands == 8) { - s16BitPool = (s16BitPool > 255) ? 255 : s16BitPool; - } else { - s16BitPool = (s16BitPool > 128) ? 128 : s16BitPool; - } - } else { - s16BitPool = (SINT16)( ((pstrEncParams->s16NumOfSubBands * - pstrEncParams->u16BitRate * 1000) - / (s16SamplingFreq * pstrEncParams->s16NumOfChannels)) - - ( ( (32 / pstrEncParams->s16NumOfChannels) + - (4 * pstrEncParams->s16NumOfSubBands) ) - / pstrEncParams->s16NumOfBlocks ) ); - - pstrEncParams->s16BitPool = (s16BitPool > - (16 * pstrEncParams->s16NumOfSubBands)) - ? (16 * pstrEncParams->s16NumOfSubBands) : s16BitPool; - } - - if (s16BitPool < 0) { - s16BitPool = 0; - } - - APPL_TRACE_EVENT("bitpool candidate : %d (%d kbps)\n", - s16BitPool, pstrEncParams->u16BitRate); - - if (s16BitPool > pUpdateAudio->MaxBitPool) { - APPL_TRACE_DEBUG("btif_media_task_enc_update computed bitpool too large (%d)\n", - s16BitPool); - /* Decrease bitrate */ - btif_media_cb.encoder.u16BitRate -= BTIF_MEDIA_BITRATE_STEP; - /* Record that we have decreased the bitrate */ - protect |= 1; - } else if (s16BitPool < pUpdateAudio->MinBitPool) { - APPL_TRACE_WARNING("btif_media_task_enc_update computed bitpool too small (%d)\n", s16BitPool); - - /* Increase bitrate */ - UINT16 previous_u16BitRate = btif_media_cb.encoder.u16BitRate; - btif_media_cb.encoder.u16BitRate += BTIF_MEDIA_BITRATE_STEP; - /* Record that we have increased the bitrate */ - protect |= 2; - /* Check over-flow */ - if (btif_media_cb.encoder.u16BitRate < previous_u16BitRate) { - protect |= 3; - } - } else { - break; - } - /* In case we have already increased and decreased the bitrate, just stop */ - if (protect == 3) { - APPL_TRACE_ERROR("btif_media_task_enc_update could not find bitpool in range"); - break; - } - } while (1); - - /* Finally update the bitpool in the encoder structure */ - pstrEncParams->s16BitPool = s16BitPool; - - APPL_TRACE_DEBUG("btif_media_task_enc_update final bit rate %d, final bit pool %d\n", - btif_media_cb.encoder.u16BitRate, btif_media_cb.encoder.s16BitPool); - - /* make sure we reinitialize encoder with new settings */ - SBC_Encoder_Init(&(btif_media_cb.encoder)); - } -} - -/******************************************************************************* - ** - ** Function btif_media_task_pcm2sbc_init - ** - ** Description Init encoding task for PCM to SBC according to feeding - ** - ** Returns void - ** - *******************************************************************************/ -static void btif_media_task_pcm2sbc_init(tBTIF_MEDIA_INIT_AUDIO_FEEDING *p_feeding) -{ - BOOLEAN reconfig_needed = FALSE; - - APPL_TRACE_DEBUG("PCM feeding:"); - APPL_TRACE_DEBUG("sampling_freq:%d\n", p_feeding->feeding.cfg.pcm.sampling_freq); - APPL_TRACE_DEBUG("num_channel:%d\n", p_feeding->feeding.cfg.pcm.num_channel); - APPL_TRACE_DEBUG("bit_per_sample:%d\n", p_feeding->feeding.cfg.pcm.bit_per_sample); - - /* Check the PCM feeding sampling_freq */ - switch (p_feeding->feeding.cfg.pcm.sampling_freq) { - case 8000: - case 12000: - case 16000: - case 24000: - case 32000: - case 48000: - /* For these sampling_freq the AV connection must be 48000 */ - if (btif_media_cb.encoder.s16SamplingFreq != SBC_sf48000) { - /* Reconfiguration needed at 48000 */ - APPL_TRACE_DEBUG("SBC Reconfiguration needed at 48000"); - btif_media_cb.encoder.s16SamplingFreq = SBC_sf48000; - reconfig_needed = TRUE; - } - break; - - case 11025: - case 22050: - case 44100: - /* For these sampling_freq the AV connection must be 44100 */ - if (btif_media_cb.encoder.s16SamplingFreq != SBC_sf44100) { - /* Reconfiguration needed at 44100 */ - APPL_TRACE_DEBUG("SBC Reconfiguration needed at 44100"); - btif_media_cb.encoder.s16SamplingFreq = SBC_sf44100; - reconfig_needed = TRUE; - } - break; - default: - APPL_TRACE_DEBUG("Feeding PCM sampling_freq unsupported"); - break; - } - - /* Some AV Headsets do not support Mono => always ask for Stereo */ - if (btif_media_cb.encoder.s16ChannelMode == SBC_MONO) { - APPL_TRACE_DEBUG("SBC Reconfiguration needed in Stereo"); - btif_media_cb.encoder.s16ChannelMode = SBC_JOINT_STEREO; - reconfig_needed = TRUE; - } - - if (reconfig_needed != FALSE) { - APPL_TRACE_DEBUG("btif_media_task_pcm2sbc_init :: mtu %d\n", btif_media_cb.TxAaMtuSize); - APPL_TRACE_DEBUG("ch mode %d, nbsubd %d, nb %d, alloc %d, rate %d, freq %d\n", - btif_media_cb.encoder.s16ChannelMode, - btif_media_cb.encoder.s16NumOfSubBands, btif_media_cb.encoder.s16NumOfBlocks, - btif_media_cb.encoder.s16AllocationMethod, btif_media_cb.encoder.u16BitRate, - btif_media_cb.encoder.s16SamplingFreq); - SBC_Encoder_Init(&(btif_media_cb.encoder)); - } else { - APPL_TRACE_DEBUG("btif_media_task_pcm2sbc_init no SBC reconfig needed"); - } -} - -/******************************************************************************* - ** - ** Function btif_media_task_audio_feeding_init - ** - ** Description Initialize the audio path according to the feeding format - ** - ** Returns void - ** - *******************************************************************************/ -static void btif_media_task_audio_feeding_init(BT_HDR *p_msg) -{ - tBTIF_MEDIA_INIT_AUDIO_FEEDING *p_feeding = (tBTIF_MEDIA_INIT_AUDIO_FEEDING *) p_msg; - - APPL_TRACE_DEBUG("btif_media_task_audio_feeding_init format:%d\n", p_feeding->feeding.format); - - /* Save Media Feeding information */ - btif_media_cb.feeding_mode = p_feeding->feeding_mode; - btif_media_cb.media_feeding = p_feeding->feeding; - - /* Handle different feeding formats */ - switch (p_feeding->feeding.format) { - case BTIF_AV_CODEC_PCM: - btif_media_cb.TxTranscoding = BTIF_MEDIA_TRSCD_PCM_2_SBC; - btif_media_task_pcm2sbc_init(p_feeding); - break; - - default : - APPL_TRACE_ERROR("unknown feeding format %d\n", p_feeding->feeding.format); - break; - } -} - -#endif /* #if (BTIF_AV_SRC_INCLUDED == TRUE) */ int btif_a2dp_get_track_frequency(UINT8 frequency) { int freq = 48000; @@ -2196,175 +1455,6 @@ static void btif_media_task_aa_handle_decoder_reset(BT_HDR *p_msg) } #endif -#if (BTIF_AV_SRC_INCLUDED == TRUE) -/******************************************************************************* - ** - ** Function btif_media_task_feeding_state_reset - ** - ** Description Reset the media feeding state - ** - ** Returns void - ** - *******************************************************************************/ -static void btif_media_task_feeding_state_reset(void) -{ - /* By default, just clear the entire state */ - memset(&btif_media_cb.media_feeding_state, 0, sizeof(btif_media_cb.media_feeding_state)); - - if (btif_media_cb.TxTranscoding == BTIF_MEDIA_TRSCD_PCM_2_SBC) { - btif_media_cb.media_feeding_state.pcm.bytes_per_tick = - (btif_media_cb.media_feeding.cfg.pcm.sampling_freq * - btif_media_cb.media_feeding.cfg.pcm.bit_per_sample / 8 * - btif_media_cb.media_feeding.cfg.pcm.num_channel * - BTIF_MEDIA_TIME_TICK) / 1000; - - APPL_TRACE_WARNING("pcm bytes per tick %d\n", - (int)btif_media_cb.media_feeding_state.pcm.bytes_per_tick); - } -} - -static void btif_media_task_alarm_cb(UNUSED_ATTR void *context) -{ - btif_media_task_post(SIG_MEDIA_TASK_AA_ALARM_TO); -} - -/******************************************************************************* - ** - ** Function btif_media_task_aa_start_tx - ** - ** Description Start media task encoding - ** - ** Returns void - ** - *******************************************************************************/ -static void btif_media_task_aa_start_tx(void) -{ - APPL_TRACE_DEBUG("btif_media_task_aa_start_tx is timer %d, feeding mode %d\n", - btif_media_cb.is_tx_timer, btif_media_cb.feeding_mode); - - /* Use a timer to poll the UIPC, get rid of the UIPC call back */ - // UIPC_Ioctl(UIPC_CH_ID_AV_AUDIO, UIPC_REG_CBACK, NULL); - - btif_media_cb.is_tx_timer = TRUE; - last_frame_us = 0; - - /* Reset the media feeding state */ - btif_media_task_feeding_state_reset(); - - APPL_TRACE_EVENT("starting timer %dms\n", BTIF_MEDIA_TIME_TICK); - - assert(btif_media_cb.media_alarm == NULL); - - btif_media_cb.media_alarm = osi_alarm_new("media_alarm\n", btif_media_task_alarm_cb, NULL, BTIF_MEDIA_TIME_TICK, true); - if (!btif_media_cb.media_alarm) { - APPL_TRACE_ERROR("%s unable to allocate media alarm.\n", __func__); - return; - } - - // alarm_set_periodic(btif_media_cb.media_alarm, BTIF_MEDIA_TIME_TICK, btif_media_task_alarm_cb, NULL); - osi_alarm_set(btif_media_cb.media_alarm, BTIF_MEDIA_TIME_TICK); -} - -/******************************************************************************* - ** - ** Function btif_media_task_aa_stop_tx - ** - ** Description Stop media task encoding - ** - ** Returns void - ** - *******************************************************************************/ -static void btif_media_task_aa_stop_tx(void) -{ - APPL_TRACE_DEBUG("%s is_tx_timer: %d\n", __func__, btif_media_cb.is_tx_timer); - - const bool send_ack = (btif_media_cb.is_tx_timer != FALSE); - - /* Stop the timer first */ - osi_alarm_free(btif_media_cb.media_alarm); - btif_media_cb.media_alarm = NULL; - btif_media_cb.is_tx_timer = FALSE; - - UIPC_Close(UIPC_CH_ID_AV_AUDIO); - - /* Try to send acknowldegment once the media stream is - stopped. This will make sure that the A2DP HAL layer is - un-blocked on wait for acknowledgment for the sent command. - This resolves a corner cases AVDTP SUSPEND collision - when the DUT and the remote device issue SUSPEND simultaneously - and due to the processing of the SUSPEND request from the remote, - the media path is torn down. If the A2DP HAL happens to wait - for ACK for the initiated SUSPEND, it would never receive it casuing - a block/wait. Due to this acknowledgement, the A2DP HAL is guranteed - to get the ACK for any pending command in such cases. */ - - if (send_ack) { - a2dp_cmd_acknowledge(A2DP_CTRL_ACK_SUCCESS); - } - - /* audio engine stopped, reset tx suspended flag */ - btif_media_cb.tx_flush = 0; - last_frame_us = 0; - - /* Reset the media feeding state */ - btif_media_task_feeding_state_reset(); -} - -/******************************************************************************* - ** - ** Function btif_get_num_aa_frame - ** - ** Description - ** - ** Returns The number of media frames in this time slice - ** - *******************************************************************************/ -static UINT8 btif_get_num_aa_frame(void) -{ - UINT8 result = 0; - - switch (btif_media_cb.TxTranscoding) { - case BTIF_MEDIA_TRSCD_PCM_2_SBC: { - UINT32 pcm_bytes_per_frame = btif_media_cb.encoder.s16NumOfSubBands * - btif_media_cb.encoder.s16NumOfBlocks * - btif_media_cb.media_feeding.cfg.pcm.num_channel * - btif_media_cb.media_feeding.cfg.pcm.bit_per_sample / 8; - - UINT32 us_this_tick = BTIF_MEDIA_TIME_TICK * 1000; - UINT64 now_us = time_now_us(); - if (last_frame_us != 0) { - us_this_tick = (now_us - last_frame_us); - } - last_frame_us = now_us; - - btif_media_cb.media_feeding_state.pcm.counter += - btif_media_cb.media_feeding_state.pcm.bytes_per_tick * - us_this_tick / (BTIF_MEDIA_TIME_TICK * 1000); - - /* calculate nbr of frames pending for this media tick */ - result = btif_media_cb.media_feeding_state.pcm.counter / pcm_bytes_per_frame; - if (result > MAX_PCM_FRAME_NUM_PER_TICK) { - APPL_TRACE_WARNING("%s() - Limiting frames to be sent from %d to %d" - , __FUNCTION__, result, MAX_PCM_FRAME_NUM_PER_TICK); - result = MAX_PCM_FRAME_NUM_PER_TICK; - } - btif_media_cb.media_feeding_state.pcm.counter -= result * pcm_bytes_per_frame; - - LOG_VERBOSE("WRITE %d FRAMES\n", result); - } - break; - - default: - APPL_TRACE_ERROR("ERROR btif_get_num_aa_frame Unsupported transcoding format 0x%x\n", - btif_media_cb.TxTranscoding); - result = 0; - break; - } - - return (UINT8)result; -} -#endif /* #if (BTIF_AV_SRC_INCLUDED == TRUE) */ - /******************************************************************************* ** ** Function btif_media_sink_enque_buf @@ -2416,340 +1506,12 @@ UINT8 btif_media_sink_enque_buf(BT_HDR *p_pkt) ** ** Returns void *******************************************************************************/ -#if (BTIF_AV_SRC_INCLUDED == TRUE) -BT_HDR *btif_media_aa_readbuf(void) -{ - return GKI_dequeue(&(btif_media_cb.TxAaQ)); -} -#else BT_HDR *btif_media_aa_readbuf(void) { return NULL; } -#endif /* BTIF_AV_SRC_INCLUDED */ - -#if (BTIF_AV_SRC_INCLUDED == TRUE) -/******************************************************************************* - ** - ** Function btif_media_aa_read_feeding - ** - ** Description - ** - ** Returns void - ** - *******************************************************************************/ -BOOLEAN btif_media_aa_read_feeding(tUIPC_CH_ID channel_id) -{ - UINT16 event; - UINT16 blocm_x_subband = btif_media_cb.encoder.s16NumOfSubBands * \ - btif_media_cb.encoder.s16NumOfBlocks; - UINT32 read_size; - UINT16 sbc_sampling = 48000; - UINT32 src_samples; - UINT16 bytes_needed = blocm_x_subband * btif_media_cb.encoder.s16NumOfChannels * \ - btif_media_cb.media_feeding.cfg.pcm.bit_per_sample / 8; - static UINT16 up_sampled_buffer[SBC_MAX_NUM_FRAME * SBC_MAX_NUM_OF_BLOCKS - * SBC_MAX_NUM_OF_CHANNELS * SBC_MAX_NUM_OF_SUBBANDS * 2]; - static UINT16 read_buffer[SBC_MAX_NUM_FRAME * SBC_MAX_NUM_OF_BLOCKS - * SBC_MAX_NUM_OF_CHANNELS * SBC_MAX_NUM_OF_SUBBANDS]; - UINT32 src_size_used; - UINT32 dst_size_used; - BOOLEAN fract_needed; - INT32 fract_max; - INT32 fract_threshold; - UINT32 nb_byte_read; - - /* Get the SBC sampling rate */ - switch (btif_media_cb.encoder.s16SamplingFreq) { - case SBC_sf48000: - sbc_sampling = 48000; - break; - case SBC_sf44100: - sbc_sampling = 44100; - break; - case SBC_sf32000: - sbc_sampling = 32000; - break; - case SBC_sf16000: - sbc_sampling = 16000; - break; - } - - if (sbc_sampling == btif_media_cb.media_feeding.cfg.pcm.sampling_freq) { - read_size = bytes_needed - btif_media_cb.media_feeding_state.pcm.aa_feed_residue; - nb_byte_read = UIPC_Read(channel_id, &event, - ((UINT8 *)btif_media_cb.encoder.as16PcmBuffer) + - btif_media_cb.media_feeding_state.pcm.aa_feed_residue, - read_size); - if (nb_byte_read == read_size) { - btif_media_cb.media_feeding_state.pcm.aa_feed_residue = 0; - return TRUE; - } else { - APPL_TRACE_WARNING("### UNDERFLOW :: ONLY READ %d BYTES OUT OF %d ###\n", - nb_byte_read, read_size); - btif_media_cb.media_feeding_state.pcm.aa_feed_residue += nb_byte_read; - return FALSE; - } - } - - /* Some Feeding PCM frequencies require to split the number of sample */ - /* to read. */ - /* E.g 128/6=21.3333 => read 22 and 21 and 21 => max = 2; threshold = 0*/ - fract_needed = FALSE; /* Default */ - switch (btif_media_cb.media_feeding.cfg.pcm.sampling_freq) { - case 32000: - case 8000: - fract_needed = TRUE; - fract_max = 2; /* 0, 1 and 2 */ - fract_threshold = 0; /* Add one for the first */ - break; - case 16000: - fract_needed = TRUE; - fract_max = 2; /* 0, 1 and 2 */ - fract_threshold = 1; /* Add one for the first two frames*/ - break; - } - - /* Compute number of sample to read from source */ - src_samples = blocm_x_subband; - src_samples *= btif_media_cb.media_feeding.cfg.pcm.sampling_freq; - src_samples /= sbc_sampling; - - /* The previous division may have a remainder not null */ - if (fract_needed) { - if (btif_media_cb.media_feeding_state.pcm.aa_feed_counter <= fract_threshold) { - src_samples++; /* for every read before threshold add one sample */ - } - - /* do nothing if counter >= threshold */ - btif_media_cb.media_feeding_state.pcm.aa_feed_counter++; /* one more read */ - if (btif_media_cb.media_feeding_state.pcm.aa_feed_counter > fract_max) { - btif_media_cb.media_feeding_state.pcm.aa_feed_counter = 0; - } - } - - /* Compute number of bytes to read from source */ - read_size = src_samples; - read_size *= btif_media_cb.media_feeding.cfg.pcm.num_channel; - read_size *= (btif_media_cb.media_feeding.cfg.pcm.bit_per_sample / 8); - - /* Read Data from UIPC channel */ - nb_byte_read = UIPC_Read(channel_id, &event, (UINT8 *)read_buffer, read_size); - - //tput_mon(TRUE, nb_byte_read, FALSE); - - if (nb_byte_read < read_size) { - APPL_TRACE_WARNING("### UNDERRUN :: ONLY READ %d BYTES OUT OF %d ###\n", - nb_byte_read, read_size); - - if (nb_byte_read == 0) { - return FALSE; - } - - if (btif_media_cb.feeding_mode == BTIF_AV_FEEDING_ASYNCHRONOUS) { - /* Fill the unfilled part of the read buffer with silence (0) */ - memset(((UINT8 *)read_buffer) + nb_byte_read, 0, read_size - nb_byte_read); - nb_byte_read = read_size; - } - } - - /* Initialize PCM up-sampling engine */ - bta_av_sbc_init_up_sample(btif_media_cb.media_feeding.cfg.pcm.sampling_freq, - sbc_sampling, btif_media_cb.media_feeding.cfg.pcm.bit_per_sample, - btif_media_cb.media_feeding.cfg.pcm.num_channel); - - /* re-sample read buffer */ - /* The output PCM buffer will be stereo, 16 bit per sample */ - dst_size_used = bta_av_sbc_up_sample((UINT8 *)read_buffer, - (UINT8 *)up_sampled_buffer + btif_media_cb.media_feeding_state.pcm.aa_feed_residue, - nb_byte_read, - sizeof(up_sampled_buffer) - btif_media_cb.media_feeding_state.pcm.aa_feed_residue, - &src_size_used); - - /* update the residue */ - btif_media_cb.media_feeding_state.pcm.aa_feed_residue += dst_size_used; - - /* only copy the pcm sample when we have up-sampled enough PCM */ - if (btif_media_cb.media_feeding_state.pcm.aa_feed_residue >= bytes_needed) { - /* Copy the output pcm samples in SBC encoding buffer */ - memcpy((UINT8 *)btif_media_cb.encoder.as16PcmBuffer, - (UINT8 *)up_sampled_buffer, - bytes_needed); - /* update the residue */ - btif_media_cb.media_feeding_state.pcm.aa_feed_residue -= bytes_needed; - - if (btif_media_cb.media_feeding_state.pcm.aa_feed_residue != 0) { - memcpy((UINT8 *)up_sampled_buffer, - (UINT8 *)up_sampled_buffer + bytes_needed, - btif_media_cb.media_feeding_state.pcm.aa_feed_residue); - } - return TRUE; - } - - return FALSE; -} - -/******************************************************************************* - ** - ** Function btif_media_aa_prep_sbc_2_send - ** - ** Description - ** - ** Returns void - ** - *******************************************************************************/ -static void btif_media_aa_prep_sbc_2_send(UINT8 nb_frame) -{ - BT_HDR *p_buf; - UINT16 blocm_x_subband = btif_media_cb.encoder.s16NumOfSubBands * - btif_media_cb.encoder.s16NumOfBlocks; - - while (nb_frame) { - if (NULL == (p_buf = GKI_getpoolbuf(BTIF_MEDIA_AA_POOL_ID))) { - APPL_TRACE_ERROR ("ERROR btif_media_aa_prep_sbc_2_send no buffer TxCnt %d \n", - GKI_queue_length(&btif_media_cb.TxAaQ)); - return; - } - - /* Init buffer */ - p_buf->offset = BTIF_MEDIA_AA_SBC_OFFSET; - p_buf->len = 0; - p_buf->layer_specific = 0; - - do { - /* Write @ of allocated buffer in encoder.pu8Packet */ - btif_media_cb.encoder.pu8Packet = (UINT8 *) (p_buf + 1) + p_buf->offset + p_buf->len; - /* Fill allocated buffer with 0 */ - memset(btif_media_cb.encoder.as16PcmBuffer, 0, blocm_x_subband - * btif_media_cb.encoder.s16NumOfChannels); - - /* Read PCM data and upsample them if needed */ - if (btif_media_aa_read_feeding(UIPC_CH_ID_AV_AUDIO)) { - /* SBC encode and descramble frame */ - SBC_Encoder(&(btif_media_cb.encoder)); - A2D_SbcChkFrInit(btif_media_cb.encoder.pu8Packet); - A2D_SbcDescramble(btif_media_cb.encoder.pu8Packet, btif_media_cb.encoder.u16PacketLength); - /* Update SBC frame length */ - p_buf->len += btif_media_cb.encoder.u16PacketLength; - nb_frame--; - p_buf->layer_specific++; - } else { - APPL_TRACE_WARNING("btif_media_aa_prep_sbc_2_send underflow %d, %d\n", - nb_frame, btif_media_cb.media_feeding_state.pcm.aa_feed_residue); - btif_media_cb.media_feeding_state.pcm.counter += nb_frame * - btif_media_cb.encoder.s16NumOfSubBands * - btif_media_cb.encoder.s16NumOfBlocks * - btif_media_cb.media_feeding.cfg.pcm.num_channel * - btif_media_cb.media_feeding.cfg.pcm.bit_per_sample / 8; - /* no more pcm to read */ - nb_frame = 0; - - /* break read loop if timer was stopped (media task stopped) */ - if ( btif_media_cb.is_tx_timer == FALSE ) { - GKI_freebuf(p_buf); - return; - } - } - - } while (((p_buf->len + btif_media_cb.encoder.u16PacketLength) < btif_media_cb.TxAaMtuSize) - && (p_buf->layer_specific < 0x0F) && nb_frame); - - if (p_buf->len) { - /* timestamp of the media packet header represent the TS of the first SBC frame - i.e the timestamp before including this frame */ - *((UINT32 *) (p_buf + 1)) = btif_media_cb.timestamp; - - btif_media_cb.timestamp += p_buf->layer_specific * blocm_x_subband; - - if (btif_media_cb.tx_flush) { - APPL_TRACE_DEBUG("### tx suspended, discarded frame ###\n"); - - if (GKI_queue_length(&btif_media_cb.TxAaQ) > 0) { - btif_media_flush_q(&(btif_media_cb.TxAaQ)); - } - - GKI_freebuf(p_buf); - return; - } - - /* Enqueue the encoded SBC frame in AA Tx Queue */ - GKI_enqueue(&(btif_media_cb.TxAaQ), p_buf); - } else { - GKI_freebuf(p_buf); - } - } -} - -/******************************************************************************* - ** - ** Function btif_media_aa_prep_2_send - ** - ** Description - ** - ** Returns void - ** - *******************************************************************************/ - -static void btif_media_aa_prep_2_send(UINT8 nb_frame) -{ - // Check for TX queue overflow - - if (nb_frame > MAX_OUTPUT_A2DP_FRAME_QUEUE_SZ) { - nb_frame = MAX_OUTPUT_A2DP_FRAME_QUEUE_SZ; - } - - if (GKI_queue_length(&btif_media_cb.TxAaQ) > (MAX_OUTPUT_A2DP_FRAME_QUEUE_SZ - nb_frame)) { - APPL_TRACE_WARNING("%s() - TX queue buffer count %d/%d\n", __func__, - GKI_queue_length(&btif_media_cb.TxAaQ), MAX_OUTPUT_A2DP_FRAME_QUEUE_SZ - nb_frame); - } - - while (GKI_queue_length(&btif_media_cb.TxAaQ) > (MAX_OUTPUT_A2DP_FRAME_QUEUE_SZ - nb_frame)) { - GKI_freebuf(GKI_dequeue(&(btif_media_cb.TxAaQ))); - } - - // Transcode frame - - switch (btif_media_cb.TxTranscoding) { - case BTIF_MEDIA_TRSCD_PCM_2_SBC: - btif_media_aa_prep_sbc_2_send(nb_frame); - break; - - default: - APPL_TRACE_ERROR("%s unsupported transcoding format 0x%x\n", __func__, btif_media_cb.TxTranscoding); - break; - } -} -#endif /* #if (BTIF_AV_SRC_INCLUDED == TRUE) */ - -#if (BTIF_AV_SRC_INCLUDED == TRUE) -/******************************************************************************* - ** - ** Function btif_media_send_aa_frame - ** - ** Description - ** - ** Returns void - ** - *******************************************************************************/ -static void btif_media_send_aa_frame(void) -{ - UINT8 nb_frame_2_send; - - /* get the number of frame to send */ - nb_frame_2_send = btif_get_num_aa_frame(); - - if (nb_frame_2_send != 0) { - /* format and Q buffer to send */ - btif_media_aa_prep_2_send(nb_frame_2_send); - } - - /* send it */ - LOG_VERBOSE("btif_media_send_aa_frame : send %d frames\n", nb_frame_2_send); - bta_av_ci_src_data_ready(BTA_AV_CHNL_AUDIO); -} #endif /* BTA_AV_INCLUDED == TRUE */ -#endif /* #if (BTIF_AV_SRC_INCLUDED == TRUE) */ /******************************************************************************* ** ** Function dump_codec_info diff --git a/examples/09_a2dp/components/bluedroid_demos/btif/include/btif_media.h b/examples/09_a2dp/components/bluedroid_demos/btif/include/btif_media.h index ff52470c52..f8c74df5c3 100644 --- a/examples/09_a2dp/components/bluedroid_demos/btif/include/btif_media.h +++ b/examples/09_a2dp/components/bluedroid_demos/btif/include/btif_media.h @@ -32,7 +32,7 @@ #include "bta_api.h" #include "gki.h" #include "btif_av_api.h" -#include "audio_a2dp_hw.h" +// #include "audio_a2dp_hw.h" /******************************************************************************* ** Constants -- 2.40.0