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:		qc_main.c
18e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
19e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Content:	Quantizing & coding functions
20e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
21956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*******************************************************************************/
22956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
23e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "basic_op.h"
24e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "oper_32b.h"
25956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "qc_main.h"
26956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "quantize.h"
27956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "interface.h"
28956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "adj_thr.h"
29956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "sf_estim.h"
30956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "stat_bits.h"
31956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "bit_cnt.h"
32956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "dyn_bits.h"
33956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "channel_map.h"
34956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "memalign.h"
35956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
3684333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber#define UNUSED(x) (void)(x)
37956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
38956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongtypedef enum{
39956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  FRAME_LEN_BYTES_MODULO =  1,
40956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  FRAME_LEN_BYTES_INT    =  2
41956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}FRAME_LEN_RESULT_MODE;
42956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
43956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic const Word16 maxFillElemBits = 7 + 270*8;
44956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
45956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/* forward declarations */
46956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
47956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 calcMaxValueInSfb(Word16 sfbCnt,
48956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                Word16 maxSfbPerGroup,
49956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                Word16 sfbPerGroup,
50956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                Word16 sfbOffset[MAX_GROUPED_SFB],
51956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                Word16 quantSpectrum[FRAME_LEN_LONG],
52956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                UWord16 maxValue[MAX_GROUPED_SFB]);
53956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
54956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
55956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*****************************************************************************
56956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
57956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: calcFrameLen
58956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: estimate the frame length according the bitrates
59956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
60956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/
61956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 calcFrameLen(Word32 bitRate,
62956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                           Word32 sampleRate,
63956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                           FRAME_LEN_RESULT_MODE mode)
64956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
65956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
66956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word32 result;
67956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word32 quot;
68956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
69956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  result = (FRAME_LEN_LONG >> 3) * bitRate;
70956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  quot = result / sampleRate;
71956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
72b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
73956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  if (mode == FRAME_LEN_BYTES_MODULO) {
74956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    result -= quot * sampleRate;
75956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
76956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  else { /* FRAME_LEN_BYTES_INT */
77b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard    result = quot;
78956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
79956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
80956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  return result;
81956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
82956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
83956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*****************************************************************************
84956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
85956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*  function name:framePadding
86956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*  description: Calculates if padding is needed for actual frame
87b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard*  returns: paddingOn or not
88956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
89956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/
90956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 framePadding(Word32 bitRate,
91956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                           Word32 sampleRate,
92956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                           Word32 *paddingRest)
93956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
94956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 paddingOn;
95956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 difference;
96956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
97b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  paddingOn = 0;
98956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
99956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  difference = calcFrameLen( bitRate,
100956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                             sampleRate,
101956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                             FRAME_LEN_BYTES_MODULO );
102956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  *paddingRest = *paddingRest - difference;
103956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
104b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
105956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  if (*paddingRest <= 0 ) {
106b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard    paddingOn = 1;
107956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    *paddingRest = *paddingRest + sampleRate;
108956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
109956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
110956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  return paddingOn;
111956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
112956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
113956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
114956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*********************************************************************************
115956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
116956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: QCOutNew
117956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: init qcout parameter
118956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns:     0 if success
119956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
120956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/
121956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
122956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongWord16 QCOutNew(QC_OUT *hQC, Word16 nChannels, VO_MEM_OPERATOR *pMemOP)
123956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
124e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard  Word32 i;
125e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard  Word16 *quantSpec;
126e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard  Word16 *scf;
127b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  UWord16 *maxValueInSfb;
128b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
129e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard  quantSpec = (Word16 *)mem_malloc(pMemOP, nChannels * FRAME_LEN_LONG * sizeof(Word16), 32, VO_INDEX_ENC_AAC);
130e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard  if(NULL == quantSpec)
131e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	  return 1;
132b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  scf = (Word16 *)mem_malloc(pMemOP, nChannels * MAX_GROUPED_SFB * sizeof(Word16), 32, VO_INDEX_ENC_AAC);
133e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard  if(NULL == scf)
134e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard  {
135956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	  return 1;
136956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
137e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard  maxValueInSfb = (UWord16 *)mem_malloc(pMemOP, nChannels * MAX_GROUPED_SFB * sizeof(UWord16), 32, VO_INDEX_ENC_AAC);
138e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard  if(NULL == maxValueInSfb)
139e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard  {
140e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	  return 1;
141e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard  }
142e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
143956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  for (i=0; i<nChannels; i++) {
144956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    hQC->qcChannel[i].quantSpec = quantSpec + i*FRAME_LEN_LONG;
145b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
146956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    hQC->qcChannel[i].maxValueInSfb = maxValueInSfb + i*MAX_GROUPED_SFB;
147b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
148956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    hQC->qcChannel[i].scf = scf + i*MAX_GROUPED_SFB;
149956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
150b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
151956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  return 0;
152956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
153956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
154956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
155956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*********************************************************************************
156956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
157956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: QCOutDelete
158956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: unint qcout parameter
159956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns:      0 if success
160956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
161956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/
162956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongvoid QCOutDelete(QC_OUT* hQC, VO_MEM_OPERATOR *pMemOP)
163956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
164e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard   Word32 i;
165e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard   if(hQC)
166e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard   {
167338b9c9020ca6be98f30670cf307ad8553f1b4c9Martin Storsjo      if(hQC->qcChannel[0].quantSpec)
168e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		 mem_free(pMemOP, hQC->qcChannel[0].quantSpec, VO_INDEX_ENC_AAC);
169b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
170e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard      if(hQC->qcChannel[0].maxValueInSfb)
171e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		  mem_free(pMemOP, hQC->qcChannel[0].maxValueInSfb, VO_INDEX_ENC_AAC);
172b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
173e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	  if(hQC->qcChannel[0].scf)
174e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		  mem_free(pMemOP, hQC->qcChannel[0].scf, VO_INDEX_ENC_AAC);
175e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
176e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	  for (i=0; i<MAX_CHANNELS; i++) {
177e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		  hQC->qcChannel[i].quantSpec = NULL;
178b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
179e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		  hQC->qcChannel[i].maxValueInSfb = NULL;
180b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
181e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		  hQC->qcChannel[i].scf = NULL;
182e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	  }
183b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard   }
184956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
185956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
186956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*********************************************************************************
187956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
188956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: QCNew
189956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: set QC to zero
190956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns:     0 if success
191956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
192956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/
193956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongWord16 QCNew(QC_STATE *hQC, VO_MEM_OPERATOR *pMemOP)
194956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
195956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  pMemOP->Set(VO_INDEX_ENC_AAC, hQC,0,sizeof(QC_STATE));
196956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
197956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  return (0);
198956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
199956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
200956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*********************************************************************************
201956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
202956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: QCDelete
203956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: unint qcout parameter
204956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
205956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/
206956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongvoid QCDelete(QC_STATE *hQC, VO_MEM_OPERATOR *pMemOP)
207956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
20884333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber  UNUSED(hQC);
20984333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber  UNUSED(pMemOP);
210956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
211956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
212956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*********************************************************************************
213956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
214956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: QCInit
215956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: init QD parameter
216956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns:     0 if success
217956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
218956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/
219956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongWord16 QCInit(QC_STATE *hQC,
220956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong              struct QC_INIT *init)
221956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
222b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  hQC->nChannels       = init->elInfo->nChannelsInEl;
223b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  hQC->maxBitsTot      = init->maxBits;
224956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  hQC->bitResTot       = sub(init->bitRes, init->averageBits);
225b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  hQC->averageBitsTot  = init->averageBits;
226b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  hQC->maxBitFac       = init->maxBitFac;
227956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
228b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  hQC->padding.paddingRest = init->padding.paddingRest;
229956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
230b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  hQC->globStatBits    = 3;                          /* for ID_END */
231956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
232956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  /* channel elements init */
233956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  InitElementBits(&hQC->elementBits,
234956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                  *init->elInfo,
235956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                  init->bitrate,
236956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                  init->averageBits,
237956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                  hQC->globStatBits);
238956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
239956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  /* threshold parameter init */
240956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  AdjThrInit(&hQC->adjThr,
241956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong             init->meanPe,
242956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong             hQC->elementBits.chBitrate);
243956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
244956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  return 0;
245956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
246956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
247956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
248956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*********************************************************************************
249b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard*
250956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: QCMain
251956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description:  quantization and coding the spectrum
252956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns:      0 if success
253956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
254956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/
255b676a05348e4c516fa8b57e33b10548e6142c3f8Mans RullgardWord16 QCMain(QC_STATE* hQC,
256956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong              ELEMENT_BITS* elBits,
257956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong              ATS_ELEMENT* adjThrStateElement,
258956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong              PSY_OUT_CHANNEL  psyOutChannel[MAX_CHANNELS],  /* may be modified in-place */
259956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong              PSY_OUT_ELEMENT* psyOutElement,
260956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong              QC_OUT_CHANNEL  qcOutChannel[MAX_CHANNELS],    /* out                      */
261956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong              QC_OUT_ELEMENT* qcOutElement,
262956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong              Word16 nChannels,
263b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			  Word16 ancillaryDataBytes)
264956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
265956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 maxChDynBits[MAX_CHANNELS];
266b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  Word16 chBitDistribution[MAX_CHANNELS];
267956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word32 ch;
268b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
269956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  if (elBits->bitResLevel < 0) {
270956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    return -1;
271956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
272b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
273956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  if (elBits->bitResLevel > elBits->maxBitResBits) {
274956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    return -1;
275956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
276956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
277956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  qcOutElement->staticBitsUsed = countStaticBitdemand(psyOutChannel,
278956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                                      psyOutElement,
279b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard                                                      nChannels,
280956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong													  qcOutElement->adtsUsed);
281956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
282b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
283956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  if (ancillaryDataBytes) {
284956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    qcOutElement->ancBitsUsed = 7 + (ancillaryDataBytes << 3);
285b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
286956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    if (ancillaryDataBytes >= 15)
287956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      qcOutElement->ancBitsUsed = qcOutElement->ancBitsUsed + 8;
288956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
289956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  else {
290b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard    qcOutElement->ancBitsUsed = 0;
291956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
292956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
293956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  CalcFormFactor(hQC->logSfbFormFactor, hQC->sfbNRelevantLines, hQC->logSfbEnergy, psyOutChannel, nChannels);
294956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
295956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  /*adjust thresholds for the desired bitrate */
296956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  AdjustThresholds(&hQC->adjThr,
297956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                   adjThrStateElement,
298956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                   psyOutChannel,
299956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                   psyOutElement,
300956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                   chBitDistribution,
301956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                   hQC->logSfbEnergy,
302b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard                   hQC->sfbNRelevantLines,
303956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                   qcOutElement,
304956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong				   elBits,
305956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong				   nChannels,
306956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong				   hQC->maxBitFac);
307956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
308956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  /*estimate scale factors */
309956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  EstimateScaleFactors(psyOutChannel,
310956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                       qcOutChannel,
311956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                       hQC->logSfbEnergy,
312956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                       hQC->logSfbFormFactor,
313956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                       hQC->sfbNRelevantLines,
314956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                       nChannels);
315956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
316956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  /* condition to prevent empty bitreservoir */
317956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  for (ch = 0; ch < nChannels; ch++) {
318956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    Word32 maxDynBits;
319956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    maxDynBits = elBits->averageBits + elBits->bitResLevel - 7; /* -7 bec. of align bits */
320956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    maxDynBits = maxDynBits - qcOutElement->staticBitsUsed + qcOutElement->ancBitsUsed;
321956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    maxChDynBits[ch] = extract_l(chBitDistribution[ch] * maxDynBits / 1000);
322956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
323956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
324b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  qcOutElement->dynBitsUsed = 0;
325956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  for (ch = 0; ch < nChannels; ch++) {
326956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    Word32 chDynBits;
327956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    Flag   constraintsFulfilled;
328956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    Word32 iter;
329b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard    iter = 0;
330956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    do {
331b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard      constraintsFulfilled = 1;
332956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
333956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      QuantizeSpectrum(psyOutChannel[ch].sfbCnt,
334956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                       psyOutChannel[ch].maxSfbPerGroup,
335956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                       psyOutChannel[ch].sfbPerGroup,
336956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                       psyOutChannel[ch].sfbOffsets,
337956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                       psyOutChannel[ch].mdctSpectrum,
338956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                       qcOutChannel[ch].globalGain,
339956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                       qcOutChannel[ch].scf,
340956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                       qcOutChannel[ch].quantSpec);
341b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
342956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      if (calcMaxValueInSfb(psyOutChannel[ch].sfbCnt,
343956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                            psyOutChannel[ch].maxSfbPerGroup,
344956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                            psyOutChannel[ch].sfbPerGroup,
345956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                            psyOutChannel[ch].sfbOffsets,
346956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                            qcOutChannel[ch].quantSpec,
347956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                            qcOutChannel[ch].maxValueInSfb) > MAX_QUANT) {
348b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard        constraintsFulfilled = 0;
349956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      }
350956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
351956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      chDynBits = dynBitCount(qcOutChannel[ch].quantSpec,
352956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                              qcOutChannel[ch].maxValueInSfb,
353956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                              qcOutChannel[ch].scf,
354956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                              psyOutChannel[ch].windowSequence,
355956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                              psyOutChannel[ch].sfbCnt,
356956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                              psyOutChannel[ch].maxSfbPerGroup,
357956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                              psyOutChannel[ch].sfbPerGroup,
358956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                              psyOutChannel[ch].sfbOffsets,
359956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                              &qcOutChannel[ch].sectionData);
360b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
361956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      if (chDynBits >= maxChDynBits[ch]) {
362b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard        constraintsFulfilled = 0;
363956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      }
364b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
365956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      if (!constraintsFulfilled) {
366956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        qcOutChannel[ch].globalGain = qcOutChannel[ch].globalGain + 1;
367956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      }
368956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
369956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      iter = iter + 1;
370b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
371956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    } while(!constraintsFulfilled);
372956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
373956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    qcOutElement->dynBitsUsed = qcOutElement->dynBitsUsed + chDynBits;
374956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
375b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard    qcOutChannel[ch].mdctScale    = psyOutChannel[ch].mdctScale;
376b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard    qcOutChannel[ch].groupingMask = psyOutChannel[ch].groupingMask;
377b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard    qcOutChannel[ch].windowShape  = psyOutChannel[ch].windowShape;
378956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
379956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
380956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  /* save dynBitsUsed for correction of bits2pe relation */
381956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  AdjThrUpdate(adjThrStateElement, qcOutElement->dynBitsUsed);
382956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
383956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  {
384956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    Word16 bitResSpace = elBits->maxBitResBits - elBits->bitResLevel;
385956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    Word16 deltaBitRes = elBits->averageBits -
386956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                        (qcOutElement->staticBitsUsed +
387956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                         qcOutElement->dynBitsUsed + qcOutElement->ancBitsUsed);
388956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
389956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    qcOutElement->fillBits = max(0, (deltaBitRes - bitResSpace));
390956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
391956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
392956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  return 0; /* OK */
393956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
394956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
395956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
396956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*********************************************************************************
397956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
398956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: calcMaxValueInSfb
399956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description:  search the max Spectrum in one sfb
400956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
401956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/
402956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 calcMaxValueInSfb(Word16 sfbCnt,
403956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                Word16 maxSfbPerGroup,
404956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                Word16 sfbPerGroup,
405956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                Word16 sfbOffset[MAX_GROUPED_SFB],
406956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                Word16 quantSpectrum[FRAME_LEN_LONG],
407956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                UWord16 maxValue[MAX_GROUPED_SFB])
408956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
409956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 sfbOffs, sfb;
410956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 maxValueAll;
411956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
412b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  maxValueAll = 0;
413956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
414956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  for(sfbOffs=0;sfbOffs<sfbCnt;sfbOffs+=sfbPerGroup) {
415956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    for (sfb = 0; sfb < maxSfbPerGroup; sfb++) {
416956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      Word16 line;
417956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      Word16 maxThisSfb;
418b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard      maxThisSfb = 0;
419956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
420956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      for (line = sfbOffset[sfbOffs+sfb]; line < sfbOffset[sfbOffs+sfb+1]; line++) {
421956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        Word16 absVal;
422956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        absVal = abs_s(quantSpectrum[line]);
423956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        maxThisSfb = max(maxThisSfb, absVal);
424956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      }
425956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
426b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard      maxValue[sfbOffs+sfb] = maxThisSfb;
427956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      maxValueAll = max(maxValueAll, maxThisSfb);
428956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
429956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
430956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  return maxValueAll;
431956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
432956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
433956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
434956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*********************************************************************************
435956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
436956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: updateBitres
437956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: update bitreservoir
438956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
439956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/
440956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongvoid updateBitres(QC_STATE* qcKernel,
441956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                  QC_OUT*   qcOut)
442b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
443956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
444956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  ELEMENT_BITS *elBits;
445b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
446b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  qcKernel->bitResTot = 0;
447956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
448956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  elBits = &qcKernel->elementBits;
449956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
450b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
451956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  if (elBits->averageBits > 0) {
452956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    /* constant bitrate */
453956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    Word16 bitsUsed;
454956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    bitsUsed = (qcOut->qcElement.staticBitsUsed + qcOut->qcElement.dynBitsUsed) +
455956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                   (qcOut->qcElement.ancBitsUsed + qcOut->qcElement.fillBits);
456956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    elBits->bitResLevel = elBits->bitResLevel + (elBits->averageBits - bitsUsed);
457956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    qcKernel->bitResTot = qcKernel->bitResTot + elBits->bitResLevel;
458956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
459956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  else {
460956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    /* variable bitrate */
461b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard    elBits->bitResLevel = elBits->maxBits;
462b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard    qcKernel->bitResTot = qcKernel->maxBitsTot;
463956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
464956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
465956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
466956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*********************************************************************************
467956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
468956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: FinalizeBitConsumption
469956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: count bits used
470956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
471956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/
472956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongWord16 FinalizeBitConsumption(QC_STATE *qcKernel,
473956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                              QC_OUT* qcOut)
474956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
475e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard  Word32 nFullFillElem;
476e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard  Word32 totFillBits;
477b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  Word16 diffBits;
478956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 bitsUsed;
479956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
480b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  totFillBits = 0;
481956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
482b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  qcOut->totStaticBitsUsed = qcKernel->globStatBits;
483956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  qcOut->totStaticBitsUsed += qcOut->qcElement.staticBitsUsed;
484956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  qcOut->totDynBitsUsed    = qcOut->qcElement.dynBitsUsed;
485956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  qcOut->totAncBitsUsed    = qcOut->qcElement.ancBitsUsed;
486956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  qcOut->totFillBits       = qcOut->qcElement.fillBits;
487b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
488956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  if (qcOut->qcElement.fillBits) {
489956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    totFillBits += qcOut->qcElement.fillBits;
490956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
491956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
492e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard  nFullFillElem = (max((qcOut->totFillBits - 1), 0) / maxFillElemBits) * maxFillElemBits;
493b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
494956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  qcOut->totFillBits = qcOut->totFillBits - nFullFillElem;
495956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
496956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  /* check fill elements */
497b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
498956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  if (qcOut->totFillBits > 0) {
499956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    /* minimum Fillelement contains 7 (TAG + byte cnt) bits */
500956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    qcOut->totFillBits = max(7, qcOut->totFillBits);
501956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    /* fill element size equals n*8 + 7 */
502b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard    qcOut->totFillBits = qcOut->totFillBits + ((8 - ((qcOut->totFillBits - 7) & 0x0007)) & 0x0007);
503956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
504956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
505956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  qcOut->totFillBits = qcOut->totFillBits + nFullFillElem;
506956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
507956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  /* now distribute extra fillbits and alignbits over channel elements */
508956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  qcOut->alignBits = 7 - ((qcOut->totDynBitsUsed + qcOut->totStaticBitsUsed +
509b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard                           qcOut->totAncBitsUsed + qcOut->totFillBits - 1) & 0x0007);
510b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
511956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
512956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  if ( (qcOut->alignBits + qcOut->totFillBits - totFillBits == 8) &&
513956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong       (qcOut->totFillBits > 8))
514956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    qcOut->totFillBits = qcOut->totFillBits - 8;
515956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
516b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
517956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  diffBits = qcOut->alignBits + qcOut->totFillBits - totFillBits;
518b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
519956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  if(diffBits>=0) {
520956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    qcOut->qcElement.fillBits += diffBits;
521956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
522956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
523956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  bitsUsed = qcOut->totDynBitsUsed + qcOut->totStaticBitsUsed + qcOut->totAncBitsUsed;
524956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  bitsUsed = bitsUsed + qcOut->totFillBits + qcOut->alignBits;
525b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
526956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  if (bitsUsed > qcKernel->maxBitsTot) {
527956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    return -1;
528956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
529956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  return bitsUsed;
530956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
531956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
532956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
533956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*********************************************************************************
534956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
535956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: AdjustBitrate
536956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description:  adjusts framelength via padding on a frame to frame basis,
537956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*               to achieve a bitrate that demands a non byte aligned
538956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*               framelength
539956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* return:       errorcode
540956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
541956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/
542956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongWord16 AdjustBitrate(QC_STATE        *hQC,
543956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                     Word32           bitRate,    /* total bitrate */
544956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                     Word32           sampleRate) /* output sampling rate */
545956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
546956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 paddingOn;
547956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 frameLen;
548956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 codeBits;
549956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 codeBitsLast;
550956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
551956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  /* Do we need a extra padding byte? */
552956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  paddingOn = framePadding(bitRate,
553956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                           sampleRate,
554956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                           &hQC->padding.paddingRest);
555956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
556956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  /* frame length */
557956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  frameLen = paddingOn + calcFrameLen(bitRate,
558956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                      sampleRate,
559956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                      FRAME_LEN_BYTES_INT);
560956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
561956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  frameLen = frameLen << 3;
562956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  codeBitsLast = hQC->averageBitsTot - hQC->globStatBits;
563956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  codeBits     = frameLen - hQC->globStatBits;
564956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
565b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  /* calculate bits for every channel element */
566956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  if (codeBits != codeBitsLast) {
567b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard    Word16 totalBits = 0;
568956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
569956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    hQC->elementBits.averageBits = (hQC->elementBits.relativeBits * codeBits) >> 16; /* relativeBits was scaled down by 2 */
570956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    totalBits += hQC->elementBits.averageBits;
571956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
572956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    hQC->elementBits.averageBits = hQC->elementBits.averageBits + (codeBits - totalBits);
573956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
574956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
575b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  hQC->averageBitsTot = frameLen;
576956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
577956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  return 0;
578956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
579