⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pmpeg4audio.c

📁 MP4编码源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*

MPEG4 Audio Decoding Module 

Base source is pMP3.c

*/
//****************************************************************************
//
// MP3InitBitstream initializes the stream to the given byte offset in the
// file.
//
//****************************************************************************

#include "include/main.h"
#include "kernel/Telechips.h"
#include "Lib76x.h"
#include "include/commoncmd.h"
#include "resource/tccresource.h"
#include "include/TCC760.h"    //dddxxx
#include "include/globals.h"

#include "MP3Dec/MP3DEC_TCC76xMP3Dec_ADS_V101.h"
#include "MP3Dec/MP3DEC_pMP3_Dec_ADS.h"
#include "MP3Dec/MP3DEC_MpgData.h"
#include "buffer/buffer.h"
#include "FS/utils.h"
//----------------------
#include "Myfifo.h"
#include "Pixfileformat.h"

#ifdef 	MP4_INCLUDE

//static unsigned int KeyIn;	// content of MessageQ
extern long 				gTotalSizeOfMPEG4Audio;
extern int 				gVideoFrameNum, gAudioFrameNum;
extern int 				gVideoTotalFrame, gAudioTotalFrame;
extern ELEMENTSTREAM 	AStreamBuf;
extern unsigned char		gPlugInSkip;
extern unsigned char		gMpegMode;

extern unsigned short 		usSRMap[];
extern unsigned short 		usBRMap[];
extern unsigned short 		usFLMap[][];
extern unsigned short 		usFLMap2[][];

extern char				gLongPusgFFRR;

unsigned char 			ISFirst;

static int bitstreamDataToProcess = -1;
static int MPEG4_buffer_size;
int 	   MPEG4_sp;
int        MPEG4FirstHeaderDecoded = 0;

int			MPEG4_BR;

#ifndef SWAP32
#define SWAP32(x)			(											\
							(((unsigned long int)(x) & 0x000000ffL) << 24) |	\
							(((unsigned long int)(x) & 0x0000ff00L) << 8)  |	\
							(((unsigned long int)(x) & 0x00ff0000L) >> 8)  |	\
							(((unsigned long int)(x) & 0xff000000L) >> 24)		\
							)
#endif

extern int GetOneFrameAudio(PELEMENTSTREAM pIdxStream,char* pFrameFiFo, unsigned int uiFrameNum);

//========================================================
// Decripton	: Check	Valid Frame	Header by Input	String
// Parameter	: header	-> Expected	data to	a Frame	Header.
// Return		: 0			-> Invalid Frame Header
//				  1			-> Valid Frame Header
//========================================================
extern unsigned char CheckValidHeader(unsigned	char *header);

//=============================================================================
// Decripton	: Determines if	the	current	frame is VBR header	frame
//				  and decodes it if	it is. (Xing and VBRI)
// Parameter	: buffer	-> the first pointer position of the MP3 file
// Return		: 0			-> Fail	to read	the	number of frame	in Header
//				  Other		-> The Number of Frame in Header
//========================================================
extern unsigned long DecodeVBRHeader(unsigned char	*buffer, unsigned int *framesize);

extern unsigned short GetFrameSize(unsigned char* pucBuffer);


extern unsigned short GetSamplingRate(unsigned	char* pucBuffer);


extern unsigned short GetBitrate(unsigned char* pucBuffer);


extern unsigned long GetHeaderInfo(unsigned char* pucBuffer);


extern unsigned char GetChannels(unsigned char* pucBuffer);

extern unsigned char GetLayerDescription(unsigned char* pucBuffer);


//****************************************************************************
//
// MP3DecodeVBRHeader determines if the current frame is a Xing VBR header
// frame and decodes it if it is.
//
//****************************************************************************
//========================================================
// Decripton	: Search MP3 Header	position
// Parameter	: MP3Data		-> String pointer of working data
// Return		: -1			-> Invalid MP3 file
//				  signed digit	-> Positoin	of first frame header
//========================================================
int	MPEG4_GetHeaderPosition(tMP3 *pMP3)//unsigned	char* MP3Data)
{
	unsigned char* MP3Data;
	unsigned int firstheaderposition = 0;
	unsigned int  searchcount = 70*1024;//1000;
	
	unsigned long ulFramesize;
	unsigned long ulTotalframes;
	
	unsigned char returnvalue;
	int result;
	
	MP3Data	= pMP3->pcEncodedData;
	
	result = GetOneFrameAudio(&AStreamBuf, MP3Data, gAudioFrameNum);
		
	firstheaderposition	= 0;
	
	// If valid	header,	check 20 times
	// else, check 1000	times. exept all 0xFF, 0x00
	while(searchcount)
	{
		returnvalue	= CheckValidHeader(MP3Data);
		
		if(returnvalue){
			// check Xing &	VBRI ==========================================================
			ulTotalframes =	DecodeVBRHeader(MP3Data, &ulFramesize);
			
			if(!ulTotalframes){
				// get header information
				pMP3->ucIsVBR		= 0;
				pMP3->ucChannels	= GetChannels(MP3Data);
				pMP3->usSampleRate	= GetSamplingRate(MP3Data);
				pMP3->ulFirstFrame	= firstheaderposition;
				ulTotalframes		= ulFramesize * gAudioTotalFrame;
				pMP3->ulLength		= ulTotalframes - pMP3->ulFirstFrame;
				pMP3->ulBitRate		= ((pMP3->ulLength / ulTotalframes)	*
										pMP3->usSampleRate)	/ (ulFramesize / 8);
				
				if(pMP3->ulBitRate == 0)
				{
					return 0;
				}
				return 1;
			}
		}
		
		searchcount--;
		
		firstheaderposition++;
		MP3Data++;
	}
	return 0;
}

void MPEG4FillBitstream(tMP3 *pMP3, int mtest)
{
    int bytesCurrent;
    int bytesNeeded;
    char *bsdata;
    
    int result_fread = 0;
 
 
 	bytesCurrent = pMP3->bitstream.dataLength - pMP3->bitstream.dataOffset;
 	bytesNeeded  = pMP3->bitstream.dataRequired - bytesCurrent;
 	
    
    /* Update bitstream structure values */
    pMP3->bitstream.data       += pMP3->bitstream.dataOffset;
    pMP3->bitstream.dataOffset = 0;
    pMP3->bitstream.dataLength = bytesCurrent;
    
    /* bsdata is the address at which to start writing new data */
    bsdata = pMP3->bitstream.data + bytesCurrent;

    if (bytesNeeded > 0)
    {
        // Will we run off the end of the bitstream buffer? 
        if ( ((pMP3->bitstream.data - pMP3->pcEncodedData) + pMP3->bitstream.dataRequired) > 1152 )
        {
            // YES: We need to move the existing data to the start of the buffer to make room at the end 
  
            mem_cpy(pMP3->pcEncodedData, pMP3->bitstream.data, bytesCurrent);
  
            pMP3->bitstream.data = pMP3->pcEncodedData;          // Move data pointer back to start of buffer           
            bsdata = pMP3->pcEncodedData + bytesCurrent;
        }
RETRY_GETAUDIO :
		if(gAudioFrameNum <=  gAudioTotalFrame)
		{
			result_fread = GetOneFrameAudio(&AStreamBuf, bsdata, gAudioFrameNum);

			if(!gLongPusgFFRR)
			{
				gAudioFrameNum += 1;
				if( gAudioFrameNum >= gAudioTotalFrame - 1 )
					gAudioTotalFrame = gAudioTotalFrame - 1;

			}
			if(result_fread == -1)
			{
#ifdef AGING_TEST
						SerialWriteString("GetOneFrameAudio Fail");
#endif	
				goto RETRY_GETAUDIO;

			}	

		}
		else{
			// If there is insufficient data, signal end of file 
			bitstreamDataToProcess = 0;
		}

        bsdata = bsdata + result_fread;
        
        if(result_fread < bytesNeeded){
        	bitstreamDataToProcess = 0;
        }
       
        pMP3->bitstream.dataLength = bsdata - pMP3->bitstream.data;
	
        // If there is insufficient data, signal end of file 
        if (pMP3->bitstream.dataLength < pMP3->bitstream.dataRequired)
        {
            bitstreamDataToProcess = 0;
        }
    }   
} 

//****************************************************************************
//
// The codec plug-in entry point for the MP4 Audio.
//
//****************************************************************************

unsigned long
MPEG4AudioFunction(unsigned long ulSubFn, unsigned long ulParam1, unsigned long ulParam2,
								unsigned long ulParam3, unsigned long ulParam4)
{
	
	// Decode a frame of data.
	if( ulSubFn == SUBFN_CODEC_DECODE)
	{
		unsigned char Cmd=0;
		short *psLeft=0, *psRight=0;
		long lLength=0;
		// The first parameter is a pointer to the MP3 persistent state.
		tMP3 *pMP3;
		int		MP4_Timer, MP4_Timer2;
		
		// The first parameter is a pointer to the MP3 persistent state.
		pMP3 = (tMP3 *)ulParam1;
		

		if( ISFirst == 0 )	// Start DeMux task for Video Decoding
		{				
			Cmd = STATE_PLAY;
			OSQPost(TCC_DEMUX_Q, (void *)&Cmd);	// pend DEmux Task				
			OSSemPend(MPEG_DEMUX_SEM, 0, &Cmd);	

			ISFirst = 1;
			while( gVideoFrameNum < 8 && !gLongPusgFFRR )
			{
				OSTimeDly(1);
			}
		}

		pMP3->status = 0;
		
		if(MPEG4FirstHeaderDecoded != 1){
			MP4_Timer = 1024;
            bitstreamDataToProcess = -1;
	        do
	        {
	            MPEG4FillBitstream(pMP3, 0);
	            
	            if (!bitstreamDataToProcess) break;
	            pMP3->status = pMP3->workspace->Decoder->DecodeHeader( pMP3->workspace->handle, 
	            													   pMP3->workspace->scratch, 
	            													   &(pMP3->bitstream) );
	            if(pMP3->bitstream.sampleRate != MPEG4_sp)
	            {
	            	pMP3->status = kDecoderStatus_ReservedSamplingFrequency;
	            }
				if ( --MP4_Timer < 0 )
					break;
	        }
	        while ( (pMP3->status != kDecoderStatus_NoError) && bitstreamDataToProcess);

	        if(pMP3->status != kDecoderStatus_NoError)
	        {
	        	OSTimeDly(5);
				return 1;
				
	        //	return(0);
	        }
		}
		//decode header
    	MPEG4FirstHeaderDecoded = 0;
		
		if(!bitstreamDataToProcess) return(0);
		
   		pMP3->bitstream.formats.outputFormats = OUTPUT_FORMAT_16BIT;
		
		// Wait until there is space in the output buffer.  This tells us
		// when it is OK to write more data into the output buffer.

		MP4_Timer = 10000;
		
		while( BufferSpaceAvailable(pMP3->pOutput,gPlugInSkip) < MP3_MAX_PCM_LENGTH )
		{
			if ( --MP4_Timer < 0 )
				break;
			OSTimeDly(2);
			Halt();
		}

		// Get a pointer to the available space in the output buffer.
		BufferGetWritePointer(pMP3->pOutput, &psLeft, &psRight, &lLength,gPlugInSkip);


		pMP3->output.channels[0] = psLeft;
		pMP3->output.channels[1] = psRight;

   		bitstreamDataToProcess = -1;
		
		MP4_Timer = 1024;
		do{
			if(pMP3->status == kDecoderStatus_FrameDiscarded || pMP3->status == kDecoderStatus_BrokenFrame)
			{
	            bitstreamDataToProcess = -1;
				MP4_Timer2 = 1024;
		        do
		        {
		            MPEG4FillBitstream(pMP3, 0);
		            
		            if (!bitstreamDataToProcess) break;
		            pMP3->status = pMP3->workspace->Decoder->DecodeHeader( pMP3->workspace->handle, 
		            													   pMP3->workspace->scratch, 
		            													   &(pMP3->bitstream) );

		            if(pMP3->bitstream.sampleRate != MPEG4_sp)
		            {
		            	pMP3->status = kDecoderStatus_ReservedSamplingFrequency;
		            }
#if 0
					if(pMP3->bitstream.bitRate!= MPEG4_BR)
					{
						pMP3->status = kDecoderStatus_ReservedBitRate;
					}
#endif
					if ( --MP4_Timer2 < 0 )
						break;

		        }
		        while ( (pMP3->status != kDecoderStatus_NoError && bitstreamDataToProcess) );  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -