📄 mpeg3dec.c
字号:
xrp1++; } } else { // ispos != is_illegal k0 = pow_iok0[ispos]; while (sb--) { *xrp0 = ST_MULT(*xrp0, k0); xrp0++; } } sfb++; } } if (gi->mixed_block_flag) { INT16 sfb_max = (lsf) ? 6 : 8; xrp0 = xr; xrp1 = &xr[MPA_GRANULE_SIZE]; if (max_sfb <= 3) { // Top of nul bands in long blocks sfb = mps->sfb_nul_l[1]; // Begin of nul bands } else { sfb = sfb_max; // Begin of nul band not in long blocks } sb = band_l[sfb]; // Implicit: ispos == is_illegal here (not nul bands) if (ms_stereo) while (sb--) { *xrp0 = ST_MULT((*xrp0 + *xrp1), sq2); xrp0++; xrp1++; } else { xrp0 += sb; xrp1 += sb; } for (; sfb < sfb_max; sfb++) { sb = band_l[sfb + 1] - band_l[sfb]; ispos = sf->l[sfb]; is_illegal = (lsf) ? mps-> is_max_l[sfb] : 7; if (ispos == is_illegal) { if (ms_stereo) while (sb--) { *xrp0 = ST_MULT((*xrp0 + *xrp1), sq2); xrp0++; xrp1++; } else { xrp0 += sb; xrp1 += sb; } } else { // ispos != is_illegal k0 = pow_iok0[ispos]; xrp1 += sb; while (sb--) { *xrp0 = ST_MULT(*xrp0, k0); xrp0++; } } } } } else { // Long blocks, intensity stereo sbmax = mps->sfb_nul_l[0]; if (sbmax < mps->sfb_nul_l[1]) sbmax = mps->sfb_nul_l[1]; sbmax++; if (sbmax > 22) sbmax = 22; xrp0 = xr; xrp1 = &xr[MPA_GRANULE_SIZE]; sfb = mps->sfb_nul_l[1]; // Begin of nul bands sb = band_l[sfb]; is_illegal = (lsf) ? mps->is_max_l[0] : 7; // Implicit: ispos == is_illegal here (not nul bands) ispos = is_illegal; if (ms_stereo) while (sb--) { *xrp0 = ST_MULT((*xrp0 + *xrp1), sq2); xrp0++; xrp1++; } else { xrp0 += sb; xrp1 += sb; } for (; sfb < sbmax; sfb++) { // #9: sbmax instead of 22 sb = band_l[sfb + 1] - band_l[sfb]; if (sfb < 21) { // keep previous ispos for last sfb ispos = sf->l[sfb]; is_illegal = (lsf) ? mps-> is_max_l[sfb] : 7; } if (ispos == is_illegal) { if (ms_stereo) while (sb--) { *xrp0 = ST_MULT((*xrp0 + *xrp1), sq2); xrp0++; xrp1++; } else { xrp0 += sb; xrp1 += sb; } } else { // ispos != is_illegal k0 = pow_iok0[ispos]; xrp1 += sb; while (sb--) { *xrp0 = ST_MULT(*xrp0, k0); xrp0++; } } } } } else if ((mps->stereo) && ms_stereo) { // MS stereo xrp0 = xr; xrp1 = &xr[MPA_GRANULE_SIZE]; sb = mps->imdct_max[0]; if (sb < mps->imdct_max[1]) sb = mps->imdct_max[1]; sb = (INT16) (sb + 1) * MPA_SSLIMIT; if (sb > MPA_GRANULE_SIZE) sb = MPA_GRANULE_SIZE; while (sb--) { *xrp0 = ST_MULT((*xrp0 + *xrp1), sq2); xrp0++; xrp1++; } } else { //Normal stereo or mono -> nothing to do ! } return(MPEGDEC_ERR_NONE);}/****************************************************************************//* * Reorder a granule (block type 2) * Return 0 if Ok*/static int MPEG3_reorder(MPA_STREAM *mps, MPEGAUD_FRACT_TYPE *xr, MPEGAUD_FRACT_TYPE *ro, INT16 gr, INT16 ch){ MPA_GRANULE_INFO *gi = &mps->side_info.ch[ch].gr[gr]; register MPEGAUD_FRACT_TYPE *pro; register MPEGAUD_FRACT_TYPE *pxr0, *pxr1, *pxr2; const INT16 *sfbindex; INT16 sfb, freq; INT16 sfb_start, sfb_lines; // In ISO/IEC 11172-3 window_switching_flag is set if window type <> 0 // so, must be set if gi->block_type == 2 ! if (gi->window_switching_flag && (gi->block_type == 2)) { pro = ro; pxr2 = xr; sfbindex = sfBandIndex_s[mps->header.ID][mps->header.sampling_frequency]; sfb = 13; if (gi->mixed_block_flag) { // No Reorder for the 2 first subbands freq = (2 * MPA_SSLIMIT); while (freq--) *pro++ = *pxr2++; sfb -= 3; sfbindex += 3; } while (sfb--) { sfb_start = *sfbindex++; sfb_lines = *sfbindex - sfb_start; pxr0 = pxr2; pxr1 = pxr0 + sfb_lines; pxr2 = pxr1 + sfb_lines; freq = sfb_lines; while (freq--) { *pro++ = *pxr0++; *pro++ = *pxr1++; *pro++ = *pxr2++; } } } else { // Long blocks are in good order memcpy(ro, xr, MPA_GRANULE_SIZE * sizeof(MPEGAUD_FRACT_TYPE)); } return(MPEGDEC_ERR_NONE);}/****************************************************************************/#ifdef MPEGAUD_INT#define ALIAS_TYPE INT16#define ALIAS_BITS 15#define ALIAS_MULT(bu, cx) (((bu) * (cx))>>(ALIAS_BITS))#else#define ALIAS_TYPE REAL#define ALIAS_MULT(bu, cx) ((bu) * (cx))#endif/****************************************************************************//* * Apply the antialiasing buterfflies on a granule * Return 0 if Ok */static int MPEG3_antialias(MPA_STREAM *mps, MPEGAUD_FRACT_TYPE *xr, INT16 gr, INT16 ch, INT16 sb_max){ MPA_GRANULE_INFO *gi = &mps->side_info.ch[ch].gr[gr];#ifdef MPEGAUD_INT // Pre-calc tables for ALIAS_BITS=15 static const ALIAS_TYPE ca[8] = { -16858, -15457, -10268, -5960, -3099, -1342, -465, -121, }; static const ALIAS_TYPE cs[8] = { 28098, 28892, 31117, 32221, 32621, 32740, 32764, 32767, };#else static const ALIAS_TYPE ca[8] = { -0.514495730, -0.471731961, -0.313377440, -0.181913197, -0.094574191, -0.040965579, -0.014198568, -0.003699975, }; static const ALIAS_TYPE cs[8] = { 0.857492924, 0.881741941, 0.949628592, 0.983314574, 0.995517790, 0.999160528, 0.999899149, 0.999993145, };#endif INT16 sb, ss, i; MPEGAUD_FRACT_TYPE *bu, *bd; // upper and lower butterfly inputs const ALIAS_TYPE *csi, *cai; MPEGAUD_FRACT_TYPE obu; // temp butterfly output INT16 sblim; if (gi->window_switching_flag && (gi->block_type == 2)) { if (!gi->mixed_block_flag) return(MPEGDEC_ERR_NONE); sblim = 1; } else { sblim = sb_max - 1; }#ifdef ASM_OPTIMIZE#ifndef MOV_FUNC MPEGSUBB_antialias( xr, sblim );#else MPEGSUBB_antialias_cp( xr, sblim );#endif#else i = MPA_SSLIMIT - 1; for (sb = 0; sb < sblim; sb++) { bu = &xr[i]; bd = bu + 1; i += MPA_SSLIMIT; csi = cs; cai = ca; for (ss = 0; ss < 8; ss++) { obu = ALIAS_MULT(*bu, *csi) - ALIAS_MULT(*bd, *cai); *bd = ALIAS_MULT(*bd, *csi) + ALIAS_MULT(*bu, *cai); *bu = obu; csi++; cai++; bd++; bu--; } }#endif return(MPEGDEC_ERR_NONE);}/****************************************************************************//* * Reset the decoder */int MPEG3_reset(MPA_STREAM *mps){ // Reset the huffman decoder return(HUFF_reset(mps->huffman));}/****************************************************************************//* * Decode the current frame * Return # of decoded samples */DEFINE_TIME;INT32 MPEG3_decode_frame(MPA_STREAM *mps){ INT16 max_gr, gr, ch; int slots; BITSTREAM *bs = mps->bitstream; HUFFMAN *h = mps->huffman; register char byte; int status; int start, seek_pos; INT16 pcm_offset[2]; INT16 sb_max; INT16 channels = (mps->force_mono) ? 1 : mps->channels; int err;#define ERR_CHECK(i) \ err = i;\ if (err) { \ printf("Error %d in decode_frame\n", i); \ return(err); \ } START_TIME(0, "Before main loop"); ERR_CHECK(MPEG3_decode_side_info(mps)); status = HUFF_set_start(h, mps->side_info.main_data_begin); slots = MPEG3_main_data_slots(mps); { // 1440 is the max theorical value for layer III int i; //char buffer[1440]; SRAM_BUF(buffer, 1440); while (slots > 0) { i = (slots > 1440) ? 1440 : slots; BSTR_read_bytes(bs, slots, buffer);#ifdef USE_RC4 if (mps->header.private_bit) { if (mps->keyp == NULL) return(-1); RC4(mps->keyp, slots, buffer, buffer); }#endif HUFF_fill_bytes(h, slots, buffer); slots -= i; } } if (BSTR_end(bs)) return(MPEGDEC_ERR_EOF); if (status) { // Can't decode this frame (not enough data) // printf("Can't decode this frame (not enough data)\n"); return(0); } max_gr = (mps->header.ID == MPA_ID_1) ? 2 : 1; pcm_offset[0] = pcm_offset[1] = 0; seek_pos = HUFF_pos(h); ELAP_TIME(0); for (gr = 0; gr < max_gr; gr++) { START_TIME(1, "Huffman & Dequantization"); for (ch = 0; ch < mps->channels; ch++) { // WE HAVE TO SEEK IN HUFFMAN DATA // use part2_3_length of each granule START_TIME(20, "Huffman"); HUFF_seek(h, seek_pos); start = HUFF_pos(h); // calculate next seek position with actual part2_3_length seek_pos += mps->side_info.ch[ch].gr[gr].part2_3_length; if (mps->header.ID == MPA_ID_1) { ERR_CHECK(MPEG3_decode_scale1(mps, gr, ch)); } else { ERR_CHECK(MPEG3_decode_scale2(mps, gr, ch)); } ERR_CHECK(MPEG3_huffman_decode (mps, mps->is, gr, ch, start)); MPEG3_get_nul_pos(mps, mps->is, gr, ch); ELAP_TIME(20); START_TIME(21, "Dequantization"); ERR_CHECK(MPEG3_dequantize_samples (mps, mps->is, &mps->xr[ch][0], gr, ch)); ELAP_TIME(21); } ELAP_TIME(1); START_TIME(2,"MPEG3_stereo_mono"); if (channels == 2) {#ifndef MOV_FUNC ERR_CHECK(MPEG3_stereo(mps, &mps->xr[0][0], gr));#else ERR_CHECK(MPEG3_stereo_cp(mps, &mps->xr[0][0], gr));#endif } else if ((channels == 1) && (mps->channels == 2)) { ERR_CHECK(MPEG3_stereo_mono(mps, &mps->xr[0][0], gr)); } ELAP_TIME(2); for (ch = 0; ch < channels; ch++) { INT16 ss; MPEGAUD_FRACT_TYPE *sub; INT16 *pcm; sb_max = mps->imdct_max[ch]; pcm = mps->pcm[ch]; START_TIME(3, "IMDCT"); if (mps->side_info.ch[ch].gr[gr].window_switching_flag && (mps->side_info.ch[ch].gr[gr].block_type == 2)) { START_TIME(40, "MPEG3_reorder"); ERR_CHECK(MPEG3_reorder(mps, &mps->xr[ch][0], &mps->lr[0][0], gr, ch)); ELAP_TIME(40); START_TIME(41, "MPEG3_antialias"); ERR_CHECK(MPEG3_antialias(mps, &mps->lr[0][0], gr, ch, sb_max)); ELAP_TIME(41); sub = &mps->lr[1][0]; START_TIME(42, "MPEGIMDCT_hybrid"); MPEGIMDCT_hybrid(mps->mpegimdct, &mps->lr[0][0], sub, mps->side_info.ch[ch].gr[gr].block_type, (BOOL) mps->side_info.ch[ch].gr[gr].mixed_block_flag, ch, sb_max); ELAP_TIME(42); } else { START_TIME(41, "MPEG3_antialias"); ERR_CHECK(MPEG3_antialias(mps, &mps->xr[ch][0], gr, ch, sb_max)); ELAP_TIME(41); START_TIME(42, "MPEGIMDCT_hybrid"); sub = &mps->lr[1][0]; MPEGIMDCT_hybrid(mps->mpegimdct, &mps->xr[ch][0], sub, mps->side_info.ch[ch].gr[gr].block_type, (BOOL) mps->side_info.ch[ch].gr[gr].mixed_block_flag, ch, sb_max); ELAP_TIME(42); } ELAP_TIME(3); START_TIME(4, "Synthesis"); for (ss = 0; ss < MPA_SSLIMIT; ss++) { pcm_offset[ch] += MPEGSUB_synthesis( mps->mpegsub, sub, ch, &pcm[pcm_offset[ch]]); sub += MPA_SBLIMIT; } ELAP_TIME(4); } } START_TIME(5,"After main loop"); HUFF_seek(h, seek_pos); ELAP_TIME(5); return((INT32) pcm_offset[0]);}/****************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -