📄 mpeg3dec.c
字号:
/*------------------------------------------------------------------------------ File : MPEG3DEC.c Author : St閜hane TAVENARD $VER: MPEG3DEC.c 1.1 (24/05/1999) (C) Copyright 1997-1999 St閜hane TAVENARD All Rights Reserved This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #Rev| Date | Comment ----|----------|-------------------------------------------------------- 0 |15/03/1997| Initial revision ST 1 |31/03/1997| First aminet release ST 2 |13/05/1997| Fixed bug in imdct_number ST 3 |23/05/1997| Added MPEGDEC_ERR_xxx ST 4 |27/05/1997| Added MPEGIMDCT ST 5 |05/06/1997| FPU Optimized version ST 6 |07/06/1997| Use now BSTR_read_bytes & HUFF_fill_bytes ST 7 |08/07/1997| Optimized dequantization for INT arithmetic ST 8 |13/07/1997| Optimized mono_forced decoding ST 9 |14/07/1997| Optimized stereo function with nul bands ST 10 |14/07/1997| Added MPEG3_get_nul_pos, optimized dequantization ST 11 |24/05/1999| Suppressed all static vars to allow multi-decoding ST ------------------------------------------------------------------------ MPEG layer III decoding functions------------------------------------------------------------------------------*/#include <stdio.h>#include "defs.h"#include "bitstr.h"#include "mpegaud.h"#include "mpegtab.h"#include "mpegsub.h"#include "mpegimdc.h" // #4#if defined(ASM_OPTIMIZE) || defined(COLDFIRE_ASM_2)#ifdef MPEGAUD_INT#include "mpegsubb.h"#else#include "mpegsubf.h" // #5#endif#endif#include "mpegdec.h"#include "mpeg3dec.h"#include <math.h>#ifdef USE_RC4#include "rc4.h"#endifstatic int MPEG3_main_data_slots( MPA_STREAM *mps )/*-------------------------------------------------------------------------- Return the main data slots of current MPEG III frame*/{ INT32 slots; MPA_HEADER *h = &mps->header; slots = ( 144000 * mps->bitrate ) / mps->sfreq; if( h->ID == MPA_ID_1 ) { // MPEG1 if( mps->stereo ) slots -= 36; else slots -= 21; } else { // MPEG2 slots >>= 1; if( mps->stereo ) slots -= 21; else slots -= 13; } if( h->padding_bit ) slots++; if( h->protection_bit ) slots -= 2; return slots;} /* MPEG3_main_data_slots */static int MPEG3_decode_side_info( MPA_STREAM *mps )/*-------------------------------------------------------------------------- Decode the sideo info of MPEG III stream Return 0 if Ok*/{ BITSTREAM *bs = mps->bitstream; MPA_SIDE_INFO *si = &mps->side_info; UINT16 ch, i, gr; UINT16 gr_max, scf; if( mps->header.ID == MPA_ID_1 ) { // MPEG1 gr_max = MPA_MAX_GRANULES; scf = 4; si->main_data_begin = BSTR_read_bits( bs, 9 ); if( mps->stereo ) si->private_bits = BSTR_read_bits( bs, 3 ); else si->private_bits = BSTR_read_bits( bs, 5 ); for( ch=0; ch<mps->channels; ch++ ) { for( i=0; i<4; i++ ) si->ch[ ch ].scfsi[ i ] = BSTR_read_bit( bs ); } } else { // MPEG2 - LSF gr_max = 1; scf = 9; si->main_data_begin = BSTR_read_bits( bs, 8 ); if( mps->stereo ) si->private_bits = BSTR_read_bits( bs, 2 ); else si->private_bits = BSTR_read_bits( bs, 1 ); }MPEGAUD_CHECK_DEMO; for( gr=0; gr<gr_max; gr++ ) { for( ch=0; ch<mps->channels; ch++ ) { MPA_GRANULE_INFO *gi = &si->ch[ ch ].gr[ gr ]; gi->part2_3_length = BSTR_read_bits( bs, 12 ); gi->big_values = BSTR_read_bits( bs, 9 ); gi->global_gain = BSTR_read_bits( bs, 8 ); gi->scalefac_compress = BSTR_read_bits( bs, scf ); gi->window_switching_flag = BSTR_read_bit( bs );#if 0 printf("gi->part2_3_length: %08x\n", gi->part2_3_length); printf("gi->big_values: %08x\n", gi->big_values); printf("gi->global_gain: %08x\n", gi->global_gain); printf("gi->scalefac_compress: %08x\n", gi->scalefac_compress); printf("gi->window_switching_flag: %08x\n", gi->window_switching_flag);#endif if( gi->window_switching_flag ) { gi->block_type = BSTR_read_bits( bs, 2 ); gi->mixed_block_flag = BSTR_read_bit( bs ); for( i=0; i<2; i++ ) gi->table_select[ i ] = BSTR_read_bits( bs, 5 ); for( i=0; i<3; i++ ) gi->subblock_gain[ i ] = BSTR_read_bits( bs, 3 ); // Implicit regionX_count parameters setting if( (gi->block_type == 2) && (!gi->mixed_block_flag) ) gi->region0_count = 8; else gi->region0_count = 7; gi->region1_count = 20 - gi->region0_count; } else { for( i=0; i<3; i++ ) gi->table_select[ i ] = BSTR_read_bits( bs, 5 ); gi->region0_count = BSTR_read_bits( bs, 4 ); gi->region1_count = BSTR_read_bits( bs, 3 ); gi->block_type = 0; } if( mps->header.ID == MPA_ID_1 ) gi->preflag = BSTR_read_bit( bs ); gi->scalefac_scale = BSTR_read_bit( bs ); gi->count1table_select = BSTR_read_bit( bs ); } }MPEGAUD_CHECK_DEMO; return MPEGDEC_ERR_NONE;} /* MPEG3_decode_side_info */static const INT16 slen[ 2 ][ 16 ] = { {0, 0, 0, 0, 3, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4}, {0, 1, 2, 3, 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 3}};static int MPEG3_decode_scale1( MPA_STREAM *mps, INT16 gr, INT16 ch )/*-------------------------------------------------------------------------- Decode the scales of MPEG1-III stream Return 0 if Ok*/{ INT16 sfb, win; MPA_GRANULE_INFO *gi = &mps->side_info.ch[ ch ].gr[ gr ]; MPA_SCALE_FAC3 *sf = &mps->scale_fac3[ ch ]; HUFFMAN *h = mps->huffman; INT16 slen1 = slen[ 0 ][ gi->scalefac_compress ]; INT16 slen2 = slen[ 1 ][ gi->scalefac_compress ]; if( (gi->window_switching_flag) && (gi->block_type == 2) ) { if( gi->mixed_block_flag ) { // Mixed block for( sfb=0; sfb<8; sfb++ ) sf->l[ sfb ] = HUFF_read_bits( h, slen1 ); for( sfb=3; sfb<6; sfb++ ) for( win=0; win<3; win++ ) sf->s[ win ][ sfb ] = HUFF_read_bits( h, slen1 ); for( sfb=6; sfb<12; sfb++ ) for( win=0; win<3; win++ ) sf->s[ win ][ sfb ] = HUFF_read_bits( h, slen2 ); sf->s[ 0 ][ 12 ] = sf->s[ 1 ][ 12 ] = sf->s[ 2 ][ 12 ] = 0; } else { // Short blocks for( sfb=0; sfb<6; sfb++ ) for( win=0; win<3; win++ ) sf->s[ win ][ sfb ] = HUFF_read_bits( h, slen1 ); for( sfb=6; sfb<12; sfb++ ) for( win=0; win<3; win++ ) sf->s[ win ][ sfb ] = HUFF_read_bits( h, slen2 ); sf->s[ 0 ][ 12 ] = sf->s[ 1 ][ 12 ] = sf->s[ 2 ][ 12 ] = 0; } } else { // Long blocks 0, 1 or 3 if( (mps->side_info.ch[ ch ].scfsi[ 0 ] == 0) || (gr == 0) ) { for( sfb = 0; sfb < 6; sfb++ ) sf->l[ sfb ] = HUFF_read_bits( h, slen1 ); } if( (mps->side_info.ch[ ch ].scfsi[ 1 ] == 0) || (gr == 0) ) { for( sfb = 6; sfb < 11; sfb++ ) sf->l[ sfb ] = HUFF_read_bits( h, slen1 ); } if( (mps->side_info.ch[ ch ].scfsi[ 2 ] == 0) || (gr == 0) ) { for( sfb = 11; sfb < 16; sfb++ ) sf->l[ sfb ] = HUFF_read_bits( h, slen2 ); } if( (mps->side_info.ch[ ch ].scfsi[ 3 ] == 0) || (gr == 0) ) { for( sfb = 16; sfb < 21; sfb++ ) sf->l[ sfb ] = HUFF_read_bits( h, slen2 ); } sf->l[ 21 ] = sf->l[ 22 ] = 0; }MPEGAUD_CHECK_DEMO; return MPEGDEC_ERR_NONE;} /* MPEG3_decode_scale1 */static const INT16 sfb_bt[ 6 ][ 3 ][ 4 ] = { { {6, 5, 5, 5}, {9, 9, 9, 9}, {6, 9, 9, 9} }, { {6, 5, 7, 3}, {9, 9, 12, 6}, {6, 9, 12, 6} }, { {11, 10, 0, 0}, {18, 18, 0, 0}, {15, 18, 0, 0} }, { {7, 7, 7, 0}, {12, 12, 12, 0}, {6, 15, 12, 0} }, { {6, 6, 6, 3}, {12, 9, 9, 6}, {6, 12, 9, 6} }, { {8, 8, 5, 0}, {15, 12, 9, 0}, {6, 18, 9, 0} }};static int MPEG3_decode_scale2( MPA_STREAM *mps, INT16 gr, INT16 ch )/*-------------------------------------------------------------------------- Decode the scales of MPEG2-III stream Return 0 if Ok*/{ INT16 i, j, k, sfb, win; MPA_GRANULE_INFO *gi = &mps->side_info.ch[ ch ].gr[ gr ]; MPA_SCALE_FAC3 *sf = &mps->scale_fac3[ ch ]; HUFFMAN *h = mps->huffman; INT16 block_type_number, block_number; INT16 slen[ 4 ]; INT16 sfb_nb, len; INT16 scalefac[ 36 ]; /* #11 suppressed static */ INT16 is_max[ 36 ]; /* #11 suppressed static *///memset( sf, 0, sizeof( MPA_SCALE_FAC3 ) ); block_type_number = 0; if( gi->block_type == 2 ) block_type_number = (gi->mixed_block_flag)?2:1;MPEGAUD_CHECK_DEMO; if( ( (mps->header.mode_extension == 1) || (mps->header.mode_extension == 3) ) && ( ch == 1 ) ) { INT16 int_scalefac_comp = gi->scalefac_compress >> 1; if( int_scalefac_comp < 180 ) { slen[ 0 ] = int_scalefac_comp / 36 ; slen[ 1 ] = (INT16)(int_scalefac_comp % 36) / 6; slen[ 2 ] = (INT16)(int_scalefac_comp % 36) % 6; slen[ 3 ] = 0; gi->preflag = 0; block_number = 3; } else if( int_scalefac_comp < 244 ) { slen[ 0 ] = ((INT16)(int_scalefac_comp - 180) % 64) >> 4; slen[ 1 ] = ((INT16)(int_scalefac_comp - 180) % 16) >> 2; slen[ 2 ] = (INT16)(int_scalefac_comp - 180) % 4; slen[ 3 ] = 0; gi->preflag = 0; block_number = 4; } else { slen[ 0 ] = (INT16)(int_scalefac_comp - 244) / 3; slen[ 1 ] = (INT16)(int_scalefac_comp - 244) % 3; slen[ 2 ] = 0 ; slen[ 3 ] = 0; gi->preflag = 0; block_number = 5; } } else { INT16 scalefac_comp = gi->scalefac_compress; if( scalefac_comp < 400 ) { slen[ 0 ] = (INT16)(scalefac_comp >> 4) / 5; slen[ 1 ] = (INT16)(scalefac_comp >> 4) % 5; slen[ 2 ] = (INT16)(scalefac_comp % 16) >> 2; slen[ 3 ] = (INT16)(scalefac_comp % 4); gi->preflag = 0; block_number = 0; } else if( scalefac_comp < 500 ) { slen[ 0 ] = ((INT16)(scalefac_comp - 400) >> 2) / 5; slen[ 1 ] = ((INT16)(scalefac_comp - 400) >> 2) % 5; slen[ 2 ] = (INT16)(scalefac_comp - 400) % 4; slen[ 3 ] = 0; gi->preflag = 0; block_number = 1; } else { slen[ 0 ] = (INT16)(scalefac_comp - 500) / 3; slen[ 1 ] = (INT16)(scalefac_comp - 500) % 3; slen[ 2 ] = 0; slen[ 3 ] = 0; gi->preflag = 1; block_number = 2; } } k = 0; for( i=0; i<4; i++ ) { sfb_nb = sfb_bt[ block_number ][ block_type_number ][ i ]; len = slen[ i ]; if( len ) { for( j=0; j<sfb_nb; j++ ) { scalefac[ k ] = HUFF_read_bits( h, len ); is_max[ k++ ] = (1<<len) - 1; } } else { for( j=0; j<sfb_nb; j++ ) { scalefac[ k ] = 0; is_max[ k++ ] = 0; } } } while( k < 36 ) scalefac[ k++ ] = 0; k = 0;MPEGAUD_CHECK_DEMO; if( (gi->window_switching_flag) && (gi->block_type == 2) ) { if( gi->mixed_block_flag ) { // Mixed block// *** WARNING// *** WARNING sfb<8 seems to be inexact, sfb<6 seems to be ok (? NO, conform to ISO/IEC)// *** WARNING for( sfb=0; sfb<6; sfb++ ) { sf->l[ sfb ] = scalefac[ k ]; mps->is_max_l[ sfb ] = is_max[ k++ ]; } for( sfb=3; sfb<12; sfb++ ) { for( win=0; win<3; win++ ) { sf->s[ win ][ sfb ] = scalefac[ k ]; mps->is_max_s[ win ][ sfb ] = is_max[ k++ ]; } } sf->s[ 0 ][ 12 ] = sf->s[ 1 ][ 12 ] = sf->s[ 2 ][ 12 ] = 0; } else { // Short blocks for( sfb=0; sfb<12; sfb++ ) { for( win=0; win<3; win++ ) { sf->s[ win ][ sfb ] = scalefac[ k ]; mps->is_max_s[ win ][ sfb ] = is_max[ k++ ]; } } sf->s[ 0 ][ 12 ] = sf->s[ 1 ][ 12 ] = sf->s[ 2 ][ 12 ] = 0; } } else { // Long blocks 0, 1 or 3 for( sfb=0; sfb<21; sfb++ ) { sf->l[ sfb ] = scalefac[ k ]; mps->is_max_l[ sfb ] = is_max[ k++ ]; } sf->l[ 21 ] = sf->l[ 22 ] = 0; } return MPEGDEC_ERR_NONE;} /* MPEG3_decode_scale2 */// Note: o
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -