📄 mp3enc_bitstream.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) 2003-2007 Intel Corporation. All Rights Reserved.
//
*/
#include "mp3enc_own.h"
#define PutBitsSI(val, len) PUT_BITS(&state->sideStream, val, len)
#define PutBits(val, len) PUT_BITS(&state->mainStream, val, len)
#define PutBitsDst(dst, val, len) PUT_BITS(dst, val, len)
/*******************************************************************/
static Ipp32s mp3enc_trans_channel_5[5][8] = {
{0, 0, 0, 0, 0, 0, 0, 0},
{1, 1, 1, 1, 1, 1, 1, 1},
{2, 5, 6, 2, 2, 2, 6, 5},
{3, 3, 3, 5, 3, 5, 5, 3},
{4, 4, 4, 4, 6, 6, 4, 6},
};
static Ipp32s mp3enc_trans_channel_4a[4][6] = {
{0, 0, 0, 0, 0, 0},
{1, 1, 1, 1, 1, 1},
{2, 5, 6, 2, 2, 5},
{3, 3, 3, 5, 6, 6},
};
static Ipp32s mp3enc_trans_channel_4b[4][4] = {
{0, 0, 0, 0},
{1, 1, 1, 1},
{2, 5, 2, 5},
{3, 3, 6, 6},
};
static Ipp32s mp3enc_trans_channel_3[5][3] = {
{0, 0, 0},
{1, 1, 1},
{2, 5, 6},
{3, 3, 3},
{4, 4, 4},
};
static Ipp32s mp3enc_dyn_channel_4[3][15] = {
{1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1},
{1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0},
{1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0},
};
static Ipp32s mp3enc_dyn_channel_3[2][5] = {
{1, 1, 0, 0, 1},
{1, 0, 1, 0, 0}
};
static Ipp32s mp3enc_dyn_channel_1[3][2] = {
{1, 0},
{1, 1},
{1, 1}
};
/*******************************************************************/
static void mp3enc_encodeBigValues(MP3Enc_com *state,
Ipp16s *pInput,
Ipp32s gr,
Ipp32s ch)
{
Ipp32s i, j, bigvalues, len;
Ipp32s shift, offset;
Ipp32s bitoffset;
Ipp16s tmp_src[288], *q;
Ipp8u *pDst;
IppsVLCEncodeSpec_32s* pVLCEncSpec;
MP3Enc_HuffmanTable *htables = state->htables;
pDst = (Ipp8u*)state->mainStream.pCurrent_dword +
((32 - state->mainStream.nBit_offset) >> 3);
bitoffset = (32 - state->mainStream.nBit_offset) & 0x7;
SAVE_BITSTREAM(&state->mainStream)
bigvalues = state->si_bigVals[gr][ch] << 1;
if (state->si_address[gr][ch][0] > 0) {
i = state->si_pTableSelect[gr][ch][0];
shift = mp3enc_VLCShifts[i];
offset = mp3enc_VLCOffsets[i];
pVLCEncSpec = (IppsVLCEncodeSpec_32s*)htables[i].phuftable;
len = state->si_address[gr][ch][0] >> 1;
q = pInput;
if (htables[i].linbits == 0) {
for (j = 0; j < len; j++) {
tmp_src[j] = (Ipp16s)((q[0] << shift) + (q[1] + offset));
q += 2;
}
ippsVLCEncodeBlock_16s1u(tmp_src, len,
&pDst, &bitoffset, pVLCEncSpec);
} else
ippsVLCEncodeEscBlock_MP3_16s1u(q, len * 2,
htables[i].linbits,
&pDst, &bitoffset, pVLCEncSpec);
}
if (state->si_address[gr][ch][1] > state->si_address[gr][ch][0]) {
i = state->si_pTableSelect[gr][ch][1];
shift = mp3enc_VLCShifts[i];
offset = mp3enc_VLCOffsets[i];
pVLCEncSpec = (IppsVLCEncodeSpec_32s*)htables[i].phuftable;
len = (state->si_address[gr][ch][1] - state->si_address[gr][ch][0]) >> 1;
q = pInput + state->si_address[gr][ch][0];
if (htables[i].linbits == 0) {
for (j = 0; j < len; j++) {
tmp_src[j] = (Ipp16s)((q[0] << shift) + (q[1] + offset));
q += 2;
}
ippsVLCEncodeBlock_16s1u(tmp_src, len,
&pDst, &bitoffset, pVLCEncSpec);
} else
ippsVLCEncodeEscBlock_MP3_16s1u(q, len * 2,
htables[i].linbits,
&pDst, &bitoffset, pVLCEncSpec);
}
if ((Ipp32u)bigvalues > state->si_address[gr][ch][1]) {
i = state->si_pTableSelect[gr][ch][2];
shift = mp3enc_VLCShifts[i];
offset = mp3enc_VLCOffsets[i];
pVLCEncSpec = (IppsVLCEncodeSpec_32s*)htables[i].phuftable;
len = (bigvalues - state->si_address[gr][ch][1]) >> 1;
q = pInput + state->si_address[gr][ch][1];
if (htables[i].linbits == 0) {
for (j = 0; j < len; j++) {
tmp_src[j] = (Ipp16s)((q[0] << shift) + (q[1] + offset));
q += 2;
}
ippsVLCEncodeBlock_16s1u(tmp_src, len,
&pDst, &bitoffset, pVLCEncSpec);
} else
ippsVLCEncodeEscBlock_MP3_16s1u(q, len * 2,
htables[i].linbits,
&pDst, &bitoffset, pVLCEncSpec);
}
state->mainStream.pCurrent_dword = (Ipp32u*)(pDst - ((Ipp32s)(pDst) & 3));
state->mainStream.nBit_offset = 32 -
((pDst - (Ipp8u*)state->mainStream.pCurrent_dword) << 3) - bitoffset;
LOAD_DWORD(&state->mainStream)
return;
}
/*******************************************************************/
static void mp3enc_huffmanCodeBits(MP3Enc_com *state,
Ipp32s gr,
Ipp32s ch)
{
Ipp32s count1End;
Ipp32s bits, bits_before;
Ipp32s i, bigvalues;
Ipp16s x, y, w, v, p, val, len;
Ipp16s *h;
bigvalues = state->si_bigVals[gr][ch] << 1;
if (bigvalues) {
if (!(state->si_mixedBlock[gr][ch]) && state->si_winSwitch[gr][ch] &&
(state->si_blockType[gr][ch] == 2)) {
GET_BITS_COUNT(&state->mainStream, bits_before)
mp3enc_encodeBigValues(state, state->quant_ix[gr][ch], gr, ch);
GET_BITS_COUNT(&state->mainStream, bits)
bits -= bits_before;
} else if (state->si_mixedBlock[gr][ch] && state->si_blockType[gr][ch] == 2) {
// vm_debug_trace(VM_DEBUG_ALL, VM_STRING("mixed block is not implemented"));
} else {
mp3enc_encodeBigValues(state, state->quant_ix[gr][ch], gr, ch);
}
}
if (state->si_cnt1TabSel[gr][ch])
h = mp3enc_table33;
else
h = mp3enc_table32;
count1End = bigvalues + (state->si_count1[gr][ch] * 4);
for (i = bigvalues; i < count1End; i += 4) {
v = (Ipp16s)abs(state->quant_ix[gr][ch][i]);
w = (Ipp16s)abs(state->quant_ix[gr][ch][i + 1]);
x = (Ipp16s)abs(state->quant_ix[gr][ch][i + 2]);
y = (Ipp16s)abs(state->quant_ix[gr][ch][i + 3]);
p = (v << 3) | (w << 2) | (x << 1) | y;
val = h[3 * p + 2];
len = h[3 * p + 1];
val = (val << v) | ((state->quant_ix[gr][ch][i] < 0) ? 1 : 0);
val = (val << w) | ((state->quant_ix[gr][ch][i + 1] < 0) ? 1 : 0);
val = (val << x) | ((state->quant_ix[gr][ch][i + 2] < 0) ? 1 : 0);
val = (val << y) | ((state->quant_ix[gr][ch][i + 3] < 0) ? 1 : 0);
PutBits(val, len);
}
}
/*******************************************************************/
static Ipp32s mp3enc_encodeHeader(MP3Enc_com *state, sBitsreamBuffer *stream) {
Ipp32s stereo = state->stereo;
state->header.mode = (stereo == 1) ? 0x3 : 0x0;
state->header.modeExt = 0;
if (state->header.layer == 3) {
if (state->stereo_mode == MPA_MS_STEREO) {
state->header.mode = 1;
state->header.modeExt = 2;
}
} else {
if (state->stereo_mode == MPA_JOINT_STEREO) {
state->header.mode = 1;
state->header.modeExt = state->stereo_mode_ext;
}
}
// header
PutBitsDst(stream, 0xfff, 12);
PutBitsDst(stream, state->header.id, 1);
PutBitsDst(stream, (4 - state->header.layer), 2);
PutBitsDst(stream, !state->header.protectionBit, 1);
PutBitsDst(stream, state->header.bitRate, 4);
PutBitsDst(stream, state->header.samplingFreq, 2);
PutBitsDst(stream, state->header.paddingBit, 1);
PutBitsDst(stream, state->header.privateBit, 1);
PutBitsDst(stream, state->header.mode, 2);
PutBitsDst(stream, state->header.modeExt, 2);
PutBitsDst(stream, state->header.copyright, 1);
PutBitsDst(stream, state->header.originalCopy, 1);
PutBitsDst(stream, state->header.emphasis, 2);
if(state->header.protectionBit)
PutBitsDst(stream, 0, 16);
return 0;
}
/*******************************************************************/
void mp3enc_mc_encodeHeader(MP3Enc_com *state, sBitsreamBuffer *stream, Ipp32s *nbits)
{
Ipp32s bits = 16;
PutBitsDst(stream, state->mc_header.ext_bit_stream_present, 1);
if(state->mc_header.ext_bit_stream_present == 1) {
PutBitsDst(stream, state->mc_header.n_ad_bytes, 8);
bits = 24;
}
PutBitsDst(stream, state->mc_header.center, 2);
PutBitsDst(stream, state->mc_header.surround, 2);
PutBitsDst(stream, state->mc_header.lfe, 1);
PutBitsDst(stream, state->mc_header.audio_mix, 1);
PutBitsDst(stream, state->mc_header.dematrix_procedure, 2);
PutBitsDst(stream, state->mc_header.no_of_multi_lingual_ch, 3);
PutBitsDst(stream, state->mc_header.multi_lingual_fs, 1);
PutBitsDst(stream, state->mc_header.multi_lingual_layer, 1);
PutBitsDst(stream, state->mc_header.copyright_identification_bit, 1);
PutBitsDst(stream, state->mc_header.copyright_identification_start, 1);
*nbits = bits;
}
/*******************************************************************/
static void mp3enc_mc_encode_composite_status_info(MP3Enc_com *state, sBitsreamBuffer *stream)
{
Ipp32s i, j;
PutBitsDst(stream, state->mc_tc_sbgr_select, 1);
PutBitsDst(stream, state->mc_dyn_cross_on, 1);
PutBitsDst(stream, state->mc_prediction_on, 1);
if (state->mc_channel_conf == 320 || state->mc_channel_conf == 310)
{
if (state->mc_tc_sbgr_select == 1) {
PutBitsDst(stream, state->mc_tc_allocation, 3);
} else {
for (i = 0; i < 12; i++)
PutBitsDst(stream, state->mc_tc_alloc[i], 3);
}
}
else if (state->mc_channel_conf == 300 || state->mc_channel_conf == 302 ||
state->mc_channel_conf == 220 || state->mc_channel_conf == 210)
{
if (state->mc_tc_sbgr_select == 1) {
PutBitsDst(stream, state->mc_tc_allocation, 2);
} else {
for (i = 0; i < 12; i++)
PutBitsDst(stream, state->mc_tc_alloc[i], 2);
}
}
if (state->mc_dyn_cross_on == 1)
{
PutBitsDst(stream, state->mc_dyn_cross_LR, 1);
for (i = 0; i < 12; i++)
{
if (state->mc_channel_conf) {
PutBitsDst(stream, state->mc_dyn_cross_mode[i], 4);
} else if (state->mc_channel_conf == 310 || state->mc_channel_conf == 220) {
PutBitsDst(stream, state->mc_dyn_cross_mode[i], 3);
} else if (state->mc_channel_conf == 300 || state->mc_channel_conf == 302 || state->mc_channel_conf == 210) {
PutBitsDst(stream, state->mc_dyn_cross_mode[i], 1);
}
if (state->mc_header.surround == 3) {
PutBitsDst(stream, state->mc_dyn_second_stereo[i], 1);
}
}
}
if (state->mc_prediction_on == 1)
{
for(i = 0; i < 8; i++)
{
PutBitsDst(stream, state->mc_prediction[i], 1);
if (state->mc_prediction[i] == 1)
{
Ipp32s val;
val = mp3_mc_pred_coef_table[state->mc_pred_mode][state->mc_dyn_cross_mode[i]];
for (j = 0; j < val; j++) {
PutBitsDst(stream, state->mc_predsi[i][j], 2);
}
}
}
}
}
/*******************************************************************/
Ipp32s mp3enc_mc_trans_channel(MP3Enc_com *state, Ipp32s sbgr, Ipp32s ch)
{
Ipp32s tca = state->mc_tc_alloc[sbgr];
if (state->mc_channel_conf == 320)
return mp3enc_trans_channel_5[ch][tca];
else if (state->mc_channel_conf == 310)
return mp3enc_trans_channel_4a[ch][tca];
else if (state->mc_channel_conf == 220)
return mp3enc_trans_channel_4b[ch][tca];
else if (state->mc_channel_conf == 300 ||
state->mc_channel_conf == 302 || state->mc_channel_conf == 210)
return mp3enc_trans_channel_3[ch][tca];
else
return ch;
}
/*******************************************************************/
static Ipp32s mp3enc_mc_dyn_channel (MP3Enc_com *state, Ipp32s sbgr, Ipp32s ch)
{
Ipp32s dyn_cross = state->mc_dyn_cross_mode[sbgr];
Ipp32s dyn_2stereo = state->mc_dyn_second_stereo[sbgr];
if (state->mc_channel_conf == 320)
return mp3enc_dyn_channel_4[ch-2][dyn_cross];
else if (state->mc_channel_conf == 310 ||
state->mc_channel_conf == 220)
return mp3enc_dyn_channel_3[ch-2][dyn_cross];
else if (state->mc_channel_conf == 300 ||
state->mc_channel_conf == 302 ||
state->mc_channel_conf == 210)
{
if (state->mc_channel_conf == 302 && dyn_2stereo && ch == 4)
return 0;
else
return mp3enc_dyn_channel_1[ch-2][dyn_cross];
}
else if (state->mc_channel_conf == 202 && dyn_2stereo && ch == 3)
return 0;
else if (state->mc_channel_conf == 102 && dyn_2stereo && ch == 2)
return 0;
else
return 1;
}
/*******************************************************************/
static void mp3enc_mc_encode_bit_alloc(MP3Enc_com *state,
sBitsreamBuffer *stream)
{
Ipp32s i, k, l, m, n;
Ipp32s stereo = state->stereo;
Ipp32s stereomc = state->mc_channel;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -