www.pudn.com > av3dec_20050318.zip > specrec.c


/* 
*********************************************************************** 
* COPYRIGHT AND WARRANTY INFORMATION 
* 
* Copyright 2004,  Audio Video Coding Standard, Part III 
* 
* This software module was originally developed by 
 
* Lei Miao (win.miaolei@samsung.com), Samsung AIT 
 
* edited by 
* 
* Lei Miao, fill data embedded, 2005-03-16 
* 
* DISCLAIMER OF WARRANTY 
* 
* These software programs are available to the users without any 
* license fee or royalty on an "as is" basis. The AVS disclaims 
* any and all warranties, whether express, implied, or statutory, 
* including any implied warranties of merchantability or of fitness 
* for a particular purpose. In no event shall the contributors or  
* the AVS be liable for any incidental, punitive, or consequential 
* damages of any kind whatsoever arising from the use of this program. 
* 
* This disclaimer of warranty extends to the user of this program 
* and user's customers, employees, agents, transferees, successors, 
* and assigns. 
* 
* The AVS does not represent or warrant that the program furnished 
* hereunder are free of infringement of any third-party patents. 
* Commercial implementations of AVS, including shareware, may be 
* subject to royalty fees to patent holders. Information regarding 
* the AVS patent policy is available from the AVS Web site at 
* http://www.avs.org.cn 
* 
* THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE AVS PATENT POLICY. 
************************************************************************ 
*/ 
#include  
#include  
#include  
#include  
 
#include "common.h" 
#include "av3dec.h" 
#include "intMDCT.h" 
#include "polar.h" 
#include "sam_decode.h" 
 
int frameCount; 
 
