1 /*
2 ** Copyright 2003-2010, VisualOn, Inc.
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 /*******************************************************************************
17 File: aacenc.c
18
19 Content: aac encoder interface functions
20
21 *******************************************************************************/
22
23 #include "voAAC.h"
24 #include "typedef.h"
25 #include "aacenc_core.h"
26 #include "aac_rom.h"
27 #include "cmnMemory.h"
28 #include "memalign.h"
29
30 #define UNUSED(x) (void)(x)
31
32 /**
33 * Init the audio codec module and return codec handle
34 * \param phCodec [OUT] Return the video codec handle
35 * \param vType [IN] The codec type if the module support multi codec.
36 * \param pUserData [IN] The init param. It is memory operator or alloced memory
37 * \retval VO_ERR_NONE Succeeded.
38 */
voAACEncInit(VO_HANDLE * phCodec,VO_AUDIO_CODINGTYPE vType,VO_CODEC_INIT_USERDATA * pUserData)39 VO_U32 VO_API voAACEncInit(VO_HANDLE * phCodec,VO_AUDIO_CODINGTYPE vType, VO_CODEC_INIT_USERDATA *pUserData)
40 {
41 AAC_ENCODER*hAacEnc;
42 int error;
43
44 #ifdef USE_DEAULT_MEM
45 VO_MEM_OPERATOR voMemoprator;
46 #endif
47 VO_MEM_OPERATOR *pMemOP;
48
49 #ifdef USE_DEAULT_MEM
50 int interMem;
51 interMem = 0;
52 #endif
53
54 UNUSED(vType);
55
56 error = 0;
57
58 /* init the memory operator */
59 if(pUserData == NULL || pUserData->memflag != VO_IMF_USERMEMOPERATOR || pUserData->memData == NULL )
60 {
61 #ifdef USE_DEAULT_MEM
62 voMemoprator.Alloc = cmnMemAlloc;
63 voMemoprator.Copy = cmnMemCopy;
64 voMemoprator.Free = cmnMemFree;
65 voMemoprator.Set = cmnMemSet;
66 voMemoprator.Check = cmnMemCheck;
67
68 interMem = 1;
69
70 pMemOP = &voMemoprator;
71 #else
72 *phCodec = NULL;
73 return VO_ERR_INVALID_ARG;
74 #endif
75 }
76 else
77 {
78 pMemOP = (VO_MEM_OPERATOR *)pUserData->memData;
79 }
80
81 /* init the aac encoder handle */
82 hAacEnc = (AAC_ENCODER*)mem_malloc(pMemOP, sizeof(AAC_ENCODER), 32, VO_INDEX_ENC_AAC);
83 if(NULL == hAacEnc)
84 {
85 error = 1;
86 }
87
88 if(!error)
89 {
90 /* init the aac encoder intra memory */
91 hAacEnc->intbuf = (short *)mem_malloc(pMemOP, AACENC_BLOCKSIZE*MAX_CHANNELS*sizeof(short), 32, VO_INDEX_ENC_AAC);
92 if(NULL == hAacEnc->intbuf)
93 {
94 error = 1;
95 }
96 }
97
98 if (!error) {
99 /* init the aac encoder psychoacoustic */
100 error = (PsyNew(&hAacEnc->psyKernel, MAX_CHANNELS, pMemOP) ||
101 PsyOutNew(&hAacEnc->psyOut, pMemOP));
102 }
103
104 if (!error) {
105 /* init the aac encoder quantization elements */
106 error = QCOutNew(&hAacEnc->qcOut,MAX_CHANNELS, pMemOP);
107 }
108
109 if (!error) {
110 /* init the aac encoder quantization state */
111 error = QCNew(&hAacEnc->qcKernel, pMemOP);
112 }
113
114 /* uninit the aac encoder if error is nozero */
115 if(error)
116 {
117 AacEncClose(hAacEnc, pMemOP);
118 if(hAacEnc)
119 {
120 mem_free(pMemOP, hAacEnc, VO_INDEX_ENC_AAC);
121 hAacEnc = NULL;
122 }
123 *phCodec = NULL;
124 return VO_ERR_OUTOF_MEMORY;
125 }
126
127 /* init the aac encoder memory operator */
128 #ifdef USE_DEAULT_MEM
129 if(interMem)
130 {
131 hAacEnc->voMemoprator.Alloc = cmnMemAlloc;
132 hAacEnc->voMemoprator.Copy = cmnMemCopy;
133 hAacEnc->voMemoprator.Free = cmnMemFree;
134 hAacEnc->voMemoprator.Set = cmnMemSet;
135 hAacEnc->voMemoprator.Check = cmnMemCheck;
136
137 pMemOP = &hAacEnc->voMemoprator;
138 }
139 #endif
140 /* init the aac encoder default parameter */
141 if(hAacEnc->initOK == 0)
142 {
143 AACENC_CONFIG config;
144 config.adtsUsed = 1;
145 config.bitRate = 128000;
146 config.nChannelsIn = 2;
147 config.nChannelsOut = 2;
148 config.sampleRate = 44100;
149 config.bandWidth = 20000;
150
151 AacEncOpen(hAacEnc, config);
152 }
153
154 hAacEnc->voMemop = pMemOP;
155
156 *phCodec = hAacEnc;
157
158 return VO_ERR_NONE;
159 }
160
161 /**
162 * Set input audio data.
163 * \param hCodec [IN]] The Codec Handle which was created by Init function.
164 * \param pInput [IN] The input buffer param.
165 * \param pOutBuffer [OUT] The output buffer info.
166 * \retval VO_ERR_NONE Succeeded.
167 */
voAACEncSetInputData(VO_HANDLE hCodec,VO_CODECBUFFER * pInput)168 VO_U32 VO_API voAACEncSetInputData(VO_HANDLE hCodec, VO_CODECBUFFER * pInput)
169 {
170 AAC_ENCODER *hAacEnc;
171 int length;
172
173 if(NULL == hCodec || NULL == pInput || NULL == pInput->Buffer)
174 {
175 return VO_ERR_INVALID_ARG;
176 }
177
178 hAacEnc = (AAC_ENCODER *)hCodec;
179
180 /* init input pcm buffer and length*/
181 hAacEnc->inbuf = (short *)pInput->Buffer;
182 hAacEnc->inlen = pInput->Length / sizeof(short);
183 hAacEnc->uselength = 0;
184
185 hAacEnc->encbuf = hAacEnc->inbuf;
186 hAacEnc->enclen = hAacEnc->inlen;
187
188 /* rebuild intra pcm buffer and length*/
189 if(hAacEnc->intlen)
190 {
191 length = min(hAacEnc->config.nChannelsIn*AACENC_BLOCKSIZE - hAacEnc->intlen, hAacEnc->inlen);
192 hAacEnc->voMemop->Copy(VO_INDEX_ENC_AAC, hAacEnc->intbuf + hAacEnc->intlen,
193 hAacEnc->inbuf, length*sizeof(short));
194
195 hAacEnc->encbuf = hAacEnc->intbuf;
196 hAacEnc->enclen = hAacEnc->intlen + length;
197
198 hAacEnc->inbuf += length;
199 hAacEnc->inlen -= length;
200 }
201
202 return VO_ERR_NONE;
203 }
204
205 /**
206 * Get the outut audio data
207 * \param hCodec [IN]] The Codec Handle which was created by Init function.
208 * \param pOutBuffer [OUT] The output audio data
209 * \param pOutInfo [OUT] The dec module filled audio format and used the input size.
210 * pOutInfo->InputUsed is total used the input size.
211 * \retval VO_ERR_NONE Succeeded.
212 * VO_ERR_INPUT_BUFFER_SMALL. The input was finished or the input data was not enought.
213 */
voAACEncGetOutputData(VO_HANDLE hCodec,VO_CODECBUFFER * pOutput,VO_AUDIO_OUTPUTINFO * pOutInfo)214 VO_U32 VO_API voAACEncGetOutputData(VO_HANDLE hCodec, VO_CODECBUFFER * pOutput, VO_AUDIO_OUTPUTINFO * pOutInfo)
215 {
216 AAC_ENCODER* hAacEnc = (AAC_ENCODER*)hCodec;
217 Word16 numAncDataBytes=0;
218 Word32 inbuflen;
219 int length;
220 if(NULL == hAacEnc)
221 return VO_ERR_INVALID_ARG;
222
223 inbuflen = AACENC_BLOCKSIZE*hAacEnc->config.nChannelsIn;
224
225 /* check the input pcm buffer and length*/
226 if(NULL == hAacEnc->encbuf || hAacEnc->enclen < inbuflen)
227 {
228 length = hAacEnc->enclen;
229 if(hAacEnc->intlen == 0)
230 {
231 hAacEnc->voMemop->Copy(VO_INDEX_ENC_AAC, hAacEnc->intbuf,
232 hAacEnc->encbuf, length*sizeof(short));
233 hAacEnc->uselength += length*sizeof(short);
234 }
235 else
236 {
237 hAacEnc->uselength += (length - hAacEnc->intlen)*sizeof(short);
238 }
239
240 hAacEnc->intlen = length;
241
242 pOutput->Length = 0;
243 if(pOutInfo)
244 pOutInfo->InputUsed = hAacEnc->uselength;
245 return VO_ERR_INPUT_BUFFER_SMALL;
246 }
247
248 /* check the output aac buffer and length*/
249 if(NULL == pOutput || NULL == pOutput->Buffer || pOutput->Length < (6144/8)*hAacEnc->config.nChannelsOut/(sizeof(Word32)))
250 return VO_ERR_OUTPUT_BUFFER_SMALL;
251
252 /* aac encoder core function */
253 AacEncEncode( hAacEnc,
254 (Word16*)hAacEnc->encbuf,
255 NULL,
256 &numAncDataBytes,
257 pOutput->Buffer,
258 &pOutput->Length);
259
260 /* update the input pcm buffer and length*/
261 if(hAacEnc->intlen)
262 {
263 length = inbuflen - hAacEnc->intlen;
264 hAacEnc->encbuf = hAacEnc->inbuf;
265 hAacEnc->enclen = hAacEnc->inlen;
266 hAacEnc->uselength += length*sizeof(short);
267 hAacEnc->intlen = 0;
268 }
269 else
270 {
271 hAacEnc->encbuf = hAacEnc->encbuf + inbuflen;
272 hAacEnc->enclen = hAacEnc->enclen - inbuflen;
273 hAacEnc->uselength += inbuflen*sizeof(short);
274 }
275
276 /* update the output aac information */
277 if(pOutInfo)
278 {
279 pOutInfo->Format.Channels = hAacEnc->config.nChannelsOut;
280 pOutInfo->Format.SampleRate = hAacEnc->config.sampleRate;
281 pOutInfo->Format.SampleBits = 16;
282 pOutInfo->InputUsed = hAacEnc->uselength;
283 }
284
285 return VO_ERR_NONE;
286 }
287
288 /**
289 * Uninit the Codec.
290 * \param hCodec [IN]] The Codec Handle which was created by Init function.
291 * \retval VO_ERR_NONE Succeeded.
292 */
voAACEncUninit(VO_HANDLE hCodec)293 VO_U32 VO_API voAACEncUninit(VO_HANDLE hCodec)
294 {
295 AAC_ENCODER* hAacEnc = (AAC_ENCODER*)hCodec;
296
297 if(NULL != hAacEnc)
298 {
299 /* close the aac encoder */
300 AacEncClose(hAacEnc, hAacEnc->voMemop);
301
302 /* free the aac encoder handle*/
303 mem_free(hAacEnc->voMemop, hAacEnc, VO_INDEX_ENC_AAC);
304 hAacEnc = NULL;
305 }
306
307 return VO_ERR_NONE;
308 }
309
310 /**
311 * Set the param for special target.
312 * \param hCodec [IN]] The Codec Handle which was created by Init function.
313 * \param uParamID [IN] The param ID.
314 * \param pData [IN] The param value depend on the ID>
315 * \retval VO_ERR_NONE Succeeded.
316 */
voAACEncSetParam(VO_HANDLE hCodec,VO_S32 uParamID,VO_PTR pData)317 VO_U32 VO_API voAACEncSetParam(VO_HANDLE hCodec, VO_S32 uParamID, VO_PTR pData)
318 {
319 AACENC_CONFIG config;
320 AACENC_PARAM* pAAC_param;
321 VO_AUDIO_FORMAT *pWAV_Format;
322 AAC_ENCODER* hAacEnc = (AAC_ENCODER*)hCodec;
323 int ret, i, bitrate, tmp;
324 int SampleRateIdx;
325
326 if(NULL == hAacEnc)
327 return VO_ERR_INVALID_ARG;
328
329 switch(uParamID)
330 {
331 case VO_PID_AAC_ENCPARAM: /* init aac encoder parameter*/
332 AacInitDefaultConfig(&config);
333 if(pData == NULL)
334 return VO_ERR_INVALID_ARG;
335 pAAC_param = (AACENC_PARAM*)pData;
336 config.adtsUsed = pAAC_param->adtsUsed;
337 config.bitRate = pAAC_param->bitRate;
338 config.nChannelsIn = pAAC_param->nChannels;
339 config.nChannelsOut = pAAC_param->nChannels;
340 config.sampleRate = pAAC_param->sampleRate;
341
342 /* check the channel */
343 if(config.nChannelsIn< 1 || config.nChannelsIn > MAX_CHANNELS ||
344 config.nChannelsOut < 1 || config.nChannelsOut > MAX_CHANNELS || config.nChannelsIn < config.nChannelsOut)
345 return VO_ERR_AUDIO_UNSCHANNEL;
346
347 /* check the samplerate */
348 ret = -1;
349 for(i = 0; i < NUM_SAMPLE_RATES; i++)
350 {
351 if(config.sampleRate == sampRateTab[i])
352 {
353 ret = 0;
354 break;
355 }
356 }
357 if(ret < 0)
358 return VO_ERR_AUDIO_UNSSAMPLERATE;
359
360 SampleRateIdx = i;
361
362 tmp = 441;
363 if(config.sampleRate%8000 == 0)
364 tmp =480;
365 /* check the bitrate */
366 if(config.bitRate!=0 && ((config.bitRate/config.nChannelsOut < 4000) ||
367 (config.bitRate/config.nChannelsOut > 160000) ||
368 (config.bitRate > config.sampleRate*6*config.nChannelsOut)))
369 {
370 config.bitRate = 640*config.sampleRate/tmp*config.nChannelsOut;
371
372 if(config.bitRate/config.nChannelsOut < 4000)
373 config.bitRate = 4000 * config.nChannelsOut;
374 else if(config.bitRate > config.sampleRate*6*config.nChannelsOut)
375 config.bitRate = config.sampleRate*6*config.nChannelsOut;
376 else if(config.bitRate/config.nChannelsOut > 160000)
377 config.bitRate = config.nChannelsOut*160000;
378 }
379
380 /* check the bandwidth */
381 bitrate = config.bitRate / config.nChannelsOut;
382 bitrate = bitrate * tmp / config.sampleRate;
383
384 for (i = 0; rates[i]; i++)
385 {
386 if (rates[i] >= bitrate)
387 break;
388 }
389
390 config.bandWidth = BandwithCoefTab[i][SampleRateIdx];
391
392 /* init aac encoder core */
393 ret = AacEncOpen(hAacEnc, config);
394 if(ret)
395 return VO_ERR_AUDIO_UNSFEATURE;
396 break;
397 case VO_PID_AUDIO_FORMAT: /* init pcm channel and samplerate*/
398 AacInitDefaultConfig(&config);
399 if(pData == NULL)
400 return VO_ERR_INVALID_ARG;
401 pWAV_Format = (VO_AUDIO_FORMAT*)pData;
402 config.adtsUsed = 1;
403 config.nChannelsIn = pWAV_Format->Channels;
404 config.nChannelsOut = pWAV_Format->Channels;
405 config.sampleRate = pWAV_Format->SampleRate;
406
407 /* check the channel */
408 if(config.nChannelsIn< 1 || config.nChannelsIn > MAX_CHANNELS ||
409 config.nChannelsOut < 1 || config.nChannelsOut > MAX_CHANNELS || config.nChannelsIn < config.nChannelsOut)
410 return VO_ERR_AUDIO_UNSCHANNEL;
411
412 /* check the samplebits */
413 if(pWAV_Format->SampleBits != 16)
414 {
415 return VO_ERR_AUDIO_UNSFEATURE;
416 }
417
418 /* check the samplerate */
419 ret = -1;
420 for(i = 0; i < NUM_SAMPLE_RATES; i++)
421 {
422 if(config.sampleRate == sampRateTab[i])
423 {
424 ret = 0;
425 break;
426 }
427 }
428 if(ret < 0)
429 return VO_ERR_AUDIO_UNSSAMPLERATE;
430
431 SampleRateIdx = i;
432
433 /* update the bitrates */
434 tmp = 441;
435 if(config.sampleRate%8000 == 0)
436 tmp =480;
437
438 config.bitRate = 640*config.sampleRate/tmp*config.nChannelsOut;
439
440 if(config.bitRate/config.nChannelsOut < 4000)
441 config.bitRate = 4000 * config.nChannelsOut;
442 else if(config.bitRate > config.sampleRate*6*config.nChannelsOut)
443 config.bitRate = config.sampleRate*6*config.nChannelsOut;
444 else if(config.bitRate/config.nChannelsOut > 160000)
445 config.bitRate = config.nChannelsOut*160000;
446
447 /* check the bandwidth */
448 bitrate = config.bitRate / config.nChannelsOut;
449 bitrate = bitrate * tmp / config.sampleRate;
450
451 for (i = 0; rates[i]; i++)
452 {
453 if (rates[i] >= bitrate)
454 break;
455 }
456
457 config.bandWidth = BandwithCoefTab[i][SampleRateIdx];
458
459 /* init aac encoder core */
460 ret = AacEncOpen(hAacEnc, config);
461 if(ret)
462 return VO_ERR_AUDIO_UNSFEATURE;
463 break;
464 default:
465 return VO_ERR_WRONG_PARAM_ID;
466 }
467
468 return VO_ERR_NONE;
469 }
470
471 /**
472 * Get the param for special target.
473 * \param hCodec [IN]] The Codec Handle which was created by Init function.
474 * \param uParamID [IN] The param ID.
475 * \param pData [IN] The param value depend on the ID>
476 * \retval VO_ERR_NONE Succeeded.
477 */
voAACEncGetParam(VO_HANDLE hCodec,VO_S32 uParamID,VO_PTR pData)478 VO_U32 VO_API voAACEncGetParam(VO_HANDLE hCodec, VO_S32 uParamID, VO_PTR pData)
479 {
480 UNUSED(hCodec);
481 UNUSED(uParamID);
482 UNUSED(pData);
483
484 return VO_ERR_NONE;
485 }
486
487 /**
488 * Get audio codec API interface
489 * \param pEncHandle [out] Return the AAC Encoder handle.
490 * \retval VO_ERR_OK Succeeded.
491 */
voGetAACEncAPI(VO_AUDIO_CODECAPI * pDecHandle)492 VO_S32 VO_API voGetAACEncAPI(VO_AUDIO_CODECAPI * pDecHandle)
493 {
494 if(pDecHandle == NULL)
495 return VO_ERR_INVALID_ARG;
496
497 pDecHandle->Init = voAACEncInit;
498 pDecHandle->SetInputData = voAACEncSetInputData;
499 pDecHandle->GetOutputData = voAACEncGetOutputData;
500 pDecHandle->SetParam = voAACEncSetParam;
501 pDecHandle->GetParam = voAACEncGetParam;
502 pDecHandle->Uninit = voAACEncUninit;
503
504 return VO_ERR_NONE;
505 }
506