summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--btif/include/btif_media.h2
-rw-r--r--btif/src/bluetooth.c4
-rwxr-xr-xbtif/src/btif_av.c1
-rwxr-xr-xbtif/src/btif_media_task.c251
-rw-r--r--gki/Android.mk1
-rwxr-xr-xgki/ulinux/gki_ulinux.c7
-rw-r--r--hci/Android.mk6
-rw-r--r--hci/src/bt_hci_bdroid.c3
-rw-r--r--main/Android.mk4
-rw-r--r--stack/Android.mk1
-rw-r--r--stack/btu/btu_task.c3
-rw-r--r--utils/Android.mk20
-rw-r--r--utils/include/bt_utils.h42
-rw-r--r--utils/src/bt_utils.c139
14 files changed, 303 insertions, 181 deletions
diff --git a/btif/include/btif_media.h b/btif/include/btif_media.h
index ce7c0a1..eb4c2b4 100644
--- a/btif/include/btif_media.h
+++ b/btif/include/btif_media.h
@@ -243,4 +243,6 @@ void btif_a2dp_on_suspend(void);
void btif_a2dp_on_suspended(tBTA_AV_SUSPEND *p_av);
void btif_a2dp_set_tx_flush(BOOLEAN enable);
+void btif_media_check_iop_exceptions(char *peer_bda);
+
#endif
diff --git a/btif/src/bluetooth.c b/btif/src/bluetooth.c
index 18e706f..20d6a07 100644
--- a/btif/src/bluetooth.c
+++ b/btif/src/bluetooth.c
@@ -40,6 +40,7 @@
#define LOG_TAG "bluedroid"
#include "btif_api.h"
+#include "bt_utils.h"
/************************************************************************************
** Constants & Macros
@@ -113,6 +114,8 @@ static int init(bt_callbacks_t* callbacks )
/* add checks for individual callbacks ? */
+ bt_utils_init();
+
/* init btif */
btif_init_bluetooth();
@@ -146,6 +149,7 @@ static void cleanup( void )
return;
btif_shutdown_bluetooth();
+ bt_utils_cleanup();
/* hal callbacks reset upon shutdown complete callback */
diff --git a/btif/src/btif_av.c b/btif/src/btif_av.c
index d25fb61..af4830f 100755
--- a/btif/src/btif_av.c
+++ b/btif/src/btif_av.c
@@ -463,6 +463,7 @@ static BOOLEAN btif_av_state_opened_handler(btif_sm_event_t event, void *p_data)
switch (event)
{
case BTIF_SM_ENTER_EVT:
+ btif_media_check_iop_exceptions((char *)btif_av_cb.peer_bda.address);
break;
case BTIF_SM_EXIT_EVT:
diff --git a/btif/src/btif_media_task.c b/btif/src/btif_media_task.c
index 6975154..68b2e4c 100755
--- a/btif/src/btif_media_task.c
+++ b/btif/src/btif_media_task.c
@@ -67,6 +67,7 @@
#include "btif_av.h"
#include "btif_sm.h"
#include "btif_util.h"
+#include "bt_utils.h"
/*****************************************************************************
** Constants
@@ -119,14 +120,20 @@ enum {
/* Media task tick in milliseconds */
#define BTIF_MEDIA_TIME_TICK (20 * BTIF_MEDIA_NUM_TICK)
-/* Number of frames per media task tick */
-/* 7.5 frames/tick @ 20 ms tick */
-#define BTIF_MEDIA_FR_PER_TICKS_48 (7 * BTIF_MEDIA_NUM_TICK)
-/* 6.89 frames/tick @ 20 ms tick */
+/* Number of frames per media task tick.
+ Configure value rounded up to closest integer and
+ adjust any deltas in btif_get_num_aa_frame */
+
+/* 7.5 frames/tick @ 20 ms tick (every 2nd frame send one less) */
+#define BTIF_MEDIA_FR_PER_TICKS_48 (8 * BTIF_MEDIA_NUM_TICK)
+
+/* 6.89 frames/tick @ 20 ms tick (7 out of 64 frames send one less */
#define BTIF_MEDIA_FR_PER_TICKS_44_1 (7 * BTIF_MEDIA_NUM_TICK)
+
/* 5.0 frames/tick @ 20 ms tick */
#define BTIF_MEDIA_FR_PER_TICKS_32 (5 * BTIF_MEDIA_NUM_TICK)
-/* 2.5 frames/tick @ 20 ms tick */
+
+/* 2.5 frames/tick @ 20 ms tick (every 2nd frame send one less) */
#define BTIF_MEDIA_FR_PER_TICKS_16 (3 * BTIF_MEDIA_NUM_TICK)
@@ -176,10 +183,7 @@ static UINT32 a2dp_media_task_stack[(A2DP_MEDIA_TASK_STACK_SIZE + 3) / 4];
/* fixme -- define this in pcm time instead of buffer count */
/* fixme -- tune optimal value. For now set a large buffer capacity */
-#define MAX_OUTPUT_BUFFER_QUEUE_SZ 12
-
-/* trigger rate adjustment if deviation is more than threshold */
-#define BTIF_RA_OFFSET_TRIGGER_US 3000
+#define MAX_OUTPUT_BUFFER_QUEUE_SZ 24
//#define BTIF_MEDIA_VERBOSE_ENABLED
@@ -208,19 +212,6 @@ typedef union
tBTIF_AV_MEDIA_FEEDINGS_PCM_STATE pcm;
} tBTIF_AV_MEDIA_FEEDINGS_STATE;
-
-/* pcm rate adjustment */
-typedef struct {
- struct timespec time_start; /* offset used to calculate time elapsed */
- unsigned long long tx_pcmtime_us; /* track pcm time transmitted since stream start */
-
- /* stats */
- int ra_adjust_cnt; /* tracks nbr of frame intervals adjusted */
- int ra_adjust_pcmtime; /* pcmtime adjusted each stats interval */
-
- /* add latency tracker */
-} tBTIF_MEDIA_RA;
-
typedef struct
{
#if (BTA_AV_INCLUDED == TRUE)
@@ -237,7 +228,7 @@ typedef struct
void* av_sm_hdl;
UINT8 a2dp_cmd_pending; /* we can have max one command pending */
BOOLEAN tx_flush; /* discards any outgoing data when true */
- tBTIF_MEDIA_RA ra; /* tx rate adjustment logic */
+ BOOLEAN scaling_disabled;
#endif
} tBTIF_MEDIA_CB;
@@ -985,132 +976,6 @@ static int btif_calc_pcmtime(UINT32 bytes_processed)
return pcm_time_us;
}
-/*****************************************************************************
-**
-** Function ra_reset
-**
-** Description Media task tx rate adjustment
-**
-** Returns void
-**
-*******************************************************************************/
-
-static void ra_reset(void)
-{
- /* initialize start time of test interval */
- btif_media_cb.ra.time_start.tv_nsec = 0;
- btif_media_cb.ra.time_start.tv_sec = 0;
- btif_media_cb.ra.tx_pcmtime_us= 0;
- btif_media_cb.ra.ra_adjust_cnt = 0;
- btif_media_cb.ra.ra_adjust_pcmtime = 0;
-}
-
-/*****************************************************************************
-**
-** Function ra_update
-**
-** Description Updates RA with amount of UIPC channel data processed
-**
-** Returns void
-**
-*******************************************************************************/
-
-static void ra_update(UINT32 bytes_processed)
-{
-#define RA_STATS_INTERVAL 3
- static unsigned long ra_stats_update = 0;
- int pcmtime_equivalent;
-
- /* if this is the first frame we will initialize tx start time */
- if ( (btif_media_cb.ra.time_start.tv_sec == 0) && (btif_media_cb.ra.time_start.tv_nsec == 0) )
- clock_gettime(CLOCK_MONOTONIC, &btif_media_cb.ra.time_start);
-
- pcmtime_equivalent = btif_calc_pcmtime(bytes_processed);
- btif_media_cb.ra.tx_pcmtime_us += pcmtime_equivalent;
-
- ra_stats_update += pcmtime_equivalent;
-
- /* converts adjusted frame count to adjusted pcmtime equivalent */
- btif_media_cb.ra.ra_adjust_pcmtime += (btif_media_cb.ra.ra_adjust_cnt)*pcmtime_equivalent;
-
- //VERBOSE("ra update %d %d %d", btif_media_cb.ra.ra_adjust_cnt,
- // btif_media_cb.ra.ra_adjust_pcmtime, ra_stats_update);
-
- /* check pcmtime adjustments every stats interval */
- if (ra_stats_update > (RA_STATS_INTERVAL*1000000L))
- {
- APPL_TRACE_DEBUG3("ra estimate : %d us for %d secs (%d ppm)",
- btif_media_cb.ra.ra_adjust_pcmtime, RA_STATS_INTERVAL,
- btif_media_cb.ra.ra_adjust_pcmtime/RA_STATS_INTERVAL);
- btif_media_cb.ra.ra_adjust_pcmtime = 0;
- ra_stats_update = 0;
-
- }
-
- /* reset count for next conversion */
- btif_media_cb.ra.ra_adjust_cnt = 0;
-}
-
-/*****************************************************************************
-**
-** Function ra_adjust
-**
-** Description Calculates deviation between PCM time processed across
-** UIPC audio channel and PCM time transmitted across the
-** A2DP stream. Is checked every time slice (media timer
-** tick).
-**
-** Returns Returns a frame count offset used to compensate for
-** any drift versus the ideal clockrate
-**
-*******************************************************************************/
-
-static int ra_adjust(void)
-{
- unsigned long long time_elapsed_us;
- struct timespec now;
- int adjust = 0;
-
- /* don't start adjusting until we have read any pcm data */
- if (btif_media_cb.ra.tx_pcmtime_us == 0)
- return 0;
-
- clock_gettime(CLOCK_MONOTONIC, &now);
-
- time_elapsed_us = ((unsigned long long)(now.tv_sec - btif_media_cb.ra.time_start.tv_sec))\
- * USEC_PER_SEC + (now.tv_nsec - btif_media_cb.ra.time_start.tv_nsec)/1000;
-
- /* compare elapsed time vs read pcm time */
- if (btif_media_cb.ra.tx_pcmtime_us > time_elapsed_us)
- {
- //VERBOSE("TOO FAST : %06d us", btif_media_cb.ra.tx_pcmtime_us - time_elapsed_us);
-
- if ((btif_media_cb.ra.tx_pcmtime_us - time_elapsed_us) > BTIF_RA_OFFSET_TRIGGER_US)
- {
- VERBOSE("RA : -1 FRAME (%06d us)", btif_media_cb.ra.tx_pcmtime_us - time_elapsed_us);
-
- /* adjust by sending one frame less this time slice */
- adjust--;
- btif_media_cb.ra.ra_adjust_cnt--;
- }
- }
- else if (btif_media_cb.ra.tx_pcmtime_us < time_elapsed_us)
- {
- //VERBOSE("TOO SLOW : %06d us", time_elapsed_us - btif_media_cb.ra.tx_pcmtime_us);
-
- if ((time_elapsed_us - btif_media_cb.ra.tx_pcmtime_us) > BTIF_RA_OFFSET_TRIGGER_US)
- {
- VERBOSE("RA : +1 FRAME (%06d us)", time_elapsed_us - btif_media_cb.ra.tx_pcmtime_us);
-
- /* adjust by sending one frame more this time slice */
- adjust++;
- btif_media_cb.ra.ra_adjust_cnt++;
- }
- }
-
- return adjust;
-}
-
/*******************************************************************************
**
@@ -1209,6 +1074,8 @@ int btif_media_task(void *p)
media_task_running = MEDIA_TASK_STATE_ON;
+ raise_priority_a2dp(TASK_HIGH_MEDIA);
+
while (1)
{
event = GKI_wait(0xffff, 0);
@@ -1860,11 +1727,6 @@ 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));
-
- /* reset pcm time tracker */
- ra_reset();
-
-
}
/*******************************************************************************
**
@@ -1928,6 +1790,8 @@ static void btif_media_task_aa_stop_tx(void)
** Returns The number of media frames in this time slice
**
*******************************************************************************/
+
+
static UINT8 btif_get_num_aa_frame(void)
{
UINT8 result=0;
@@ -1938,35 +1802,46 @@ static UINT8 btif_get_num_aa_frame(void)
switch (btif_media_cb.encoder.s16SamplingFreq)
{
case SBC_sf16000:
- result = BTIF_MEDIA_FR_PER_TICKS_16;
+ if (!btif_media_cb.scaling_disabled &&
+ (btif_media_cb.media_feeding_state.pcm.aa_frame_counter++ % 2) == 0)
+ {
+ result = BTIF_MEDIA_FR_PER_TICKS_16-1;
+ }
+ else
+ {
+ result = BTIF_MEDIA_FR_PER_TICKS_16;
+ }
break;
+
case SBC_sf32000:
result = BTIF_MEDIA_FR_PER_TICKS_32;
break;
+
case SBC_sf48000:
- result = BTIF_MEDIA_FR_PER_TICKS_48;
+ if (!btif_media_cb.scaling_disabled &&
+ (btif_media_cb.media_feeding_state.pcm.aa_frame_counter++ % 2) == 0)
+ {
+ result = BTIF_MEDIA_FR_PER_TICKS_48-1;
+ }
+ else
+ {
+ result = BTIF_MEDIA_FR_PER_TICKS_48;
+ }
break;
+
case SBC_sf44100:
- result = BTIF_MEDIA_FR_PER_TICKS_44_1;
+ if (!btif_media_cb.scaling_disabled &&
+ (btif_media_cb.media_feeding_state.pcm.aa_frame_counter++ % 64) < 7)
+ {
+ result = BTIF_MEDIA_FR_PER_TICKS_44_1-1;
+ }
+ else
+ {
+ result = BTIF_MEDIA_FR_PER_TICKS_44_1;
+ }
break;
}
- /* Frames per tick should be selected to come as close as possible
- to the ideal framecount. Any residue compared to ideal framecount
- is compensated here.
-
- Although we can estimate the frames per tick using modula
- counters using the rate adapter logic smoothes out the compensation
- over time and tracks transmitted time vs elapsed time counted from the first
- frame sent out. Hence regardless of the reason for the drift (gki timer
- inaccuracies or media tick frame residues) the rate
- adaptor will compensate as soon as we drift outside the configued
- threshold
- */
-
- // TODO(BT) ra_adjust causes problem, need correction
- // result += ra_adjust();
-
VERBOSE("WRITE %d FRAMES", result);
break;
@@ -2093,9 +1968,6 @@ BOOLEAN btif_media_aa_read_feeding(tUIPC_CH_ID channel_id)
/* Read Data from UIPC channel */
nb_byte_read = UIPC_Read(channel_id, &event, (UINT8 *)read_buffer, read_size);
- /* update read 'pcmtime' */
- ra_update(nb_byte_read);
-
//tput_mon(TRUE, nb_byte_read, FALSE);
if (nb_byte_read < read_size)
@@ -2310,6 +2182,33 @@ static void btif_media_send_aa_frame(void)
bta_av_ci_src_data_ready(BTA_AV_CHNL_AUDIO);
}
+/*******************************************************************************
+ **
+ ** Function btif_media_check_iop_exceptions
+ **
+ ** Description Perform any device specific iop changes
+ **
+ ** Returns void
+ **
+ *******************************************************************************/
+
+void btif_media_check_iop_exceptions(char *peer_bda)
+{
+ /* disable rate scaling for pcm carkit */
+ if ((peer_bda[0] == 0x00) &&
+ (peer_bda[1] == 0x0E) &&
+ (peer_bda[2] == 0x9F))
+ {
+ BTIF_TRACE_WARNING0("detected pcm carkit, disable rate scaling");
+ btif_media_cb.scaling_disabled = TRUE;
+ }
+ else
+ {
+ btif_media_cb.scaling_disabled = FALSE;
+ }
+}
+
+
#endif /* BTA_AV_INCLUDED == TRUE */
/*******************************************************************************
diff --git a/gki/Android.mk b/gki/Android.mk
index c76c237..0ece25b 100644
--- a/gki/Android.mk
+++ b/gki/Android.mk
@@ -8,6 +8,7 @@ LOCAL_C_INCLUDES:= $(LOCAL_PATH)/common \
$(LOCAL_PATH)/ulinux \
$(LOCAL_PATH)/../include \
$(LOCAL_PATH)/../stack/include \
+ $(LOCAL_PATH)/../utils/include \
$(bdroid_C_INCLUDES) \
LOCAL_CFLAGS += -Werror $(bdroid_CFLAGS)
diff --git a/gki/ulinux/gki_ulinux.c b/gki/ulinux/gki_ulinux.c
index 97a7f41..57ff7bb 100755
--- a/gki/ulinux/gki_ulinux.c
+++ b/gki/ulinux/gki_ulinux.c
@@ -33,6 +33,7 @@
#include <pthread.h> /* must be 1st header defined */
#include <time.h>
#include "gki_int.h"
+#include "bt_utils.h"
#define LOG_TAG "GKI_LINUX"
@@ -618,6 +619,10 @@ void* timer_thread(void *arg)
/* Indicate that tick is just starting */
restart = 1;
+ prctl(PR_SET_NAME, (unsigned long)"gki timer", 0, 0, 0);
+
+ raise_priority_a2dp(TASK_HIGH_GKI_TIMER);
+
while(!shutdown_timer)
{
/* If the timer has been stopped (no SW timer running) */
@@ -807,8 +812,6 @@ void GKI_run (void *p_task_id)
return;
}
- prctl(PR_SET_NAME, (unsigned long)"gki timer", 0, 0, 0);
-
#else
GKI_TRACE("GKI_run ");
for (;;)
diff --git a/hci/Android.mk b/hci/Android.mk
index 875197c..f2a63e5 100644
--- a/hci/Android.mk
+++ b/hci/Android.mk
@@ -26,11 +26,13 @@ LOCAL_SRC_FILES += \
endif
LOCAL_C_INCLUDES += \
- $(LOCAL_PATH)/include
+ $(LOCAL_PATH)/include \
+ $(LOCAL_PATH)/../utils/include
LOCAL_SHARED_LIBRARIES := \
libcutils \
- libdl
+ libdl \
+ libbt-utils
LOCAL_MODULE := libbt-hci
LOCAL_MODULE_TAGS := optional
diff --git a/hci/src/bt_hci_bdroid.c b/hci/src/bt_hci_bdroid.c
index 27d190e..7b14eb3 100644
--- a/hci/src/bt_hci_bdroid.c
+++ b/hci/src/bt_hci_bdroid.c
@@ -34,6 +34,7 @@
#include "utils.h"
#include "hci.h"
#include "userial.h"
+#include "bt_utils.h"
#include <sys/prctl.h>
#ifndef BTHC_DBG
@@ -344,6 +345,8 @@ static void *bt_hc_worker_thread(void *arg)
prctl(PR_SET_NAME, (unsigned long)"bt_hc_worker", 0, 0, 0);
tx_cmd_pkts_pending = FALSE;
+ raise_priority_a2dp(TASK_HIGH_HCI_WORKER);
+
while (lib_running)
{
pthread_mutex_lock(&hc_cb.mutex);
diff --git a/main/Android.mk b/main/Android.mk
index 2a5ed93..8ecb3c3 100644
--- a/main/Android.mk
+++ b/main/Android.mk
@@ -88,6 +88,7 @@ LOCAL_C_INCLUDES+= . \
$(LOCAL_PATH)/../brcm/include \
$(LOCAL_PATH)/../embdrv/sbc/encoder/include \
$(LOCAL_PATH)/../audio_a2dp_hw \
+ $(LOCAL_PATH)/../utils/include \
$(bdroid_C_INCLUDES) \
external/tinyxml2
@@ -113,7 +114,8 @@ endif
LOCAL_SHARED_LIBRARIES := \
libcutils \
libpower \
- libbt-hci
+ libbt-hci \
+ libbt-utils
#LOCAL_WHOLE_STATIC_LIBRARIES := libbt-brcm_gki libbt-brcm_stack libbt-brcm_bta
LOCAL_STATIC_LIBRARIES := libbt-brcm_gki libbt-brcm_bta libbt-brcm_stack libtinyxml2
diff --git a/stack/Android.mk b/stack/Android.mk
index 968cfdb..0c24805 100644
--- a/stack/Android.mk
+++ b/stack/Android.mk
@@ -28,6 +28,7 @@ LOCAL_C_INCLUDES:= . \
$(LOCAL_PATH)/../bta/include \
$(LOCAL_PATH)/../bta/sys \
$(LOCAL_PATH)/../brcm/include \
+ $(LOCAL_PATH)/../utils/include \
$(bdroid_C_INCLUDES) \
LOCAL_CFLAGS += $(bdroid_CFLAGS)
diff --git a/stack/btu/btu_task.c b/stack/btu/btu_task.c
index 1041307..48ce489 100644
--- a/stack/btu/btu_task.c
+++ b/stack/btu/btu_task.c
@@ -38,6 +38,7 @@
#include "hcimsgs.h"
#include "l2c_int.h"
#include "btu.h"
+#include "bt_utils.h"
#include "sdpint.h"
@@ -192,6 +193,8 @@ BTU_API UINT32 btu_task (UINT32 param)
/* Send a startup evt message to BTIF_TASK to kickstart the init procedure */
GKI_send_event(BTIF_TASK, BT_EVT_TRIGGER_STACK_INIT);
+ raise_priority_a2dp(TASK_HIGH_BTU);
+
/* Wait for, and process, events */
for (;;)
{
diff --git a/utils/Android.mk b/utils/Android.mk
new file mode 100644
index 0000000..4e66705
--- /dev/null
+++ b/utils/Android.mk
@@ -0,0 +1,20 @@
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_C_INCLUDES:= $(LOCAL_PATH)/include \
+ $(LOCAL_PATH)/../gki/ulinux \
+ $(bdroid_C_INCLUDES)
+
+LOCAL_CFLAGS += -Werror $(bdroid_CFLAGS)
+
+LOCAL_PRELINK_MODULE:=false
+LOCAL_SRC_FILES:= \
+ ./src/bt_utils.c
+
+LOCAL_MODULE := libbt-utils
+LOCAL_MODULE_TAGS := optional
+LOCAL_SHARED_LIBRARIES := libcutils libc
+LOCAL_MODULE_CLASS := SHARED_LIBRARIES
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/utils/include/bt_utils.h b/utils/include/bt_utils.h
new file mode 100644
index 0000000..ef4fc18
--- /dev/null
+++ b/utils/include/bt_utils.h
@@ -0,0 +1,42 @@
+/******************************************************************************
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+#ifndef BT_UTILS_H
+#define BT_UTILS_H
+
+/*******************************************************************************
+** Type definitions
+********************************************************************************/
+
+typedef enum {
+ TASK_HIGH_MEDIA = 0,
+ TASK_HIGH_GKI_TIMER,
+ TASK_HIGH_BTU,
+ TASK_HIGH_HCI_WORKER,
+ TASK_HIGH_MAX
+} tHIGH_PRIORITY_TASK;
+
+/*******************************************************************************
+** Functions
+********************************************************************************/
+
+void bt_utils_init();
+void bt_utils_cleanup();
+void raise_priority_a2dp(tHIGH_PRIORITY_TASK high_task);
+
+#endif /* BT_UTILS_H */
diff --git a/utils/src/bt_utils.c b/utils/src/bt_utils.c
new file mode 100644
index 0000000..aeb9292
--- /dev/null
+++ b/utils/src/bt_utils.c
@@ -0,0 +1,139 @@
+/******************************************************************************
+ *
+ * Copyright (C) 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: bt_utils.c
+ *
+ * Description: Miscellaneous helper functions
+ *
+ *
+ ***********************************************************************************/
+
+#include <cutils/properties.h>
+#include <cutils/sched_policy.h>
+#include <errno.h>
+#include <pthread.h>
+#include <sys/resource.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <utils/ThreadDefs.h>
+
+#define LOG_TAG "BT_UTILS"
+
+#include <utils/Log.h>
+
+#include "data_types.h"
+#include "bt_utils.h"
+
+
+/*******************************************************************************
+** Type definitions for callback functions
+********************************************************************************/
+static pthread_once_t g_DoSchedulingGroupOnce[TASK_HIGH_MAX];
+static BOOLEAN g_DoSchedulingGroup[TASK_HIGH_MAX];
+static pthread_mutex_t gIdxLock;
+static int g_TaskIdx;
+
+/*****************************************************************************
+**
+** Function bt_utils_init
+**
+** Description Initialize bluedroid util
+**
+** Returns void
+**
+*******************************************************************************/
+void bt_utils_init() {
+ int i;
+ pthread_mutexattr_t lock_attr;
+
+ for(i = 0; i < TASK_HIGH_MAX; i++) {
+ g_DoSchedulingGroupOnce[i] = PTHREAD_ONCE_INIT;
+ g_DoSchedulingGroup[i] = TRUE;
+ }
+ pthread_mutexattr_init(&lock_attr);
+ pthread_mutex_init(&gIdxLock, &lock_attr);
+}
+
+/*****************************************************************************
+**
+** Function bt_utils_cleanup
+**
+** Description Clean up bluedroid util
+**
+** Returns void
+**
+*******************************************************************************/
+void bt_utils_cleanup() {
+ pthread_mutex_destroy(&gIdxLock);
+}
+
+/*****************************************************************************
+**
+** Function check_do_scheduling_group
+**
+** Description check if it is ok to change schedule group
+**
+** Returns void
+**
+*******************************************************************************/
+static void check_do_scheduling_group(void) {
+ char buf[PROPERTY_VALUE_MAX];
+ int len = property_get("debug.sys.noschedgroups", buf, "");
+ if (len > 0) {
+ int temp;
+ if (sscanf(buf, "%d", &temp) == 1) {
+ g_DoSchedulingGroup[g_TaskIdx] = temp == 0;
+ }
+ }
+}
+
+/*****************************************************************************
+**
+** Function raise_priority_a2dp
+**
+** Description Raise task priority for A2DP streaming
+**
+** Returns void
+**
+*******************************************************************************/
+void raise_priority_a2dp(tHIGH_PRIORITY_TASK high_task) {
+ int rc = 0;
+ int tid = gettid();
+
+ pthread_mutex_lock(&gIdxLock);
+ g_TaskIdx = high_task;
+
+ pthread_once(&g_DoSchedulingGroupOnce[g_TaskIdx], check_do_scheduling_group);
+ if (g_DoSchedulingGroup[g_TaskIdx]) {
+ // set_sched_policy does not support tid == 0
+ rc = set_sched_policy(tid, SP_FOREGROUND);
+ }
+ pthread_mutex_unlock(&gIdxLock);
+
+ if (rc) {
+ ALOGW("failed to change sched policy, tid %d, err: %d", tid, errno);
+ }
+
+ if (setpriority(PRIO_PROCESS, tid, ANDROID_PRIORITY_AUDIO) < 0) {
+ ALOGW("failed to change priority tid: %d to %d", tid, ANDROID_PRIORITY_AUDIO);
+ }
+}
+