1 /*
2  ** Copyright 2003-2010, VisualOn, Inc.
3  **
4  ** Licensed under the Apache License, Version 2.0 (the "License");
5  ** you may not use this file except in compliance with the License.
6  ** You may obtain a copy of the License at
7  **
8  **     http://www.apache.org/licenses/LICENSE-2.0
9  **
10  ** Unless required by applicable law or agreed to in writing, software
11  ** distributed under the License is distributed on an "AS IS" BASIS,
12  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  ** See the License for the specific language governing permissions and
14  ** limitations under the License.
15  */
16 /*******************************************************************************
17 	File:		dyn_bits.c
18 
19 	Content:	Noiseless coder module functions
20 
21 *******************************************************************************/
22 
23 #include "aac_rom.h"
24 #include "dyn_bits.h"
25 #include "bit_cnt.h"
26 #include "psy_const.h"
27 
28 /*****************************************************************************
29 *
30 * function name: buildBitLookUp
31 * description:  count bits using all possible tables
32 *
33 *****************************************************************************/
34 static void
buildBitLookUp(const Word16 * quantSpectrum,const Word16 maxSfb,const Word16 * sfbOffset,const UWord16 * sfbMax,Word16 bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX+1],SECTION_INFO * sectionInfo)35 buildBitLookUp(const Word16 *quantSpectrum,
36                const Word16 maxSfb,
37                const Word16 *sfbOffset,
38                const UWord16 *sfbMax,
39                Word16 bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1],
40                SECTION_INFO * sectionInfo)
41 {
42   Word32 i;
43 
44   for (i=0; i<maxSfb; i++) {
45     Word16 sfbWidth, maxVal;
46 
47     sectionInfo[i].sfbCnt = 1;
48     sectionInfo[i].sfbStart = i;
49     sectionInfo[i].sectionBits = INVALID_BITCOUNT;
50     sectionInfo[i].codeBook = -1;
51     sfbWidth = sfbOffset[i + 1] - sfbOffset[i];
52     maxVal = sfbMax[i];
53     bitCount(quantSpectrum + sfbOffset[i], sfbWidth, maxVal, bitLookUp[i]);
54   }
55 }
56 
57 
58 /*****************************************************************************
59 *
60 * function name: findBestBook
61 * description:  essential helper functions
62 *
63 *****************************************************************************/
64 static Word16
findBestBook(const Word16 * bc,Word16 * book)65 findBestBook(const Word16 *bc, Word16 *book)
66 {
67   Word32 minBits, j;
68   minBits = INVALID_BITCOUNT;
69 
70   for (j=0; j<=CODE_BOOK_ESC_NDX; j++) {
71 
72     if (bc[j] < minBits) {
73       minBits = bc[j];
74       *book = j;
75     }
76   }
77   return extract_l(minBits);
78 }
79 
80 static Word16
findMinMergeBits(const Word16 * bc1,const Word16 * bc2)81 findMinMergeBits(const Word16 *bc1, const Word16 *bc2)
82 {
83   Word32 minBits, j, sum;
84   minBits = INVALID_BITCOUNT;
85 
86   for (j=0; j<=CODE_BOOK_ESC_NDX; j++) {
87     sum = bc1[j] + bc2[j];
88     if (sum < minBits) {
89       minBits = sum;
90     }
91   }
92   return extract_l(minBits);
93 }
94 
95 static void
mergeBitLookUp(Word16 * bc1,const Word16 * bc2)96 mergeBitLookUp(Word16 *bc1, const Word16 *bc2)
97 {
98   Word32 j;
99 
100   for (j=0; j<=CODE_BOOK_ESC_NDX; j++) {
101     bc1[j] = min(bc1[j] + bc2[j], INVALID_BITCOUNT);
102   }
103 }
104 
105 static Word16
findMaxMerge(const Word16 mergeGainLookUp[MAX_SFB_LONG],const SECTION_INFO * sectionInfo,const Word16 maxSfb,Word16 * maxNdx)106 findMaxMerge(const Word16 mergeGainLookUp[MAX_SFB_LONG],
107              const SECTION_INFO *sectionInfo,
108              const Word16 maxSfb, Word16 *maxNdx)
109 {
110   Word32 i, maxMergeGain;
111   maxMergeGain = 0;
112 
113   for (i=0; i+sectionInfo[i].sfbCnt < maxSfb; i += sectionInfo[i].sfbCnt) {
114 
115     if (mergeGainLookUp[i] > maxMergeGain) {
116       maxMergeGain = mergeGainLookUp[i];
117       *maxNdx = i;
118     }
119   }
120   return extract_l(maxMergeGain);
121 }
122 
123 
124 
125 static Word16
CalcMergeGain(const SECTION_INFO * sectionInfo,Word16 bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX+1],const Word16 * sideInfoTab,const Word16 ndx1,const Word16 ndx2)126 CalcMergeGain(const SECTION_INFO *sectionInfo,
127               Word16 bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1],
128               const Word16 *sideInfoTab,
129               const Word16 ndx1,
130               const Word16 ndx2)
131 {
132   Word32 SplitBits;
133   Word32 MergeBits;
134   Word32 MergeGain;
135 
136   /*
137     Bit amount for splitted sections
138   */
139   SplitBits = sectionInfo[ndx1].sectionBits + sectionInfo[ndx2].sectionBits;
140 
141   MergeBits = sideInfoTab[sectionInfo[ndx1].sfbCnt + sectionInfo[ndx2].sfbCnt] +
142                   findMinMergeBits(bitLookUp[ndx1], bitLookUp[ndx2]);
143   MergeGain = (SplitBits - MergeBits);
144 
145   return extract_l(MergeGain);
146 }
147 
148 /*
149   sectioning Stage 0:find minimum codbooks
150 */
151 
152 static void
gmStage0(SECTION_INFO * sectionInfo,Word16 bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX+1],const Word16 maxSfb)153 gmStage0(SECTION_INFO * sectionInfo,
154          Word16 bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1],
155          const Word16 maxSfb)
156 {
157   Word32 i;
158 
159   for (i=0; i<maxSfb; i++) {
160     /* Side-Info bits will be calculated in Stage 1!  */
161 
162     if (sectionInfo[i].sectionBits == INVALID_BITCOUNT) {
163       sectionInfo[i].sectionBits = findBestBook(bitLookUp[i], &(sectionInfo[i].codeBook));
164     }
165   }
166 }
167 
168 /*
169   sectioning Stage 1:merge all connected regions with the same code book and
170   calculate side info
171 */
172 
173 static void
gmStage1(SECTION_INFO * sectionInfo,Word16 bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX+1],const Word16 maxSfb,const Word16 * sideInfoTab)174 gmStage1(SECTION_INFO * sectionInfo,
175          Word16 bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1],
176          const Word16 maxSfb,
177          const Word16 *sideInfoTab)
178 {
179   SECTION_INFO * sectionInfo_s;
180   SECTION_INFO * sectionInfo_e;
181   Word32 mergeStart, mergeEnd;
182   mergeStart = 0;
183 
184   do {
185 
186     sectionInfo_s = sectionInfo + mergeStart;
187 	for (mergeEnd=mergeStart+1; mergeEnd<maxSfb; mergeEnd++) {
188       sectionInfo_e = sectionInfo + mergeEnd;
189       if (sectionInfo_s->codeBook != sectionInfo_e->codeBook)
190         break;
191       sectionInfo_s->sfbCnt += 1;
192       sectionInfo_s->sectionBits += sectionInfo_e->sectionBits;
193 
194       mergeBitLookUp(bitLookUp[mergeStart], bitLookUp[mergeEnd]);
195     }
196 
197     sectionInfo_s->sectionBits += sideInfoTab[sectionInfo_s->sfbCnt];
198     sectionInfo[mergeEnd - 1].sfbStart = sectionInfo_s->sfbStart;      /* speed up prev search */
199 
200     mergeStart = mergeEnd;
201 
202 
203   } while (mergeStart - maxSfb < 0);
204 }
205 
206 /*
207   sectioning Stage 2:greedy merge algorithm, merge connected sections with
208   maximum bit gain until no more gain is possible
209 */
210 static void
gmStage2(SECTION_INFO * sectionInfo,Word16 mergeGainLookUp[MAX_SFB_LONG],Word16 bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX+1],const Word16 maxSfb,const Word16 * sideInfoTab)211 gmStage2(SECTION_INFO *sectionInfo,
212          Word16 mergeGainLookUp[MAX_SFB_LONG],
213          Word16 bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1],
214          const Word16 maxSfb,
215          const Word16 *sideInfoTab)
216 {
217   Word16 i;
218 
219   for (i=0; i+sectionInfo[i].sfbCnt<maxSfb; i+=sectionInfo[i].sfbCnt) {
220     mergeGainLookUp[i] = CalcMergeGain(sectionInfo,
221                                        bitLookUp,
222                                        sideInfoTab,
223                                        i,
224                                        (i + sectionInfo[i].sfbCnt));
225   }
226 
227   while (TRUE) {
228     Word16 maxMergeGain, maxNdx = 0, maxNdxNext, maxNdxLast;
229 
230     maxMergeGain = findMaxMerge(mergeGainLookUp, sectionInfo, maxSfb, &maxNdx);
231 
232 
233     if (maxMergeGain <= 0)
234       break;
235 
236 
237     maxNdxNext = maxNdx + sectionInfo[maxNdx].sfbCnt;
238 
239     sectionInfo[maxNdx].sfbCnt = sectionInfo[maxNdx].sfbCnt + sectionInfo[maxNdxNext].sfbCnt;
240     sectionInfo[maxNdx].sectionBits = sectionInfo[maxNdx].sectionBits +
241                                           (sectionInfo[maxNdxNext].sectionBits - maxMergeGain);
242 
243 
244     mergeBitLookUp(bitLookUp[maxNdx], bitLookUp[maxNdxNext]);
245 
246 
247     if (maxNdx != 0) {
248       maxNdxLast = sectionInfo[maxNdx - 1].sfbStart;
249       mergeGainLookUp[maxNdxLast] = CalcMergeGain(sectionInfo,
250                                                   bitLookUp,
251                                                   sideInfoTab,
252                                                   maxNdxLast,
253                                                   maxNdx);
254     }
255     maxNdxNext = maxNdx + sectionInfo[maxNdx].sfbCnt;
256 
257     sectionInfo[maxNdxNext - 1].sfbStart = sectionInfo[maxNdx].sfbStart;
258 
259 
260     if (maxNdxNext - maxSfb < 0) {
261       mergeGainLookUp[maxNdx] = CalcMergeGain(sectionInfo,
262                                               bitLookUp,
263                                               sideInfoTab,
264                                               maxNdx,
265                                               maxNdxNext);
266     }
267   }
268 }
269 
270 /*
271   count bits used by the noiseless coder
272 */
273 static void
noiselessCounter(SECTION_DATA * sectionData,Word16 mergeGainLookUp[MAX_SFB_LONG],Word16 bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX+1],const Word16 * quantSpectrum,const UWord16 * maxValueInSfb,const Word16 * sfbOffset,const Word32 blockType)274 noiselessCounter(SECTION_DATA *sectionData,
275                  Word16 mergeGainLookUp[MAX_SFB_LONG],
276                  Word16 bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1],
277                  const Word16 *quantSpectrum,
278                  const UWord16 *maxValueInSfb,
279                  const Word16 *sfbOffset,
280                  const Word32 blockType)
281 {
282   Word32 grpNdx, i;
283   const Word16 *sideInfoTab = NULL;
284   SECTION_INFO *sectionInfo;
285 
286   /*
287     use appropriate side info table
288   */
289   switch (blockType)
290   {
291     case LONG_WINDOW:
292     case START_WINDOW:
293     case STOP_WINDOW:
294       sideInfoTab = sideInfoTabLong;
295       break;
296     case SHORT_WINDOW:
297       sideInfoTab = sideInfoTabShort;
298       break;
299   }
300 
301 
302   sectionData->noOfSections = 0;
303   sectionData->huffmanBits = 0;
304   sectionData->sideInfoBits = 0;
305 
306 
307   if (sectionData->maxSfbPerGroup == 0)
308     return;
309 
310   /*
311     loop trough groups
312   */
313   for (grpNdx=0; grpNdx<sectionData->sfbCnt; grpNdx+=sectionData->sfbPerGroup) {
314 
315     sectionInfo = sectionData->sectionInfo + sectionData->noOfSections;
316 
317     buildBitLookUp(quantSpectrum,
318                    sectionData->maxSfbPerGroup,
319                    sfbOffset + grpNdx,
320                    maxValueInSfb + grpNdx,
321                    bitLookUp,
322                    sectionInfo);
323 
324     /*
325        0.Stage
326     */
327     gmStage0(sectionInfo, bitLookUp, sectionData->maxSfbPerGroup);
328 
329     /*
330        1.Stage
331     */
332     gmStage1(sectionInfo, bitLookUp, sectionData->maxSfbPerGroup, sideInfoTab);
333 
334 
335     /*
336        2.Stage
337     */
338     gmStage2(sectionInfo,
339              mergeGainLookUp,
340              bitLookUp,
341              sectionData->maxSfbPerGroup,
342              sideInfoTab);
343 
344 
345     /*
346        compress output, calculate total huff and side bits
347     */
348     for (i=0; i<sectionData->maxSfbPerGroup; i+=sectionInfo[i].sfbCnt) {
349       findBestBook(bitLookUp[i], &(sectionInfo[i].codeBook));
350       sectionInfo[i].sfbStart = sectionInfo[i].sfbStart + grpNdx;
351 
352       sectionData->huffmanBits = (sectionData->huffmanBits +
353                                      (sectionInfo[i].sectionBits - sideInfoTab[sectionInfo[i].sfbCnt]));
354       sectionData->sideInfoBits = (sectionData->sideInfoBits + sideInfoTab[sectionInfo[i].sfbCnt]);
355       sectionData->sectionInfo[sectionData->noOfSections] = sectionInfo[i];
356       sectionData->noOfSections = sectionData->noOfSections + 1;
357     }
358   }
359 }
360 
361 
362 /*******************************************************************************
363 *
364 * functionname: scfCount
365 * returns     : ---
366 * description : count bits used by scalefactors.
367 *
368 ********************************************************************************/
scfCount(const Word16 * scalefacGain,const UWord16 * maxValueInSfb,SECTION_DATA * sectionData)369 static void scfCount(const Word16 *scalefacGain,
370                      const UWord16 *maxValueInSfb,
371                      SECTION_DATA * sectionData)
372 
373 {
374   SECTION_INFO *psectionInfo;
375   SECTION_INFO *psectionInfom;
376 
377   /* counter */
378   Word32 i = 0; /* section counter */
379   Word32 j = 0; /* sfb counter */
380   Word32 k = 0; /* current section auxiliary counter */
381   Word32 m = 0; /* other section auxiliary counter */
382   Word32 n = 0; /* other sfb auxiliary counter */
383 
384   /* further variables */
385   Word32 lastValScf     = 0;
386   Word32 deltaScf       = 0;
387   Flag found            = 0;
388   Word32 scfSkipCounter = 0;
389 
390 
391   sectionData->scalefacBits = 0;
392 
393 
394   if (scalefacGain == NULL) {
395     return;
396   }
397 
398   lastValScf = 0;
399   sectionData->firstScf = 0;
400 
401   psectionInfo = sectionData->sectionInfo;
402   for (i=0; i<sectionData->noOfSections; i++) {
403 
404     if (psectionInfo->codeBook != CODE_BOOK_ZERO_NO) {
405       sectionData->firstScf = psectionInfo->sfbStart;
406       lastValScf = scalefacGain[sectionData->firstScf];
407       break;
408     }
409 	psectionInfo += 1;
410   }
411 
412   psectionInfo = sectionData->sectionInfo;
413   for (i=0; i<sectionData->noOfSections; i++, psectionInfo += 1) {
414 
415     if (psectionInfo->codeBook != CODE_BOOK_ZERO_NO
416         && psectionInfo->codeBook != CODE_BOOK_PNS_NO) {
417       for (j = psectionInfo->sfbStart;
418            j < (psectionInfo->sfbStart + psectionInfo->sfbCnt); j++) {
419         /* check if we can repeat the last value to save bits */
420 
421         if (maxValueInSfb[j] == 0) {
422           found = 0;
423 
424           if (scfSkipCounter == 0) {
425             /* end of section */
426 
427             if (j - ((psectionInfo->sfbStart + psectionInfo->sfbCnt) - 1) == 0) {
428               found = 0;
429             }
430             else {
431               for (k = j + 1; k < psectionInfo->sfbStart + psectionInfo->sfbCnt; k++) {
432 
433                 if (maxValueInSfb[k] != 0) {
434                   int tmp = L_abs(scalefacGain[k] - lastValScf);
435 				  found = 1;
436 
437                   if ( tmp < CODE_BOOK_SCF_LAV) {
438                     /* save bits */
439                     deltaScf = 0;
440                   }
441                   else {
442                     /* do not save bits */
443                     deltaScf = lastValScf - scalefacGain[j];
444                     lastValScf = scalefacGain[j];
445                     scfSkipCounter = 0;
446                   }
447                   break;
448                 }
449                 /* count scalefactor skip */
450                 scfSkipCounter = scfSkipCounter + 1;
451               }
452             }
453 
454 			psectionInfom = psectionInfo + 1;
455             /* search for the next maxValueInSfb[] != 0 in all other sections */
456             for (m = i + 1; (m < sectionData->noOfSections) && (found == 0); m++) {
457 
458               if ((psectionInfom->codeBook != CODE_BOOK_ZERO_NO) &&
459                   (psectionInfom->codeBook != CODE_BOOK_PNS_NO)) {
460                 for (n = psectionInfom->sfbStart;
461                      n < (psectionInfom->sfbStart + psectionInfom->sfbCnt); n++) {
462 
463                   if (maxValueInSfb[n] != 0) {
464                     found = 1;
465 
466                     if ( (abs_s(scalefacGain[n] - lastValScf) < CODE_BOOK_SCF_LAV)) {
467                       deltaScf = 0;
468                     }
469                     else {
470                       deltaScf = (lastValScf - scalefacGain[j]);
471                       lastValScf = scalefacGain[j];
472                       scfSkipCounter = 0;
473                     }
474                     break;
475                   }
476                   /* count scalefactor skip */
477                   scfSkipCounter = scfSkipCounter + 1;
478                 }
479               }
480 
481 			  psectionInfom += 1;
482             }
483 
484             if (found == 0) {
485               deltaScf = 0;
486               scfSkipCounter = 0;
487             }
488           }
489           else {
490             deltaScf = 0;
491             scfSkipCounter = scfSkipCounter - 1;
492           }
493         }
494         else {
495           deltaScf = lastValScf - scalefacGain[j];
496           lastValScf = scalefacGain[j];
497         }
498         sectionData->scalefacBits += bitCountScalefactorDelta(deltaScf);
499       }
500     }
501   }
502 }
503 
504 
505 typedef Word16 (*lookUpTable)[CODE_BOOK_ESC_NDX + 1];
506 
507 
508 Word16
dynBitCount(const Word16 * quantSpectrum,const UWord16 * maxValueInSfb,const Word16 * scalefac,const Word16 blockType,const Word16 sfbCnt,const Word16 maxSfbPerGroup,const Word16 sfbPerGroup,const Word16 * sfbOffset,SECTION_DATA * sectionData)509 dynBitCount(const Word16  *quantSpectrum,
510             const UWord16 *maxValueInSfb,
511             const Word16  *scalefac,
512             const Word16   blockType,
513             const Word16   sfbCnt,
514             const Word16   maxSfbPerGroup,
515             const Word16   sfbPerGroup,
516             const Word16  *sfbOffset,
517             SECTION_DATA  *sectionData)
518 {
519   sectionData->blockType      = blockType;
520   sectionData->sfbCnt         = sfbCnt;
521   sectionData->sfbPerGroup    = sfbPerGroup;
522   if(sfbPerGroup)
523 	sectionData->noOfGroups   = sfbCnt/sfbPerGroup;
524   else
525 	sectionData->noOfGroups   = 0x7fff;
526   sectionData->maxSfbPerGroup = maxSfbPerGroup;
527 
528   noiselessCounter(sectionData,
529                    sectionData->mergeGainLookUp,
530                    (lookUpTable)sectionData->bitLookUp,
531                    quantSpectrum,
532                    maxValueInSfb,
533                    sfbOffset,
534                    blockType);
535 
536   scfCount(scalefac,
537            maxValueInSfb,
538            sectionData);
539 
540 
541   return (sectionData->huffmanBits + sectionData->sideInfoBits +
542 	      sectionData->scalefacBits);
543 }
544 
545