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*****************************************************************************/
34static void
35buildBitLookUp(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*****************************************************************************/
64static Word16
65findBestBook(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
80static Word16
81findMinMergeBits(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
95static void
96mergeBitLookUp(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
105static Word16
106findMaxMerge(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
125static Word16
126CalcMergeGain(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
152static void
153gmStage0(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
173static void
174gmStage1(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*/
210static void
211gmStage2(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*/
273static void
274noiselessCounter(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********************************************************************************/
369static 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
505typedef Word16 (*lookUpTable)[CODE_BOOK_ESC_NDX + 1];
506
507
508Word16
509dynBitCount(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