198 lines
7.2 KiB
C++
198 lines
7.2 KiB
C++
/* Copyright Statement:
|
|
* *
|
|
* * This software/firmware and related documentation ("MediaTek Software") are
|
|
* * protected under relevant copyright laws. The information contained herein
|
|
* * is confidential and proprietary to MediaTek Inc. and/or its licensors.
|
|
* * Without the prior written permission of MediaTek inc. and/or its licensors,
|
|
* * any reproduction, modification, use or disclosure of MediaTek Software,
|
|
* * and information contained herein, in whole or in part, shall be strictly
|
|
* * prohibited.
|
|
* *
|
|
* * MediaTek Inc. (C) 2016. All rights reserved.
|
|
* *
|
|
* * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
|
|
* * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
|
|
* * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
|
|
* * ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL
|
|
* * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
|
|
* * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
|
|
* * NONINFRINGEMENT.
|
|
* * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
|
|
* * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
|
|
* * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO
|
|
* * SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER
|
|
* * EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN
|
|
* * FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN MEDIATEK SOFTWARE.
|
|
* * MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES
|
|
* * MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR
|
|
* * OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
|
|
* * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED
|
|
* * HEREUNDER WILL BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK
|
|
* * SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE
|
|
* * PAID BY RECEIVER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
|
|
* *
|
|
* * The following software/firmware and/or related documentation ("MediaTek Software")
|
|
* * have been modified by MediaTek Inc. All revisions are subject to any receiver's
|
|
* * applicable license agreements with MediaTek Inc.
|
|
* */
|
|
|
|
|
|
#define LOG_TAG "a2dp_aac_vbr"
|
|
#define ATRACE_TAG ATRACE_TAG_AUDIO
|
|
|
|
#include <stdlib.h>
|
|
#ifndef OS_GENERIC
|
|
#include <cutils/trace.h>
|
|
#endif
|
|
#include <dlfcn.h>
|
|
#include <inttypes.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#include "common/time_util.h"
|
|
#include "osi/include/log.h"
|
|
#include "osi/include/osi.h"
|
|
#include "mtk_btif_av.h"
|
|
|
|
#include "a2dp_aac_encoder.h"
|
|
#include "a2dp_aac_constants.h"
|
|
#include "osi/include/properties.h"
|
|
#include "mediatek/stack/include/a2dp_aac_vbr.h"
|
|
|
|
#if defined(MTK_INTEROP_EXTENSION) && (MTK_INTEROP_EXTENSION == TRUE)
|
|
#include "interop_mtk.h"
|
|
#include "btif_av.h"
|
|
#endif
|
|
|
|
static bool bPropSupportVbr;
|
|
static int iPeerSupportVbrVal;
|
|
static bool bPropUpdate = false;
|
|
static int iMaxVbrMode;
|
|
|
|
// Here, Set VBR params:
|
|
#define DOWN_QUEUE_LENGTH (2) /*!< If >= DOWN_QUEUE_LENGTH, It's mean link bad state */
|
|
#define UP_QUEUE_LENGTH (0) /*!< If = UP_QUEUE_LENGTH, It's mean link good state */
|
|
#define DOWN_SAMPLE_COUNT (10) /*!< Down: Sample 10*20ms=200ms. */
|
|
#define UP_SAMPLE_COUNT (50) /*!< Up: Sample 50*20ms=1s. */
|
|
#define DOWN_ADJ_VBR_LEVEL (2) /*!< If the current mode >= mode3, adjust to reduce two level */
|
|
|
|
#define MIN_A2DP_VBR_MODE (AACENC_BR_MODE_VBR_1)
|
|
#define MAX_A2DP_VBR_MODE (AACENC_BR_MODE_VBR_5)
|
|
#define AAC_VBR_DEFAULT_MODE (AACENC_BR_MODE_VBR_4)
|
|
|
|
struct vbr_helper_st {
|
|
unsigned int dnBitrateCnt;
|
|
unsigned int dnBitrateSum;
|
|
unsigned int dnthreshold;
|
|
|
|
unsigned int upBitrateCnt;
|
|
unsigned int upBitrateSum;
|
|
unsigned int upthreshold;
|
|
|
|
int last_mode;
|
|
int cur_mode;
|
|
};
|
|
|
|
static struct vbr_helper_st stVbrHelper = {
|
|
0, 0, DOWN_SAMPLE_COUNT, 0, 0, UP_SAMPLE_COUNT, AACENC_BR_MODE_INVALID, AAC_VBR_DEFAULT_MODE};
|
|
|
|
static void resetDnBitRateParam() {
|
|
stVbrHelper.dnBitrateCnt = 0;
|
|
stVbrHelper.dnBitrateSum = 0;
|
|
}
|
|
|
|
static void resetUpBitRateParam() {
|
|
stVbrHelper.upBitrateCnt = 0;
|
|
stVbrHelper.upBitrateSum = 0;
|
|
}
|
|
|
|
void mtk_aac_vbr_prop_updated() {
|
|
bPropUpdate = false;
|
|
}
|
|
|
|
void mtk_aac_vbr_set_support(int bitrate_support_val) {
|
|
iPeerSupportVbrVal = bitrate_support_val;
|
|
}
|
|
|
|
void mtk_aac_vbr_set_max_mode(int max_vbr_mode) {
|
|
iMaxVbrMode = max_vbr_mode;
|
|
}
|
|
|
|
int mtk_aac_vbr_get_max_mode() {
|
|
return (int)iMaxVbrMode > MAX_A2DP_VBR_MODE ? AAC_VBR_DEFAULT_MODE : iMaxVbrMode;
|
|
}
|
|
|
|
/*******************************************************************************
|
|
**
|
|
** Function mtk_aac_vbr_enabled
|
|
**
|
|
** Description Check AAC VBR for enable, Input three Vaule:
|
|
** 1). persist.bluetooth.a2dp_aac_vbr.enable.
|
|
** 2). iPeerSupportVbrVal.
|
|
** 3). bPropUpdate.
|
|
**
|
|
** Returns bool
|
|
**
|
|
*******************************************************************************/
|
|
bool mtk_aac_vbr_enabled() {
|
|
if (!bPropUpdate) {
|
|
char value_aacvbr[PROPERTY_VALUE_MAX] = {'\0'};
|
|
osi_property_get("vendor.bluetooth.a2dp_aac_vbr.enable", value_aacvbr, "true");
|
|
bPropSupportVbr = (strcmp(value_aacvbr, "true") == 0);
|
|
bPropUpdate = true;
|
|
}
|
|
return (iPeerSupportVbrVal == A2DP_AAC_VARIABLE_BIT_RATE_ENABLED) &&
|
|
bPropUpdate && bPropSupportVbr;
|
|
}
|
|
|
|
/*******************************************************************************
|
|
**
|
|
** Function mtk_aac_vbr_get_mode
|
|
**
|
|
** Description Input queueLen to gets the current VBR mode.
|
|
**
|
|
** Returns int vbr_mode
|
|
**
|
|
*******************************************************************************/
|
|
int mtk_aac_vbr_get_mode(size_t queueLen) {
|
|
int vbr_mode = AACENC_BR_MODE_INVALID;
|
|
|
|
stVbrHelper.upBitrateSum += queueLen;
|
|
stVbrHelper.dnBitrateSum += queueLen;
|
|
stVbrHelper.upBitrateCnt++;
|
|
stVbrHelper.dnBitrateCnt++;
|
|
|
|
if (stVbrHelper.dnBitrateCnt >= stVbrHelper.dnthreshold) {
|
|
size_t queueLength = stVbrHelper.dnBitrateSum / stVbrHelper.dnBitrateCnt;
|
|
resetDnBitRateParam();
|
|
if (queueLength >= DOWN_QUEUE_LENGTH && stVbrHelper.cur_mode > MIN_A2DP_VBR_MODE) {
|
|
if (stVbrHelper.cur_mode >= AACENC_BR_MODE_VBR_3) stVbrHelper.cur_mode -= DOWN_ADJ_VBR_LEVEL;
|
|
else stVbrHelper.cur_mode = MIN_A2DP_VBR_MODE;
|
|
LOG_INFO("%s: [Down Bitrate] Adjust to low VBR mode(%d), queue length(%zu)",
|
|
__func__, stVbrHelper.cur_mode, queueLength);
|
|
resetUpBitRateParam();
|
|
}
|
|
}
|
|
|
|
if (stVbrHelper.upBitrateCnt >= stVbrHelper.upthreshold) {
|
|
size_t queueLength = stVbrHelper.upBitrateSum / stVbrHelper.upBitrateCnt;
|
|
resetUpBitRateParam();
|
|
int support_max_vbr_mode = mtk_aac_vbr_get_max_mode();
|
|
if (queueLength == UP_QUEUE_LENGTH && stVbrHelper.cur_mode < support_max_vbr_mode) {
|
|
stVbrHelper.cur_mode++;
|
|
if (stVbrHelper.cur_mode > support_max_vbr_mode) stVbrHelper.cur_mode = support_max_vbr_mode;
|
|
LOG_INFO("%s: [Up Bitrate] Adjust to high VBR mode(%d)",
|
|
__func__, stVbrHelper.cur_mode);
|
|
resetDnBitRateParam();
|
|
}
|
|
}
|
|
|
|
if (stVbrHelper.last_mode != stVbrHelper.cur_mode) {
|
|
vbr_mode = stVbrHelper.cur_mode;
|
|
stVbrHelper.last_mode = vbr_mode;
|
|
}
|
|
return vbr_mode;
|
|
}
|
|
|
|
#undef ATRACE_TAG
|