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