unplugged-vendor/system/bt/mediatek/stack/a2dp/a2dp_aac_vbr.cc

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