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
36956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
37956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongtypedef enum{
38956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  FRAME_LEN_BYTES_MODULO =  1,
39956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  FRAME_LEN_BYTES_INT    =  2
40956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}FRAME_LEN_RESULT_MODE;
41956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
42956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic const Word16 maxFillElemBits = 7 + 270*8;
43956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
44956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/* forward declarations */
45956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
46956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 calcMaxValueInSfb(Word16 sfbCnt,
47956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                Word16 maxSfbPerGroup,
48956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                Word16 sfbPerGroup,
49956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                Word16 sfbOffset[MAX_GROUPED_SFB],
50956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                Word16 quantSpectrum[FRAME_LEN_LONG],
51956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                UWord16 maxValue[MAX_GROUPED_SFB]);
52956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
53956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
54956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*****************************************************************************
55956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
56956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: calcFrameLen
57956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: estimate the frame length according the bitrates
58956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
59956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/
60956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 calcFrameLen(Word32 bitRate,
61956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                           Word32 sampleRate,
62956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                           FRAME_LEN_RESULT_MODE mode)
63956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
64956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
65956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word32 result;
66956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word32 quot;
67956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
68956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  result = (FRAME_LEN_LONG >> 3) * bitRate;
69956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  quot = result / sampleRate;
70956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
71b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
72956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  if (mode == FRAME_LEN_BYTES_MODULO) {
73956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    result -= quot * sampleRate;
74956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
75956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  else { /* FRAME_LEN_BYTES_INT */
76b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard    result = quot;
77956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
78956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
79956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  return result;
80956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
81956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
82956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*****************************************************************************
83956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
84956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*  function name:framePadding
85956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*  description: Calculates if padding is needed for actual frame
86b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard*  returns: paddingOn or not
87956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
88956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/
89956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 framePadding(Word32 bitRate,
90956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                           Word32 sampleRate,
91956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                           Word32 *paddingRest)
92956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
93956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 paddingOn;
94956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 difference;
95956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
96b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  paddingOn = 0;
97956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
98956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  difference = calcFrameLen( bitRate,
99956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                             sampleRate,
100956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                             FRAME_LEN_BYTES_MODULO );
101956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  *paddingRest = *paddingRest - difference;
102956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
103b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
104956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  if (*paddingRest <= 0 ) {
105b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard    paddingOn = 1;
106956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    *paddingRest = *paddingRest + sampleRate;
107956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
108956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
109956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  return paddingOn;
110956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
111956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
112956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
113956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*********************************************************************************
114956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
115956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: QCOutNew
116956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: init qcout parameter
117956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns:     0 if success
118956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
119956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/
120956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
121956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongWord16 QCOutNew(QC_OUT *hQC, Word16 nChannels, VO_MEM_OPERATOR *pMemOP)
122956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
123e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard  Word32 i;
124e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard  Word16 *quantSpec;
125e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard  Word16 *scf;
126b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  UWord16 *maxValueInSfb;
127b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
128e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard  quantSpec = (Word16 *)mem_malloc(pMemOP, nChannels * FRAME_LEN_LONG * sizeof(Word16), 32, VO_INDEX_ENC_AAC);
129e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard  if(NULL == quantSpec)
130e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	  return 1;
131b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  scf = (Word16 *)mem_malloc(pMemOP, nChannels * MAX_GROUPED_SFB * sizeof(Word16), 32, VO_INDEX_ENC_AAC);
132e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard  if(NULL == scf)
133e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard  {
134956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	  return 1;
135956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
136e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard  maxValueInSfb = (UWord16 *)mem_malloc(pMemOP, nChannels * MAX_GROUPED_SFB * sizeof(UWord16), 32, VO_INDEX_ENC_AAC);
137e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard  if(NULL == maxValueInSfb)
138e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard  {
139e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	  return 1;
140e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard  }
141e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
142956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  for (i=0; i<nChannels; i++) {
143956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    hQC->qcChannel[i].quantSpec = quantSpec + i*FRAME_LEN_LONG;
144b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
145956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    hQC->qcChannel[i].maxValueInSfb = maxValueInSfb + i*MAX_GROUPED_SFB;
146b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
147956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    hQC->qcChannel[i].scf = scf + i*MAX_GROUPED_SFB;
148956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
149b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
150956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  return 0;
151956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
152956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
153956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
154956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*********************************************************************************
155956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
156956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: QCOutDelete
157956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: unint qcout parameter
158956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns:      0 if success
159956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
160956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/
161956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongvoid QCOutDelete(QC_OUT* hQC, VO_MEM_OPERATOR *pMemOP)
162956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
163e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard   Word32 i;
164e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard   if(hQC)
165e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard   {
166338b9c9020ca6be98f30670cf307ad8553f1b4c9Martin Storsjo      if(hQC->qcChannel[0].quantSpec)
167e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		 mem_free(pMemOP, hQC->qcChannel[0].quantSpec, VO_INDEX_ENC_AAC);
168b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
169e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard      if(hQC->qcChannel[0].maxValueInSfb)
170e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		  mem_free(pMemOP, hQC->qcChannel[0].maxValueInSfb, VO_INDEX_ENC_AAC);
171b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
172e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	  if(hQC->qcChannel[0].scf)
173e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		  mem_free(pMemOP, hQC->qcChannel[0].scf, VO_INDEX_ENC_AAC);
174e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
175e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	  for (i=0; i<MAX_CHANNELS; i++) {
176e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		  hQC->qcChannel[i].quantSpec = NULL;
177b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
178e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		  hQC->qcChannel[i].maxValueInSfb = NULL;
179b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
180e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		  hQC->qcChannel[i].scf = NULL;
181e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	  }
182b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard   }
183956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
184956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
185956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*********************************************************************************
186956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
187956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: QCNew
188956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: set QC to zero
189956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns:     0 if success
190956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
191956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/
192956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongWord16 QCNew(QC_STATE *hQC, VO_MEM_OPERATOR *pMemOP)
193956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
194956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  pMemOP->Set(VO_INDEX_ENC_AAC, hQC,0,sizeof(QC_STATE));
195956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
196956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  return (0);
197956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
198956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
199956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*********************************************************************************
200956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
201956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: QCDelete
202956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: unint qcout parameter
203956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
204956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/
205956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongvoid QCDelete(QC_STATE *hQC, VO_MEM_OPERATOR *pMemOP)
206956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
207b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
208b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  /*
209956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong     nothing to do
210956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  */
211956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  hQC=NULL;
212956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
213956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
214956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*********************************************************************************
215956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
216956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: QCInit
217956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: init QD parameter
218956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns:     0 if success
219956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
220956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/
221956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongWord16 QCInit(QC_STATE *hQC,
222956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong              struct QC_INIT *init)
223956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
224b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  hQC->nChannels       = init->elInfo->nChannelsInEl;
225b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  hQC->maxBitsTot      = init->maxBits;
226956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  hQC->bitResTot       = sub(init->bitRes, init->averageBits);
227b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  hQC->averageBitsTot  = init->averageBits;
228b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  hQC->maxBitFac       = init->maxBitFac;
229956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
230b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  hQC->padding.paddingRest = init->padding.paddingRest;
231956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
232b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  hQC->globStatBits    = 3;                          /* for ID_END */
233956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
234956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  /* channel elements init */
235956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  InitElementBits(&hQC->elementBits,
236956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                  *init->elInfo,
237956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                  init->bitrate,
238956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                  init->averageBits,
239956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                  hQC->globStatBits);
240956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
241956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  /* threshold parameter init */
242956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  AdjThrInit(&hQC->adjThr,
243956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong             init->meanPe,
244956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong             hQC->elementBits.chBitrate);
245956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
246956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  return 0;
247956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
248956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
249956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
250956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*********************************************************************************
251b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard*
252956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: QCMain
253956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description:  quantization and coding the spectrum
254956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns:      0 if success
255956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
256956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/
257b676a05348e4c516fa8b57e33b10548e6142c3f8Mans RullgardWord16 QCMain(QC_STATE* hQC,
258956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong              ELEMENT_BITS* elBits,
259956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong              ATS_ELEMENT* adjThrStateElement,
260956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong              PSY_OUT_CHANNEL  psyOutChannel[MAX_CHANNELS],  /* may be modified in-place */
261956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong              PSY_OUT_ELEMENT* psyOutElement,
262956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong              QC_OUT_CHANNEL  qcOutChannel[MAX_CHANNELS],    /* out                      */
263956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong              QC_OUT_ELEMENT* qcOutElement,
264956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong              Word16 nChannels,
265b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			  Word16 ancillaryDataBytes)
266956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
267956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 maxChDynBits[MAX_CHANNELS];
268b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  Word16 chBitDistribution[MAX_CHANNELS];
269956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word32 ch;
270b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
271956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  if (elBits->bitResLevel < 0) {
272956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    return -1;
273956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
274b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
275956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  if (elBits->bitResLevel > elBits->maxBitResBits) {
276956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    return -1;
277956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
278956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
279956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  qcOutElement->staticBitsUsed = countStaticBitdemand(psyOutChannel,
280956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                                      psyOutElement,
281b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard                                                      nChannels,
282956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong													  qcOutElement->adtsUsed);
283956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
284b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
285956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  if (ancillaryDataBytes) {
286956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    qcOutElement->ancBitsUsed = 7 + (ancillaryDataBytes << 3);
287b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
288956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    if (ancillaryDataBytes >= 15)
289956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      qcOutElement->ancBitsUsed = qcOutElement->ancBitsUsed + 8;
290956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
291956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  else {
292b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard    qcOutElement->ancBitsUsed = 0;
293956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
294956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
295956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  CalcFormFactor(hQC->logSfbFormFactor, hQC->sfbNRelevantLines, hQC->logSfbEnergy, psyOutChannel, nChannels);
296956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
297956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  /*adjust thresholds for the desired bitrate */
298956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  AdjustThresholds(&hQC->adjThr,
299956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                   adjThrStateElement,
300956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                   psyOutChannel,
301956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                   psyOutElement,
302956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                   chBitDistribution,
303956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                   hQC->logSfbEnergy,
304b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard                   hQC->sfbNRelevantLines,
305956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                   qcOutElement,
306956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong				   elBits,
307956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong				   nChannels,
308956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong				   hQC->maxBitFac);
309956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
310956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  /*estimate scale factors */
311956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  EstimateScaleFactors(psyOutChannel,
312956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                       qcOutChannel,
313956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                       hQC->logSfbEnergy,
314956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                       hQC->logSfbFormFactor,
315956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                       hQC->sfbNRelevantLines,
316956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                       nChannels);
317956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
318956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  /* condition to prevent empty bitreservoir */
319956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  for (ch = 0; ch < nChannels; ch++) {
320956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    Word32 maxDynBits;
321956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    maxDynBits = elBits->averageBits + elBits->bitResLevel - 7; /* -7 bec. of align bits */
322956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    maxDynBits = maxDynBits - qcOutElement->staticBitsUsed + qcOutElement->ancBitsUsed;
323956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    maxChDynBits[ch] = extract_l(chBitDistribution[ch] * maxDynBits / 1000);
324956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
325956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
326b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  qcOutElement->dynBitsUsed = 0;
327956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  for (ch = 0; ch < nChannels; ch++) {
328956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    Word32 chDynBits;
329956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    Flag   constraintsFulfilled;
330956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    Word32 iter;
331b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard    iter = 0;
332956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    do {
333b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard      constraintsFulfilled = 1;
334956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
335956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      QuantizeSpectrum(psyOutChannel[ch].sfbCnt,
336956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                       psyOutChannel[ch].maxSfbPerGroup,
337956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                       psyOutChannel[ch].sfbPerGroup,
338956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                       psyOutChannel[ch].sfbOffsets,
339956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                       psyOutChannel[ch].mdctSpectrum,
340956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                       qcOutChannel[ch].globalGain,
341956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                       qcOutChannel[ch].scf,
342956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                       qcOutChannel[ch].quantSpec);
343b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
344956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      if (calcMaxValueInSfb(psyOutChannel[ch].sfbCnt,
345956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                            psyOutChannel[ch].maxSfbPerGroup,
346956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                            psyOutChannel[ch].sfbPerGroup,
347956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                            psyOutChannel[ch].sfbOffsets,
348956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                            qcOutChannel[ch].quantSpec,
349956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                            qcOutChannel[ch].maxValueInSfb) > MAX_QUANT) {
350b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard        constraintsFulfilled = 0;
351956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      }
352956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
353956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      chDynBits = dynBitCount(qcOutChannel[ch].quantSpec,
354956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                              qcOutChannel[ch].maxValueInSfb,
355956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                              qcOutChannel[ch].scf,
356956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                              psyOutChannel[ch].windowSequence,
357956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                              psyOutChannel[ch].sfbCnt,
358956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                              psyOutChannel[ch].maxSfbPerGroup,
359956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                              psyOutChannel[ch].sfbPerGroup,
360956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                              psyOutChannel[ch].sfbOffsets,
361956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                              &qcOutChannel[ch].sectionData);
362b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
363956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      if (chDynBits >= maxChDynBits[ch]) {
364b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard        constraintsFulfilled = 0;
365956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      }
366b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
367956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      if (!constraintsFulfilled) {
368956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        qcOutChannel[ch].globalGain = qcOutChannel[ch].globalGain + 1;
369956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      }
370956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
371956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      iter = iter + 1;
372b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
373956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    } while(!constraintsFulfilled);
374956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
375956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    qcOutElement->dynBitsUsed = qcOutElement->dynBitsUsed + chDynBits;
376956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
377b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard    qcOutChannel[ch].mdctScale    = psyOutChannel[ch].mdctScale;
378b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard    qcOutChannel[ch].groupingMask = psyOutChannel[ch].groupingMask;
379b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard    qcOutChannel[ch].windowShape  = psyOutChannel[ch].windowShape;
380956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
381956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
382956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  /* save dynBitsUsed for correction of bits2pe relation */
383956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  AdjThrUpdate(adjThrStateElement, qcOutElement->dynBitsUsed);
384956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
385956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  {
386956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    Word16 bitResSpace = elBits->maxBitResBits - elBits->bitResLevel;
387956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    Word16 deltaBitRes = elBits->averageBits -
388956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                        (qcOutElement->staticBitsUsed +
389956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                         qcOutElement->dynBitsUsed + qcOutElement->ancBitsUsed);
390956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
391956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    qcOutElement->fillBits = max(0, (deltaBitRes - bitResSpace));
392956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
393956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
394956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  return 0; /* OK */
395956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
396956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
397956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
398956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*********************************************************************************
399956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
400956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: calcMaxValueInSfb
401956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description:  search the max Spectrum in one sfb
402956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
403956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/
404956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 calcMaxValueInSfb(Word16 sfbCnt,
405956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                Word16 maxSfbPerGroup,
406956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                Word16 sfbPerGroup,
407956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                Word16 sfbOffset[MAX_GROUPED_SFB],
408956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                Word16 quantSpectrum[FRAME_LEN_LONG],
409956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                UWord16 maxValue[MAX_GROUPED_SFB])
410956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
411956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 sfbOffs, sfb;
412956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 maxValueAll;
413956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
414b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  maxValueAll = 0;
415956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
416956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  for(sfbOffs=0;sfbOffs<sfbCnt;sfbOffs+=sfbPerGroup) {
417956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    for (sfb = 0; sfb < maxSfbPerGroup; sfb++) {
418956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      Word16 line;
419956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      Word16 maxThisSfb;
420b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard      maxThisSfb = 0;
421956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
422956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      for (line = sfbOffset[sfbOffs+sfb]; line < sfbOffset[sfbOffs+sfb+1]; line++) {
423956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        Word16 absVal;
424956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        absVal = abs_s(quantSpectrum[line]);
425956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        maxThisSfb = max(maxThisSfb, absVal);
426956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      }
427956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
428b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard      maxValue[sfbOffs+sfb] = maxThisSfb;
429956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      maxValueAll = max(maxValueAll, maxThisSfb);
430956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
431956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
432956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  return maxValueAll;
433956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
434956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
435956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
436956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*********************************************************************************
437956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
438956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: updateBitres
439956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: update bitreservoir
440956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
441956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/
442956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongvoid updateBitres(QC_STATE* qcKernel,
443956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                  QC_OUT*   qcOut)
444b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
445956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
446956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  ELEMENT_BITS *elBits;
447b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
448b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  qcKernel->bitResTot = 0;
449956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
450956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  elBits = &qcKernel->elementBits;
451956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
452b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
453956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  if (elBits->averageBits > 0) {
454956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    /* constant bitrate */
455956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    Word16 bitsUsed;
456956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    bitsUsed = (qcOut->qcElement.staticBitsUsed + qcOut->qcElement.dynBitsUsed) +
457956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                   (qcOut->qcElement.ancBitsUsed + qcOut->qcElement.fillBits);
458956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    elBits->bitResLevel = elBits->bitResLevel + (elBits->averageBits - bitsUsed);
459956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    qcKernel->bitResTot = qcKernel->bitResTot + elBits->bitResLevel;
460956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
461956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  else {
462956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    /* variable bitrate */
463b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard    elBits->bitResLevel = elBits->maxBits;
464b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard    qcKernel->bitResTot = qcKernel->maxBitsTot;
465956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
466956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
467956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
468956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*********************************************************************************
469956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
470956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: FinalizeBitConsumption
471956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: count bits used
472956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
473956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/
474956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongWord16 FinalizeBitConsumption(QC_STATE *qcKernel,
475956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                              QC_OUT* qcOut)
476956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
477e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard  Word32 nFullFillElem;
478e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard  Word32 totFillBits;
479b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  Word16 diffBits;
480956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 bitsUsed;
481956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
482b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  totFillBits = 0;
483956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
484b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  qcOut->totStaticBitsUsed = qcKernel->globStatBits;
485956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  qcOut->totStaticBitsUsed += qcOut->qcElement.staticBitsUsed;
486956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  qcOut->totDynBitsUsed    = qcOut->qcElement.dynBitsUsed;
487956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  qcOut->totAncBitsUsed    = qcOut->qcElement.ancBitsUsed;
488956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  qcOut->totFillBits       = qcOut->qcElement.fillBits;
489b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
490956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  if (qcOut->qcElement.fillBits) {
491956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    totFillBits += qcOut->qcElement.fillBits;
492956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
493956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
494e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard  nFullFillElem = (max((qcOut->totFillBits - 1), 0) / maxFillElemBits) * maxFillElemBits;
495b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
496956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  qcOut->totFillBits = qcOut->totFillBits - nFullFillElem;
497956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
498956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  /* check fill elements */
499b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
500956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  if (qcOut->totFillBits > 0) {
501956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    /* minimum Fillelement contains 7 (TAG + byte cnt) bits */
502956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    qcOut->totFillBits = max(7, qcOut->totFillBits);
503956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    /* fill element size equals n*8 + 7 */
504b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard    qcOut->totFillBits = qcOut->totFillBits + ((8 - ((qcOut->totFillBits - 7) & 0x0007)) & 0x0007);
505956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
506956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
507956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  qcOut->totFillBits = qcOut->totFillBits + nFullFillElem;
508956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
509956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  /* now distribute extra fillbits and alignbits over channel elements */
510956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  qcOut->alignBits = 7 - ((qcOut->totDynBitsUsed + qcOut->totStaticBitsUsed +
511b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard                           qcOut->totAncBitsUsed + qcOut->totFillBits - 1) & 0x0007);
512b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
513956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
514956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  if ( (qcOut->alignBits + qcOut->totFillBits - totFillBits == 8) &&
515956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong       (qcOut->totFillBits > 8))
516956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    qcOut->totFillBits = qcOut->totFillBits - 8;
517956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
518b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
519956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  diffBits = qcOut->alignBits + qcOut->totFillBits - totFillBits;
520b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
521956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  if(diffBits>=0) {
522956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    qcOut->qcElement.fillBits += diffBits;
523956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
524956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
525956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  bitsUsed = qcOut->totDynBitsUsed + qcOut->totStaticBitsUsed + qcOut->totAncBitsUsed;
526956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  bitsUsed = bitsUsed + qcOut->totFillBits + qcOut->alignBits;
527b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
528956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  if (bitsUsed > qcKernel->maxBitsTot) {
529956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    return -1;
530956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
531956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  return bitsUsed;
532956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
533956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
534956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
535956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*********************************************************************************
536956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
537956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: AdjustBitrate
538956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description:  adjusts framelength via padding on a frame to frame basis,
539956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*               to achieve a bitrate that demands a non byte aligned
540956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*               framelength
541956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* return:       errorcode
542956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
543956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/
544956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongWord16 AdjustBitrate(QC_STATE        *hQC,
545956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                     Word32           bitRate,    /* total bitrate */
546956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                     Word32           sampleRate) /* output sampling rate */
547956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
548956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 paddingOn;
549956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 frameLen;
550956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 codeBits;
551956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 codeBitsLast;
552956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
553956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  /* Do we need a extra padding byte? */
554956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  paddingOn = framePadding(bitRate,
555956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                           sampleRate,
556956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                           &hQC->padding.paddingRest);
557956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
558956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  /* frame length */
559956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  frameLen = paddingOn + calcFrameLen(bitRate,
560956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                      sampleRate,
561956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                      FRAME_LEN_BYTES_INT);
562956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
563956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  frameLen = frameLen << 3;
564956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  codeBitsLast = hQC->averageBitsTot - hQC->globStatBits;
565956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  codeBits     = frameLen - hQC->globStatBits;
566956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
567b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  /* calculate bits for every channel element */
568956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  if (codeBits != codeBitsLast) {
569b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard    Word16 totalBits = 0;
570956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
571956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    hQC->elementBits.averageBits = (hQC->elementBits.relativeBits * codeBits) >> 16; /* relativeBits was scaled down by 2 */
572956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    totalBits += hQC->elementBits.averageBits;
573956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
574956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    hQC->elementBits.averageBits = hQC->elementBits.averageBits + (codeBits - totalBits);
575956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
576956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
577b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  hQC->averageBitsTot = frameLen;
578956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
579956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  return 0;
580956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
581