📄 mp3enc_quantization.c
字号:
/*//////////////////////////////////////////////////////////////////////////////
//
// INTEL CORPORATION PROPRIETARY INFORMATION
// This software is supplied under the terms of a license agreement or
// nondisclosure agreement with Intel Corporation and may not be copied
// or disclosed except in accordance with the terms of that agreement.
// Copyright(c) 2002-2006 Intel Corporation. All Rights Reserved.
//
*/
#include "mp3enc_own.h"
/******************************************************************************
// Name:
// chooseTableLong
//
// Description:
// The function selects proper huffman table for part of spectrum and
// calculate count of bits necessary to encoding
//
// Input Arguments:
// EC - pointer to encoder context
// gr - number of granule
// ch - number of channel
// pInput - pointer to array of quantized samples
// length - count of samples in the input array which should be encoded
// table - number of part of spectrum. can be 0,1,2.
// (big values are divided on three part. each is coded by using different table)
//
// Output Arguments:
// -
//
// Returns:
// count of bits necessary to encoding
//
******************************************************************************/
static Ipp8s *tables_info_full[16] = {
"\0",
"\1\2\3\5\6\7\10\11\12\13\14\15\17",
"\2\3\5\6\7\10\11\12\13\14\15\17",
"\5\6\7\10\11\12\13\14\15\17",
"\7\10\11\12\13\14\15\17",
"\7\10\11\12\13\14\15\17",
"\12\13\14\15\17",
"\12\13\14\15\17",
"\15\17",
"\15\17",
"\15\17",
"\15\17",
"\15\17",
"\15\17",
"\15\17",
"\0\0"
};
static Ipp8s *tables_info_short[16] = {
"\0",
"\1",
"\2\3",
"\5\6",
"\7\10\11",
"\7\10\11",
"\12\13\14",
"\12\13\14",
"\15\17",
"\15\17",
"\15\17",
"\15\17",
"\15\17",
"\15\17",
"\15\17",
"\0\0"
};
Ipp32s mp3enc_quantChooseTableLong(MP3Enc_com *state,
Ipp32s gr,
Ipp32s ch,
Ipp16s *pInput,
Ipp32s length,
Ipp32s table)
{
Ipp32s choice0, choice1, i, tbl;
Ipp32s sum0, sum1;
Ipp16s max;
Ipp8s *tables;
Ipp8s tbuf[3];
MP3Enc_HuffmanTable *htables;
Ipp16s tmp_src[288];
htables = state->htables;
ippsMax_16s(pInput, length, &max);
if (max == 0 || length == 0)
return 0;
choice0 = 0;
choice1 = 0;
sum0 = sum1 = 32767;
if (max >= 15) {
/*
* try tables with linbits
*/
choice0 = 15;
while (htables[choice0].mav_value < max)
choice0++;
choice1 = 24;
while (htables[choice1].mav_value < max)
choice1++;
tables = tbuf;
tbuf[0] = (Ipp8u)choice0;
tbuf[1] = (Ipp8u)choice1;
tbuf[2] = 0;
} else {
if (!state->quant_mode_fast)
tables = tables_info_full[max];
else
tables = tables_info_short[max];
}
for (i = 0; (tbl = tables[i]) != 0; i++) {
IppsVLCEncodeSpec_32s* VLCSpec;
Ipp32s linbits;
VLCSpec = (IppsVLCEncodeSpec_32s*)(htables[tbl].phuftable);
linbits = htables[tbl].linbits;
if (linbits == 0) {
Ipp16s *q;
Ipp32s j;
Ipp32s shift = mp3enc_VLCShifts[tbl];
Ipp32s offset = mp3enc_VLCOffsets[tbl];
q = pInput;
for (j = 0; j < (length >> 1); j++) {
tmp_src[j] = (Ipp16s)((q[0] << shift) + (q[1] + offset));
q += 2;
}
ippsVLCCountBits_16s32s(tmp_src, length >> 1, &sum1, VLCSpec);
} else {
ippsVLCCountEscBits_MP3_16s32s(pInput, length, linbits,
&sum1, VLCSpec);
}
if (sum1 < sum0) {
choice0 = tbl;
sum0 = sum1;
}
}
state->si_pTableSelect[gr][ch][table] = choice0;
return sum0;
}
static Ipp32s mp3enc_quantChooseTableLong_opt(MP3Enc_com *state,
Ipp16s *pInput,
Ipp16s *max_table,
Ipp16s (*bit_table)[22],
Ipp32u *sfb_table,
Ipp32s sfb_start,
Ipp32s sfb_num,
Ipp32s bigv_region,
Ipp32s *table)
{
Ipp32s choice0, choice1, i, jj, tbl;
Ipp32s sum0, sum1, csum;
Ipp16s max;
Ipp8s *tables;
Ipp8s tbuf[3];
MP3Enc_HuffmanTable *htables;
Ipp16s tmp_src[288];
htables = state->htables;
*table = 0;
max = 0;
for (i = sfb_start; i < sfb_start + sfb_num; i++) {
if (max < max_table[i])
max = max_table[i];
}
if (max == 0)
return 0;
choice0 = 0;
choice1 = 0;
sum0 = sum1 = 32767;
if (max >= 15) {
/*
* try tables with linbits
*/
choice0 = 15;
while (htables[choice0].mav_value < max)
choice0++;
choice1 = 24;
while (htables[choice1].mav_value < max)
choice1++;
tables = tbuf;
tbuf[0] = (Ipp8s)choice0;
tbuf[1] = (Ipp8s)choice1;
tbuf[2] = 0;
} else {
if (!state->quant_mode_fast)
tables = tables_info_full[max];
else
tables = tables_info_short[max];
}
for (i = 0; (tbl = tables[i]) != 0; i++) {
sum1 = 0;
for (jj = sfb_start; jj < sfb_start + sfb_num; jj++) {
if (sfb_table[jj] >= (Ipp32u)bigv_region)
break;
if (bit_table[tbl][jj] == -1) {
Ipp32s length;
IppsVLCEncodeSpec_32s* VLCSpec;
Ipp32s linbits;
VLCSpec = (IppsVLCEncodeSpec_32s*)(htables[tbl].phuftable);
linbits = htables[tbl].linbits;
if (sfb_table[jj + 1] > (Ipp32u)bigv_region)
length = bigv_region - sfb_table[jj];
else
length = sfb_table[jj + 1] - sfb_table[jj];
if (linbits == 0) {
Ipp16s *q;
Ipp32s j;
Ipp32s shift = mp3enc_VLCShifts[tbl];
Ipp32s offset = mp3enc_VLCOffsets[tbl];
q = pInput + sfb_table[jj];
for (j = 0; j < (length >> 1); j++) {
tmp_src[j] = (Ipp16s)((q[0] << shift) + (q[1] + offset));
q += 2;
}
ippsVLCCountBits_16s32s(tmp_src, length >> 1, &csum, VLCSpec);
} else {
ippsVLCCountEscBits_MP3_16s32s(pInput + sfb_table[jj], length, linbits,
&csum, VLCSpec);
}
bit_table[tbl][jj] = (Ipp16s)csum;
}
sum1 += bit_table[tbl][jj];
}
if (sum1 < sum0) {
choice0 = tbl;
sum0 = sum1;
}
}
*table = choice0;
return sum0;
}
/******************************************************************************
// Name:
// calc_bits_long
//
// Description:
//
//
// Input Arguments:
//
//
// Output Arguments:
//
//
// Returns:
//
//
******************************************************************************/
Ipp32s mp3enc_quantCalcBitsLong(MP3Enc_com *state,
Ipp16s *pInput,
Ipp32s gr,
Ipp32s ch)
{
Ipp32s bits = 0;
Ipp32s bigv_region = state->si_bigVals[gr][ch] << 1;
state->si_pTableSelect[gr][ch][0] = 0;
state->si_pTableSelect[gr][ch][1] = 0;
state->si_pTableSelect[gr][ch][2] = 0;
if (state->si_address[gr][ch][0] > (Ipp32u)bigv_region)
state->si_address[gr][ch][0] = bigv_region;
if (state->si_address[gr][ch][1] < state->si_address[gr][ch][0])
state->si_address[gr][ch][1] = state->si_address[gr][ch][0];
if (state->si_address[gr][ch][2] < state->si_address[gr][ch][1])
state->si_address[gr][ch][2] = state->si_address[gr][ch][1];
if (state->si_address[gr][ch][0] > 0) {
bits +=
mp3enc_quantChooseTableLong(state, gr, ch, pInput, state->si_address[gr][ch][0], 0);
}
if (state->si_address[gr][ch][1] > state->si_address[gr][ch][0]) {
bits +=
mp3enc_quantChooseTableLong(state, gr, ch, pInput + state->si_address[gr][ch][0],
state->si_address[gr][ch][1] - state->si_address[gr][ch][0], 1);
}
if ((Ipp32u)bigv_region * 2 > state->si_address[gr][ch][1]) {
bits +=
mp3enc_quantChooseTableLong(state, gr, ch, pInput + state->si_address[gr][ch][1],
bigv_region - state->si_address[gr][ch][1], 2);
}
return bits;
}
/******************************************************************************
// Name:
// calc_bits
//
// Description:
//
//
// Input Arguments:
//
//
// Output Arguments:
//
//
// Returns:
//
//
******************************************************************************/
Ipp32s mp3enc_quantCalcBits(MP3Enc_com *state,
Ipp32s gr,
Ipp32s ch)
{
Ipp32u zero_region = 576;
Ipp32u bigv_region = 576;
Ipp16s tbits[32][22];
Ipp16s tmax[22];
Ipp32s bits = 0;
Ipp32s sum0 = 0;
Ipp32s sum1 = 0;
Ipp32s i;
Ipp32s t0, t1, t2, st_t0 = 0, st_t1 = 0, st_t2 = 0;
Ipp32s last_reg_bits[22];
Ipp32s last_reg_tbl[22];
Ipp32u *sfb_long;
Ipp32s p;
Ipp32s *ptr_int;
sfb_long = mp3enc_sfBandIndex[state->header.id][state->header.samplingFreq].l;
if ((state->si_blockType[gr][ch] != 2)) {
ptr_int = (Ipp32s *)&state->quant_ix[gr][ch][zero_region - 2];
while(zero_region > 1 &&
(*ptr_int-- == 0))
zero_region -= 2;
bigv_region = zero_region;
while(bigv_region > 3) {
Ipp32s p0, p1, p2, p3;
p0 = state->quant_ix[gr][ch][bigv_region - 4];
p1 = state->quant_ix[gr][ch][bigv_region - 3];
p2 = state->quant_ix[gr][ch][bigv_region - 2];
p3 = state->quant_ix[gr][ch][bigv_region - 1];
if ((p0 | p1 | p2 | p3) > 1)
break;
bigv_region -= 4;
p = (p0 << 3) | (p1 << 2) | (p2 << 1) | (p3);
sum0 += mp3enc_table32[3 * p + 1];
sum1 += mp3enc_table33[3 * p + 1];
}
}
state->si_count1[gr][ch] = (zero_region - bigv_region) >> 2;
state->si_bigVals[gr][ch] = bigv_region >> 1;
if (sum0 < sum1) {
bits += sum0;
state->si_cnt1TabSel[gr][ch] = 0;
} else {
bits += sum1;
state->si_cnt1TabSel[gr][ch] = 1;
}
if (bigv_region) {
ippsSet_16s(-1, &tbits[0][0], 32*22);
for (i = 0; i < 22; i++) {
Ipp32s length = sfb_long[i+1] - sfb_long[i];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -