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:		bitenc.c
18
19	Content:	Bitstream encoder functions
20
21*******************************************************************************/
22
23#include "bitenc.h"
24#include "bit_cnt.h"
25#include "dyn_bits.h"
26#include "qc_data.h"
27#include "interface.h"
28
29#define UNUSED(x) (void)(x)
30
31static const  Word16 globalGainOffset = 100;
32static const  Word16 icsReservedBit   = 0;
33
34
35/*****************************************************************************
36*
37* function name: encodeSpectralData
38* description:  encode spectral data
39* returns:      spectral bits used
40*
41*****************************************************************************/
42static Word32 encodeSpectralData(Word16             *sfbOffset,
43                                 SECTION_DATA       *sectionData,
44                                 Word16             *quantSpectrum,
45                                 HANDLE_BIT_BUF      hBitStream)
46{
47  Word16 i,sfb;
48  Word16 dbgVal;
49  SECTION_INFO* psectioninfo;
50  dbgVal = GetBitsAvail(hBitStream);
51
52  for(i=0; i<sectionData->noOfSections; i++) {
53    psectioninfo = &(sectionData->sectionInfo[i]);
54	/*
55       huffencode spectral data for this section
56    */
57    for(sfb=psectioninfo->sfbStart;
58        sfb<psectioninfo->sfbStart+psectioninfo->sfbCnt;
59        sfb++) {
60      codeValues(quantSpectrum+sfbOffset[sfb],
61                 sfbOffset[sfb+1] - sfbOffset[sfb],
62                 psectioninfo->codeBook,
63                 hBitStream);
64    }
65  }
66
67  return(GetBitsAvail(hBitStream)-dbgVal);
68}
69
70/*****************************************************************************
71*
72* function name:encodeGlobalGain
73* description: encodes Global Gain (common scale factor)
74* returns:     none
75*
76*****************************************************************************/
77static void encodeGlobalGain(Word16 globalGain,
78                             Word16 logNorm,
79                             Word16 scalefac,
80                             HANDLE_BIT_BUF hBitStream)
81{
82  WriteBits(hBitStream, ((globalGain - scalefac) + globalGainOffset-(logNorm << 2)), 8);
83}
84
85
86/*****************************************************************************
87*
88* function name:encodeIcsInfo
89* description: encodes Ics Info
90* returns:     none
91*
92*****************************************************************************/
93
94static void encodeIcsInfo(Word16 blockType,
95                          Word16 windowShape,
96                          Word16 groupingMask,
97                          SECTION_DATA *sectionData,
98                          HANDLE_BIT_BUF  hBitStream)
99{
100  WriteBits(hBitStream,icsReservedBit,1);
101  WriteBits(hBitStream,blockType,2);
102  WriteBits(hBitStream,windowShape,1);
103
104
105  switch(blockType){
106    case LONG_WINDOW:
107    case START_WINDOW:
108    case STOP_WINDOW:
109      WriteBits(hBitStream,sectionData->maxSfbPerGroup,6);
110
111      /* No predictor data present */
112      WriteBits(hBitStream, 0, 1);
113      break;
114
115    case SHORT_WINDOW:
116      WriteBits(hBitStream,sectionData->maxSfbPerGroup,4);
117
118      /*
119      Write grouping bits
120      */
121      WriteBits(hBitStream,groupingMask,TRANS_FAC-1);
122      break;
123  }
124}
125
126/*****************************************************************************
127*
128* function name: encodeSectionData
129* description:  encode section data (common Huffman codebooks for adjacent
130*               SFB's)
131* returns:      none
132*
133*****************************************************************************/
134static Word32 encodeSectionData(SECTION_DATA *sectionData,
135                                HANDLE_BIT_BUF hBitStream)
136{
137  Word16 sectEscapeVal=0,sectLenBits=0;
138  Word16 sectLen;
139  Word16 i;
140  Word16 dbgVal=GetBitsAvail(hBitStream);
141
142
143
144  switch(sectionData->blockType)
145  {
146    case LONG_WINDOW:
147    case START_WINDOW:
148    case STOP_WINDOW:
149      sectEscapeVal = SECT_ESC_VAL_LONG;
150      sectLenBits   = SECT_BITS_LONG;
151      break;
152
153    case SHORT_WINDOW:
154      sectEscapeVal = SECT_ESC_VAL_SHORT;
155      sectLenBits   = SECT_BITS_SHORT;
156      break;
157  }
158
159  for(i=0;i<sectionData->noOfSections;i++) {
160    WriteBits(hBitStream,sectionData->sectionInfo[i].codeBook,4);
161    sectLen = sectionData->sectionInfo[i].sfbCnt;
162
163    while(sectLen >= sectEscapeVal) {
164
165      WriteBits(hBitStream,sectEscapeVal,sectLenBits);
166      sectLen = sectLen - sectEscapeVal;
167    }
168    WriteBits(hBitStream,sectLen,sectLenBits);
169  }
170  return(GetBitsAvail(hBitStream)-dbgVal);
171}
172
173/*****************************************************************************
174*
175* function name: encodeScaleFactorData
176* description:  encode DPCM coded scale factors
177* returns:      none
178*
179*****************************************************************************/
180static Word32 encodeScaleFactorData(UWord16        *maxValueInSfb,
181                                    SECTION_DATA   *sectionData,
182                                    Word16         *scalefac,
183                                    HANDLE_BIT_BUF  hBitStream)
184{
185  Word16 i,j,lastValScf,deltaScf;
186  Word16 dbgVal = GetBitsAvail(hBitStream);
187  SECTION_INFO* psectioninfo;
188
189  lastValScf=scalefac[sectionData->firstScf];
190
191  for(i=0;i<sectionData->noOfSections;i++){
192    psectioninfo = &(sectionData->sectionInfo[i]);
193    if (psectioninfo->codeBook != CODE_BOOK_ZERO_NO){
194      for (j=psectioninfo->sfbStart;
195           j<psectioninfo->sfbStart+psectioninfo->sfbCnt; j++){
196
197        if(maxValueInSfb[j] == 0) {
198          deltaScf = 0;
199        }
200        else {
201          deltaScf = lastValScf - scalefac[j];
202          lastValScf = scalefac[j];
203        }
204
205        if(codeScalefactorDelta(deltaScf,hBitStream)){
206          return(1);
207        }
208      }
209    }
210
211  }
212  return(GetBitsAvail(hBitStream)-dbgVal);
213}
214
215/*****************************************************************************
216*
217* function name:encodeMsInfo
218* description: encodes MS-Stereo Info
219* returns:     none
220*
221*****************************************************************************/
222static void encodeMSInfo(Word16          sfbCnt,
223                         Word16          grpSfb,
224                         Word16          maxSfb,
225                         Word16          msDigest,
226                         Word16         *jsFlags,
227                         HANDLE_BIT_BUF  hBitStream)
228{
229  Word16 sfb, sfbOff;
230
231
232  switch(msDigest)
233  {
234    case MS_NONE:
235      WriteBits(hBitStream,SI_MS_MASK_NONE,2);
236      break;
237
238    case MS_ALL:
239      WriteBits(hBitStream,SI_MS_MASK_ALL,2);
240      break;
241
242    case MS_SOME:
243      WriteBits(hBitStream,SI_MS_MASK_SOME,2);
244      for(sfbOff = 0; sfbOff < sfbCnt; sfbOff+=grpSfb) {
245        for(sfb=0; sfb<maxSfb; sfb++) {
246
247          if(jsFlags[sfbOff+sfb] & MS_ON) {
248            WriteBits(hBitStream,1,1);
249          }
250          else{
251            WriteBits(hBitStream,0,1);
252          }
253        }
254      }
255      break;
256  }
257
258}
259
260/*****************************************************************************
261*
262* function name: encodeTnsData
263* description:  encode TNS data (filter order, coeffs, ..)
264* returns:      none
265*
266*****************************************************************************/
267static void encodeTnsData(TNS_INFO tnsInfo,
268                          Word16 blockType,
269                          HANDLE_BIT_BUF hBitStream) {
270  Word16 i,k;
271  Flag tnsPresent;
272  Word16 numOfWindows;
273  Word16 coefBits;
274  Flag isShort;
275
276
277  if (blockType==2) {
278    isShort = 1;
279    numOfWindows = TRANS_FAC;
280  }
281  else {
282    isShort = 0;
283    numOfWindows = 1;
284  }
285
286  tnsPresent=0;
287  for (i=0; i<numOfWindows; i++) {
288
289    if (tnsInfo.tnsActive[i]) {
290      tnsPresent=1;
291    }
292  }
293
294  if (tnsPresent==0) {
295    WriteBits(hBitStream,0,1);
296  }
297  else{ /* there is data to be written*/
298    WriteBits(hBitStream,1,1); /*data_present */
299    for (i=0; i<numOfWindows; i++) {
300
301      WriteBits(hBitStream,tnsInfo.tnsActive[i],(isShort?1:2));
302
303      if (tnsInfo.tnsActive[i]) {
304
305        WriteBits(hBitStream,((tnsInfo.coefRes[i] - 4)==0?1:0),1);
306
307        WriteBits(hBitStream,tnsInfo.length[i],(isShort?4:6));
308
309        WriteBits(hBitStream,tnsInfo.order[i],(isShort?3:5));
310
311        if (tnsInfo.order[i]){
312          WriteBits(hBitStream, FILTER_DIRECTION, 1);
313
314          if(tnsInfo.coefRes[i] == 4) {
315            coefBits = 3;
316            for(k=0; k<tnsInfo.order[i]; k++) {
317
318              if (tnsInfo.coef[i*TNS_MAX_ORDER_SHORT+k] > 3 ||
319                  tnsInfo.coef[i*TNS_MAX_ORDER_SHORT+k] < -4) {
320                coefBits = 4;
321                break;
322              }
323            }
324          }
325          else {
326            coefBits = 2;
327            for(k=0; k<tnsInfo.order[i]; k++) {
328
329              if (tnsInfo.coef[i*TNS_MAX_ORDER_SHORT+k] > 1 ||
330                  tnsInfo.coef[i*TNS_MAX_ORDER_SHORT+k] < -2) {
331                coefBits = 3;
332                break;
333              }
334            }
335          }
336          WriteBits(hBitStream, tnsInfo.coefRes[i] - coefBits, 1); /*coef_compres*/
337          for (k=0; k<tnsInfo.order[i]; k++ ) {
338            static const Word16 rmask[] = {0,1,3,7,15};
339
340            WriteBits(hBitStream,tnsInfo.coef[i*TNS_MAX_ORDER_SHORT+k] & rmask[coefBits],coefBits);
341          }
342        }
343      }
344    }
345  }
346
347}
348
349/*****************************************************************************
350*
351* function name: encodeGainControlData
352* description:  unsupported
353* returns:      none
354*
355*****************************************************************************/
356static void encodeGainControlData(HANDLE_BIT_BUF hBitStream)
357{
358  WriteBits(hBitStream,0,1);
359}
360
361/*****************************************************************************
362*
363* function name: encodePulseData
364* description:  not supported yet (dummy)
365* returns:      none
366*
367*****************************************************************************/
368static void encodePulseData(HANDLE_BIT_BUF hBitStream)
369{
370  WriteBits(hBitStream,0,1);
371}
372
373
374/*****************************************************************************
375*
376* function name: WriteIndividualChannelStream
377* description:  management of write process of individual channel stream
378* returns:      none
379*
380*****************************************************************************/
381static void
382writeIndividualChannelStream(Flag   commonWindow,
383                             Word16 mdctScale,
384                             Word16 windowShape,
385                             Word16 groupingMask,
386                             Word16 *sfbOffset,
387                             Word16 scf[],
388                             UWord16 *maxValueInSfb,
389                             Word16 globalGain,
390                             Word16 quantSpec[],
391                             SECTION_DATA *sectionData,
392                             HANDLE_BIT_BUF hBitStream,
393                             TNS_INFO tnsInfo)
394{
395  Word16 logNorm;
396
397  logNorm = LOG_NORM_PCM - (mdctScale + 1);
398
399  encodeGlobalGain(globalGain, logNorm,scf[sectionData->firstScf], hBitStream);
400
401
402  if(!commonWindow) {
403    encodeIcsInfo(sectionData->blockType, windowShape, groupingMask, sectionData, hBitStream);
404  }
405
406  encodeSectionData(sectionData, hBitStream);
407
408  encodeScaleFactorData(maxValueInSfb,
409                        sectionData,
410                        scf,
411                        hBitStream);
412
413  encodePulseData(hBitStream);
414
415  encodeTnsData(tnsInfo, sectionData->blockType, hBitStream);
416
417  encodeGainControlData(hBitStream);
418
419  encodeSpectralData(sfbOffset,
420                     sectionData,
421                     quantSpec,
422                     hBitStream);
423
424}
425
426/*****************************************************************************
427*
428* function name: writeSingleChannelElement
429* description:  write single channel element to bitstream
430* returns:      none
431*
432*****************************************************************************/
433static Word16 writeSingleChannelElement(Word16 instanceTag,
434                                        Word16 *sfbOffset,
435                                        QC_OUT_CHANNEL* qcOutChannel,
436                                        HANDLE_BIT_BUF hBitStream,
437                                        TNS_INFO tnsInfo)
438{
439  WriteBits(hBitStream,ID_SCE,3);
440  WriteBits(hBitStream,instanceTag,4);
441  writeIndividualChannelStream(0,
442                               qcOutChannel->mdctScale,
443                               qcOutChannel->windowShape,
444                               qcOutChannel->groupingMask,
445                               sfbOffset,
446                               qcOutChannel->scf,
447                               qcOutChannel->maxValueInSfb,
448                               qcOutChannel->globalGain,
449                               qcOutChannel->quantSpec,
450                               &(qcOutChannel->sectionData),
451                               hBitStream,
452                               tnsInfo
453                               );
454  return(0);
455}
456
457
458
459/*****************************************************************************
460*
461* function name: writeChannelPairElement
462* description:
463* returns:      none
464*
465*****************************************************************************/
466static Word16 writeChannelPairElement(Word16 instanceTag,
467                                      Word16 msDigest,
468                                      Word16 msFlags[MAX_GROUPED_SFB],
469                                      Word16 *sfbOffset[2],
470                                      QC_OUT_CHANNEL qcOutChannel[2],
471                                      HANDLE_BIT_BUF hBitStream,
472                                      TNS_INFO tnsInfo[2])
473{
474  WriteBits(hBitStream,ID_CPE,3);
475  WriteBits(hBitStream,instanceTag,4);
476  WriteBits(hBitStream,1,1); /* common window */
477
478  encodeIcsInfo(qcOutChannel[0].sectionData.blockType,
479                qcOutChannel[0].windowShape,
480                qcOutChannel[0].groupingMask,
481                &(qcOutChannel[0].sectionData),
482                hBitStream);
483
484  encodeMSInfo(qcOutChannel[0].sectionData.sfbCnt,
485               qcOutChannel[0].sectionData.sfbPerGroup,
486               qcOutChannel[0].sectionData.maxSfbPerGroup,
487               msDigest,
488               msFlags,
489               hBitStream);
490
491  writeIndividualChannelStream(1,
492                               qcOutChannel[0].mdctScale,
493                               qcOutChannel[0].windowShape,
494                               qcOutChannel[0].groupingMask,
495                               sfbOffset[0],
496                               qcOutChannel[0].scf,
497                               qcOutChannel[0].maxValueInSfb,
498                               qcOutChannel[0].globalGain,
499                               qcOutChannel[0].quantSpec,
500                               &(qcOutChannel[0].sectionData),
501                               hBitStream,
502                               tnsInfo[0]);
503
504  writeIndividualChannelStream(1,
505                               qcOutChannel[1].mdctScale,
506                               qcOutChannel[1].windowShape,
507                               qcOutChannel[1].groupingMask,
508                               sfbOffset[1],
509                               qcOutChannel[1].scf,
510                               qcOutChannel[1].maxValueInSfb,
511                               qcOutChannel[1].globalGain,
512                               qcOutChannel[1].quantSpec,
513                               &(qcOutChannel[1].sectionData),
514                               hBitStream,
515                               tnsInfo[1]);
516
517  return(0);
518}
519
520
521
522/*****************************************************************************
523*
524* function name: writeFillElement
525* description:  write fill elements to bitstream
526* returns:      none
527*
528*****************************************************************************/
529static void writeFillElement( const UWord8 *ancBytes,
530                              Word16 totFillBits,
531                              HANDLE_BIT_BUF hBitStream)
532{
533  Word16 i;
534  Word16 cnt,esc_count;
535
536  /*
537    Write fill Element(s):
538    amount of a fill element can be 7+X*8 Bits, X element of [0..270]
539  */
540
541  while(totFillBits >= (3+4)) {
542    cnt = min(((totFillBits - (3+4)) >> 3), ((1<<4)-1));
543
544    WriteBits(hBitStream,ID_FIL,3);
545    WriteBits(hBitStream,cnt,4);
546
547    totFillBits = totFillBits - (3+4);
548
549
550    if ((cnt == (1<<4)-1)) {
551
552      esc_count = min( ((totFillBits >> 3) - ((1<<4)-1)), (1<<8)-1);
553      WriteBits(hBitStream,esc_count,8);
554      totFillBits = (totFillBits - 8);
555      cnt = cnt + (esc_count - 1);
556    }
557
558    for(i=0;i<cnt;i++) {
559
560      if(ancBytes)
561        WriteBits(hBitStream, *ancBytes++,8);
562      else
563        WriteBits(hBitStream,0,8);
564      totFillBits = totFillBits - 8;
565    }
566  }
567}
568
569/*****************************************************************************
570*
571* function name: WriteBitStream
572* description:  main function of write bitsteam process
573* returns:      0 if success
574*
575*****************************************************************************/
576Word16 WriteBitstream (HANDLE_BIT_BUF hBitStream,
577                       ELEMENT_INFO elInfo,
578                       QC_OUT *qcOut,
579                       PSY_OUT *psyOut,
580                       Word16 *globUsedBits,
581                       const UWord8 *ancBytes,
582					   Word16 sampindex
583                       ) /* returns error code */
584{
585  Word16 bitMarkUp;
586  Word16 elementUsedBits;
587  Word16 frameBits=0;
588
589  UNUSED(ancBytes);
590
591  /*   struct bitbuffer bsWriteCopy; */
592  bitMarkUp = GetBitsAvail(hBitStream);
593  if(qcOut->qcElement.adtsUsed)  /*  write adts header*/
594  {
595	  WriteBits(hBitStream, 0xFFF, 12); /* 12 bit Syncword */
596	  WriteBits(hBitStream, 1, 1); /* ID == 0 for MPEG4 AAC, 1 for MPEG2 AAC */
597	  WriteBits(hBitStream, 0, 2); /* layer == 0 */
598	  WriteBits(hBitStream, 1, 1); /* protection absent */
599	  WriteBits(hBitStream, 1, 2); /* profile */
600	  WriteBits(hBitStream, sampindex, 4); /* sampling rate */
601	  WriteBits(hBitStream, 0, 1); /* private bit */
602	  WriteBits(hBitStream, elInfo.nChannelsInEl, 3); /* ch. config (must be > 0) */
603								   /* simply using numChannels only works for
604									6 channels or less, else a channel
605									configuration should be written */
606	  WriteBits(hBitStream, 0, 1); /* original/copy */
607	  WriteBits(hBitStream, 0, 1); /* home */
608
609	  /* Variable ADTS header */
610	  WriteBits(hBitStream, 0, 1); /* copyr. id. bit */
611	  WriteBits(hBitStream, 0, 1); /* copyr. id. start */
612	  WriteBits(hBitStream, *globUsedBits >> 3, 13);
613	  WriteBits(hBitStream, 0x7FF, 11); /* buffer fullness (0x7FF for VBR) */
614	  WriteBits(hBitStream, 0, 2); /* raw data blocks (0+1=1) */
615  }
616
617  *globUsedBits=0;
618
619  {
620
621    Word16 *sfbOffset[2];
622    TNS_INFO tnsInfo[2];
623    elementUsedBits = 0;
624
625    switch (elInfo.elType) {
626
627      case ID_SCE:      /* single channel */
628        sfbOffset[0] = psyOut->psyOutChannel[elInfo.ChannelIndex[0]].sfbOffsets;
629        tnsInfo[0] = psyOut->psyOutChannel[elInfo.ChannelIndex[0]].tnsInfo;
630
631        writeSingleChannelElement(elInfo.instanceTag,
632                                  sfbOffset[0],
633                                  &qcOut->qcChannel[elInfo.ChannelIndex[0]],
634                                  hBitStream,
635                                  tnsInfo[0]);
636        break;
637
638      case ID_CPE:     /* channel pair */
639        {
640          Word16 msDigest;
641          Word16 *msFlags = psyOut->psyOutElement.toolsInfo.msMask;
642          msDigest = psyOut->psyOutElement.toolsInfo.msDigest;
643          sfbOffset[0] =
644            psyOut->psyOutChannel[elInfo.ChannelIndex[0]].sfbOffsets;
645          sfbOffset[1] =
646            psyOut->psyOutChannel[elInfo.ChannelIndex[1]].sfbOffsets;
647
648          tnsInfo[0]=
649            psyOut->psyOutChannel[elInfo.ChannelIndex[0]].tnsInfo;
650          tnsInfo[1]=
651            psyOut->psyOutChannel[elInfo.ChannelIndex[1]].tnsInfo;
652          writeChannelPairElement(elInfo.instanceTag,
653                                  msDigest,
654                                  msFlags,
655                                  sfbOffset,
656                                  &qcOut->qcChannel[elInfo.ChannelIndex[0]],
657                                  hBitStream,
658                                  tnsInfo);
659        }
660        break;
661
662      default:
663        return(1);
664
665      }   /* switch */
666
667    elementUsedBits = elementUsedBits - bitMarkUp;
668    bitMarkUp = GetBitsAvail(hBitStream);
669    frameBits = frameBits + elementUsedBits + bitMarkUp;
670
671  }
672
673  writeFillElement(NULL,
674                   qcOut->totFillBits,
675                   hBitStream);
676
677  WriteBits(hBitStream,ID_END,3);
678
679  /* byte alignement */
680  WriteBits(hBitStream,0, (8 - (hBitStream->cntBits & 7)) & 7);
681
682  *globUsedBits = *globUsedBits- bitMarkUp;
683  bitMarkUp = GetBitsAvail(hBitStream);
684  *globUsedBits = *globUsedBits + bitMarkUp;
685  frameBits = frameBits + *globUsedBits;
686
687
688  if (frameBits !=  (qcOut->totStaticBitsUsed+qcOut->totDynBitsUsed + qcOut->totAncBitsUsed +
689                     qcOut->totFillBits + qcOut->alignBits)) {
690    return(-1);
691  }
692  return(0);
693}
694