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
2984333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber#define UNUSED(x) (void)(x)
30956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
31956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic const  Word16 globalGainOffset = 100;
32956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic const  Word16 icsReservedBit   = 0;
33956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
34956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
35956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*****************************************************************************
36956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
37956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: encodeSpectralData
38956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description:  encode spectral data
39956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns:      spectral bits used
40956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
41956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/
42956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word32 encodeSpectralData(Word16             *sfbOffset,
43956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                 SECTION_DATA       *sectionData,
44956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                 Word16             *quantSpectrum,
45956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                 HANDLE_BIT_BUF      hBitStream)
46956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
47956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 i,sfb;
48956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 dbgVal;
49956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  SECTION_INFO* psectioninfo;
50b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  dbgVal = GetBitsAvail(hBitStream);
51956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
52956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  for(i=0; i<sectionData->noOfSections; i++) {
53e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard    psectioninfo = &(sectionData->sectionInfo[i]);
54956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	/*
55956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong       huffencode spectral data for this section
56956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    */
57956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    for(sfb=psectioninfo->sfbStart;
58956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        sfb<psectioninfo->sfbStart+psectioninfo->sfbCnt;
59956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        sfb++) {
60956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      codeValues(quantSpectrum+sfbOffset[sfb],
61956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                 sfbOffset[sfb+1] - sfbOffset[sfb],
62956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                 psectioninfo->codeBook,
63956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                 hBitStream);
64956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
65956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
66956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
67956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  return(GetBitsAvail(hBitStream)-dbgVal);
68956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
69956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
70956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*****************************************************************************
71956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
72956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name:encodeGlobalGain
73956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: encodes Global Gain (common scale factor)
74956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns:     none
75956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
76956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/
77956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic void encodeGlobalGain(Word16 globalGain,
78956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                             Word16 logNorm,
79956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                             Word16 scalefac,
80956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                             HANDLE_BIT_BUF hBitStream)
81956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
82956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  WriteBits(hBitStream, ((globalGain - scalefac) + globalGainOffset-(logNorm << 2)), 8);
83956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
84956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
85956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
86956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*****************************************************************************
87956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
88956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name:encodeIcsInfo
89956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: encodes Ics Info
90956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns:     none
91956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
92956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/
93956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
94956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic void encodeIcsInfo(Word16 blockType,
95956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                          Word16 windowShape,
96956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                          Word16 groupingMask,
97956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                          SECTION_DATA *sectionData,
98956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                          HANDLE_BIT_BUF  hBitStream)
99956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
100956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  WriteBits(hBitStream,icsReservedBit,1);
101956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  WriteBits(hBitStream,blockType,2);
102956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  WriteBits(hBitStream,windowShape,1);
103956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
104b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
105956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  switch(blockType){
106956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    case LONG_WINDOW:
107956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    case START_WINDOW:
108956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    case STOP_WINDOW:
109956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      WriteBits(hBitStream,sectionData->maxSfbPerGroup,6);
110956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
111956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      /* No predictor data present */
112956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      WriteBits(hBitStream, 0, 1);
113956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      break;
114956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
115956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    case SHORT_WINDOW:
116956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      WriteBits(hBitStream,sectionData->maxSfbPerGroup,4);
117956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
118956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      /*
119956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      Write grouping bits
120956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      */
121956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      WriteBits(hBitStream,groupingMask,TRANS_FAC-1);
122956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      break;
123956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
124956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
125956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
126956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*****************************************************************************
127956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
128956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: encodeSectionData
129956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description:  encode section data (common Huffman codebooks for adjacent
130956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*               SFB's)
131956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns:      none
132956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
133956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/
134956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word32 encodeSectionData(SECTION_DATA *sectionData,
135956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                HANDLE_BIT_BUF hBitStream)
136956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
137956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 sectEscapeVal=0,sectLenBits=0;
138956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 sectLen;
139956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 i;
140956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 dbgVal=GetBitsAvail(hBitStream);
141956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
142b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
143b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
144956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  switch(sectionData->blockType)
145956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  {
146956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    case LONG_WINDOW:
147956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    case START_WINDOW:
148956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    case STOP_WINDOW:
149b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard      sectEscapeVal = SECT_ESC_VAL_LONG;
150b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard      sectLenBits   = SECT_BITS_LONG;
151956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      break;
152956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
153956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    case SHORT_WINDOW:
154b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard      sectEscapeVal = SECT_ESC_VAL_SHORT;
155b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard      sectLenBits   = SECT_BITS_SHORT;
156956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      break;
157956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
158956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
159956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  for(i=0;i<sectionData->noOfSections;i++) {
160956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    WriteBits(hBitStream,sectionData->sectionInfo[i].codeBook,4);
161b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard    sectLen = sectionData->sectionInfo[i].sfbCnt;
162956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
163956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    while(sectLen >= sectEscapeVal) {
164b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
165956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      WriteBits(hBitStream,sectEscapeVal,sectLenBits);
166956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      sectLen = sectLen - sectEscapeVal;
167956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
168956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    WriteBits(hBitStream,sectLen,sectLenBits);
169956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
170956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  return(GetBitsAvail(hBitStream)-dbgVal);
171956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
172956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
173956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*****************************************************************************
174956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
175956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: encodeScaleFactorData
176956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description:  encode DPCM coded scale factors
177956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns:      none
178956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
179956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/
180956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word32 encodeScaleFactorData(UWord16        *maxValueInSfb,
181956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                    SECTION_DATA   *sectionData,
182956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                    Word16         *scalefac,
183956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                    HANDLE_BIT_BUF  hBitStream)
184956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
185956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 i,j,lastValScf,deltaScf;
186956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 dbgVal = GetBitsAvail(hBitStream);
187b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  SECTION_INFO* psectioninfo;
188956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
189b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  lastValScf=scalefac[sectionData->firstScf];
190956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
191956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  for(i=0;i<sectionData->noOfSections;i++){
192b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard    psectioninfo = &(sectionData->sectionInfo[i]);
193956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    if (psectioninfo->codeBook != CODE_BOOK_ZERO_NO){
194956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      for (j=psectioninfo->sfbStart;
195956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong           j<psectioninfo->sfbStart+psectioninfo->sfbCnt; j++){
196b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
197956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        if(maxValueInSfb[j] == 0) {
198b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard          deltaScf = 0;
199956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        }
200956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        else {
201956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong          deltaScf = lastValScf - scalefac[j];
202b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard          lastValScf = scalefac[j];
203956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        }
204b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
205956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        if(codeScalefactorDelta(deltaScf,hBitStream)){
206956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong          return(1);
207956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        }
208956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      }
209956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
210956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
211956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
212956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  return(GetBitsAvail(hBitStream)-dbgVal);
213956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
214956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
215956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*****************************************************************************
216956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
217956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name:encodeMsInfo
218956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: encodes MS-Stereo Info
219956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns:     none
220956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
221956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/
222956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic void encodeMSInfo(Word16          sfbCnt,
223956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                         Word16          grpSfb,
224956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                         Word16          maxSfb,
225956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                         Word16          msDigest,
226956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                         Word16         *jsFlags,
227956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                         HANDLE_BIT_BUF  hBitStream)
228956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
229956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 sfb, sfbOff;
230956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
231b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
232956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  switch(msDigest)
233956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  {
234956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    case MS_NONE:
235956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      WriteBits(hBitStream,SI_MS_MASK_NONE,2);
236956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      break;
237956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
238956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    case MS_ALL:
239956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      WriteBits(hBitStream,SI_MS_MASK_ALL,2);
240956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      break;
241956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
242956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    case MS_SOME:
243956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      WriteBits(hBitStream,SI_MS_MASK_SOME,2);
244956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      for(sfbOff = 0; sfbOff < sfbCnt; sfbOff+=grpSfb) {
245956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        for(sfb=0; sfb<maxSfb; sfb++) {
246b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
247956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong          if(jsFlags[sfbOff+sfb] & MS_ON) {
248956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong            WriteBits(hBitStream,1,1);
249956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong          }
250956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong          else{
251956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong            WriteBits(hBitStream,0,1);
252956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong          }
253956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        }
254956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      }
255956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      break;
256956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
257956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
258956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
259956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
260956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*****************************************************************************
261956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
262956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: encodeTnsData
263956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description:  encode TNS data (filter order, coeffs, ..)
264956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns:      none
265956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
266956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/
267956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic void encodeTnsData(TNS_INFO tnsInfo,
268956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                          Word16 blockType,
269956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                          HANDLE_BIT_BUF hBitStream) {
270956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 i,k;
271956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Flag tnsPresent;
272956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 numOfWindows;
273956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 coefBits;
274956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Flag isShort;
275956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
276b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
277956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  if (blockType==2) {
278956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    isShort = 1;
279956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    numOfWindows = TRANS_FAC;
280956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
281956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  else {
282956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    isShort = 0;
283956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    numOfWindows = 1;
284956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
285956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
286b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  tnsPresent=0;
287956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  for (i=0; i<numOfWindows; i++) {
288b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
289956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    if (tnsInfo.tnsActive[i]) {
290b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard      tnsPresent=1;
291956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
292956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
293b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
294956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  if (tnsPresent==0) {
295956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    WriteBits(hBitStream,0,1);
296956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
297956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  else{ /* there is data to be written*/
298956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    WriteBits(hBitStream,1,1); /*data_present */
299956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    for (i=0; i<numOfWindows; i++) {
300b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
301956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      WriteBits(hBitStream,tnsInfo.tnsActive[i],(isShort?1:2));
302b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
303956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      if (tnsInfo.tnsActive[i]) {
304b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
305956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        WriteBits(hBitStream,((tnsInfo.coefRes[i] - 4)==0?1:0),1);
306b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
307956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        WriteBits(hBitStream,tnsInfo.length[i],(isShort?4:6));
308b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
309956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        WriteBits(hBitStream,tnsInfo.order[i],(isShort?3:5));
310b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
311956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        if (tnsInfo.order[i]){
312956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong          WriteBits(hBitStream, FILTER_DIRECTION, 1);
313b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
314956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong          if(tnsInfo.coefRes[i] == 4) {
315b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard            coefBits = 3;
316956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong            for(k=0; k<tnsInfo.order[i]; k++) {
317b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
318956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong              if (tnsInfo.coef[i*TNS_MAX_ORDER_SHORT+k] > 3 ||
319956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                  tnsInfo.coef[i*TNS_MAX_ORDER_SHORT+k] < -4) {
320b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard                coefBits = 4;
321956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                break;
322956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong              }
323956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong            }
324956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong          }
325956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong          else {
326b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard            coefBits = 2;
327956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong            for(k=0; k<tnsInfo.order[i]; k++) {
328b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
329956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong              if (tnsInfo.coef[i*TNS_MAX_ORDER_SHORT+k] > 1 ||
330956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                  tnsInfo.coef[i*TNS_MAX_ORDER_SHORT+k] < -2) {
331b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard                coefBits = 3;
332956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                break;
333956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong              }
334956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong            }
335956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong          }
336956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong          WriteBits(hBitStream, tnsInfo.coefRes[i] - coefBits, 1); /*coef_compres*/
337956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong          for (k=0; k<tnsInfo.order[i]; k++ ) {
338956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong            static const Word16 rmask[] = {0,1,3,7,15};
339b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
340956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong            WriteBits(hBitStream,tnsInfo.coef[i*TNS_MAX_ORDER_SHORT+k] & rmask[coefBits],coefBits);
341956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong          }
342956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        }
343956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      }
344956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
345956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
346956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
347956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
348956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
349956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*****************************************************************************
350956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
351956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: encodeGainControlData
352956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description:  unsupported
353956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns:      none
354956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
355956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/
356956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic void encodeGainControlData(HANDLE_BIT_BUF hBitStream)
357956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
358956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  WriteBits(hBitStream,0,1);
359956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
360956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
361956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*****************************************************************************
362956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
363956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: encodePulseData
364956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description:  not supported yet (dummy)
365956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns:      none
366956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
367956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/
368956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic void encodePulseData(HANDLE_BIT_BUF hBitStream)
369956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
370956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  WriteBits(hBitStream,0,1);
371956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
372956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
373956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
374956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*****************************************************************************
375956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
376956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: WriteIndividualChannelStream
377956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description:  management of write process of individual channel stream
378956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns:      none
379956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
380956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/
381956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic void
382956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongwriteIndividualChannelStream(Flag   commonWindow,
383956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                             Word16 mdctScale,
384956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                             Word16 windowShape,
385956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                             Word16 groupingMask,
386956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                             Word16 *sfbOffset,
387956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                             Word16 scf[],
388956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                             UWord16 *maxValueInSfb,
389956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                             Word16 globalGain,
390956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                             Word16 quantSpec[],
391956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                             SECTION_DATA *sectionData,
392956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                             HANDLE_BIT_BUF hBitStream,
393956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                             TNS_INFO tnsInfo)
394956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
395956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 logNorm;
396956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
397956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  logNorm = LOG_NORM_PCM - (mdctScale + 1);
398956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
399956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  encodeGlobalGain(globalGain, logNorm,scf[sectionData->firstScf], hBitStream);
400956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
401b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
402956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  if(!commonWindow) {
403956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    encodeIcsInfo(sectionData->blockType, windowShape, groupingMask, sectionData, hBitStream);
404956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
405956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
406956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  encodeSectionData(sectionData, hBitStream);
407956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
408956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  encodeScaleFactorData(maxValueInSfb,
409956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                        sectionData,
410956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                        scf,
411956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                        hBitStream);
412956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
413956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  encodePulseData(hBitStream);
414956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
415956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  encodeTnsData(tnsInfo, sectionData->blockType, hBitStream);
416956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
417956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  encodeGainControlData(hBitStream);
418956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
419956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  encodeSpectralData(sfbOffset,
420956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                     sectionData,
421956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                     quantSpec,
422956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                     hBitStream);
423956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
424956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
425956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
426956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*****************************************************************************
427956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
428956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: writeSingleChannelElement
429956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description:  write single channel element to bitstream
430956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns:      none
431956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
432956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/
433956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 writeSingleChannelElement(Word16 instanceTag,
434956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                        Word16 *sfbOffset,
435956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                        QC_OUT_CHANNEL* qcOutChannel,
436956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                        HANDLE_BIT_BUF hBitStream,
437956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                        TNS_INFO tnsInfo)
438956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
439956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  WriteBits(hBitStream,ID_SCE,3);
440956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  WriteBits(hBitStream,instanceTag,4);
441956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  writeIndividualChannelStream(0,
442956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               qcOutChannel->mdctScale,
443956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               qcOutChannel->windowShape,
444956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               qcOutChannel->groupingMask,
445956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               sfbOffset,
446956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               qcOutChannel->scf,
447956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               qcOutChannel->maxValueInSfb,
448956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               qcOutChannel->globalGain,
449956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               qcOutChannel->quantSpec,
450956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               &(qcOutChannel->sectionData),
451956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               hBitStream,
452956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               tnsInfo
453956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               );
454956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  return(0);
455956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
456956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
457956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
458956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
459956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*****************************************************************************
460956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
461956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: writeChannelPairElement
462956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description:
463956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns:      none
464956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
465956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/
466956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 writeChannelPairElement(Word16 instanceTag,
467956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                      Word16 msDigest,
468956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                      Word16 msFlags[MAX_GROUPED_SFB],
469956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                      Word16 *sfbOffset[2],
470956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                      QC_OUT_CHANNEL qcOutChannel[2],
471956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                      HANDLE_BIT_BUF hBitStream,
472956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                      TNS_INFO tnsInfo[2])
473956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
474956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  WriteBits(hBitStream,ID_CPE,3);
475956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  WriteBits(hBitStream,instanceTag,4);
476956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  WriteBits(hBitStream,1,1); /* common window */
477956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
478956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  encodeIcsInfo(qcOutChannel[0].sectionData.blockType,
479956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                qcOutChannel[0].windowShape,
480956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                qcOutChannel[0].groupingMask,
481956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                &(qcOutChannel[0].sectionData),
482956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                hBitStream);
483956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
484956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  encodeMSInfo(qcOutChannel[0].sectionData.sfbCnt,
485956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong               qcOutChannel[0].sectionData.sfbPerGroup,
486956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong               qcOutChannel[0].sectionData.maxSfbPerGroup,
487956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong               msDigest,
488956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong               msFlags,
489956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong               hBitStream);
490956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
491956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  writeIndividualChannelStream(1,
492956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               qcOutChannel[0].mdctScale,
493956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               qcOutChannel[0].windowShape,
494956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               qcOutChannel[0].groupingMask,
495956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               sfbOffset[0],
496956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               qcOutChannel[0].scf,
497956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               qcOutChannel[0].maxValueInSfb,
498956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               qcOutChannel[0].globalGain,
499956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               qcOutChannel[0].quantSpec,
500956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               &(qcOutChannel[0].sectionData),
501956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               hBitStream,
502956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               tnsInfo[0]);
503956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
504956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  writeIndividualChannelStream(1,
505956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               qcOutChannel[1].mdctScale,
506956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               qcOutChannel[1].windowShape,
507956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               qcOutChannel[1].groupingMask,
508956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               sfbOffset[1],
509956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               qcOutChannel[1].scf,
510956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               qcOutChannel[1].maxValueInSfb,
511956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               qcOutChannel[1].globalGain,
512956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               qcOutChannel[1].quantSpec,
513956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               &(qcOutChannel[1].sectionData),
514956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               hBitStream,
515956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               tnsInfo[1]);
516956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
517956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  return(0);
518956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
519956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
520956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
521956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
522956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*****************************************************************************
523956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
524956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: writeFillElement
525956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description:  write fill elements to bitstream
526956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns:      none
527956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
528956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/
529956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic void writeFillElement( const UWord8 *ancBytes,
530956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                              Word16 totFillBits,
531956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                              HANDLE_BIT_BUF hBitStream)
532956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
533956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 i;
534956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 cnt,esc_count;
535956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
536956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  /*
537956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    Write fill Element(s):
538956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    amount of a fill element can be 7+X*8 Bits, X element of [0..270]
539956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  */
540b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
541956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  while(totFillBits >= (3+4)) {
542956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    cnt = min(((totFillBits - (3+4)) >> 3), ((1<<4)-1));
543956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
544956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    WriteBits(hBitStream,ID_FIL,3);
545956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    WriteBits(hBitStream,cnt,4);
546956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
547956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    totFillBits = totFillBits - (3+4);
548956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
549b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
550956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    if ((cnt == (1<<4)-1)) {
551956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
552956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      esc_count = min( ((totFillBits >> 3) - ((1<<4)-1)), (1<<8)-1);
553956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      WriteBits(hBitStream,esc_count,8);
554956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      totFillBits = (totFillBits - 8);
555956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      cnt = cnt + (esc_count - 1);
556956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
557956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
558956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    for(i=0;i<cnt;i++) {
559b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
560956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      if(ancBytes)
561956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        WriteBits(hBitStream, *ancBytes++,8);
562956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      else
563956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        WriteBits(hBitStream,0,8);
564956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      totFillBits = totFillBits - 8;
565956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
566956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
567956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
568e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
569956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*****************************************************************************
570956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
571956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: WriteBitStream
572956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description:  main function of write bitsteam process
573956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns:      0 if success
574956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
575956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/
576956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongWord16 WriteBitstream (HANDLE_BIT_BUF hBitStream,
577956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                       ELEMENT_INFO elInfo,
578956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                       QC_OUT *qcOut,
579956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                       PSY_OUT *psyOut,
580b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard                       Word16 *globUsedBits,
581e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard                       const UWord8 *ancBytes,
582956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong					   Word16 sampindex
583956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                       ) /* returns error code */
584956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
585956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 bitMarkUp;
586956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 elementUsedBits;
587e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard  Word16 frameBits=0;
588e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
58984333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber  UNUSED(ancBytes);
59084333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber
591e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard  /*   struct bitbuffer bsWriteCopy; */
592b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  bitMarkUp = GetBitsAvail(hBitStream);
593e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard  if(qcOut->qcElement.adtsUsed)  /*  write adts header*/
594e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard  {
595e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	  WriteBits(hBitStream, 0xFFF, 12); /* 12 bit Syncword */
596e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	  WriteBits(hBitStream, 1, 1); /* ID == 0 for MPEG4 AAC, 1 for MPEG2 AAC */
597e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	  WriteBits(hBitStream, 0, 2); /* layer == 0 */
598e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	  WriteBits(hBitStream, 1, 1); /* protection absent */
599e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	  WriteBits(hBitStream, 1, 2); /* profile */
600e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	  WriteBits(hBitStream, sampindex, 4); /* sampling rate */
601e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	  WriteBits(hBitStream, 0, 1); /* private bit */
602e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	  WriteBits(hBitStream, elInfo.nChannelsInEl, 3); /* ch. config (must be > 0) */
603e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard								   /* simply using numChannels only works for
604e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard									6 channels or less, else a channel
605e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard									configuration should be written */
606e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	  WriteBits(hBitStream, 0, 1); /* original/copy */
607b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	  WriteBits(hBitStream, 0, 1); /* home */
608b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
609e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	  /* Variable ADTS header */
610e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	  WriteBits(hBitStream, 0, 1); /* copyr. id. bit */
611e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	  WriteBits(hBitStream, 0, 1); /* copyr. id. start */
612e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	  WriteBits(hBitStream, *globUsedBits >> 3, 13);
613e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	  WriteBits(hBitStream, 0x7FF, 11); /* buffer fullness (0x7FF for VBR) */
614b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	  WriteBits(hBitStream, 0, 2); /* raw data blocks (0+1=1) */
615e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard  }
616956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
617b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  *globUsedBits=0;
618956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
619956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  {
620956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
621956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    Word16 *sfbOffset[2];
622956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    TNS_INFO tnsInfo[2];
623b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard    elementUsedBits = 0;
624956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
625956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    switch (elInfo.elType) {
626956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
627956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      case ID_SCE:      /* single channel */
628956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        sfbOffset[0] = psyOut->psyOutChannel[elInfo.ChannelIndex[0]].sfbOffsets;
629956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        tnsInfo[0] = psyOut->psyOutChannel[elInfo.ChannelIndex[0]].tnsInfo;
630956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
631956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        writeSingleChannelElement(elInfo.instanceTag,
632956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                  sfbOffset[0],
633956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                  &qcOut->qcChannel[elInfo.ChannelIndex[0]],
634956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                  hBitStream,
635956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                  tnsInfo[0]);
636956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        break;
637956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
638956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      case ID_CPE:     /* channel pair */
639956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        {
640956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong          Word16 msDigest;
641956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong          Word16 *msFlags = psyOut->psyOutElement.toolsInfo.msMask;
642b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard          msDigest = psyOut->psyOutElement.toolsInfo.msDigest;
643956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong          sfbOffset[0] =
644956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong            psyOut->psyOutChannel[elInfo.ChannelIndex[0]].sfbOffsets;
645956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong          sfbOffset[1] =
646956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong            psyOut->psyOutChannel[elInfo.ChannelIndex[1]].sfbOffsets;
647956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
648956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong          tnsInfo[0]=
649956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong            psyOut->psyOutChannel[elInfo.ChannelIndex[0]].tnsInfo;
650956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong          tnsInfo[1]=
651956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong            psyOut->psyOutChannel[elInfo.ChannelIndex[1]].tnsInfo;
652956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong          writeChannelPairElement(elInfo.instanceTag,
653956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                  msDigest,
654956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                  msFlags,
655956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                  sfbOffset,
656956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                  &qcOut->qcChannel[elInfo.ChannelIndex[0]],
657956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                  hBitStream,
658956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                  tnsInfo);
659956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        }
660956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        break;
661956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
662956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      default:
663956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        return(1);
664956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
665956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      }   /* switch */
666956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
667956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    elementUsedBits = elementUsedBits - bitMarkUp;
668956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    bitMarkUp = GetBitsAvail(hBitStream);
669956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    frameBits = frameBits + elementUsedBits + bitMarkUp;
670956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
671956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
672956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
673956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  writeFillElement(NULL,
674b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard                   qcOut->totFillBits,
675956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                   hBitStream);
676956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
677956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  WriteBits(hBitStream,ID_END,3);
678956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
679956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  /* byte alignement */
680b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  WriteBits(hBitStream,0, (8 - (hBitStream->cntBits & 7)) & 7);
681b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
682956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  *globUsedBits = *globUsedBits- bitMarkUp;
683b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  bitMarkUp = GetBitsAvail(hBitStream);
684956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  *globUsedBits = *globUsedBits + bitMarkUp;
685956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  frameBits = frameBits + *globUsedBits;
686956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
687b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
688956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  if (frameBits !=  (qcOut->totStaticBitsUsed+qcOut->totDynBitsUsed + qcOut->totAncBitsUsed +
689956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                     qcOut->totFillBits + qcOut->alignBits)) {
690956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    return(-1);
691956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
692956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  return(0);
693956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
694