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: qc_main.c 18e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 19e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Content: Quantizing & coding functions 20e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 21956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*******************************************************************************/ 22956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 23e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "basic_op.h" 24e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "oper_32b.h" 25956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "qc_main.h" 26956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "quantize.h" 27956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "interface.h" 28956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "adj_thr.h" 29956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "sf_estim.h" 30956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "stat_bits.h" 31956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "bit_cnt.h" 32956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "dyn_bits.h" 33956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "channel_map.h" 34956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "memalign.h" 35956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 3684333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber#define UNUSED(x) (void)(x) 37956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 38956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongtypedef enum{ 39956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong FRAME_LEN_BYTES_MODULO = 1, 40956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong FRAME_LEN_BYTES_INT = 2 41956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}FRAME_LEN_RESULT_MODE; 42956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 43956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic const Word16 maxFillElemBits = 7 + 270*8; 44956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 45956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/* forward declarations */ 46956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 47956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 calcMaxValueInSfb(Word16 sfbCnt, 48956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 maxSfbPerGroup, 49956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 sfbPerGroup, 50956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 sfbOffset[MAX_GROUPED_SFB], 51956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 quantSpectrum[FRAME_LEN_LONG], 52956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong UWord16 maxValue[MAX_GROUPED_SFB]); 53956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 54956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 55956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 56956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 57956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: calcFrameLen 58956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: estimate the frame length according the bitrates 59956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 60956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/ 61956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 calcFrameLen(Word32 bitRate, 62956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 sampleRate, 63956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong FRAME_LEN_RESULT_MODE mode) 64956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 65956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 66956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 result; 67956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 quot; 68956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 69956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong result = (FRAME_LEN_LONG >> 3) * bitRate; 70956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong quot = result / sampleRate; 71956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 72b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 73956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (mode == FRAME_LEN_BYTES_MODULO) { 74956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong result -= quot * sampleRate; 75956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 76956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else { /* FRAME_LEN_BYTES_INT */ 77b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard result = quot; 78956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 79956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 80956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return result; 81956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 82956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 83956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 84956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 85956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name:framePadding 86956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: Calculates if padding is needed for actual frame 87b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard* returns: paddingOn or not 88956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 89956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/ 90956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 framePadding(Word32 bitRate, 91956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 sampleRate, 92956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 *paddingRest) 93956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 94956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 paddingOn; 95956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 difference; 96956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 97b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard paddingOn = 0; 98956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 99956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong difference = calcFrameLen( bitRate, 100956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong sampleRate, 101956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong FRAME_LEN_BYTES_MODULO ); 102956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong *paddingRest = *paddingRest - difference; 103956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 104b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 105956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (*paddingRest <= 0 ) { 106b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard paddingOn = 1; 107956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong *paddingRest = *paddingRest + sampleRate; 108956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 109956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 110956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return paddingOn; 111956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 112956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 113956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 114956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/********************************************************************************* 115956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 116956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: QCOutNew 117956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: init qcout parameter 118956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns: 0 if success 119956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 120956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/ 121956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 122956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongWord16 QCOutNew(QC_OUT *hQC, Word16 nChannels, VO_MEM_OPERATOR *pMemOP) 123956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 124e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 i; 125e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 *quantSpec; 126e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 *scf; 127b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard UWord16 *maxValueInSfb; 128b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 129e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard quantSpec = (Word16 *)mem_malloc(pMemOP, nChannels * FRAME_LEN_LONG * sizeof(Word16), 32, VO_INDEX_ENC_AAC); 130e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(NULL == quantSpec) 131e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard return 1; 132b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard scf = (Word16 *)mem_malloc(pMemOP, nChannels * MAX_GROUPED_SFB * sizeof(Word16), 32, VO_INDEX_ENC_AAC); 133e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(NULL == scf) 134e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 135956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return 1; 136956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 137e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard maxValueInSfb = (UWord16 *)mem_malloc(pMemOP, nChannels * MAX_GROUPED_SFB * sizeof(UWord16), 32, VO_INDEX_ENC_AAC); 138e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(NULL == maxValueInSfb) 139e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 140e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard return 1; 141e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 142e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 143956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (i=0; i<nChannels; i++) { 144956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hQC->qcChannel[i].quantSpec = quantSpec + i*FRAME_LEN_LONG; 145b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 146956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hQC->qcChannel[i].maxValueInSfb = maxValueInSfb + i*MAX_GROUPED_SFB; 147b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 148956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hQC->qcChannel[i].scf = scf + i*MAX_GROUPED_SFB; 149956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 150b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 151956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return 0; 152956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 153956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 154956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 155956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/********************************************************************************* 156956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 157956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: QCOutDelete 158956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: unint qcout parameter 159956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns: 0 if success 160956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 161956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/ 162956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongvoid QCOutDelete(QC_OUT* hQC, VO_MEM_OPERATOR *pMemOP) 163956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 164e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 i; 165e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(hQC) 166e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 167338b9c9020ca6be98f30670cf307ad8553f1b4c9Martin Storsjo if(hQC->qcChannel[0].quantSpec) 168e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard mem_free(pMemOP, hQC->qcChannel[0].quantSpec, VO_INDEX_ENC_AAC); 169b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 170e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(hQC->qcChannel[0].maxValueInSfb) 171e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard mem_free(pMemOP, hQC->qcChannel[0].maxValueInSfb, VO_INDEX_ENC_AAC); 172b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 173e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(hQC->qcChannel[0].scf) 174e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard mem_free(pMemOP, hQC->qcChannel[0].scf, VO_INDEX_ENC_AAC); 175e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 176e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (i=0; i<MAX_CHANNELS; i++) { 177e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard hQC->qcChannel[i].quantSpec = NULL; 178b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 179e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard hQC->qcChannel[i].maxValueInSfb = NULL; 180b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 181e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard hQC->qcChannel[i].scf = NULL; 182e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 183b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard } 184956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 185956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 186956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/********************************************************************************* 187956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 188956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: QCNew 189956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: set QC to zero 190956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns: 0 if success 191956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 192956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/ 193956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongWord16 QCNew(QC_STATE *hQC, VO_MEM_OPERATOR *pMemOP) 194956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 195956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong pMemOP->Set(VO_INDEX_ENC_AAC, hQC,0,sizeof(QC_STATE)); 196956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 197956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return (0); 198956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 199956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 200956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/********************************************************************************* 201956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 202956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: QCDelete 203956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: unint qcout parameter 204956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 205956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/ 206956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongvoid QCDelete(QC_STATE *hQC, VO_MEM_OPERATOR *pMemOP) 207956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 20884333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber UNUSED(hQC); 20984333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber UNUSED(pMemOP); 210956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 211956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 212956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/********************************************************************************* 213956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 214956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: QCInit 215956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: init QD parameter 216956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns: 0 if success 217956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 218956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/ 219956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongWord16 QCInit(QC_STATE *hQC, 220956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong struct QC_INIT *init) 221956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 222b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard hQC->nChannels = init->elInfo->nChannelsInEl; 223b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard hQC->maxBitsTot = init->maxBits; 224956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hQC->bitResTot = sub(init->bitRes, init->averageBits); 225b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard hQC->averageBitsTot = init->averageBits; 226b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard hQC->maxBitFac = init->maxBitFac; 227956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 228b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard hQC->padding.paddingRest = init->padding.paddingRest; 229956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 230b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard hQC->globStatBits = 3; /* for ID_END */ 231956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 232956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* channel elements init */ 233956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong InitElementBits(&hQC->elementBits, 234956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong *init->elInfo, 235956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong init->bitrate, 236956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong init->averageBits, 237956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hQC->globStatBits); 238956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 239956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* threshold parameter init */ 240956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong AdjThrInit(&hQC->adjThr, 241956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong init->meanPe, 242956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hQC->elementBits.chBitrate); 243956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 244956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return 0; 245956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 246956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 247956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 248956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/********************************************************************************* 249b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard* 250956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: QCMain 251956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: quantization and coding the spectrum 252956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns: 0 if success 253956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 254956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/ 255b676a05348e4c516fa8b57e33b10548e6142c3f8Mans RullgardWord16 QCMain(QC_STATE* hQC, 256956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong ELEMENT_BITS* elBits, 257956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong ATS_ELEMENT* adjThrStateElement, 258956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS], /* may be modified in-place */ 259956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong PSY_OUT_ELEMENT* psyOutElement, 260956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong QC_OUT_CHANNEL qcOutChannel[MAX_CHANNELS], /* out */ 261956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong QC_OUT_ELEMENT* qcOutElement, 262956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 nChannels, 263b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard Word16 ancillaryDataBytes) 264956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 265956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 maxChDynBits[MAX_CHANNELS]; 266b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard Word16 chBitDistribution[MAX_CHANNELS]; 267956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 ch; 268b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 269956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (elBits->bitResLevel < 0) { 270956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return -1; 271956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 272b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 273956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (elBits->bitResLevel > elBits->maxBitResBits) { 274956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return -1; 275956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 276956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 277956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcOutElement->staticBitsUsed = countStaticBitdemand(psyOutChannel, 278956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyOutElement, 279b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard nChannels, 280956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcOutElement->adtsUsed); 281956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 282b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 283956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (ancillaryDataBytes) { 284956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcOutElement->ancBitsUsed = 7 + (ancillaryDataBytes << 3); 285b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 286956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (ancillaryDataBytes >= 15) 287956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcOutElement->ancBitsUsed = qcOutElement->ancBitsUsed + 8; 288956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 289956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else { 290b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard qcOutElement->ancBitsUsed = 0; 291956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 292956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 293956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong CalcFormFactor(hQC->logSfbFormFactor, hQC->sfbNRelevantLines, hQC->logSfbEnergy, psyOutChannel, nChannels); 294956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 295956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /*adjust thresholds for the desired bitrate */ 296956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong AdjustThresholds(&hQC->adjThr, 297956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong adjThrStateElement, 298956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyOutChannel, 299956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyOutElement, 300956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong chBitDistribution, 301956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hQC->logSfbEnergy, 302b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard hQC->sfbNRelevantLines, 303956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcOutElement, 304956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong elBits, 305956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong nChannels, 306956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hQC->maxBitFac); 307956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 308956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /*estimate scale factors */ 309956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong EstimateScaleFactors(psyOutChannel, 310956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcOutChannel, 311956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hQC->logSfbEnergy, 312956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hQC->logSfbFormFactor, 313956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hQC->sfbNRelevantLines, 314956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong nChannels); 315956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 316956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* condition to prevent empty bitreservoir */ 317956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (ch = 0; ch < nChannels; ch++) { 318956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 maxDynBits; 319956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong maxDynBits = elBits->averageBits + elBits->bitResLevel - 7; /* -7 bec. of align bits */ 320956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong maxDynBits = maxDynBits - qcOutElement->staticBitsUsed + qcOutElement->ancBitsUsed; 321956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong maxChDynBits[ch] = extract_l(chBitDistribution[ch] * maxDynBits / 1000); 322956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 323956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 324b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard qcOutElement->dynBitsUsed = 0; 325956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (ch = 0; ch < nChannels; ch++) { 326956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 chDynBits; 327956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Flag constraintsFulfilled; 328956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 iter; 329b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard iter = 0; 330956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong do { 331b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard constraintsFulfilled = 1; 332956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 333956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong QuantizeSpectrum(psyOutChannel[ch].sfbCnt, 334956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyOutChannel[ch].maxSfbPerGroup, 335956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyOutChannel[ch].sfbPerGroup, 336956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyOutChannel[ch].sfbOffsets, 337956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyOutChannel[ch].mdctSpectrum, 338956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcOutChannel[ch].globalGain, 339956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcOutChannel[ch].scf, 340956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcOutChannel[ch].quantSpec); 341b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 342956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (calcMaxValueInSfb(psyOutChannel[ch].sfbCnt, 343956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyOutChannel[ch].maxSfbPerGroup, 344956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyOutChannel[ch].sfbPerGroup, 345956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyOutChannel[ch].sfbOffsets, 346956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcOutChannel[ch].quantSpec, 347956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcOutChannel[ch].maxValueInSfb) > MAX_QUANT) { 348b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard constraintsFulfilled = 0; 349956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 350956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 351956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong chDynBits = dynBitCount(qcOutChannel[ch].quantSpec, 352956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcOutChannel[ch].maxValueInSfb, 353956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcOutChannel[ch].scf, 354956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyOutChannel[ch].windowSequence, 355956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyOutChannel[ch].sfbCnt, 356956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyOutChannel[ch].maxSfbPerGroup, 357956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyOutChannel[ch].sfbPerGroup, 358956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyOutChannel[ch].sfbOffsets, 359956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &qcOutChannel[ch].sectionData); 360b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 361956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (chDynBits >= maxChDynBits[ch]) { 362b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard constraintsFulfilled = 0; 363956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 364b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 365956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (!constraintsFulfilled) { 366956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcOutChannel[ch].globalGain = qcOutChannel[ch].globalGain + 1; 367956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 368956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 369956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong iter = iter + 1; 370b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 371956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } while(!constraintsFulfilled); 372956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 373956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcOutElement->dynBitsUsed = qcOutElement->dynBitsUsed + chDynBits; 374956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 375b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard qcOutChannel[ch].mdctScale = psyOutChannel[ch].mdctScale; 376b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard qcOutChannel[ch].groupingMask = psyOutChannel[ch].groupingMask; 377b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard qcOutChannel[ch].windowShape = psyOutChannel[ch].windowShape; 378956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 379956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 380956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* save dynBitsUsed for correction of bits2pe relation */ 381956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong AdjThrUpdate(adjThrStateElement, qcOutElement->dynBitsUsed); 382956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 383956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong { 384956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 bitResSpace = elBits->maxBitResBits - elBits->bitResLevel; 385956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 deltaBitRes = elBits->averageBits - 386956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong (qcOutElement->staticBitsUsed + 387956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcOutElement->dynBitsUsed + qcOutElement->ancBitsUsed); 388956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 389956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcOutElement->fillBits = max(0, (deltaBitRes - bitResSpace)); 390956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 391956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 392956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return 0; /* OK */ 393956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 394956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 395956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 396956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/********************************************************************************* 397956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 398956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: calcMaxValueInSfb 399956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: search the max Spectrum in one sfb 400956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 401956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/ 402956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 calcMaxValueInSfb(Word16 sfbCnt, 403956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 maxSfbPerGroup, 404956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 sfbPerGroup, 405956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 sfbOffset[MAX_GROUPED_SFB], 406956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 quantSpectrum[FRAME_LEN_LONG], 407956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong UWord16 maxValue[MAX_GROUPED_SFB]) 408956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 409956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 sfbOffs, sfb; 410956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 maxValueAll; 411956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 412b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard maxValueAll = 0; 413956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 414956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for(sfbOffs=0;sfbOffs<sfbCnt;sfbOffs+=sfbPerGroup) { 415956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (sfb = 0; sfb < maxSfbPerGroup; sfb++) { 416956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 line; 417956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 maxThisSfb; 418b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard maxThisSfb = 0; 419956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 420956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (line = sfbOffset[sfbOffs+sfb]; line < sfbOffset[sfbOffs+sfb+1]; line++) { 421956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 absVal; 422956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong absVal = abs_s(quantSpectrum[line]); 423956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong maxThisSfb = max(maxThisSfb, absVal); 424956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 425956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 426b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard maxValue[sfbOffs+sfb] = maxThisSfb; 427956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong maxValueAll = max(maxValueAll, maxThisSfb); 428956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 429956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 430956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return maxValueAll; 431956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 432956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 433956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 434956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/********************************************************************************* 435956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 436956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: updateBitres 437956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: update bitreservoir 438956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 439956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/ 440956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongvoid updateBitres(QC_STATE* qcKernel, 441956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong QC_OUT* qcOut) 442b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 443956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 444956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong ELEMENT_BITS *elBits; 445b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 446b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard qcKernel->bitResTot = 0; 447956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 448956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong elBits = &qcKernel->elementBits; 449956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 450b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 451956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (elBits->averageBits > 0) { 452956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* constant bitrate */ 453956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 bitsUsed; 454956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong bitsUsed = (qcOut->qcElement.staticBitsUsed + qcOut->qcElement.dynBitsUsed) + 455956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong (qcOut->qcElement.ancBitsUsed + qcOut->qcElement.fillBits); 456956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong elBits->bitResLevel = elBits->bitResLevel + (elBits->averageBits - bitsUsed); 457956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcKernel->bitResTot = qcKernel->bitResTot + elBits->bitResLevel; 458956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 459956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else { 460956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* variable bitrate */ 461b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard elBits->bitResLevel = elBits->maxBits; 462b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard qcKernel->bitResTot = qcKernel->maxBitsTot; 463956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 464956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 465956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 466956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/********************************************************************************* 467956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 468956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: FinalizeBitConsumption 469956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: count bits used 470956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 471956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/ 472956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongWord16 FinalizeBitConsumption(QC_STATE *qcKernel, 473956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong QC_OUT* qcOut) 474956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 475e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 nFullFillElem; 476e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 totFillBits; 477b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard Word16 diffBits; 478956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 bitsUsed; 479956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 480b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard totFillBits = 0; 481956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 482b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard qcOut->totStaticBitsUsed = qcKernel->globStatBits; 483956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcOut->totStaticBitsUsed += qcOut->qcElement.staticBitsUsed; 484956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcOut->totDynBitsUsed = qcOut->qcElement.dynBitsUsed; 485956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcOut->totAncBitsUsed = qcOut->qcElement.ancBitsUsed; 486956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcOut->totFillBits = qcOut->qcElement.fillBits; 487b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 488956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (qcOut->qcElement.fillBits) { 489956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong totFillBits += qcOut->qcElement.fillBits; 490956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 491956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 492e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard nFullFillElem = (max((qcOut->totFillBits - 1), 0) / maxFillElemBits) * maxFillElemBits; 493b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 494956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcOut->totFillBits = qcOut->totFillBits - nFullFillElem; 495956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 496956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* check fill elements */ 497b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 498956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (qcOut->totFillBits > 0) { 499956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* minimum Fillelement contains 7 (TAG + byte cnt) bits */ 500956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcOut->totFillBits = max(7, qcOut->totFillBits); 501956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* fill element size equals n*8 + 7 */ 502b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard qcOut->totFillBits = qcOut->totFillBits + ((8 - ((qcOut->totFillBits - 7) & 0x0007)) & 0x0007); 503956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 504956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 505956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcOut->totFillBits = qcOut->totFillBits + nFullFillElem; 506956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 507956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* now distribute extra fillbits and alignbits over channel elements */ 508956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcOut->alignBits = 7 - ((qcOut->totDynBitsUsed + qcOut->totStaticBitsUsed + 509b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard qcOut->totAncBitsUsed + qcOut->totFillBits - 1) & 0x0007); 510b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 511956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 512956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if ( (qcOut->alignBits + qcOut->totFillBits - totFillBits == 8) && 513956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong (qcOut->totFillBits > 8)) 514956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcOut->totFillBits = qcOut->totFillBits - 8; 515956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 516b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 517956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong diffBits = qcOut->alignBits + qcOut->totFillBits - totFillBits; 518b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 519956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if(diffBits>=0) { 520956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcOut->qcElement.fillBits += diffBits; 521956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 522956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 523956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong bitsUsed = qcOut->totDynBitsUsed + qcOut->totStaticBitsUsed + qcOut->totAncBitsUsed; 524956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong bitsUsed = bitsUsed + qcOut->totFillBits + qcOut->alignBits; 525b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 526956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (bitsUsed > qcKernel->maxBitsTot) { 527956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return -1; 528956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 529956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return bitsUsed; 530956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 531956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 532956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 533956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/********************************************************************************* 534956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 535956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: AdjustBitrate 536956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: adjusts framelength via padding on a frame to frame basis, 537956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* to achieve a bitrate that demands a non byte aligned 538956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* framelength 539956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* return: errorcode 540956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 541956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/ 542956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongWord16 AdjustBitrate(QC_STATE *hQC, 543956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 bitRate, /* total bitrate */ 544956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 sampleRate) /* output sampling rate */ 545956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 546956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 paddingOn; 547956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 frameLen; 548956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 codeBits; 549956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 codeBitsLast; 550956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 551956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* Do we need a extra padding byte? */ 552956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong paddingOn = framePadding(bitRate, 553956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong sampleRate, 554956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &hQC->padding.paddingRest); 555956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 556956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* frame length */ 557956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong frameLen = paddingOn + calcFrameLen(bitRate, 558956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong sampleRate, 559956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong FRAME_LEN_BYTES_INT); 560956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 561956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong frameLen = frameLen << 3; 562956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong codeBitsLast = hQC->averageBitsTot - hQC->globStatBits; 563956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong codeBits = frameLen - hQC->globStatBits; 564956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 565b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard /* calculate bits for every channel element */ 566956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (codeBits != codeBitsLast) { 567b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard Word16 totalBits = 0; 568956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 569956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hQC->elementBits.averageBits = (hQC->elementBits.relativeBits * codeBits) >> 16; /* relativeBits was scaled down by 2 */ 570956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong totalBits += hQC->elementBits.averageBits; 571956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 572956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hQC->elementBits.averageBits = hQC->elementBits.averageBits + (codeBits - totalBits); 573956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 574956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 575b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard hQC->averageBitsTot = frameLen; 576956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 577956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return 0; 578956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 579