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:		bitenc.c
18e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
19e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Content:	Bitstream encoder functions
20e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
21956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*******************************************************************************/
22956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
23956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "bitenc.h"
24956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "bit_cnt.h"
25956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "dyn_bits.h"
26956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "qc_data.h"
27956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "interface.h"
28956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
29956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
30956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic const  Word16 globalGainOffset = 100;
31956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic const  Word16 icsReservedBit   = 0;
32956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
33956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
34956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*****************************************************************************
35956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
36956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: encodeSpectralData
37956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description:  encode spectral data
38956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns:      spectral bits used
39956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
40956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/
41956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word32 encodeSpectralData(Word16             *sfbOffset,
42956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                 SECTION_DATA       *sectionData,
43956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                 Word16             *quantSpectrum,
44956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                 HANDLE_BIT_BUF      hBitStream)
45956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
46956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 i,sfb;
47956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 dbgVal;
48956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  SECTION_INFO* psectioninfo;
49b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  dbgVal = GetBitsAvail(hBitStream);
50956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
51956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  for(i=0; i<sectionData->noOfSections; i++) {
52e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard    psectioninfo = &(sectionData->sectionInfo[i]);
53956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	/*
54956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong       huffencode spectral data for this section
55956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    */
56956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    for(sfb=psectioninfo->sfbStart;
57956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        sfb<psectioninfo->sfbStart+psectioninfo->sfbCnt;
58956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        sfb++) {
59956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      codeValues(quantSpectrum+sfbOffset[sfb],
60956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                 sfbOffset[sfb+1] - sfbOffset[sfb],
61956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                 psectioninfo->codeBook,
62956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                 hBitStream);
63956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
64956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
65956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
66956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  return(GetBitsAvail(hBitStream)-dbgVal);
67956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
68956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
69956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*****************************************************************************
70956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
71956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name:encodeGlobalGain
72956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: encodes Global Gain (common scale factor)
73956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns:     none
74956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
75956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/
76956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic void encodeGlobalGain(Word16 globalGain,
77956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                             Word16 logNorm,
78956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                             Word16 scalefac,
79956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                             HANDLE_BIT_BUF hBitStream)
80956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
81956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  WriteBits(hBitStream, ((globalGain - scalefac) + globalGainOffset-(logNorm << 2)), 8);
82956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
83956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
84956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
85956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*****************************************************************************
86956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
87956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name:encodeIcsInfo
88956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: encodes Ics Info
89956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns:     none
90956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
91956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/
92956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
93956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic void encodeIcsInfo(Word16 blockType,
94956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                          Word16 windowShape,
95956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                          Word16 groupingMask,
96956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                          SECTION_DATA *sectionData,
97956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                          HANDLE_BIT_BUF  hBitStream)
98956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
99956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  WriteBits(hBitStream,icsReservedBit,1);
100956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  WriteBits(hBitStream,blockType,2);
101956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  WriteBits(hBitStream,windowShape,1);
102956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
103b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
104956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  switch(blockType){
105956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    case LONG_WINDOW:
106956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    case START_WINDOW:
107956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    case STOP_WINDOW:
108956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      WriteBits(hBitStream,sectionData->maxSfbPerGroup,6);
109956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
110956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      /* No predictor data present */
111956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      WriteBits(hBitStream, 0, 1);
112956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      break;
113956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
114956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    case SHORT_WINDOW:
115956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      WriteBits(hBitStream,sectionData->maxSfbPerGroup,4);
116956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
117956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      /*
118956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      Write grouping bits
119956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      */
120956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      WriteBits(hBitStream,groupingMask,TRANS_FAC-1);
121956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      break;
122956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
123956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
124956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
125956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*****************************************************************************
126956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
127956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: encodeSectionData
128956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description:  encode section data (common Huffman codebooks for adjacent
129956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*               SFB's)
130956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns:      none
131956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
132956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/
133956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word32 encodeSectionData(SECTION_DATA *sectionData,
134956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                HANDLE_BIT_BUF hBitStream)
135956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
136956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 sectEscapeVal=0,sectLenBits=0;
137956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 sectLen;
138956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 i;
139956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 dbgVal=GetBitsAvail(hBitStream);
140956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
141b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
142b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
143956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  switch(sectionData->blockType)
144956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  {
145956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    case LONG_WINDOW:
146956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    case START_WINDOW:
147956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    case STOP_WINDOW:
148b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard      sectEscapeVal = SECT_ESC_VAL_LONG;
149b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard      sectLenBits   = SECT_BITS_LONG;
150956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      break;
151956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
152956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    case SHORT_WINDOW:
153b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard      sectEscapeVal = SECT_ESC_VAL_SHORT;
154b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard      sectLenBits   = SECT_BITS_SHORT;
155956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      break;
156956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
157956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
158956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  for(i=0;i<sectionData->noOfSections;i++) {
159956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    WriteBits(hBitStream,sectionData->sectionInfo[i].codeBook,4);
160b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard    sectLen = sectionData->sectionInfo[i].sfbCnt;
161956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
162956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    while(sectLen >= sectEscapeVal) {
163b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
164956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      WriteBits(hBitStream,sectEscapeVal,sectLenBits);
165956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      sectLen = sectLen - sectEscapeVal;
166956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
167956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    WriteBits(hBitStream,sectLen,sectLenBits);
168956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
169956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  return(GetBitsAvail(hBitStream)-dbgVal);
170956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
171956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
172956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*****************************************************************************
173956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
174956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: encodeScaleFactorData
175956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description:  encode DPCM coded scale factors
176956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns:      none
177956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
178956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/
179956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word32 encodeScaleFactorData(UWord16        *maxValueInSfb,
180956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                    SECTION_DATA   *sectionData,
181956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                    Word16         *scalefac,
182956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                    HANDLE_BIT_BUF  hBitStream)
183956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
184956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 i,j,lastValScf,deltaScf;
185956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 dbgVal = GetBitsAvail(hBitStream);
186b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  SECTION_INFO* psectioninfo;
187956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
188b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  lastValScf=scalefac[sectionData->firstScf];
189956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
190956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  for(i=0;i<sectionData->noOfSections;i++){
191b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard    psectioninfo = &(sectionData->sectionInfo[i]);
192956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    if (psectioninfo->codeBook != CODE_BOOK_ZERO_NO){
193956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      for (j=psectioninfo->sfbStart;
194956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong           j<psectioninfo->sfbStart+psectioninfo->sfbCnt; j++){
195b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
196956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        if(maxValueInSfb[j] == 0) {
197b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard          deltaScf = 0;
198956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        }
199956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        else {
200956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong          deltaScf = lastValScf - scalefac[j];
201b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard          lastValScf = scalefac[j];
202956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        }
203b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
204956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        if(codeScalefactorDelta(deltaScf,hBitStream)){
205956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong          return(1);
206956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        }
207956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      }
208956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
209956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
210956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
211956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  return(GetBitsAvail(hBitStream)-dbgVal);
212956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
213956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
214956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*****************************************************************************
215956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
216956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name:encodeMsInfo
217956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: encodes MS-Stereo Info
218956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns:     none
219956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
220956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/
221956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic void encodeMSInfo(Word16          sfbCnt,
222956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                         Word16          grpSfb,
223956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                         Word16          maxSfb,
224956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                         Word16          msDigest,
225956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                         Word16         *jsFlags,
226956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                         HANDLE_BIT_BUF  hBitStream)
227956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
228956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 sfb, sfbOff;
229956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
230b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
231956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  switch(msDigest)
232956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  {
233956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    case MS_NONE:
234956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      WriteBits(hBitStream,SI_MS_MASK_NONE,2);
235956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      break;
236956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
237956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    case MS_ALL:
238956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      WriteBits(hBitStream,SI_MS_MASK_ALL,2);
239956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      break;
240956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
241956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    case MS_SOME:
242956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      WriteBits(hBitStream,SI_MS_MASK_SOME,2);
243956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      for(sfbOff = 0; sfbOff < sfbCnt; sfbOff+=grpSfb) {
244956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        for(sfb=0; sfb<maxSfb; sfb++) {
245b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
246956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong          if(jsFlags[sfbOff+sfb] & MS_ON) {
247956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong            WriteBits(hBitStream,1,1);
248956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong          }
249956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong          else{
250956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong            WriteBits(hBitStream,0,1);
251956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong          }
252956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        }
253956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      }
254956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      break;
255956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
256956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
257956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
258956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
259956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*****************************************************************************
260956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
261956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: encodeTnsData
262956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description:  encode TNS data (filter order, coeffs, ..)
263956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns:      none
264956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
265956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/
266956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic void encodeTnsData(TNS_INFO tnsInfo,
267956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                          Word16 blockType,
268956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                          HANDLE_BIT_BUF hBitStream) {
269956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 i,k;
270956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Flag tnsPresent;
271956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 numOfWindows;
272956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 coefBits;
273956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Flag isShort;
274956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
275b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
276956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  if (blockType==2) {
277956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    isShort = 1;
278956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    numOfWindows = TRANS_FAC;
279956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
280956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  else {
281956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    isShort = 0;
282956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    numOfWindows = 1;
283956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
284956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
285b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  tnsPresent=0;
286956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  for (i=0; i<numOfWindows; i++) {
287b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
288956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    if (tnsInfo.tnsActive[i]) {
289b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard      tnsPresent=1;
290956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
291956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
292b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
293956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  if (tnsPresent==0) {
294956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    WriteBits(hBitStream,0,1);
295956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
296956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  else{ /* there is data to be written*/
297956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    WriteBits(hBitStream,1,1); /*data_present */
298956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    for (i=0; i<numOfWindows; i++) {
299b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
300956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      WriteBits(hBitStream,tnsInfo.tnsActive[i],(isShort?1:2));
301b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
302956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      if (tnsInfo.tnsActive[i]) {
303b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
304956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        WriteBits(hBitStream,((tnsInfo.coefRes[i] - 4)==0?1:0),1);
305b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
306956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        WriteBits(hBitStream,tnsInfo.length[i],(isShort?4:6));
307b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
308956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        WriteBits(hBitStream,tnsInfo.order[i],(isShort?3:5));
309b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
310956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        if (tnsInfo.order[i]){
311956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong          WriteBits(hBitStream, FILTER_DIRECTION, 1);
312b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
313956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong          if(tnsInfo.coefRes[i] == 4) {
314b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard            coefBits = 3;
315956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong            for(k=0; k<tnsInfo.order[i]; k++) {
316b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
317956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong              if (tnsInfo.coef[i*TNS_MAX_ORDER_SHORT+k] > 3 ||
318956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                  tnsInfo.coef[i*TNS_MAX_ORDER_SHORT+k] < -4) {
319b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard                coefBits = 4;
320956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                break;
321956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong              }
322956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong            }
323956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong          }
324956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong          else {
325b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard            coefBits = 2;
326956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong            for(k=0; k<tnsInfo.order[i]; k++) {
327b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
328956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong              if (tnsInfo.coef[i*TNS_MAX_ORDER_SHORT+k] > 1 ||
329956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                  tnsInfo.coef[i*TNS_MAX_ORDER_SHORT+k] < -2) {
330b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard                coefBits = 3;
331956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                break;
332956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong              }
333956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong            }
334956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong          }
335956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong          WriteBits(hBitStream, tnsInfo.coefRes[i] - coefBits, 1); /*coef_compres*/
336956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong          for (k=0; k<tnsInfo.order[i]; k++ ) {
337956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong            static const Word16 rmask[] = {0,1,3,7,15};
338b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
339956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong            WriteBits(hBitStream,tnsInfo.coef[i*TNS_MAX_ORDER_SHORT+k] & rmask[coefBits],coefBits);
340956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong          }
341956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        }
342956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      }
343956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
344956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
345956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
346956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
347956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
348956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*****************************************************************************
349956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
350956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: encodeGainControlData
351956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description:  unsupported
352956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns:      none
353956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
354956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/
355956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic void encodeGainControlData(HANDLE_BIT_BUF hBitStream)
356956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
357956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  WriteBits(hBitStream,0,1);
358956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
359956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
360956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*****************************************************************************
361956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
362956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: encodePulseData
363956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description:  not supported yet (dummy)
364956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns:      none
365956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
366956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/
367956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic void encodePulseData(HANDLE_BIT_BUF hBitStream)
368956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
369956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  WriteBits(hBitStream,0,1);
370956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
371956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
372956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
373956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*****************************************************************************
374956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
375956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: WriteIndividualChannelStream
376956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description:  management of write process of individual channel stream
377956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns:      none
378956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
379956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/
380956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic void
381956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongwriteIndividualChannelStream(Flag   commonWindow,
382956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                             Word16 mdctScale,
383956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                             Word16 windowShape,
384956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                             Word16 groupingMask,
385956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                             Word16 *sfbOffset,
386956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                             Word16 scf[],
387956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                             UWord16 *maxValueInSfb,
388956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                             Word16 globalGain,
389956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                             Word16 quantSpec[],
390956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                             SECTION_DATA *sectionData,
391956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                             HANDLE_BIT_BUF hBitStream,
392956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                             TNS_INFO tnsInfo)
393956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
394956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 logNorm;
395956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
396956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  logNorm = LOG_NORM_PCM - (mdctScale + 1);
397956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
398956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  encodeGlobalGain(globalGain, logNorm,scf[sectionData->firstScf], hBitStream);
399956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
400b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
401956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  if(!commonWindow) {
402956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    encodeIcsInfo(sectionData->blockType, windowShape, groupingMask, sectionData, hBitStream);
403956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
404956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
405956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  encodeSectionData(sectionData, hBitStream);
406956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
407956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  encodeScaleFactorData(maxValueInSfb,
408956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                        sectionData,
409956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                        scf,
410956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                        hBitStream);
411956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
412956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  encodePulseData(hBitStream);
413956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
414956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  encodeTnsData(tnsInfo, sectionData->blockType, hBitStream);
415956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
416956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  encodeGainControlData(hBitStream);
417956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
418956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  encodeSpectralData(sfbOffset,
419956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                     sectionData,
420956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                     quantSpec,
421956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                     hBitStream);
422956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
423956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
424956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
425956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*****************************************************************************
426956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
427956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: writeSingleChannelElement
428956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description:  write single channel element to bitstream
429956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns:      none
430956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
431956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/
432956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 writeSingleChannelElement(Word16 instanceTag,
433956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                        Word16 *sfbOffset,
434956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                        QC_OUT_CHANNEL* qcOutChannel,
435956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                        HANDLE_BIT_BUF hBitStream,
436956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                        TNS_INFO tnsInfo)
437956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
438956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  WriteBits(hBitStream,ID_SCE,3);
439956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  WriteBits(hBitStream,instanceTag,4);
440956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  writeIndividualChannelStream(0,
441956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               qcOutChannel->mdctScale,
442956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               qcOutChannel->windowShape,
443956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               qcOutChannel->groupingMask,
444956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               sfbOffset,
445956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               qcOutChannel->scf,
446956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               qcOutChannel->maxValueInSfb,
447956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               qcOutChannel->globalGain,
448956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               qcOutChannel->quantSpec,
449956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               &(qcOutChannel->sectionData),
450956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               hBitStream,
451956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               tnsInfo
452956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               );
453956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  return(0);
454956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
455956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
456956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
457956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
458956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*****************************************************************************
459956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
460956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: writeChannelPairElement
461956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description:
462956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns:      none
463956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
464956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/
465956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 writeChannelPairElement(Word16 instanceTag,
466956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                      Word16 msDigest,
467956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                      Word16 msFlags[MAX_GROUPED_SFB],
468956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                      Word16 *sfbOffset[2],
469956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                      QC_OUT_CHANNEL qcOutChannel[2],
470956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                      HANDLE_BIT_BUF hBitStream,
471956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                      TNS_INFO tnsInfo[2])
472956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
473956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  WriteBits(hBitStream,ID_CPE,3);
474956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  WriteBits(hBitStream,instanceTag,4);
475956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  WriteBits(hBitStream,1,1); /* common window */
476956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
477956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  encodeIcsInfo(qcOutChannel[0].sectionData.blockType,
478956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                qcOutChannel[0].windowShape,
479956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                qcOutChannel[0].groupingMask,
480956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                &(qcOutChannel[0].sectionData),
481956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                hBitStream);
482956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
483956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  encodeMSInfo(qcOutChannel[0].sectionData.sfbCnt,
484956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong               qcOutChannel[0].sectionData.sfbPerGroup,
485956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong               qcOutChannel[0].sectionData.maxSfbPerGroup,
486956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong               msDigest,
487956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong               msFlags,
488956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong               hBitStream);
489956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
490956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  writeIndividualChannelStream(1,
491956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               qcOutChannel[0].mdctScale,
492956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               qcOutChannel[0].windowShape,
493956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               qcOutChannel[0].groupingMask,
494956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               sfbOffset[0],
495956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               qcOutChannel[0].scf,
496956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               qcOutChannel[0].maxValueInSfb,
497956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               qcOutChannel[0].globalGain,
498956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               qcOutChannel[0].quantSpec,
499956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               &(qcOutChannel[0].sectionData),
500956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               hBitStream,
501956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               tnsInfo[0]);
502956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
503956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  writeIndividualChannelStream(1,
504956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               qcOutChannel[1].mdctScale,
505956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               qcOutChannel[1].windowShape,
506956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               qcOutChannel[1].groupingMask,
507956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               sfbOffset[1],
508956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               qcOutChannel[1].scf,
509956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               qcOutChannel[1].maxValueInSfb,
510956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               qcOutChannel[1].globalGain,
511956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               qcOutChannel[1].quantSpec,
512956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               &(qcOutChannel[1].sectionData),
513956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               hBitStream,
514956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               tnsInfo[1]);
515956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
516956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  return(0);
517956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
518956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
519956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
520956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
521956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*****************************************************************************
522956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
523956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: writeFillElement
524956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description:  write fill elements to bitstream
525956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns:      none
526956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
527956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/
528956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic void writeFillElement( const UWord8 *ancBytes,
529956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                              Word16 totFillBits,
530956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                              HANDLE_BIT_BUF hBitStream)
531956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
532956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 i;
533956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 cnt,esc_count;
534956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
535956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  /*
536956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    Write fill Element(s):
537956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    amount of a fill element can be 7+X*8 Bits, X element of [0..270]
538956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  */
539b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
540956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  while(totFillBits >= (3+4)) {
541956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    cnt = min(((totFillBits - (3+4)) >> 3), ((1<<4)-1));
542956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
543956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    WriteBits(hBitStream,ID_FIL,3);
544956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    WriteBits(hBitStream,cnt,4);
545956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
546956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    totFillBits = totFillBits - (3+4);
547956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
548b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
549956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    if ((cnt == (1<<4)-1)) {
550956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
551956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      esc_count = min( ((totFillBits >> 3) - ((1<<4)-1)), (1<<8)-1);
552956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      WriteBits(hBitStream,esc_count,8);
553956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      totFillBits = (totFillBits - 8);
554956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      cnt = cnt + (esc_count - 1);
555956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
556956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
557956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    for(i=0;i<cnt;i++) {
558b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
559956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      if(ancBytes)
560956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        WriteBits(hBitStream, *ancBytes++,8);
561956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      else
562956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        WriteBits(hBitStream,0,8);
563956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      totFillBits = totFillBits - 8;
564956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
565956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
566956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
567e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
568956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*****************************************************************************
569956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
570956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: WriteBitStream
571956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description:  main function of write bitsteam process
572956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns:      0 if success
573956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
574956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/
575956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongWord16 WriteBitstream (HANDLE_BIT_BUF hBitStream,
576956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                       ELEMENT_INFO elInfo,
577956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                       QC_OUT *qcOut,
578956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                       PSY_OUT *psyOut,
579b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard                       Word16 *globUsedBits,
580e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard                       const UWord8 *ancBytes,
581956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong					   Word16 sampindex
582956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                       ) /* returns error code */
583956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
584956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 bitMarkUp;
585956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 elementUsedBits;
586e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard  Word16 frameBits=0;
587e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
588e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard  /*   struct bitbuffer bsWriteCopy; */
589b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  bitMarkUp = GetBitsAvail(hBitStream);
590e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard  if(qcOut->qcElement.adtsUsed)  /*  write adts header*/
591e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard  {
592e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	  WriteBits(hBitStream, 0xFFF, 12); /* 12 bit Syncword */
593e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	  WriteBits(hBitStream, 1, 1); /* ID == 0 for MPEG4 AAC, 1 for MPEG2 AAC */
594e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	  WriteBits(hBitStream, 0, 2); /* layer == 0 */
595e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	  WriteBits(hBitStream, 1, 1); /* protection absent */
596e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	  WriteBits(hBitStream, 1, 2); /* profile */
597e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	  WriteBits(hBitStream, sampindex, 4); /* sampling rate */
598e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	  WriteBits(hBitStream, 0, 1); /* private bit */
599e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	  WriteBits(hBitStream, elInfo.nChannelsInEl, 3); /* ch. config (must be > 0) */
600e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard								   /* simply using numChannels only works for
601e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard									6 channels or less, else a channel
602e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard									configuration should be written */
603e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	  WriteBits(hBitStream, 0, 1); /* original/copy */
604b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	  WriteBits(hBitStream, 0, 1); /* home */
605b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
606e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	  /* Variable ADTS header */
607e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	  WriteBits(hBitStream, 0, 1); /* copyr. id. bit */
608e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	  WriteBits(hBitStream, 0, 1); /* copyr. id. start */
609e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	  WriteBits(hBitStream, *globUsedBits >> 3, 13);
610e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	  WriteBits(hBitStream, 0x7FF, 11); /* buffer fullness (0x7FF for VBR) */
611b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	  WriteBits(hBitStream, 0, 2); /* raw data blocks (0+1=1) */
612e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard  }
613956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
614b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  *globUsedBits=0;
615956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
616956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  {
617956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
618956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    Word16 *sfbOffset[2];
619956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    TNS_INFO tnsInfo[2];
620b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard    elementUsedBits = 0;
621956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
622956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    switch (elInfo.elType) {
623956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
624956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      case ID_SCE:      /* single channel */
625956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        sfbOffset[0] = psyOut->psyOutChannel[elInfo.ChannelIndex[0]].sfbOffsets;
626956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        tnsInfo[0] = psyOut->psyOutChannel[elInfo.ChannelIndex[0]].tnsInfo;
627956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
628956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        writeSingleChannelElement(elInfo.instanceTag,
629956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                  sfbOffset[0],
630956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                  &qcOut->qcChannel[elInfo.ChannelIndex[0]],
631956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                  hBitStream,
632956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                  tnsInfo[0]);
633956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        break;
634956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
635956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      case ID_CPE:     /* channel pair */
636956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        {
637956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong          Word16 msDigest;
638956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong          Word16 *msFlags = psyOut->psyOutElement.toolsInfo.msMask;
639b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard          msDigest = psyOut->psyOutElement.toolsInfo.msDigest;
640956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong          sfbOffset[0] =
641956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong            psyOut->psyOutChannel[elInfo.ChannelIndex[0]].sfbOffsets;
642956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong          sfbOffset[1] =
643956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong            psyOut->psyOutChannel[elInfo.ChannelIndex[1]].sfbOffsets;
644956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
645956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong          tnsInfo[0]=
646956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong            psyOut->psyOutChannel[elInfo.ChannelIndex[0]].tnsInfo;
647956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong          tnsInfo[1]=
648956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong            psyOut->psyOutChannel[elInfo.ChannelIndex[1]].tnsInfo;
649956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong          writeChannelPairElement(elInfo.instanceTag,
650956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                  msDigest,
651956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                  msFlags,
652956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                  sfbOffset,
653956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                  &qcOut->qcChannel[elInfo.ChannelIndex[0]],
654956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                  hBitStream,
655956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                  tnsInfo);
656956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        }
657956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        break;
658956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
659956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      default:
660956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        return(1);
661956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
662956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      }   /* switch */
663956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
664956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    elementUsedBits = elementUsedBits - bitMarkUp;
665956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    bitMarkUp = GetBitsAvail(hBitStream);
666956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    frameBits = frameBits + elementUsedBits + bitMarkUp;
667956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
668956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
669956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
670956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  writeFillElement(NULL,
671b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard                   qcOut->totFillBits,
672956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                   hBitStream);
673956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
674956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  WriteBits(hBitStream,ID_END,3);
675956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
676956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  /* byte alignement */
677b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  WriteBits(hBitStream,0, (8 - (hBitStream->cntBits & 7)) & 7);
678b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
679956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  *globUsedBits = *globUsedBits- bitMarkUp;
680b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  bitMarkUp = GetBitsAvail(hBitStream);
681956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  *globUsedBits = *globUsedBits + bitMarkUp;
682956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  frameBits = frameBits + *globUsedBits;
683956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
684b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
685956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  if (frameBits !=  (qcOut->totStaticBitsUsed+qcOut->totDynBitsUsed + qcOut->totAncBitsUsed +
686956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                     qcOut->totFillBits + qcOut->alignBits)) {
687956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    return(-1);
688956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
689956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  return(0);
690956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
691