2 ** Copyright 2003-2010, VisualOn, Inc.
\r
4 ** Licensed under the Apache License, Version 2.0 (the "License");
\r
5 ** you may not use this file except in compliance with the License.
\r
6 ** You may obtain a copy of the License at
\r
8 ** http://www.apache.org/licenses/LICENSE-2.0
\r
10 ** Unless required by applicable law or agreed to in writing, software
\r
11 ** distributed under the License is distributed on an "AS IS" BASIS,
\r
12 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
13 ** See the License for the specific language governing permissions and
\r
14 ** limitations under the License.
\r
16 /*******************************************************************************
\r
19 Content: Bitstream encoder functions
\r
21 *******************************************************************************/
27 #include "interface.h"
30 static const Word16 globalGainOffset = 100;
31 static const Word16 icsReservedBit = 0;
34 /*****************************************************************************
36 * function name: encodeSpectralData
37 * description: encode spectral data
38 * returns: spectral bits used
40 *****************************************************************************/
41 static Word32 encodeSpectralData(Word16 *sfbOffset,
42 SECTION_DATA *sectionData,
43 Word16 *quantSpectrum,
44 HANDLE_BIT_BUF hBitStream)
48 SECTION_INFO* psectioninfo;
49 dbgVal = GetBitsAvail(hBitStream);
51 for(i=0; i<sectionData->noOfSections; i++) {
52 psectioninfo = &(sectionData->sectionInfo[i]);
\r
54 huffencode spectral data for this section
56 for(sfb=psectioninfo->sfbStart;
57 sfb<psectioninfo->sfbStart+psectioninfo->sfbCnt;
59 codeValues(quantSpectrum+sfbOffset[sfb],
60 sfbOffset[sfb+1] - sfbOffset[sfb],
61 psectioninfo->codeBook,
66 return(GetBitsAvail(hBitStream)-dbgVal);
69 /*****************************************************************************
71 * function name:encodeGlobalGain
72 * description: encodes Global Gain (common scale factor)
75 *****************************************************************************/
76 static void encodeGlobalGain(Word16 globalGain,
79 HANDLE_BIT_BUF hBitStream)
81 WriteBits(hBitStream, ((globalGain - scalefac) + globalGainOffset-(logNorm << 2)), 8);
85 /*****************************************************************************
87 * function name:encodeIcsInfo
88 * description: encodes Ics Info
91 *****************************************************************************/
93 static void encodeIcsInfo(Word16 blockType,
96 SECTION_DATA *sectionData,
97 HANDLE_BIT_BUF hBitStream)
99 WriteBits(hBitStream,icsReservedBit,1);
100 WriteBits(hBitStream,blockType,2);
101 WriteBits(hBitStream,windowShape,1);
108 WriteBits(hBitStream,sectionData->maxSfbPerGroup,6);
110 /* No predictor data present */
111 WriteBits(hBitStream, 0, 1);
115 WriteBits(hBitStream,sectionData->maxSfbPerGroup,4);
120 WriteBits(hBitStream,groupingMask,TRANS_FAC-1);
125 /*****************************************************************************
127 * function name: encodeSectionData
128 * description: encode section data (common Huffman codebooks for adjacent
132 *****************************************************************************/
133 static Word32 encodeSectionData(SECTION_DATA *sectionData,
134 HANDLE_BIT_BUF hBitStream)
136 Word16 sectEscapeVal=0,sectLenBits=0;
139 Word16 dbgVal=GetBitsAvail(hBitStream);
143 switch(sectionData->blockType)
148 sectEscapeVal = SECT_ESC_VAL_LONG;
149 sectLenBits = SECT_BITS_LONG;
153 sectEscapeVal = SECT_ESC_VAL_SHORT;
154 sectLenBits = SECT_BITS_SHORT;
158 for(i=0;i<sectionData->noOfSections;i++) {
159 WriteBits(hBitStream,sectionData->sectionInfo[i].codeBook,4);
160 sectLen = sectionData->sectionInfo[i].sfbCnt;
162 while(sectLen >= sectEscapeVal) {
164 WriteBits(hBitStream,sectEscapeVal,sectLenBits);
165 sectLen = sectLen - sectEscapeVal;
167 WriteBits(hBitStream,sectLen,sectLenBits);
169 return(GetBitsAvail(hBitStream)-dbgVal);
172 /*****************************************************************************
174 * function name: encodeScaleFactorData
175 * description: encode DPCM coded scale factors
178 *****************************************************************************/
179 static Word32 encodeScaleFactorData(UWord16 *maxValueInSfb,
180 SECTION_DATA *sectionData,
182 HANDLE_BIT_BUF hBitStream)
184 Word16 i,j,lastValScf,deltaScf;
185 Word16 dbgVal = GetBitsAvail(hBitStream);
186 SECTION_INFO* psectioninfo;
188 lastValScf=scalefac[sectionData->firstScf];
190 for(i=0;i<sectionData->noOfSections;i++){
191 psectioninfo = &(sectionData->sectionInfo[i]);
192 if (psectioninfo->codeBook != CODE_BOOK_ZERO_NO){
193 for (j=psectioninfo->sfbStart;
194 j<psectioninfo->sfbStart+psectioninfo->sfbCnt; j++){
196 if(maxValueInSfb[j] == 0) {
200 deltaScf = lastValScf - scalefac[j];
201 lastValScf = scalefac[j];
204 if(codeScalefactorDelta(deltaScf,hBitStream)){
211 return(GetBitsAvail(hBitStream)-dbgVal);
214 /*****************************************************************************
216 * function name:encodeMsInfo
217 * description: encodes MS-Stereo Info
220 *****************************************************************************/
221 static void encodeMSInfo(Word16 sfbCnt,
226 HANDLE_BIT_BUF hBitStream)
234 WriteBits(hBitStream,SI_MS_MASK_NONE,2);
238 WriteBits(hBitStream,SI_MS_MASK_ALL,2);
242 WriteBits(hBitStream,SI_MS_MASK_SOME,2);
243 for(sfbOff = 0; sfbOff < sfbCnt; sfbOff+=grpSfb) {
244 for(sfb=0; sfb<maxSfb; sfb++) {
246 if(jsFlags[sfbOff+sfb] & MS_ON) {
247 WriteBits(hBitStream,1,1);
250 WriteBits(hBitStream,0,1);
259 /*****************************************************************************
261 * function name: encodeTnsData
262 * description: encode TNS data (filter order, coeffs, ..)
265 *****************************************************************************/
266 static void encodeTnsData(TNS_INFO tnsInfo,
268 HANDLE_BIT_BUF hBitStream) {
278 numOfWindows = TRANS_FAC;
286 for (i=0; i<numOfWindows; i++) {
288 if (tnsInfo.tnsActive[i]) {
294 WriteBits(hBitStream,0,1);
296 else{ /* there is data to be written*/
297 WriteBits(hBitStream,1,1); /*data_present */
298 for (i=0; i<numOfWindows; i++) {
300 WriteBits(hBitStream,tnsInfo.tnsActive[i],(isShort?1:2));
302 if (tnsInfo.tnsActive[i]) {
304 WriteBits(hBitStream,((tnsInfo.coefRes[i] - 4)==0?1:0),1);
306 WriteBits(hBitStream,tnsInfo.length[i],(isShort?4:6));
308 WriteBits(hBitStream,tnsInfo.order[i],(isShort?3:5));
310 if (tnsInfo.order[i]){
311 WriteBits(hBitStream, FILTER_DIRECTION, 1);
313 if(tnsInfo.coefRes[i] == 4) {
315 for(k=0; k<tnsInfo.order[i]; k++) {
317 if (tnsInfo.coef[i*TNS_MAX_ORDER_SHORT+k] > 3 ||
318 tnsInfo.coef[i*TNS_MAX_ORDER_SHORT+k] < -4) {
326 for(k=0; k<tnsInfo.order[i]; k++) {
328 if (tnsInfo.coef[i*TNS_MAX_ORDER_SHORT+k] > 1 ||
329 tnsInfo.coef[i*TNS_MAX_ORDER_SHORT+k] < -2) {
335 WriteBits(hBitStream, tnsInfo.coefRes[i] - coefBits, 1); /*coef_compres*/
336 for (k=0; k<tnsInfo.order[i]; k++ ) {
337 static const Word16 rmask[] = {0,1,3,7,15};
339 WriteBits(hBitStream,tnsInfo.coef[i*TNS_MAX_ORDER_SHORT+k] & rmask[coefBits],coefBits);
348 /*****************************************************************************
350 * function name: encodeGainControlData
351 * description: unsupported
354 *****************************************************************************/
355 static void encodeGainControlData(HANDLE_BIT_BUF hBitStream)
357 WriteBits(hBitStream,0,1);
360 /*****************************************************************************
362 * function name: encodePulseData
363 * description: not supported yet (dummy)
366 *****************************************************************************/
367 static void encodePulseData(HANDLE_BIT_BUF hBitStream)
369 WriteBits(hBitStream,0,1);
373 /*****************************************************************************
375 * function name: WriteIndividualChannelStream
376 * description: management of write process of individual channel stream
379 *****************************************************************************/
381 writeIndividualChannelStream(Flag commonWindow,
387 UWord16 *maxValueInSfb,
390 SECTION_DATA *sectionData,
391 HANDLE_BIT_BUF hBitStream,
396 logNorm = LOG_NORM_PCM - (mdctScale + 1);
398 encodeGlobalGain(globalGain, logNorm,scf[sectionData->firstScf], hBitStream);
402 encodeIcsInfo(sectionData->blockType, windowShape, groupingMask, sectionData, hBitStream);
405 encodeSectionData(sectionData, hBitStream);
407 encodeScaleFactorData(maxValueInSfb,
412 encodePulseData(hBitStream);
414 encodeTnsData(tnsInfo, sectionData->blockType, hBitStream);
416 encodeGainControlData(hBitStream);
418 encodeSpectralData(sfbOffset,
425 /*****************************************************************************
427 * function name: writeSingleChannelElement
428 * description: write single channel element to bitstream
431 *****************************************************************************/
432 static Word16 writeSingleChannelElement(Word16 instanceTag,
434 QC_OUT_CHANNEL* qcOutChannel,
435 HANDLE_BIT_BUF hBitStream,
438 WriteBits(hBitStream,ID_SCE,3);
439 WriteBits(hBitStream,instanceTag,4);
440 writeIndividualChannelStream(0,
441 qcOutChannel->mdctScale,
442 qcOutChannel->windowShape,
443 qcOutChannel->groupingMask,
446 qcOutChannel->maxValueInSfb,
447 qcOutChannel->globalGain,
448 qcOutChannel->quantSpec,
449 &(qcOutChannel->sectionData),
458 /*****************************************************************************
460 * function name: writeChannelPairElement
464 *****************************************************************************/
465 static Word16 writeChannelPairElement(Word16 instanceTag,
467 Word16 msFlags[MAX_GROUPED_SFB],
468 Word16 *sfbOffset[2],
469 QC_OUT_CHANNEL qcOutChannel[2],
470 HANDLE_BIT_BUF hBitStream,
473 WriteBits(hBitStream,ID_CPE,3);
474 WriteBits(hBitStream,instanceTag,4);
475 WriteBits(hBitStream,1,1); /* common window */
477 encodeIcsInfo(qcOutChannel[0].sectionData.blockType,
478 qcOutChannel[0].windowShape,
479 qcOutChannel[0].groupingMask,
480 &(qcOutChannel[0].sectionData),
483 encodeMSInfo(qcOutChannel[0].sectionData.sfbCnt,
484 qcOutChannel[0].sectionData.sfbPerGroup,
485 qcOutChannel[0].sectionData.maxSfbPerGroup,
490 writeIndividualChannelStream(1,
491 qcOutChannel[0].mdctScale,
492 qcOutChannel[0].windowShape,
493 qcOutChannel[0].groupingMask,
496 qcOutChannel[0].maxValueInSfb,
497 qcOutChannel[0].globalGain,
498 qcOutChannel[0].quantSpec,
499 &(qcOutChannel[0].sectionData),
503 writeIndividualChannelStream(1,
504 qcOutChannel[1].mdctScale,
505 qcOutChannel[1].windowShape,
506 qcOutChannel[1].groupingMask,
509 qcOutChannel[1].maxValueInSfb,
510 qcOutChannel[1].globalGain,
511 qcOutChannel[1].quantSpec,
512 &(qcOutChannel[1].sectionData),
521 /*****************************************************************************
523 * function name: writeFillElement
524 * description: write fill elements to bitstream
527 *****************************************************************************/
528 static void writeFillElement( const UWord8 *ancBytes,
530 HANDLE_BIT_BUF hBitStream)
533 Word16 cnt,esc_count;
536 Write fill Element(s):
537 amount of a fill element can be 7+X*8 Bits, X element of [0..270]
540 while(totFillBits >= (3+4)) {
541 cnt = min(((totFillBits - (3+4)) >> 3), ((1<<4)-1));
543 WriteBits(hBitStream,ID_FIL,3);
544 WriteBits(hBitStream,cnt,4);
546 totFillBits = totFillBits - (3+4);
549 if ((cnt == (1<<4)-1)) {
551 esc_count = min( ((totFillBits >> 3) - ((1<<4)-1)), (1<<8)-1);
552 WriteBits(hBitStream,esc_count,8);
553 totFillBits = (totFillBits - 8);
554 cnt = cnt + (esc_count - 1);
560 WriteBits(hBitStream, *ancBytes++,8);
562 WriteBits(hBitStream,0,8);
563 totFillBits = totFillBits - 8;
568 /*****************************************************************************
570 * function name: WriteBitStream
571 * description: main function of write bitsteam process
572 * returns: 0 if success
574 *****************************************************************************/
575 Word16 WriteBitstream (HANDLE_BIT_BUF hBitStream,
579 Word16 *globUsedBits,
580 const UWord8 *ancBytes,
\r
582 ) /* returns error code */
585 Word16 elementUsedBits;
586 Word16 frameBits=0;
\r
588 /* struct bitbuffer bsWriteCopy; */
\r
589 bitMarkUp = GetBitsAvail(hBitStream);
\r
590 if(qcOut->qcElement.adtsUsed) /* write adts header*/
\r
592 WriteBits(hBitStream, 0xFFF, 12); /* 12 bit Syncword */
\r
593 WriteBits(hBitStream, 1, 1); /* ID == 0 for MPEG4 AAC, 1 for MPEG2 AAC */
\r
594 WriteBits(hBitStream, 0, 2); /* layer == 0 */
\r
595 WriteBits(hBitStream, 1, 1); /* protection absent */
\r
596 WriteBits(hBitStream, 1, 2); /* profile */
\r
597 WriteBits(hBitStream, sampindex, 4); /* sampling rate */
\r
598 WriteBits(hBitStream, 0, 1); /* private bit */
\r
599 WriteBits(hBitStream, elInfo.nChannelsInEl, 3); /* ch. config (must be > 0) */
\r
600 /* simply using numChannels only works for
\r
601 6 channels or less, else a channel
\r
602 configuration should be written */
\r
603 WriteBits(hBitStream, 0, 1); /* original/copy */
\r
604 WriteBits(hBitStream, 0, 1); /* home */
\r
606 /* Variable ADTS header */
\r
607 WriteBits(hBitStream, 0, 1); /* copyr. id. bit */
\r
608 WriteBits(hBitStream, 0, 1); /* copyr. id. start */
\r
609 WriteBits(hBitStream, *globUsedBits >> 3, 13);
\r
610 WriteBits(hBitStream, 0x7FF, 11); /* buffer fullness (0x7FF for VBR) */
\r
611 WriteBits(hBitStream, 0, 2); /* raw data blocks (0+1=1) */
\r
618 Word16 *sfbOffset[2];
622 switch (elInfo.elType) {
624 case ID_SCE: /* single channel */
625 sfbOffset[0] = psyOut->psyOutChannel[elInfo.ChannelIndex[0]].sfbOffsets;
626 tnsInfo[0] = psyOut->psyOutChannel[elInfo.ChannelIndex[0]].tnsInfo;
628 writeSingleChannelElement(elInfo.instanceTag,
630 &qcOut->qcChannel[elInfo.ChannelIndex[0]],
635 case ID_CPE: /* channel pair */
638 Word16 *msFlags = psyOut->psyOutElement.toolsInfo.msMask;
639 msDigest = psyOut->psyOutElement.toolsInfo.msDigest;
641 psyOut->psyOutChannel[elInfo.ChannelIndex[0]].sfbOffsets;
643 psyOut->psyOutChannel[elInfo.ChannelIndex[1]].sfbOffsets;
646 psyOut->psyOutChannel[elInfo.ChannelIndex[0]].tnsInfo;
648 psyOut->psyOutChannel[elInfo.ChannelIndex[1]].tnsInfo;
649 writeChannelPairElement(elInfo.instanceTag,
653 &qcOut->qcChannel[elInfo.ChannelIndex[0]],
664 elementUsedBits = elementUsedBits - bitMarkUp;
665 bitMarkUp = GetBitsAvail(hBitStream);
666 frameBits = frameBits + elementUsedBits + bitMarkUp;
670 writeFillElement(NULL,
674 WriteBits(hBitStream,ID_END,3);
676 /* byte alignement */
677 WriteBits(hBitStream,0, (8 - (hBitStream->cntBits & 7)) & 7);
679 *globUsedBits = *globUsedBits- bitMarkUp;
680 bitMarkUp = GetBitsAvail(hBitStream);
681 *globUsedBits = *globUsedBits + bitMarkUp;
682 frameBits = frameBits + *globUsedBits;
685 if (frameBits != (qcOut->totStaticBitsUsed+qcOut->totDynBitsUsed + qcOut->totAncBitsUsed +
686 qcOut->totFillBits + qcOut->alignBits)) {