diff options
-rw-r--r-- | btif/include/btif_media.h | 2 | ||||
-rw-r--r-- | btif/src/bluetooth.c | 4 | ||||
-rwxr-xr-x | btif/src/btif_av.c | 1 | ||||
-rwxr-xr-x | btif/src/btif_media_task.c | 251 | ||||
-rw-r--r-- | gki/Android.mk | 1 | ||||
-rwxr-xr-x | gki/ulinux/gki_ulinux.c | 7 | ||||
-rw-r--r-- | hci/Android.mk | 6 | ||||
-rw-r--r-- | hci/src/bt_hci_bdroid.c | 3 | ||||
-rw-r--r-- | main/Android.mk | 4 | ||||
-rw-r--r-- | stack/Android.mk | 1 | ||||
-rw-r--r-- | stack/btu/btu_task.c | 3 | ||||
-rw-r--r-- | utils/Android.mk | 20 | ||||
-rw-r--r-- | utils/include/bt_utils.h | 42 | ||||
-rw-r--r-- | utils/src/bt_utils.c | 139 |
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); + } +} + |