blob: 7ce5c9d2f2098878446391c70aa644d351f3d030 [file] [log] [blame]
Pawin Vongmasa36653902018-11-15 00:10:25 -08001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#include "DrcPresModeWrap.h"
17
18#include <assert.h>
19
20#define LOG_TAG "C2SoftAacDrcWrapper"
21//#define LOG_NDEBUG 0
22#include <utils/Log.h>
23
24//#define DRC_PRES_MODE_WRAP_DEBUG
25
26#define GPM_ENCODER_TARGET_LEVEL 64
27#define MAX_TARGET_LEVEL 40
28
29CDrcPresModeWrapper::CDrcPresModeWrapper()
30{
31 mDataUpdate = true;
32
33 /* Data from streamInfo. */
34 /* Initialized to the same values as in the aac decoder */
35 mStreamPRL = -1;
36 mStreamDRCPresMode = -1;
37 mStreamNrAACChan = 0;
38 mStreamNrOutChan = 0;
39
40 /* Desired values (set by user). */
41 /* Initialized to the same values as in the aac decoder */
42 mDesTarget = -1;
43 mDesAttFactor = 0;
44 mDesBoostFactor = 0;
45 mDesHeavy = 0;
46
47 mEncoderTarget = -1;
48
49 /* Values from last time. */
Jean-Michel Trivi41ce3372020-02-17 10:08:10 -080050 mLastTarget = -2;
51 mLastAttFactor = -1;
52 mLastBoostFactor = -1;
Pawin Vongmasa36653902018-11-15 00:10:25 -080053 mLastHeavy = 0;
54}
55
56CDrcPresModeWrapper::~CDrcPresModeWrapper()
57{
58}
59
60void
61CDrcPresModeWrapper::setDecoderHandle(const HANDLE_AACDECODER handle)
62{
63 mHandleDecoder = handle;
64}
65
66void
67CDrcPresModeWrapper::submitStreamData(CStreamInfo* pStreamInfo)
68{
69 assert(pStreamInfo);
70
71 if (mStreamPRL != pStreamInfo->drcProgRefLev) {
72 mStreamPRL = pStreamInfo->drcProgRefLev;
73 mDataUpdate = true;
74#ifdef DRC_PRES_MODE_WRAP_DEBUG
75 ALOGV("DRC presentation mode wrapper: drcProgRefLev is %d\n", mStreamPRL);
76#endif
77 }
78
79 if (mStreamDRCPresMode != pStreamInfo->drcPresMode) {
80 mStreamDRCPresMode = pStreamInfo->drcPresMode;
81 mDataUpdate = true;
82#ifdef DRC_PRES_MODE_WRAP_DEBUG
83 ALOGV("DRC presentation mode wrapper: drcPresMode is %d\n", mStreamDRCPresMode);
84#endif
85 }
86
87 if (mStreamNrAACChan != pStreamInfo->aacNumChannels) {
88 mStreamNrAACChan = pStreamInfo->aacNumChannels;
89 mDataUpdate = true;
90#ifdef DRC_PRES_MODE_WRAP_DEBUG
91 ALOGV("DRC presentation mode wrapper: aacNumChannels is %d\n", mStreamNrAACChan);
92#endif
93 }
94
95 if (mStreamNrOutChan != pStreamInfo->numChannels) {
96 mStreamNrOutChan = pStreamInfo->numChannels;
97 mDataUpdate = true;
98#ifdef DRC_PRES_MODE_WRAP_DEBUG
99 ALOGV("DRC presentation mode wrapper: numChannels is %d\n", mStreamNrOutChan);
100#endif
101 }
102
103
104
105 if (mStreamNrOutChan<mStreamNrAACChan) {
106 mIsDownmix = true;
107 } else {
108 mIsDownmix = false;
109 }
110
111 if (mIsDownmix && (mStreamNrOutChan == 1)) {
112 mIsMonoDownmix = true;
113 } else {
114 mIsMonoDownmix = false;
115 }
116
117 if (mIsDownmix && mStreamNrOutChan == 2){
118 mIsStereoDownmix = true;
119 } else {
120 mIsStereoDownmix = false;
121 }
122
123}
124
125void
126CDrcPresModeWrapper::setParam(const DRC_PRES_MODE_WRAP_PARAM param, const int value)
127{
128 switch (param) {
129 case DRC_PRES_MODE_WRAP_DESIRED_TARGET:
130 mDesTarget = value;
131 break;
132 case DRC_PRES_MODE_WRAP_DESIRED_ATT_FACTOR:
133 mDesAttFactor = value;
134 break;
135 case DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR:
136 mDesBoostFactor = value;
137 break;
138 case DRC_PRES_MODE_WRAP_DESIRED_HEAVY:
139 mDesHeavy = value;
140 break;
141 case DRC_PRES_MODE_WRAP_ENCODER_TARGET:
142 mEncoderTarget = value;
143 break;
144 default:
145 break;
146 }
147 mDataUpdate = true;
148}
149
150void
151CDrcPresModeWrapper::update()
152{
153 // Get Data from Decoder
154 int progRefLevel = mStreamPRL;
155 int drcPresMode = mStreamDRCPresMode;
156
157 // by default, do as desired
158 int newTarget = mDesTarget;
159 int newAttFactor = mDesAttFactor;
160 int newBoostFactor = mDesBoostFactor;
161 int newHeavy = mDesHeavy;
162
163 if (mDataUpdate) {
Alice Kuob52337f2020-08-05 01:09:04 +0800164 // Validation check
Jean-Michel Trivi41ce3372020-02-17 10:08:10 -0800165 if ((mDesTarget < MAX_TARGET_LEVEL) && (mDesTarget != -1)){
Pawin Vongmasa36653902018-11-15 00:10:25 -0800166 mDesTarget = MAX_TARGET_LEVEL; // limit target level to -10 dB or below
167 newTarget = MAX_TARGET_LEVEL;
168 }
169
170 if (mEncoderTarget != -1) {
171 if (mDesTarget<124) { // if target level > -31 dB
172 if ((mIsStereoDownmix == false) && (mIsMonoDownmix == false)) {
173 // no stereo or mono downmixing, calculated scaling of light DRC
174 /* use as little compression as possible */
175 newAttFactor = 0;
176 newBoostFactor = 0;
177 if (mDesTarget<progRefLevel) { // if target level > PRL
178 if (mEncoderTarget < mDesTarget) { // if mEncoderTarget > target level
179 // mEncoderTarget > target level > PRL
180 int calcFactor;
181 float calcFactor_norm;
182 // 0.0f < calcFactor_norm < 1.0f
183 calcFactor_norm = (float)(mDesTarget - progRefLevel) /
184 (float)(mEncoderTarget - progRefLevel);
185 calcFactor = (int)(calcFactor_norm*127.0f); // 0 <= calcFactor < 127
186 // calcFactor is the lower limit
187 newAttFactor = (calcFactor>newAttFactor) ? calcFactor : newAttFactor;
188 // new AttFactor will be always = calcFactor, as it is set to 0 before.
189 newBoostFactor = newAttFactor;
190 } else {
191 /* target level > mEncoderTarget > PRL */
192 // newTDLimiterEnable = 1;
193 // the time domain limiter must always be active in this case.
194 // It is assumed that the framework activates it by default
195 newAttFactor = 127;
196 newBoostFactor = 127;
197 }
198 } else { // target level <= PRL
199 // no restrictions required
200 // newAttFactor = newAttFactor;
201 }
202 } else { // downmixing
203 // if target level > -23 dB or mono downmix
204 if ( (mDesTarget<92) || mIsMonoDownmix ) {
205 newHeavy = 1;
206 } else {
207 // we perform a downmix, so, we need at least full light DRC
208 newAttFactor = 127;
209 }
210 }
211 } else { // target level <= -31 dB
212 // playback -31 dB: light DRC only needed if we perform downmixing
213 if (mIsDownmix) { // we do downmixing
214 newAttFactor = 127;
215 }
216 }
217 }
218 else { // handle other used encoder target levels
219
Alice Kuob52337f2020-08-05 01:09:04 +0800220 // Validation check: DRC presentation mode is only specified for max. 5.1 channels
Pawin Vongmasa36653902018-11-15 00:10:25 -0800221 if (mStreamNrAACChan > 6) {
222 drcPresMode = 0;
223 }
224
225 switch (drcPresMode) {
226 case 0:
227 default: // presentation mode not indicated
228 {
229
230 if (mDesTarget<124) { // if target level > -31 dB
231 // no stereo or mono downmixing
232 if ((mIsStereoDownmix == false) && (mIsMonoDownmix == false)) {
233 if (mDesTarget<progRefLevel) { // if target level > PRL
234 // newTDLimiterEnable = 1;
235 // the time domain limiter must always be active in this case.
236 // It is assumed that the framework activates it by default
237 newAttFactor = 127; // at least, use light compression
238 } else { // target level <= PRL
239 // no restrictions required
240 // newAttFactor = newAttFactor;
241 }
242 } else { // downmixing
243 // newTDLimiterEnable = 1;
244 // the time domain limiter must always be active in this case.
245 // It is assumed that the framework activates it by default
246
247 // if target level > -23 dB or mono downmix
248 if ( (mDesTarget < 92) || mIsMonoDownmix ) {
249 newHeavy = 1;
250 } else{
251 // we perform a downmix, so, we need at least full light DRC
252 newAttFactor = 127;
253 }
254 }
255 } else { // target level <= -31 dB
256 if (mIsDownmix) { // we do downmixing.
257 // newTDLimiterEnable = 1;
258 // the time domain limiter must always be active in this case.
259 // It is assumed that the framework activates it by default
260 newAttFactor = 127;
261 }
262 }
263 }
264 break;
265
266 // Presentation mode 1 and 2 according to ETSI TS 101 154:
267 // Digital Video Broadcasting (DVB); Specification for the use of Video and Audio Coding
268 // in Broadcasting Applications based on the MPEG-2 Transport Stream,
269 // section C.5.4., "Decoding", and Table C.33
270 // ISO DRC -> newHeavy = 0 (Use light compression, MPEG-style)
271 // Compression_value -> newHeavy = 1 (Use heavy compression, DVB-style)
272 // scaling restricted -> newAttFactor = 127
273
274 case 1: // presentation mode 1, Light:-31/Heavy:-23
275 {
276 if (mDesTarget < 124) { // if target level > -31 dB
277 // playback up to -23 dB
278 newHeavy = 1;
279 } else { // target level <= -31 dB
280 // playback -31 dB
281 if (mIsDownmix) { // we do downmixing.
282 newAttFactor = 127;
283 }
284 }
285 }
286 break;
287
288 case 2: // presentation mode 2, Light:-23/Heavy:-23
289 {
290 if (mDesTarget < 124) { // if target level > -31 dB
291 // playback up to -23 dB
292 if (mIsMonoDownmix) { // if mono downmix
293 newHeavy = 1;
294 } else {
295 newHeavy = 0;
296 newAttFactor = 127;
297 }
298 } else { // target level <= -31 dB
299 // playback -31 dB
300 newHeavy = 0;
301 if (mIsDownmix) { // we do downmixing.
302 newAttFactor = 127;
303 }
304 }
305 }
306 break;
307
308 } // switch()
309 } // if (mEncoderTarget == GPM_ENCODER_TARGET_LEVEL)
310
Alice Kuob52337f2020-08-05 01:09:04 +0800311 // Validation check again
Pawin Vongmasa36653902018-11-15 00:10:25 -0800312 if (newHeavy == 1) {
313 newBoostFactor=127; // not really needed as the same would be done by the decoder anyway
314 newAttFactor = 127;
315 }
316
317 // update the decoder
318 if (newTarget != mLastTarget) {
319 aacDecoder_SetParam(mHandleDecoder, AAC_DRC_REFERENCE_LEVEL, newTarget);
320 mLastTarget = newTarget;
321#ifdef DRC_PRES_MODE_WRAP_DEBUG
322 if (newTarget != mDesTarget)
323 ALOGV("DRC presentation mode wrapper: forced target level to %d (from %d)\n", newTarget, mDesTarget);
324 else
325 ALOGV("DRC presentation mode wrapper: set target level to %d\n", newTarget);
326#endif
327 }
328
329 if (newAttFactor != mLastAttFactor) {
330 aacDecoder_SetParam(mHandleDecoder, AAC_DRC_ATTENUATION_FACTOR, newAttFactor);
331 mLastAttFactor = newAttFactor;
332#ifdef DRC_PRES_MODE_WRAP_DEBUG
333 if (newAttFactor != mDesAttFactor)
334 ALOGV("DRC presentation mode wrapper: forced attenuation factor to %d (from %d)\n", newAttFactor, mDesAttFactor);
335 else
336 ALOGV("DRC presentation mode wrapper: set attenuation factor to %d\n", newAttFactor);
337#endif
338 }
339
340 if (newBoostFactor != mLastBoostFactor) {
341 aacDecoder_SetParam(mHandleDecoder, AAC_DRC_BOOST_FACTOR, newBoostFactor);
342 mLastBoostFactor = newBoostFactor;
343#ifdef DRC_PRES_MODE_WRAP_DEBUG
344 if (newBoostFactor != mDesBoostFactor)
345 ALOGV("DRC presentation mode wrapper: forced boost factor to %d (from %d)\n",
346 newBoostFactor, mDesBoostFactor);
347 else
348 ALOGV("DRC presentation mode wrapper: set boost factor to %d\n", newBoostFactor);
349#endif
350 }
351
352 if (newHeavy != mLastHeavy) {
353 aacDecoder_SetParam(mHandleDecoder, AAC_DRC_HEAVY_COMPRESSION, newHeavy);
354 mLastHeavy = newHeavy;
355#ifdef DRC_PRES_MODE_WRAP_DEBUG
356 if (newHeavy != mDesHeavy)
357 ALOGV("DRC presentation mode wrapper: forced heavy compression to %d (from %d)\n",
358 newHeavy, mDesHeavy);
359 else
360 ALOGV("DRC presentation mode wrapper: set heavy compression to %d\n", newHeavy);
361#endif
362 }
363
364#ifdef DRC_PRES_MODE_WRAP_DEBUG
365 ALOGV("DRC config: tgt_lev: %3d, cut: %3d, boost: %3d, heavy: %d\n", newTarget,
366 newAttFactor, newBoostFactor, newHeavy);
367#endif
368 mDataUpdate = false;
369
370 } // if (mDataUpdate)
371}