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 36956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 37956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongtypedef enum{ 38956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong FRAME_LEN_BYTES_MODULO = 1, 39956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong FRAME_LEN_BYTES_INT = 2 40956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}FRAME_LEN_RESULT_MODE; 41956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 42956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic const Word16 maxFillElemBits = 7 + 270*8; 43956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 44956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/* forward declarations */ 45956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 46956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 calcMaxValueInSfb(Word16 sfbCnt, 47956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 maxSfbPerGroup, 48956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 sfbPerGroup, 49956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 sfbOffset[MAX_GROUPED_SFB], 50956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 quantSpectrum[FRAME_LEN_LONG], 51956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong UWord16 maxValue[MAX_GROUPED_SFB]); 52956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 53956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 54956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 55956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 56956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: calcFrameLen 57956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: estimate the frame length according the bitrates 58956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 59956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/ 60956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 calcFrameLen(Word32 bitRate, 61956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 sampleRate, 62956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong FRAME_LEN_RESULT_MODE mode) 63956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 64956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 65956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 result; 66956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 quot; 67956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 68956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong result = (FRAME_LEN_LONG >> 3) * bitRate; 69956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong quot = result / sampleRate; 70956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 71b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 72956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (mode == FRAME_LEN_BYTES_MODULO) { 73956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong result -= quot * sampleRate; 74956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 75956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else { /* FRAME_LEN_BYTES_INT */ 76b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard result = quot; 77956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 78956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 79956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return result; 80956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 81956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 82956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 83956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 84956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name:framePadding 85956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: Calculates if padding is needed for actual frame 86b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard* returns: paddingOn or not 87956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 88956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/ 89956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 framePadding(Word32 bitRate, 90956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 sampleRate, 91956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 *paddingRest) 92956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 93956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 paddingOn; 94956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 difference; 95956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 96b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard paddingOn = 0; 97956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 98956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong difference = calcFrameLen( bitRate, 99956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong sampleRate, 100956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong FRAME_LEN_BYTES_MODULO ); 101956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong *paddingRest = *paddingRest - difference; 102956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 103b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 104956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (*paddingRest <= 0 ) { 105b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard paddingOn = 1; 106956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong *paddingRest = *paddingRest + sampleRate; 107956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 108956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 109956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return paddingOn; 110956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 111956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 112956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 113956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/********************************************************************************* 114956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 115956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: QCOutNew 116956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: init qcout parameter 117956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns: 0 if success 118956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 119956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/ 120956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 121956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongWord16 QCOutNew(QC_OUT *hQC, Word16 nChannels, VO_MEM_OPERATOR *pMemOP) 122956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 123e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 i; 124e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 *quantSpec; 125e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 *scf; 126b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard UWord16 *maxValueInSfb; 127b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 128e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard quantSpec = (Word16 *)mem_malloc(pMemOP, nChannels * FRAME_LEN_LONG * sizeof(Word16), 32, VO_INDEX_ENC_AAC); 129e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(NULL == quantSpec) 130e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard return 1; 131b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard scf = (Word16 *)mem_malloc(pMemOP, nChannels * MAX_GROUPED_SFB * sizeof(Word16), 32, VO_INDEX_ENC_AAC); 132e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(NULL == scf) 133e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 134956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return 1; 135956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 136e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard maxValueInSfb = (UWord16 *)mem_malloc(pMemOP, nChannels * MAX_GROUPED_SFB * sizeof(UWord16), 32, VO_INDEX_ENC_AAC); 137e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(NULL == maxValueInSfb) 138e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 139e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard return 1; 140e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 141e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 142956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (i=0; i<nChannels; i++) { 143956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hQC->qcChannel[i].quantSpec = quantSpec + i*FRAME_LEN_LONG; 144b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 145956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hQC->qcChannel[i].maxValueInSfb = maxValueInSfb + i*MAX_GROUPED_SFB; 146b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 147956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hQC->qcChannel[i].scf = scf + i*MAX_GROUPED_SFB; 148956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 149b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 150956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return 0; 151956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 152956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 153956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 154956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/********************************************************************************* 155956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 156956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: QCOutDelete 157956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: unint qcout parameter 158956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns: 0 if success 159956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 160956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/ 161956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongvoid QCOutDelete(QC_OUT* hQC, VO_MEM_OPERATOR *pMemOP) 162956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 163e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 i; 164e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(hQC) 165e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 166338b9c9020ca6be98f30670cf307ad8553f1b4c9Martin Storsjo if(hQC->qcChannel[0].quantSpec) 167e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard mem_free(pMemOP, hQC->qcChannel[0].quantSpec, VO_INDEX_ENC_AAC); 168b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 169e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(hQC->qcChannel[0].maxValueInSfb) 170e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard mem_free(pMemOP, hQC->qcChannel[0].maxValueInSfb, VO_INDEX_ENC_AAC); 171b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 172e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(hQC->qcChannel[0].scf) 173e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard mem_free(pMemOP, hQC->qcChannel[0].scf, VO_INDEX_ENC_AAC); 174e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 175e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (i=0; i<MAX_CHANNELS; i++) { 176e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard hQC->qcChannel[i].quantSpec = NULL; 177b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 178e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard hQC->qcChannel[i].maxValueInSfb = NULL; 179b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 180e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard hQC->qcChannel[i].scf = NULL; 181e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 182b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard } 183956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 184956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 185956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/********************************************************************************* 186956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 187956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: QCNew 188956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: set QC to zero 189956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns: 0 if success 190956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 191956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/ 192956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongWord16 QCNew(QC_STATE *hQC, VO_MEM_OPERATOR *pMemOP) 193956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 194956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong pMemOP->Set(VO_INDEX_ENC_AAC, hQC,0,sizeof(QC_STATE)); 195956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 196956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return (0); 197956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 198956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 199956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/********************************************************************************* 200956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 201956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: QCDelete 202956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: unint qcout parameter 203956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 204956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/ 205956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongvoid QCDelete(QC_STATE *hQC, VO_MEM_OPERATOR *pMemOP) 206956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 207b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 208b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard /* 209956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong nothing to do 210956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong */ 211956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hQC=NULL; 212956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 213956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 214956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/********************************************************************************* 215956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 216956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: QCInit 217956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: init QD parameter 218956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns: 0 if success 219956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 220956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/ 221956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongWord16 QCInit(QC_STATE *hQC, 222956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong struct QC_INIT *init) 223956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 224b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard hQC->nChannels = init->elInfo->nChannelsInEl; 225b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard hQC->maxBitsTot = init->maxBits; 226956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hQC->bitResTot = sub(init->bitRes, init->averageBits); 227b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard hQC->averageBitsTot = init->averageBits; 228b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard hQC->maxBitFac = init->maxBitFac; 229956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 230b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard hQC->padding.paddingRest = init->padding.paddingRest; 231956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 232b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard hQC->globStatBits = 3; /* for ID_END */ 233956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 234956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* channel elements init */ 235956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong InitElementBits(&hQC->elementBits, 236956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong *init->elInfo, 237956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong init->bitrate, 238956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong init->averageBits, 239956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hQC->globStatBits); 240956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 241956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* threshold parameter init */ 242956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong AdjThrInit(&hQC->adjThr, 243956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong init->meanPe, 244956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hQC->elementBits.chBitrate); 245956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 246956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return 0; 247956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 248956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 249956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 250956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/********************************************************************************* 251b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard* 252956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: QCMain 253956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: quantization and coding the spectrum 254956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns: 0 if success 255956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 256956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/ 257b676a05348e4c516fa8b57e33b10548e6142c3f8Mans RullgardWord16 QCMain(QC_STATE* hQC, 258956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong ELEMENT_BITS* elBits, 259956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong ATS_ELEMENT* adjThrStateElement, 260956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS], /* may be modified in-place */ 261956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong PSY_OUT_ELEMENT* psyOutElement, 262956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong QC_OUT_CHANNEL qcOutChannel[MAX_CHANNELS], /* out */ 263956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong QC_OUT_ELEMENT* qcOutElement, 264956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 nChannels, 265b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard Word16 ancillaryDataBytes) 266956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 267956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 maxChDynBits[MAX_CHANNELS]; 268b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard Word16 chBitDistribution[MAX_CHANNELS]; 269956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 ch; 270b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 271956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (elBits->bitResLevel < 0) { 272956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return -1; 273956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 274b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 275956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (elBits->bitResLevel > elBits->maxBitResBits) { 276956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return -1; 277956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 278956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 279956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcOutElement->staticBitsUsed = countStaticBitdemand(psyOutChannel, 280956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyOutElement, 281b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard nChannels, 282956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcOutElement->adtsUsed); 283956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 284b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 285956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (ancillaryDataBytes) { 286956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcOutElement->ancBitsUsed = 7 + (ancillaryDataBytes << 3); 287b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 288956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (ancillaryDataBytes >= 15) 289956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcOutElement->ancBitsUsed = qcOutElement->ancBitsUsed + 8; 290956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 291956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else { 292b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard qcOutElement->ancBitsUsed = 0; 293956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 294956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 295956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong CalcFormFactor(hQC->logSfbFormFactor, hQC->sfbNRelevantLines, hQC->logSfbEnergy, psyOutChannel, nChannels); 296956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 297956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /*adjust thresholds for the desired bitrate */ 298956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong AdjustThresholds(&hQC->adjThr, 299956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong adjThrStateElement, 300956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyOutChannel, 301956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyOutElement, 302956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong chBitDistribution, 303956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hQC->logSfbEnergy, 304b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard hQC->sfbNRelevantLines, 305956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcOutElement, 306956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong elBits, 307956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong nChannels, 308956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hQC->maxBitFac); 309956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 310956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /*estimate scale factors */ 311956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong EstimateScaleFactors(psyOutChannel, 312956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcOutChannel, 313956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hQC->logSfbEnergy, 314956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hQC->logSfbFormFactor, 315956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hQC->sfbNRelevantLines, 316956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong nChannels); 317956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 318956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* condition to prevent empty bitreservoir */ 319956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (ch = 0; ch < nChannels; ch++) { 320956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 maxDynBits; 321956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong maxDynBits = elBits->averageBits + elBits->bitResLevel - 7; /* -7 bec. of align bits */ 322956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong maxDynBits = maxDynBits - qcOutElement->staticBitsUsed + qcOutElement->ancBitsUsed; 323956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong maxChDynBits[ch] = extract_l(chBitDistribution[ch] * maxDynBits / 1000); 324956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 325956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 326b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard qcOutElement->dynBitsUsed = 0; 327956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (ch = 0; ch < nChannels; ch++) { 328956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 chDynBits; 329956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Flag constraintsFulfilled; 330956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 iter; 331b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard iter = 0; 332956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong do { 333b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard constraintsFulfilled = 1; 334956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 335956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong QuantizeSpectrum(psyOutChannel[ch].sfbCnt, 336956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyOutChannel[ch].maxSfbPerGroup, 337956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyOutChannel[ch].sfbPerGroup, 338956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyOutChannel[ch].sfbOffsets, 339956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyOutChannel[ch].mdctSpectrum, 340956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcOutChannel[ch].globalGain, 341956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcOutChannel[ch].scf, 342956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcOutChannel[ch].quantSpec); 343b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 344956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (calcMaxValueInSfb(psyOutChannel[ch].sfbCnt, 345956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyOutChannel[ch].maxSfbPerGroup, 346956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyOutChannel[ch].sfbPerGroup, 347956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyOutChannel[ch].sfbOffsets, 348956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcOutChannel[ch].quantSpec, 349956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcOutChannel[ch].maxValueInSfb) > MAX_QUANT) { 350b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard constraintsFulfilled = 0; 351956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 352956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 353956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong chDynBits = dynBitCount(qcOutChannel[ch].quantSpec, 354956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcOutChannel[ch].maxValueInSfb, 355956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcOutChannel[ch].scf, 356956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyOutChannel[ch].windowSequence, 357956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyOutChannel[ch].sfbCnt, 358956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyOutChannel[ch].maxSfbPerGroup, 359956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyOutChannel[ch].sfbPerGroup, 360956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psyOutChannel[ch].sfbOffsets, 361956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &qcOutChannel[ch].sectionData); 362b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 363956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (chDynBits >= maxChDynBits[ch]) { 364b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard constraintsFulfilled = 0; 365956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 366b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 367956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (!constraintsFulfilled) { 368956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcOutChannel[ch].globalGain = qcOutChannel[ch].globalGain + 1; 369956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 370956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 371956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong iter = iter + 1; 372b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 373956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } while(!constraintsFulfilled); 374956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 375956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcOutElement->dynBitsUsed = qcOutElement->dynBitsUsed + chDynBits; 376956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 377b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard qcOutChannel[ch].mdctScale = psyOutChannel[ch].mdctScale; 378b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard qcOutChannel[ch].groupingMask = psyOutChannel[ch].groupingMask; 379b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard qcOutChannel[ch].windowShape = psyOutChannel[ch].windowShape; 380956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 381956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 382956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* save dynBitsUsed for correction of bits2pe relation */ 383956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong AdjThrUpdate(adjThrStateElement, qcOutElement->dynBitsUsed); 384956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 385956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong { 386956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 bitResSpace = elBits->maxBitResBits - elBits->bitResLevel; 387956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 deltaBitRes = elBits->averageBits - 388956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong (qcOutElement->staticBitsUsed + 389956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcOutElement->dynBitsUsed + qcOutElement->ancBitsUsed); 390956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 391956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcOutElement->fillBits = max(0, (deltaBitRes - bitResSpace)); 392956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 393956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 394956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return 0; /* OK */ 395956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 396956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 397956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 398956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/********************************************************************************* 399956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 400956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: calcMaxValueInSfb 401956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: search the max Spectrum in one sfb 402956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 403956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/ 404956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 calcMaxValueInSfb(Word16 sfbCnt, 405956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 maxSfbPerGroup, 406956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 sfbPerGroup, 407956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 sfbOffset[MAX_GROUPED_SFB], 408956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 quantSpectrum[FRAME_LEN_LONG], 409956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong UWord16 maxValue[MAX_GROUPED_SFB]) 410956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 411956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 sfbOffs, sfb; 412956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 maxValueAll; 413956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 414b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard maxValueAll = 0; 415956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 416956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for(sfbOffs=0;sfbOffs<sfbCnt;sfbOffs+=sfbPerGroup) { 417956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (sfb = 0; sfb < maxSfbPerGroup; sfb++) { 418956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 line; 419956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 maxThisSfb; 420b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard maxThisSfb = 0; 421956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 422956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (line = sfbOffset[sfbOffs+sfb]; line < sfbOffset[sfbOffs+sfb+1]; line++) { 423956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 absVal; 424956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong absVal = abs_s(quantSpectrum[line]); 425956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong maxThisSfb = max(maxThisSfb, absVal); 426956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 427956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 428b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard maxValue[sfbOffs+sfb] = maxThisSfb; 429956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong maxValueAll = max(maxValueAll, maxThisSfb); 430956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 431956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 432956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return maxValueAll; 433956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 434956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 435956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 436956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/********************************************************************************* 437956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 438956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: updateBitres 439956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: update bitreservoir 440956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 441956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/ 442956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongvoid updateBitres(QC_STATE* qcKernel, 443956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong QC_OUT* qcOut) 444b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 445956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 446956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong ELEMENT_BITS *elBits; 447b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 448b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard qcKernel->bitResTot = 0; 449956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 450956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong elBits = &qcKernel->elementBits; 451956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 452b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 453956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (elBits->averageBits > 0) { 454956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* constant bitrate */ 455956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 bitsUsed; 456956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong bitsUsed = (qcOut->qcElement.staticBitsUsed + qcOut->qcElement.dynBitsUsed) + 457956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong (qcOut->qcElement.ancBitsUsed + qcOut->qcElement.fillBits); 458956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong elBits->bitResLevel = elBits->bitResLevel + (elBits->averageBits - bitsUsed); 459956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcKernel->bitResTot = qcKernel->bitResTot + elBits->bitResLevel; 460956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 461956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else { 462956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* variable bitrate */ 463b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard elBits->bitResLevel = elBits->maxBits; 464b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard qcKernel->bitResTot = qcKernel->maxBitsTot; 465956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 466956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 467956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 468956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/********************************************************************************* 469956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 470956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: FinalizeBitConsumption 471956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: count bits used 472956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 473956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/ 474956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongWord16 FinalizeBitConsumption(QC_STATE *qcKernel, 475956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong QC_OUT* qcOut) 476956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 477e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 nFullFillElem; 478e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 totFillBits; 479b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard Word16 diffBits; 480956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 bitsUsed; 481956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 482b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard totFillBits = 0; 483956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 484b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard qcOut->totStaticBitsUsed = qcKernel->globStatBits; 485956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcOut->totStaticBitsUsed += qcOut->qcElement.staticBitsUsed; 486956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcOut->totDynBitsUsed = qcOut->qcElement.dynBitsUsed; 487956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcOut->totAncBitsUsed = qcOut->qcElement.ancBitsUsed; 488956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcOut->totFillBits = qcOut->qcElement.fillBits; 489b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 490956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (qcOut->qcElement.fillBits) { 491956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong totFillBits += qcOut->qcElement.fillBits; 492956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 493956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 494e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard nFullFillElem = (max((qcOut->totFillBits - 1), 0) / maxFillElemBits) * maxFillElemBits; 495b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 496956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcOut->totFillBits = qcOut->totFillBits - nFullFillElem; 497956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 498956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* check fill elements */ 499b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 500956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (qcOut->totFillBits > 0) { 501956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* minimum Fillelement contains 7 (TAG + byte cnt) bits */ 502956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcOut->totFillBits = max(7, qcOut->totFillBits); 503956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* fill element size equals n*8 + 7 */ 504b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard qcOut->totFillBits = qcOut->totFillBits + ((8 - ((qcOut->totFillBits - 7) & 0x0007)) & 0x0007); 505956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 506956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 507956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcOut->totFillBits = qcOut->totFillBits + nFullFillElem; 508956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 509956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* now distribute extra fillbits and alignbits over channel elements */ 510956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcOut->alignBits = 7 - ((qcOut->totDynBitsUsed + qcOut->totStaticBitsUsed + 511b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard qcOut->totAncBitsUsed + qcOut->totFillBits - 1) & 0x0007); 512b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 513956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 514956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if ( (qcOut->alignBits + qcOut->totFillBits - totFillBits == 8) && 515956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong (qcOut->totFillBits > 8)) 516956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcOut->totFillBits = qcOut->totFillBits - 8; 517956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 518b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 519956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong diffBits = qcOut->alignBits + qcOut->totFillBits - totFillBits; 520b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 521956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if(diffBits>=0) { 522956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qcOut->qcElement.fillBits += diffBits; 523956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 524956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 525956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong bitsUsed = qcOut->totDynBitsUsed + qcOut->totStaticBitsUsed + qcOut->totAncBitsUsed; 526956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong bitsUsed = bitsUsed + qcOut->totFillBits + qcOut->alignBits; 527b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 528956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (bitsUsed > qcKernel->maxBitsTot) { 529956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return -1; 530956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 531956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return bitsUsed; 532956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 533956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 534956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 535956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/********************************************************************************* 536956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 537956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: AdjustBitrate 538956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: adjusts framelength via padding on a frame to frame basis, 539956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* to achieve a bitrate that demands a non byte aligned 540956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* framelength 541956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* return: errorcode 542956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 543956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/ 544956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongWord16 AdjustBitrate(QC_STATE *hQC, 545956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 bitRate, /* total bitrate */ 546956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 sampleRate) /* output sampling rate */ 547956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 548956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 paddingOn; 549956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 frameLen; 550956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 codeBits; 551956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 codeBitsLast; 552956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 553956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* Do we need a extra padding byte? */ 554956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong paddingOn = framePadding(bitRate, 555956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong sampleRate, 556956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &hQC->padding.paddingRest); 557956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 558956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* frame length */ 559956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong frameLen = paddingOn + calcFrameLen(bitRate, 560956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong sampleRate, 561956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong FRAME_LEN_BYTES_INT); 562956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 563956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong frameLen = frameLen << 3; 564956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong codeBitsLast = hQC->averageBitsTot - hQC->globStatBits; 565956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong codeBits = frameLen - hQC->globStatBits; 566956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 567b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard /* calculate bits for every channel element */ 568956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (codeBits != codeBitsLast) { 569b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard Word16 totalBits = 0; 570956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 571956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hQC->elementBits.averageBits = (hQC->elementBits.relativeBits * codeBits) >> 16; /* relativeBits was scaled down by 2 */ 572956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong totalBits += hQC->elementBits.averageBits; 573956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 574956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong hQC->elementBits.averageBits = hQC->elementBits.averageBits + (codeBits - totalBits); 575956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 576956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 577b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard hQC->averageBitsTot = frameLen; 578956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 579956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return 0; 580956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 581