void sam_decode(int target, char OutName[], int fformat, FILE *fpinfo, AV3DecFrameInfo* hDecoder) 
{ 
	int				i, j, ch, nch; 
	int				used_bits; 
	int				stereo_mode; 
	int				fsize_len; 
	int				common_window; 
 
	int				Sfreq, SfreqIdx; 
	int				FLflag; 
 
	int				frameLength; 
	int				enc_top_layer; 
	int				base_snf; 
	int				base_band; 
 
	int				ics_reserved; 
	int				windowSequence[2], windowShape[2]; 
	int				maxSfb[2]; 
	int				groupInfo[2][7]; 
 
	int				num_window_groups; 
	int				window_group_length[8]; 
 
	int				swb_offset_long[60]; 
	int				swb_offset_short[20]; 
	int				ps_mask[130]; 
	 
 
	int				samples[2][FRAMESIZE]; 
	int				scalefactors[2][8][MAX_SCFAC_BANDS]; 
	Float			spectrums[2][FRAMESIZE]; 
	float			pcmOut[2][FRAMESIZE]; 
	float			pcmOverlap[2][FRAMESIZE]; 
	int				frameStart; 
	static int		FirstTime; 
 
 
	AFILE			*AFpO; 
	float			*OutBuff; 
	char	av3fileHeader[4]; 
 
	/* fill element variables */ 
	int fill_enable; 
	int fill_length=0; 
	int fill_type=0; 
 
	frameCount = 0; 
	frameStart = 0; 
 
	///////////////////////////////////////////////////////// 
	//                CBC   FRAME   HEADER                // 
	///////////////////////////////////////////////////////// 
	av3fileHeader[0] = (char)sam_getbits(8); 
	av3fileHeader[1] = (char)sam_getbits(8); 
	av3fileHeader[2] = (char)sam_getbits(8); 
	av3fileHeader[3] = (char)sam_getbits(8); 
 
	if(av3fileHeader[0]!='A' && av3fileHeader[1]!='V' && av3fileHeader[2]!='S' && av3fileHeader[3]!='3') 
	{ 
		fprintf(stderr,"\nerror in open av3 file.\n"); 
		return; 
	} 
 
	nch   = sam_getbits(4); 
	SfreqIdx  = sam_getbits(4); 
 
	Sfreq = sam_init_cbc(SfreqIdx); 
  
	cbc_swboffset_for_polarstereo(swb_offset_long, swb_offset_short, SfreqIdx); 
 
	AFpO = AFopenWrite(OutName, fformat, nch, (float)Sfreq, fpinfo); 
 
    OutBuff = (float *)av3_malloc(FRAMESIZE*nch*sizeof(float)); 
	fprintf(fpinfo, "\nOutput file name: %s\n", OutName); 
	//fprintf(fpinfo, "Decoding Bitrate: %d kbps/ch\n", target); 
 
	/////////////////////////////////////////////////////// 
	//                main decoding loop                 // 
	////////////////////////////////////////////////////// 
	while (!sam_end_bs()) { 
		/* initialize variables*/ 
		for (i = 0; i < 120; i++) { 
			ps_mask[i] = 0;		 
 
			for (j = 0; j < 8; j++) { 
				scalefactors[0][j][i] = 0; 
				scalefactors[1][j][i] = 0; 
			} 
		} 
		stereo_mode = 0; 
	 
		fsize_len = 11; 
		common_window = 0; 
		if (nch != 1) 
			common_window = 1; 
 
		frameStart = i_sstell(); 
		 
		///////////////////////////////////////////////////////// 
		//            CBC   GLOBAL  HEADER                    // 
		///////////////////////////////////////////////////////// 
		/*frame length*/ 
		frameLength = sam_getbits(fsize_len) * 8; 
 
		if (frameLength == 0) { 
			fprintf(fpinfo, "end of bitstream\n"); 
			break; 
		} 
		 
		/*top layer index*/ 
		enc_top_layer = sam_getbits(6); 
 
		if(!FirstTime) 
		{ 
			if((enc_top_layer+16) != 64) 
			{ 
				if((target == 64) || (target > (enc_top_layer+16))) 
					target = enc_top_layer+16; 
			} 
			fprintf(fpinfo, "Decoding Bitrate: %d kbps/ch\n", target); 
			FirstTime = 1; 
		} 
 
		/*base_snf*/ 
		base_snf = sam_getbits(2) + 1; 
 
		/*base band*/ 
		base_band = sam_getbits(5); 
 
		/*ics_reserved_bit*/ 
		ics_reserved = sam_getbits(1);  
 
		for (ch = 0; ch < nch; ch++) 
			scalefactors[ch][0][0] = sam_getbits(8); 
 
		/*window sequence*/ 
		windowSequence[0] = sam_getbits(2);  
 
		/*window shape*/ 
		windowShape[0] = sam_getbits(1);  
 
		num_window_groups = 1; 
		window_group_length[0] = 1; 
		siCodeMode = 0; 
		if (windowSequence[0] == EIGHT_SHORT_SEQUENCE) { 
			maxSfb[0] = sam_getbits(4); 
       
			for (i = 0; i < 7; i++) { 
          		groupInfo[0][i] =  sam_getbits(1);  
		  		if (groupInfo[0][i] == 0) { 
					window_group_length[num_window_groups] = 1; 
					num_window_groups++; 
		  		}  
				else 
					window_group_length[num_window_groups-1]++; 
			} 
			siCodeMode = sam_getbits(1); 
		}  
		else			             
			maxSfb[0] = sam_getbits(6); 
 
		if (nch == 2 && common_window) { 
			windowSequence[1] = windowSequence[0]; 
			windowShape[1] = windowShape[0]; 
			maxSfb[1] = maxSfb[0]; 
			for (i = 0; i < 7; i++)			/*useless*/ 
				groupInfo[1][i] = groupInfo[0][i]; 
		} 
 
		if (nch == 2) { 
			stereo_mode = sam_getbits(2); 
			if (stereo_mode == 2) { 
				ps_mask[0] = 2; 
			} else if (stereo_mode != 0) 
				ps_mask[0] = 1; 
		} 
 
		/* fill enable */ 
		fill_enable = sam_getbits(1); 
		if(fill_enable) 
		{ 
			/* fill element length */ 
			fill_length = sam_getbits(4); 
			if(fill_length == 15) 
				fill_length += sam_getbits(8); 
		} 
 
		/*Byte align*/ 
		used_bits = i_sstell() - frameStart; 
		if (used_bits % 8) { 
			int	dummy, nn; 
			nn = 8 - (used_bits % 8); 
			dummy = sam_getbits(nn); 
			used_bits += nn; 
		} 
	 
		///////////////////////////////////////////////////////// 
		//            CBC   MAIN   DECODING                   // 
		///////////////////////////////////////////////////////// 
		if (maxSfb[0] != 0) 
			sam_decodeCBC(target, stereo_mode,	windowSequence,	num_window_groups, 
				window_group_length, scalefactors, samples,	maxSfb,ps_mask, 
				used_bits, frameLength, enc_top_layer, base_snf, base_band, nch, fill_length); 
 
		/* fill data decoding */ 
		if(fill_enable) 
		{ 
			fill_type = sam_getbits(4); 
			for(i = 0; i < 8*(fill_length-1)+4; i ++) 
				sam_getbits(1); 
		} 
 
		///////////////////////////////////////////////////////// 
		//            DEQUANTIZATION                           // 
		///////////////////////////////////////////////////////// 
		for (ch = 0; ch < nch; ch++) 
			sam_dequantization(target, windowSequence[ch], scalefactors[ch], num_window_groups, 
				window_group_length, samples[ch], maxSfb[ch], spectrums[ch], ch); 
 
		/*************SQUARE POLAR STEREO***********************/ 
		if(ps_mask[0]){ 
			int* swb_offset; 
			if(windowSequence[0] == EIGHT_SHORT_SEQUENCE) 
				swb_offset = swb_offset_short; 
			else 
				swb_offset = swb_offset_long; 
			 
			polar_decode(spectrums[0], 
						 spectrums[1], 
						 ps_mask[0], 
						 ps_mask+1, 
						 num_window_groups, 
						 window_group_length, 
						 swb_offset, 
						 *maxSfb, 
						 FRAMESIZE); 
		} 
 
		///////////////////////////////////////////////////////// 
		//            INVERSE MDCT                             // 
		/////////////////////////////////////////////////////////			 
		for (ch = 0; ch < nch; ch++) {			 
			intIMDCT(spectrums[ch],  
				pcmOverlap[ch], 
				pcmOut[ch],  
				windowSequence[ch]); 
		} 
 
		/*Write Output PCM data*/ 
		if (frameCount > 0) { 
			j = 0; 
			for (i = 0; i < FRAMESIZE; i++) 
				for (ch = 0; ch < nch; ch++) 
				{ 
					OutBuff[j++] = pcmOut[ch][i]; 
				} 
 
			AFwriteData(AFpO, OutBuff, FRAMESIZE * nch); 
		} 
 
		used_bits = i_sstell() - frameStart; 
		if (used_bits > frameLength) 
			fprintf(fpinfo, "Error: Decoding Bits(%d) > Framelength(%d)\n", used_bits, frameLength); 
 
		/*Byte align*/ 
		while (used_bits < frameLength) { 
			int  remain, read_bits; 
 
			remain = frameLength - used_bits; 
			read_bits = remain > 8 ? 8 : remain; 
			i = sam_getbits(read_bits); 
			used_bits = i_sstell() - frameStart; 
		} 
		fprintf(fpinfo, "\rFrame # : %d\t%d", frameCount++, i_sstell()-frameStart); 
	} 
 
	free(OutBuff); 
	AFclose(AFpO); 
	fprintf(fpinfo, "\n"); 
}