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