• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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