xref: /aosp_15_r20/external/libldac/abr/src/ldacBT_abr.c (revision aef9bcd9217ad2365ebc8e70efaf94b64e04df14)
1*aef9bcd9SKiyoung Kim /*
2*aef9bcd9SKiyoung Kim  * Copyright (C) 2014 - 2017 Sony Corporation
3*aef9bcd9SKiyoung Kim  *
4*aef9bcd9SKiyoung Kim  * Licensed under the Apache License, Version 2.0 (the "License");
5*aef9bcd9SKiyoung Kim  * you may not use this file except in compliance with the License.
6*aef9bcd9SKiyoung Kim  * You may obtain a copy of the License at
7*aef9bcd9SKiyoung Kim  *
8*aef9bcd9SKiyoung Kim  *      http://www.apache.org/licenses/LICENSE-2.0
9*aef9bcd9SKiyoung Kim  *
10*aef9bcd9SKiyoung Kim  * Unless required by applicable law or agreed to in writing, software
11*aef9bcd9SKiyoung Kim  * distributed under the License is distributed on an "AS IS" BASIS,
12*aef9bcd9SKiyoung Kim  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*aef9bcd9SKiyoung Kim  * See the License for the specific language governing permissions and
14*aef9bcd9SKiyoung Kim  * limitations under the License.
15*aef9bcd9SKiyoung Kim  */
16*aef9bcd9SKiyoung Kim 
17*aef9bcd9SKiyoung Kim #include "ldacBT_abr.h"
18*aef9bcd9SKiyoung Kim 
19*aef9bcd9SKiyoung Kim #include <stdlib.h>
20*aef9bcd9SKiyoung Kim #include <string.h>
21*aef9bcd9SKiyoung Kim 
22*aef9bcd9SKiyoung Kim #define LDAC_ABR_OBSERVING_TIME_MS 500 /* [ms] the time length for storing Tx Queue Depth */
23*aef9bcd9SKiyoung Kim #define LDAC_ABR_PENALTY_MAX 4
24*aef9bcd9SKiyoung Kim 
25*aef9bcd9SKiyoung Kim /* Number of observing count to judge whether EQMID may be increase.
26*aef9bcd9SKiyoung Kim  * Those count can convert in time by following formula:
27*aef9bcd9SKiyoung Kim  *    Time [ms] = (Count - abrQualityModeID) * LDAC_ABR_OBSERVING_TIME_MS
28*aef9bcd9SKiyoung Kim  *    where abrQualityModeID is the value which converted EQMID by aEqmidToAbrQualityModeID[].
29*aef9bcd9SKiyoung Kim  * Therefore, using the default value of 12, the observation time in each abrQualityModeID is
30*aef9bcd9SKiyoung Kim  * as follows:
31*aef9bcd9SKiyoung Kim  *       ----------------------------------------------------
32*aef9bcd9SKiyoung Kim  *      | abrQualityModeID     |  0  |  1  |  2  |  3  |  4  |
33*aef9bcd9SKiyoung Kim  *      | observation time [s] |  6  |  5  |  4  |  3  |  2  |
34*aef9bcd9SKiyoung Kim  *       ----------------------------------------------------
35*aef9bcd9SKiyoung Kim  */
36*aef9bcd9SKiyoung Kim #define LDAC_ABR_OBSERVING_COUNT_TO_JUDGE_INC_QUALITY 12
37*aef9bcd9SKiyoung Kim #define LDAC_ABR_OBSERVING_COUNT_FOR_INIT 6 /* = 3sec. keep same EQMID in first 3sec */
38*aef9bcd9SKiyoung Kim /* Default value for thresholds */
39*aef9bcd9SKiyoung Kim #define LDAC_ABR_THRESHOLD_CRITICAL_DEFAULT 6
40*aef9bcd9SKiyoung Kim #define LDAC_ABR_THRESHOLD_DANGEROUSTREND_DEFAULT 4
41*aef9bcd9SKiyoung Kim #define LDAC_ABR_THRESHOLD_SAFETY_FOR_HQSQ_DEFAULT 2
42*aef9bcd9SKiyoung Kim /* Number of steady state count to judge */
43*aef9bcd9SKiyoung Kim #define LDAC_ABR_NUM_STEADY_STATE_TO_JUDGE_STEADY 3
44*aef9bcd9SKiyoung Kim /* Number of steady state count to reset for LDACBT_EQMID_HQ */
45*aef9bcd9SKiyoung Kim #define LDAC_ABR_NUM_STEADY_STATE_TO_RESET_PENALTY_FOR_HQ 60
46*aef9bcd9SKiyoung Kim 
47*aef9bcd9SKiyoung Kim 
48*aef9bcd9SKiyoung Kim typedef struct _tx_queue_param
49*aef9bcd9SKiyoung Kim {
50*aef9bcd9SKiyoung Kim     unsigned char *pHist;
51*aef9bcd9SKiyoung Kim     unsigned int szHist;
52*aef9bcd9SKiyoung Kim     int  sum;
53*aef9bcd9SKiyoung Kim     unsigned int  cnt;
54*aef9bcd9SKiyoung Kim     unsigned int idx;
55*aef9bcd9SKiyoung Kim } TxQ_INFO;
56*aef9bcd9SKiyoung Kim 
57*aef9bcd9SKiyoung Kim typedef struct _ldacbt_abr_param
58*aef9bcd9SKiyoung Kim {
59*aef9bcd9SKiyoung Kim     TxQ_INFO TxQD_Info;
60*aef9bcd9SKiyoung Kim     int  cntToIncQuality;
61*aef9bcd9SKiyoung Kim     int  nSteadyState;
62*aef9bcd9SKiyoung Kim     int  nPenalty;
63*aef9bcd9SKiyoung Kim     int  abrQualityModeIdSteady;
64*aef9bcd9SKiyoung Kim     unsigned int  numToEvaluate;
65*aef9bcd9SKiyoung Kim     /* thresholds */
66*aef9bcd9SKiyoung Kim     unsigned int  thCritical;
67*aef9bcd9SKiyoung Kim     unsigned int  thDangerousTrend;
68*aef9bcd9SKiyoung Kim     unsigned int  thSafety4HQSQ;
69*aef9bcd9SKiyoung Kim } LDAC_ABR_PARAMS;
70*aef9bcd9SKiyoung Kim 
71*aef9bcd9SKiyoung Kim #define clear_data(ptr, n) memset(ptr, 0, n)
72*aef9bcd9SKiyoung Kim 
73*aef9bcd9SKiyoung Kim #ifdef LOCAL_DEBUG
74*aef9bcd9SKiyoung Kim #include <android/log.h>
75*aef9bcd9SKiyoung Kim #define ABRDBG(fmt, ... ) \
76*aef9bcd9SKiyoung Kim     __android_log_print( ANDROID_LOG_INFO, "******** LDAC ABR ********",\
77*aef9bcd9SKiyoung Kim             "%s@%s:%d::"fmt, __func__, __FILE__, __LINE__, ## __VA_ARGS__ )
78*aef9bcd9SKiyoung Kim #else
79*aef9bcd9SKiyoung Kim #define ABRDBG(fmt, ...)
80*aef9bcd9SKiyoung Kim #endif /* LOCAL_DEBUG */
81*aef9bcd9SKiyoung Kim 
82*aef9bcd9SKiyoung Kim /* A table for converting EQMID to abrQualityModeID which is sorted in descending order by bit rate.
83*aef9bcd9SKiyoung Kim  * The relationship between EQMID, bit rate and abrQualityModeID when the sampling frequency is
84*aef9bcd9SKiyoung Kim  * 96 kHz is as follows:
85*aef9bcd9SKiyoung Kim  *       ----------------------------------------------------
86*aef9bcd9SKiyoung Kim  *      | EQMID                |  0  |  1  |  2  |  3  |  4  |
87*aef9bcd9SKiyoung Kim  *      | bit rate [kbps]      | 990 | 660 | 330 | 492 | 396 |
88*aef9bcd9SKiyoung Kim  *      | abrQualityModeID     |  0  |  1  |  4  |  2  |  3  |
89*aef9bcd9SKiyoung Kim  *       ----------------------------------------------------
90*aef9bcd9SKiyoung Kim  */
91*aef9bcd9SKiyoung Kim static const int aEqmidToAbrQualityModeID[]={ 0, 1, 4, 2, 3};
92*aef9bcd9SKiyoung Kim static const int sizeOfEqmidToBitrateSortedIdTable = (int)(sizeof(aEqmidToAbrQualityModeID)
93*aef9bcd9SKiyoung Kim                                                      / sizeof(aEqmidToAbrQualityModeID[0]));
94*aef9bcd9SKiyoung Kim 
95*aef9bcd9SKiyoung Kim /* Get LDAC ABR handle */
ldac_ABR_get_handle(void)96*aef9bcd9SKiyoung Kim HANDLE_LDAC_ABR ldac_ABR_get_handle(void)
97*aef9bcd9SKiyoung Kim {
98*aef9bcd9SKiyoung Kim     HANDLE_LDAC_ABR hLdacAbr;
99*aef9bcd9SKiyoung Kim     ABRDBG( "" );
100*aef9bcd9SKiyoung Kim     if ((hLdacAbr = (HANDLE_LDAC_ABR)malloc(sizeof(LDAC_ABR_PARAMS))) == NULL) {
101*aef9bcd9SKiyoung Kim         ABRDBG( "[ERR] Failed to allocate memory for handle." );
102*aef9bcd9SKiyoung Kim         return NULL;
103*aef9bcd9SKiyoung Kim     }
104*aef9bcd9SKiyoung Kim     hLdacAbr->TxQD_Info.pHist = NULL;
105*aef9bcd9SKiyoung Kim     return hLdacAbr;
106*aef9bcd9SKiyoung Kim }
107*aef9bcd9SKiyoung Kim 
108*aef9bcd9SKiyoung Kim /* Free LDAC ABR handle */
ldac_ABR_free_handle(HANDLE_LDAC_ABR hLdacAbr)109*aef9bcd9SKiyoung Kim void ldac_ABR_free_handle(HANDLE_LDAC_ABR hLdacAbr)
110*aef9bcd9SKiyoung Kim {
111*aef9bcd9SKiyoung Kim     ABRDBG( "" );
112*aef9bcd9SKiyoung Kim     if (hLdacAbr != NULL) {
113*aef9bcd9SKiyoung Kim         if (hLdacAbr->TxQD_Info.pHist) {
114*aef9bcd9SKiyoung Kim             free(hLdacAbr->TxQD_Info.pHist);
115*aef9bcd9SKiyoung Kim         }
116*aef9bcd9SKiyoung Kim         free(hLdacAbr);
117*aef9bcd9SKiyoung Kim     }
118*aef9bcd9SKiyoung Kim }
119*aef9bcd9SKiyoung Kim 
120*aef9bcd9SKiyoung Kim /* Initialize LDAC ABR */
ldac_ABR_Init(HANDLE_LDAC_ABR hLdacAbr,unsigned int interval_ms)121*aef9bcd9SKiyoung Kim int ldac_ABR_Init( HANDLE_LDAC_ABR hLdacAbr, unsigned int interval_ms )
122*aef9bcd9SKiyoung Kim {
123*aef9bcd9SKiyoung Kim     ABRDBG( "hLdacAbr:0x%x, interval_ms:%u", (unsigned int)hLdacAbr, interval_ms );
124*aef9bcd9SKiyoung Kim     if (hLdacAbr == NULL) return -1;
125*aef9bcd9SKiyoung Kim     if (interval_ms == 0) return -1;
126*aef9bcd9SKiyoung Kim     if (interval_ms > LDAC_ABR_OBSERVING_TIME_MS) return -1;
127*aef9bcd9SKiyoung Kim 
128*aef9bcd9SKiyoung Kim     hLdacAbr->numToEvaluate = LDAC_ABR_OBSERVING_TIME_MS / interval_ms;
129*aef9bcd9SKiyoung Kim     hLdacAbr->TxQD_Info.sum = 0;
130*aef9bcd9SKiyoung Kim     hLdacAbr->TxQD_Info.cnt = 0;
131*aef9bcd9SKiyoung Kim     hLdacAbr->TxQD_Info.idx = 0;
132*aef9bcd9SKiyoung Kim     hLdacAbr->TxQD_Info.szHist = hLdacAbr->numToEvaluate + 1;
133*aef9bcd9SKiyoung Kim     if (hLdacAbr->TxQD_Info.pHist) free(hLdacAbr->TxQD_Info.pHist);
134*aef9bcd9SKiyoung Kim     if ((hLdacAbr->TxQD_Info.pHist =
135*aef9bcd9SKiyoung Kim             (unsigned char*)malloc(hLdacAbr->TxQD_Info.szHist * sizeof(unsigned char))) == NULL){
136*aef9bcd9SKiyoung Kim         return -1;
137*aef9bcd9SKiyoung Kim     }
138*aef9bcd9SKiyoung Kim     clear_data(hLdacAbr->TxQD_Info.pHist, hLdacAbr->TxQD_Info.szHist * sizeof(unsigned char));
139*aef9bcd9SKiyoung Kim 
140*aef9bcd9SKiyoung Kim     hLdacAbr->nSteadyState = 0;
141*aef9bcd9SKiyoung Kim     hLdacAbr->nPenalty = 1;
142*aef9bcd9SKiyoung Kim     hLdacAbr->abrQualityModeIdSteady = aEqmidToAbrQualityModeID[LDACBT_EQMID_HQ];
143*aef9bcd9SKiyoung Kim     hLdacAbr->cntToIncQuality = LDAC_ABR_OBSERVING_COUNT_FOR_INIT;
144*aef9bcd9SKiyoung Kim     /* thresholds */
145*aef9bcd9SKiyoung Kim     hLdacAbr->thCritical = LDAC_ABR_THRESHOLD_CRITICAL_DEFAULT;
146*aef9bcd9SKiyoung Kim     hLdacAbr->thDangerousTrend = LDAC_ABR_THRESHOLD_DANGEROUSTREND_DEFAULT;
147*aef9bcd9SKiyoung Kim     hLdacAbr->thSafety4HQSQ = LDAC_ABR_THRESHOLD_SAFETY_FOR_HQSQ_DEFAULT;
148*aef9bcd9SKiyoung Kim 
149*aef9bcd9SKiyoung Kim     return 0;
150*aef9bcd9SKiyoung Kim }
151*aef9bcd9SKiyoung Kim 
152*aef9bcd9SKiyoung Kim /* Setup thresholds for LDAC ABR */
ldac_ABR_set_thresholds(HANDLE_LDAC_ABR hLdacAbr,unsigned int thCritical,unsigned int thDangerousTrend,unsigned int thSafety4HQSQ)153*aef9bcd9SKiyoung Kim int ldac_ABR_set_thresholds( HANDLE_LDAC_ABR hLdacAbr, unsigned int thCritical,
154*aef9bcd9SKiyoung Kim                         unsigned int thDangerousTrend, unsigned int thSafety4HQSQ )
155*aef9bcd9SKiyoung Kim {
156*aef9bcd9SKiyoung Kim     ABRDBG( "thCritical=%u, thDangerousTrend=%u, thSafety4HQSQ=%u",
157*aef9bcd9SKiyoung Kim              thCritical, thDangerousTrend, thSafety4HQSQ);
158*aef9bcd9SKiyoung Kim     if (hLdacAbr == NULL) return -1;
159*aef9bcd9SKiyoung Kim     if (thCritical < thDangerousTrend) return -1;
160*aef9bcd9SKiyoung Kim     if (thDangerousTrend < thSafety4HQSQ) return -1;
161*aef9bcd9SKiyoung Kim     hLdacAbr->thCritical = thCritical;
162*aef9bcd9SKiyoung Kim     hLdacAbr->thDangerousTrend = thDangerousTrend;
163*aef9bcd9SKiyoung Kim     hLdacAbr->thSafety4HQSQ = thSafety4HQSQ;
164*aef9bcd9SKiyoung Kim     return 0;
165*aef9bcd9SKiyoung Kim }
166*aef9bcd9SKiyoung Kim 
167*aef9bcd9SKiyoung Kim /* LDAC ABR main process */
ldac_ABR_Proc(HANDLE_LDAC_BT hLDAC,HANDLE_LDAC_ABR hLdacAbr,unsigned int TxQueueDepth,unsigned int flagEnable)168*aef9bcd9SKiyoung Kim int ldac_ABR_Proc( HANDLE_LDAC_BT hLDAC, HANDLE_LDAC_ABR hLdacAbr,
169*aef9bcd9SKiyoung Kim               unsigned int TxQueueDepth, unsigned int flagEnable)
170*aef9bcd9SKiyoung Kim {
171*aef9bcd9SKiyoung Kim     int nStepsToChangeEQMID, abrQualityModeID, eqmid, i;
172*aef9bcd9SKiyoung Kim     unsigned int TxQD_curr, TxQD_prev;
173*aef9bcd9SKiyoung Kim #ifdef LOCAL_DEBUG
174*aef9bcd9SKiyoung Kim     int qd, TxQ; // for debug
175*aef9bcd9SKiyoung Kim #endif
176*aef9bcd9SKiyoung Kim 
177*aef9bcd9SKiyoung Kim     if (hLDAC == NULL) return -1;
178*aef9bcd9SKiyoung Kim     if (hLdacAbr == NULL) return -1;
179*aef9bcd9SKiyoung Kim 
180*aef9bcd9SKiyoung Kim     eqmid = ldacBT_get_eqmid(hLDAC);
181*aef9bcd9SKiyoung Kim     abrQualityModeID = -1;
182*aef9bcd9SKiyoung Kim     if ((LDACBT_EQMID_HQ <= eqmid) && (eqmid < sizeOfEqmidToBitrateSortedIdTable)) {
183*aef9bcd9SKiyoung Kim         abrQualityModeID = aEqmidToAbrQualityModeID[eqmid];
184*aef9bcd9SKiyoung Kim     }
185*aef9bcd9SKiyoung Kim #ifdef LOCAL_DEBUG
186*aef9bcd9SKiyoung Kim     ABRDBG( "[LDAC ABR] - abrQualityModeID : %d -- eqmid : %d -- TxQue : %d --------------",
187*aef9bcd9SKiyoung Kim             abrQualityModeID, eqmid, TxQueueDepth);
188*aef9bcd9SKiyoung Kim #endif
189*aef9bcd9SKiyoung Kim     /* check for the situation when unsupported eqmid was return from ldacBT_get_eqmid(). */
190*aef9bcd9SKiyoung Kim     if (abrQualityModeID < 0) return eqmid; /* return current eqmid. */
191*aef9bcd9SKiyoung Kim 
192*aef9bcd9SKiyoung Kim     /* update */
193*aef9bcd9SKiyoung Kim     TxQD_curr = TxQueueDepth;
194*aef9bcd9SKiyoung Kim     if ((i = hLdacAbr->TxQD_Info.idx - 1) < 0 ) i = hLdacAbr->TxQD_Info.szHist - 1;
195*aef9bcd9SKiyoung Kim     TxQD_prev = hLdacAbr->TxQD_Info.pHist[i];
196*aef9bcd9SKiyoung Kim 
197*aef9bcd9SKiyoung Kim     hLdacAbr->TxQD_Info.sum -= hLdacAbr->TxQD_Info.pHist[hLdacAbr->TxQD_Info.idx];
198*aef9bcd9SKiyoung Kim     hLdacAbr->TxQD_Info.pHist[hLdacAbr->TxQD_Info.idx] = (unsigned char)TxQD_curr;
199*aef9bcd9SKiyoung Kim     if (++hLdacAbr->TxQD_Info.idx >= hLdacAbr->TxQD_Info.szHist) hLdacAbr->TxQD_Info.idx = 0;
200*aef9bcd9SKiyoung Kim 
201*aef9bcd9SKiyoung Kim     hLdacAbr->TxQD_Info.sum += TxQD_curr;
202*aef9bcd9SKiyoung Kim     ++hLdacAbr->TxQD_Info.cnt;
203*aef9bcd9SKiyoung Kim 
204*aef9bcd9SKiyoung Kim #ifdef LOCAL_DEBUG
205*aef9bcd9SKiyoung Kim     qd  = (abrQualityModeID    * 100000000);
206*aef9bcd9SKiyoung Kim     qd += (hLdacAbr->nPenalty  *   1000000);
207*aef9bcd9SKiyoung Kim     qd += (hLdacAbr->cntToIncQuality *1000);
208*aef9bcd9SKiyoung Kim     qd += (hLdacAbr->nSteadyState);
209*aef9bcd9SKiyoung Kim     TxQ = TxQD_prev * 100 + TxQD_curr;
210*aef9bcd9SKiyoung Kim #endif
211*aef9bcd9SKiyoung Kim 
212*aef9bcd9SKiyoung Kim     /* judge */
213*aef9bcd9SKiyoung Kim     nStepsToChangeEQMID = 0;
214*aef9bcd9SKiyoung Kim     if (TxQD_curr >= hLdacAbr->thCritical) {
215*aef9bcd9SKiyoung Kim         /* for Critical situation */
216*aef9bcd9SKiyoung Kim         ABRDBG("Critical: %d, %d", TxQ, qd);
217*aef9bcd9SKiyoung Kim         nStepsToChangeEQMID = -1;
218*aef9bcd9SKiyoung Kim         if ((eqmid == LDACBT_EQMID_HQ) || (eqmid == LDACBT_EQMID_SQ)) {
219*aef9bcd9SKiyoung Kim             nStepsToChangeEQMID = -2;
220*aef9bcd9SKiyoung Kim         }
221*aef9bcd9SKiyoung Kim     }
222*aef9bcd9SKiyoung Kim     else if ((TxQD_curr > hLdacAbr->thDangerousTrend) && (TxQD_curr > TxQD_prev)) {
223*aef9bcd9SKiyoung Kim         ABRDBG("Dangerous: %d, %d", TxQ, qd);
224*aef9bcd9SKiyoung Kim         nStepsToChangeEQMID = -1;
225*aef9bcd9SKiyoung Kim     }
226*aef9bcd9SKiyoung Kim     else if ((TxQD_curr > hLdacAbr->thSafety4HQSQ) &&
227*aef9bcd9SKiyoung Kim              ((eqmid == LDACBT_EQMID_HQ) || (eqmid == LDACBT_EQMID_SQ))) {
228*aef9bcd9SKiyoung Kim         ABRDBG("Safety4HQSQ: %d, %d", TxQ, qd);
229*aef9bcd9SKiyoung Kim         nStepsToChangeEQMID = -1;
230*aef9bcd9SKiyoung Kim     }
231*aef9bcd9SKiyoung Kim     else if (hLdacAbr->TxQD_Info.cnt >= hLdacAbr->numToEvaluate) {
232*aef9bcd9SKiyoung Kim         int ave10;
233*aef9bcd9SKiyoung Kim         hLdacAbr->TxQD_Info.cnt = hLdacAbr->numToEvaluate;
234*aef9bcd9SKiyoung Kim         /* eanble average process */
235*aef9bcd9SKiyoung Kim         ave10 = (hLdacAbr->TxQD_Info.sum * 10) / hLdacAbr->TxQD_Info.cnt;
236*aef9bcd9SKiyoung Kim 
237*aef9bcd9SKiyoung Kim         if (ave10 > 15) { /* if average of TxQue_Count in 0.5[s] was larger than 1.5 */
238*aef9bcd9SKiyoung Kim             ABRDBG("ave: %d, %d, %d", TxQ, qd, ave10);
239*aef9bcd9SKiyoung Kim             nStepsToChangeEQMID = -1;
240*aef9bcd9SKiyoung Kim         }
241*aef9bcd9SKiyoung Kim         else {
242*aef9bcd9SKiyoung Kim             ++hLdacAbr->nSteadyState;
243*aef9bcd9SKiyoung Kim #ifdef LOCAL_DEBUG
244*aef9bcd9SKiyoung Kim             qd  = (abrQualityModeID    * 100000000);
245*aef9bcd9SKiyoung Kim             qd += (hLdacAbr->nPenalty  *   1000000);
246*aef9bcd9SKiyoung Kim             qd += (hLdacAbr->cntToIncQuality *1000);
247*aef9bcd9SKiyoung Kim             qd += (hLdacAbr->nSteadyState);
248*aef9bcd9SKiyoung Kim #endif
249*aef9bcd9SKiyoung Kim 
250*aef9bcd9SKiyoung Kim             if (hLdacAbr->TxQD_Info.sum == 0) {
251*aef9bcd9SKiyoung Kim                 if (--hLdacAbr->cntToIncQuality <= 0) {
252*aef9bcd9SKiyoung Kim                     ABRDBG("inc1: %d, %d, %d", TxQ, qd, ave10);
253*aef9bcd9SKiyoung Kim                     nStepsToChangeEQMID = 1;
254*aef9bcd9SKiyoung Kim                 }
255*aef9bcd9SKiyoung Kim                 else {
256*aef9bcd9SKiyoung Kim                     ABRDBG("reset: %d, %d, %d", TxQ, qd, ave10);
257*aef9bcd9SKiyoung Kim                     hLdacAbr->TxQD_Info.cnt = 0; // reset the number of sample for average proc.
258*aef9bcd9SKiyoung Kim                 }
259*aef9bcd9SKiyoung Kim             }
260*aef9bcd9SKiyoung Kim             else {
261*aef9bcd9SKiyoung Kim                 ABRDBG( "reset cntToIncQuality, %d,%d, %d", TxQ,qd, ave10);
262*aef9bcd9SKiyoung Kim                 hLdacAbr->cntToIncQuality = LDAC_ABR_OBSERVING_COUNT_TO_JUDGE_INC_QUALITY
263*aef9bcd9SKiyoung Kim                                             - 2 * abrQualityModeID;
264*aef9bcd9SKiyoung Kim                 if (abrQualityModeID >= hLdacAbr->abrQualityModeIdSteady) {
265*aef9bcd9SKiyoung Kim                     hLdacAbr->cntToIncQuality *= hLdacAbr->nPenalty;
266*aef9bcd9SKiyoung Kim                 }
267*aef9bcd9SKiyoung Kim             }
268*aef9bcd9SKiyoung Kim         }
269*aef9bcd9SKiyoung Kim     }
270*aef9bcd9SKiyoung Kim #ifdef LOCAL_DEBUG
271*aef9bcd9SKiyoung Kim     else {
272*aef9bcd9SKiyoung Kim         ABRDBG("Nothing %d, hLdacAbr->TxQD_Info.cnt %u", TxQ, hLdacAbr->TxQD_Info.cnt);
273*aef9bcd9SKiyoung Kim     }
274*aef9bcd9SKiyoung Kim #endif
275*aef9bcd9SKiyoung Kim     if (flagEnable) {
276*aef9bcd9SKiyoung Kim         if (nStepsToChangeEQMID) {
277*aef9bcd9SKiyoung Kim             int abrQualityModeIDNew;
278*aef9bcd9SKiyoung Kim             if (nStepsToChangeEQMID < 0) {
279*aef9bcd9SKiyoung Kim                 for (i = 0; i > nStepsToChangeEQMID; --i) {
280*aef9bcd9SKiyoung Kim                     if (ldacBT_alter_eqmid_priority(hLDAC, LDACBT_EQMID_INC_CONNECTION)) {
281*aef9bcd9SKiyoung Kim #ifdef LOCAL_DEBUG
282*aef9bcd9SKiyoung Kim                         int err;
283*aef9bcd9SKiyoung Kim                         err = ldacBT_get_error_code(hLDAC);
284*aef9bcd9SKiyoung Kim                         ABRDBG("Info@%d : %d ,%d, %d", __LINE__,
285*aef9bcd9SKiyoung Kim                                LDACBT_API_ERR(err), LDACBT_HANDLE_ERR(err), LDACBT_BLOCK_ERR(err));
286*aef9bcd9SKiyoung Kim #endif
287*aef9bcd9SKiyoung Kim                         break;// EQMID was already the ID of the highest connectivity.
288*aef9bcd9SKiyoung Kim                     }
289*aef9bcd9SKiyoung Kim                 }
290*aef9bcd9SKiyoung Kim 
291*aef9bcd9SKiyoung Kim                 eqmid = ldacBT_get_eqmid(hLDAC);
292*aef9bcd9SKiyoung Kim                 abrQualityModeIDNew = abrQualityModeID;
293*aef9bcd9SKiyoung Kim                 if (eqmid >= 0) {
294*aef9bcd9SKiyoung Kim                     if (eqmid < sizeOfEqmidToBitrateSortedIdTable) {
295*aef9bcd9SKiyoung Kim                         abrQualityModeIDNew = aEqmidToAbrQualityModeID[eqmid];
296*aef9bcd9SKiyoung Kim                     }
297*aef9bcd9SKiyoung Kim                 }
298*aef9bcd9SKiyoung Kim 
299*aef9bcd9SKiyoung Kim                 if (hLdacAbr->nSteadyState < LDAC_ABR_NUM_STEADY_STATE_TO_JUDGE_STEADY) {
300*aef9bcd9SKiyoung Kim                     hLdacAbr->abrQualityModeIdSteady = abrQualityModeIDNew - 1;
301*aef9bcd9SKiyoung Kim                     if (hLdacAbr->abrQualityModeIdSteady < 0) hLdacAbr->abrQualityModeIdSteady = 0;
302*aef9bcd9SKiyoung Kim                     hLdacAbr->nPenalty *= 2;
303*aef9bcd9SKiyoung Kim                     if(hLdacAbr->nPenalty > LDAC_ABR_PENALTY_MAX) {
304*aef9bcd9SKiyoung Kim                         hLdacAbr->nPenalty = LDAC_ABR_PENALTY_MAX; // MAX PENALTY
305*aef9bcd9SKiyoung Kim                     }
306*aef9bcd9SKiyoung Kim                 }
307*aef9bcd9SKiyoung Kim             }
308*aef9bcd9SKiyoung Kim             else {
309*aef9bcd9SKiyoung Kim                 if (ldacBT_alter_eqmid_priority( hLDAC, LDACBT_EQMID_INC_QUALITY )) {
310*aef9bcd9SKiyoung Kim #ifdef LOCAL_DEBUG
311*aef9bcd9SKiyoung Kim                     int err;
312*aef9bcd9SKiyoung Kim                     err = ldacBT_get_error_code(hLDAC);
313*aef9bcd9SKiyoung Kim                     ABRDBG("Info@%d : %d ,%d, %d", __LINE__,
314*aef9bcd9SKiyoung Kim                             LDACBT_API_ERR(err), LDACBT_HANDLE_ERR(err), LDACBT_BLOCK_ERR(err));
315*aef9bcd9SKiyoung Kim #endif
316*aef9bcd9SKiyoung Kim                     ;// EQMID was already the ID of the highest sound quality.
317*aef9bcd9SKiyoung Kim                 }
318*aef9bcd9SKiyoung Kim                 eqmid = ldacBT_get_eqmid(hLDAC);
319*aef9bcd9SKiyoung Kim                 abrQualityModeIDNew = abrQualityModeID;
320*aef9bcd9SKiyoung Kim                 if (eqmid >= 0) {
321*aef9bcd9SKiyoung Kim                     if (eqmid < sizeOfEqmidToBitrateSortedIdTable) {
322*aef9bcd9SKiyoung Kim                         abrQualityModeIDNew = aEqmidToAbrQualityModeID[eqmid];
323*aef9bcd9SKiyoung Kim                     }
324*aef9bcd9SKiyoung Kim                 }
325*aef9bcd9SKiyoung Kim                 if (abrQualityModeIDNew < hLdacAbr->abrQualityModeIdSteady) {
326*aef9bcd9SKiyoung Kim                     hLdacAbr->nPenalty = 1;
327*aef9bcd9SKiyoung Kim                 }
328*aef9bcd9SKiyoung Kim                 if (abrQualityModeIDNew == aEqmidToAbrQualityModeID[0]) { /* for HQ */
329*aef9bcd9SKiyoung Kim                     if (hLdacAbr->nSteadyState > LDAC_ABR_NUM_STEADY_STATE_TO_RESET_PENALTY_FOR_HQ) {
330*aef9bcd9SKiyoung Kim                         hLdacAbr->nPenalty = 1;
331*aef9bcd9SKiyoung Kim                     }
332*aef9bcd9SKiyoung Kim                 }
333*aef9bcd9SKiyoung Kim             }
334*aef9bcd9SKiyoung Kim 
335*aef9bcd9SKiyoung Kim             hLdacAbr->nSteadyState = 0;
336*aef9bcd9SKiyoung Kim             // reset the number of sample for average proc.
337*aef9bcd9SKiyoung Kim             hLdacAbr->TxQD_Info.cnt = 0;
338*aef9bcd9SKiyoung Kim             hLdacAbr->cntToIncQuality = LDAC_ABR_OBSERVING_COUNT_TO_JUDGE_INC_QUALITY
339*aef9bcd9SKiyoung Kim                                         - 2 * abrQualityModeIDNew;
340*aef9bcd9SKiyoung Kim             if (hLdacAbr->cntToIncQuality <= 0) {
341*aef9bcd9SKiyoung Kim                 // set minimum value.  e1 f == 0.5[s]
342*aef9bcd9SKiyoung Kim                 hLdacAbr->cntToIncQuality = 1;
343*aef9bcd9SKiyoung Kim             }
344*aef9bcd9SKiyoung Kim             hLdacAbr->cntToIncQuality *= hLdacAbr->nPenalty;
345*aef9bcd9SKiyoung Kim             ABRDBG("EQMID NOW %d", eqmid);
346*aef9bcd9SKiyoung Kim         }
347*aef9bcd9SKiyoung Kim     }
348*aef9bcd9SKiyoung Kim #ifdef LOCAL_DEBUG
349*aef9bcd9SKiyoung Kim     else if (TxQueueDepth) {
350*aef9bcd9SKiyoung Kim         ABRDBG("flagEnable false: %d ,%d", TxQ, qd);
351*aef9bcd9SKiyoung Kim     }
352*aef9bcd9SKiyoung Kim #endif
353*aef9bcd9SKiyoung Kim 
354*aef9bcd9SKiyoung Kim     return eqmid;
355*aef9bcd9SKiyoung Kim }
356