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_core.c
18
19 Content: aac encoder core functions
20
21 *******************************************************************************/
22
23 #include "typedef.h"
24 #include "aacenc_core.h"
25 #include "bitenc.h"
26
27 #include "psy_configuration.h"
28 #include "psy_main.h"
29 #include "qc_main.h"
30 #include "psy_main.h"
31 #include "channel_map.h"
32 #include "aac_rom.h"
33
34 /********************************************************************************
35 *
36 * function name: AacInitDefaultConfig
37 * description: gives reasonable default configuration
38 *
39 **********************************************************************************/
AacInitDefaultConfig(AACENC_CONFIG * config)40 void AacInitDefaultConfig(AACENC_CONFIG *config)
41 {
42 /* default configurations */
43 config->adtsUsed = 1;
44 config->nChannelsIn = 2;
45 config->nChannelsOut = 2;
46 config->bitRate = 128000;
47 config->bandWidth = 0;
48 }
49
50 /********************************************************************************
51 *
52 * function name: AacEncOpen
53 * description: allocate and initialize a new encoder instance
54 * returns: 0 if success
55 *
56 **********************************************************************************/
AacEncOpen(AAC_ENCODER * hAacEnc,const AACENC_CONFIG config)57 Word16 AacEncOpen( AAC_ENCODER* hAacEnc, /* pointer to an encoder handle, initialized on return */
58 const AACENC_CONFIG config /* pre-initialized config struct */
59 )
60 {
61 Word32 error = 0;
62 Word16 profile = 1;
63
64 ELEMENT_INFO *elInfo = NULL;
65
66 if (hAacEnc==0) {
67 error=1;
68 }
69
70 if (!error) {
71 hAacEnc->config = config;
72 }
73
74 if (!error) {
75 error = InitElementInfo (config.nChannelsOut,
76 &hAacEnc->elInfo);
77 }
78
79 if (!error) {
80 elInfo = &hAacEnc->elInfo;
81 }
82
83 if (!error) {
84 /* use or not tns tool for long and short block */
85 Word16 tnsMask=3;
86
87 /* init encoder psychoacoustic */
88 error = psyMainInit(&hAacEnc->psyKernel,
89 config.sampleRate,
90 config.bitRate,
91 elInfo->nChannelsInEl,
92 tnsMask,
93 hAacEnc->config.bandWidth);
94 }
95
96 /* use or not adts header */
97 if(!error) {
98 hAacEnc->qcOut.qcElement.adtsUsed = config.adtsUsed;
99 }
100
101 /* init encoder quantization */
102 if (!error) {
103 struct QC_INIT qcInit;
104
105 /*qcInit.channelMapping = &hAacEnc->channelMapping;*/
106 qcInit.elInfo = &hAacEnc->elInfo;
107
108 qcInit.maxBits = (Word16) (MAXBITS_COEF*elInfo->nChannelsInEl);
109 qcInit.bitRes = qcInit.maxBits;
110 qcInit.averageBits = (Word16) ((config.bitRate * FRAME_LEN_LONG) / config.sampleRate);
111
112 qcInit.padding.paddingRest = config.sampleRate;
113
114 qcInit.meanPe = (Word16) ((10 * FRAME_LEN_LONG * hAacEnc->config.bandWidth) /
115 (config.sampleRate>>1));
116
117 qcInit.maxBitFac = (Word16) ((100 * (MAXBITS_COEF-MINBITS_COEF)* elInfo->nChannelsInEl)/
118 (qcInit.averageBits?qcInit.averageBits:1));
119
120 qcInit.bitrate = config.bitRate;
121
122 error = QCInit(&hAacEnc->qcKernel, &qcInit);
123 }
124
125 /* init bitstream encoder */
126 if (!error) {
127 hAacEnc->bseInit.nChannels = elInfo->nChannelsInEl;
128 hAacEnc->bseInit.bitrate = config.bitRate;
129 hAacEnc->bseInit.sampleRate = config.sampleRate;
130 hAacEnc->bseInit.profile = profile;
131 }
132
133 return error;
134 }
135
136 /********************************************************************************
137 *
138 * function name: AacEncEncode
139 * description: encode pcm to aac data core function
140 * returns: 0 if success
141 *
142 **********************************************************************************/
AacEncEncode(AAC_ENCODER * aacEnc,Word16 * timeSignal,const UWord8 * ancBytes,Word16 * numAncBytes,UWord8 * outBytes,VO_U32 * numOutBytes)143 Word16 AacEncEncode(AAC_ENCODER *aacEnc, /*!< an encoder handle */
144 Word16 *timeSignal, /*!< BLOCKSIZE*nChannels audio samples, interleaved */
145 const UWord8 *ancBytes, /*!< pointer to ancillary data bytes */
146 Word16 *numAncBytes, /*!< number of ancillary Data Bytes */
147 UWord8 *outBytes, /*!< pointer to output buffer (must be large MINBITS_COEF/8*MAX_CHANNELS bytes) */
148 VO_U32 *numOutBytes /*!< number of bytes in output buffer after processing */
149 )
150 {
151 ELEMENT_INFO *elInfo = &aacEnc->elInfo;
152 Word16 globUsedBits;
153 Word16 ancDataBytes, ancDataBytesLeft;
154
155 ancDataBytes = ancDataBytesLeft = *numAncBytes;
156
157 /* init output aac data buffer and length */
158 aacEnc->hBitStream = CreateBitBuffer(&aacEnc->bitStream, outBytes, *numOutBytes);
159
160 /* psychoacoustic process */
161 psyMain(aacEnc->config.nChannelsOut,
162 elInfo,
163 timeSignal,
164 &aacEnc->psyKernel.psyData[elInfo->ChannelIndex[0]],
165 &aacEnc->psyKernel.tnsData[elInfo->ChannelIndex[0]],
166 &aacEnc->psyKernel.psyConfLong,
167 &aacEnc->psyKernel.psyConfShort,
168 &aacEnc->psyOut.psyOutChannel[elInfo->ChannelIndex[0]],
169 &aacEnc->psyOut.psyOutElement,
170 aacEnc->psyKernel.pScratchTns,
171 aacEnc->config.sampleRate);
172
173 /* adjust bitrate and frame length */
174 AdjustBitrate(&aacEnc->qcKernel,
175 aacEnc->config.bitRate,
176 aacEnc->config.sampleRate);
177
178 /* quantization and coding process */
179 QCMain(&aacEnc->qcKernel,
180 &aacEnc->qcKernel.elementBits,
181 &aacEnc->qcKernel.adjThr.adjThrStateElem,
182 &aacEnc->psyOut.psyOutChannel[elInfo->ChannelIndex[0]],
183 &aacEnc->psyOut.psyOutElement,
184 &aacEnc->qcOut.qcChannel[elInfo->ChannelIndex[0]],
185 &aacEnc->qcOut.qcElement,
186 elInfo->nChannelsInEl,
187 min(ancDataBytesLeft,ancDataBytes));
188
189 ancDataBytesLeft = ancDataBytesLeft - ancDataBytes;
190
191 globUsedBits = FinalizeBitConsumption(&aacEnc->qcKernel,
192 &aacEnc->qcOut);
193
194 /* write bitstream process */
195 WriteBitstream(aacEnc->hBitStream,
196 *elInfo,
197 &aacEnc->qcOut,
198 &aacEnc->psyOut,
199 &globUsedBits,
200 ancBytes,
201 aacEnc->psyKernel.sampleRateIdx);
202
203 updateBitres(&aacEnc->qcKernel,
204 &aacEnc->qcOut);
205
206 /* write out the bitstream */
207 *numOutBytes = GetBitsAvail(aacEnc->hBitStream) >> 3;
208
209 return 0;
210 }
211
212
213 /********************************************************************************
214 *
215 * function name:AacEncClose
216 * description: deallocate an encoder instance
217 *
218 **********************************************************************************/
AacEncClose(AAC_ENCODER * hAacEnc,VO_MEM_OPERATOR * pMemOP)219 void AacEncClose (AAC_ENCODER* hAacEnc, VO_MEM_OPERATOR *pMemOP)
220 {
221 if (hAacEnc) {
222 QCDelete(&hAacEnc->qcKernel, pMemOP);
223
224 QCOutDelete(&hAacEnc->qcOut, pMemOP);
225
226 PsyDelete(&hAacEnc->psyKernel, pMemOP);
227
228 PsyOutDelete(&hAacEnc->psyOut, pMemOP);
229
230 DeleteBitBuffer(&hAacEnc->hBitStream);
231
232 if(hAacEnc->intbuf)
233 {
234 mem_free(pMemOP, hAacEnc->intbuf, VO_INDEX_ENC_AAC);
235 hAacEnc->intbuf = NULL;
236 }
237 }
238 }
239