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

📄 decoder_task.c

📁 本程序为ST公司开发的源代码
💻 C
字号:
/************************************************** * * decoder.c * * CVS ID:   $Id: decoder_task.c,v 1.67 2007/03/19 17:58:06 belardi Exp $ * Author:   Raffaele Belardi [RB] - STM * Date:     $Date: 2007/03/19 17:58:06 $ * Revision: $Revision: 1.67 $ *  * Description: *  * Main entry point for Accordo+ Decoder task. *  * The functions here are mainly concerned with interactions with  * the other OS threads. The structure of the function should be * sufficiently generic to be able to use MP3 or WMA (or other types) * of bitstream decoders. *  *************************************************** *  * COPYRIGHT (C) ST Microelectronics  2005 *            All Rights Reserved * **************************************************** * * STM CVS Log: * * $Log: decoder_task.c,v $ * Revision 1.67  2007/03/19 17:58:06  belardi * Integration of Optomech AAC decoder P150307 * * Revision 1.66  2007/01/30 13:29:39  marcucci * 16/32 bit run-time selection * * Revision 1.65  2006/11/01 10:35:57  chlapik * - decoder_immediate_eof which is set from CTR, when modified in DEC task, disable/enable scheduling used * - when waiting for AB empty, if stop cmd arrived (state DECODER_WAIT_AB_EMPTY), don't call ResumeDecoder(), instead of it do immediate stop * * Revision 1.64  2006/10/31 14:14:19  chlapik * support for Layer I & II: * - Layer type, sample rate and channel number are determined by BitrateParser before playback * - mp3 decoder checks if these parameters found in valid header matches, if not scan bitstream per bytes * * Revision 1.63  2006/09/27 19:48:48  belardi * Removed (global) unused variables * * Revision 1.62  2006/09/26 13:16:33  belardi * Removed compilation warnings * * Revision 1.61  2006/09/18 09:55:21  belardi * Corrected CVS keyword usage * * Revision 1.60  2006/09/18 09:23:02  belardi * Added Log CVS keyword into file header * * ***************************************************/#include <string.h> // for memcpy#include "configuration.h"//#include "os20.h"#include "gendef.h"#include "hwreg.h"#include "osal.h"#include "allocation.h"	//[LL]#include "decoder_task.h"#include "controller.h"#include "audiobuffer.h"#if (HAVE_WMA!=0)#include "wmawrap.h"	//M.Ch. //[LL]#endif#include "mp3wrap.h"#if (0 != HAVE_AAC)#include "aacwrap.h"#endif#include "audiowrap.h"//#include "framebuffer.h"#include "mp3dec.h" // ARM library include file/********* GLOBALS ********/t_decoder_status_event  decoder_status_event;//int g_decoderFastSeekJumpBytes; // [RB] unusedt_PlayMode decoderPlayMode;t_fileType NextFileType = ft_unknown;t_fileType CurrentFileType = ft_unknown;t_fileType PreviousFileType = ft_unknown;uint16 CurrentSampling_fr = kDecoderSampleRate_Undefined;uint8  CurrentCh_num = 0;uint32 CurrentBistreamType = 0;uint8 decoder_immediate_eof;uint32 decoder_task_state;char WaitingMode = 0; //[LL]uint32 pcm_size;extern uint8 g_FB_readFrom;extern eDecoderSampleRate CurrentSampleRateConverterFrequency;extern void ReconfigureDMA_CH0(t_fileType FileType);			/* defined in audiobuffer.c */ //[LL]/***** OS related stuff *******/#if (DEBUG_INCLUDE_COUNTERS==1)static uint32 countFBUnderflows;uint32 countABUnderflows;uint32 countMP3GoodFrames;uint32 countMP3BadFrames;#endif/***** Decoder related stuff *****/tDecoderTime_event decoder_time_event[EVENT_MAX_STAGES]; // send time events from DEC to CTR/* Internal function prototypes */uint32 InitializeDecoder(t_fileType file_type);void ResumeDecoder(int flag);void KillDecoder(DecoderKillType killType);void SelectDecodersPCMSampleSize(void){ pcm_size = OUTPUT_FORMAT_32BIT;}/********* FUNCTIONS ********/void InitDecoderTask(void){	// Initialize Audio Buffer (output buffer)	AudioBufferInit();		decoder_status_event.state = DECODER_STATE_RESET;	decoder_immediate_eof = 0;	decoder_task_state = DECODER_PLAYBACK;	#if (DEBUG_INCLUDE_COUNTERS==1)    countFBUnderflows = 0; // [RB] debug    countABUnderflows = 0; // [RB] debug    countMP3GoodFrames = 0; // [RB] debug	countMP3BadFrames = 0;  // [RB] debug#endif    	}/***********************************************************************//* Function:  get_decoder_time_event_data                              *//*                                                                     *//*! \brief    return pointer to decoder time information *  \param *  \return   pointer to time information structure *  \remark *//***********************************************************************/void * get_decoder_time_event_data(t_event_stage i){  return (void *) &decoder_time_event[i];}/********************************************* * * InitializeDecoder() * * Decide which decoder to initialize and call * the appropriate initialization function. * * Set up an array of pointers to funtions pointing * to the right decoder functions * * ******************************************/uint32 InitializeDecoder(t_fileType file_type){	t_bool IsSameFileType = FALSE;		if (CurrentFileType == file_type)	{	  IsSameFileType = TRUE;	}		/* initialize the decoder */	switch (file_type) {#if (HAVE_WMA!=0)		case ft_WMA:			//debugStartProfiling();		    WMAInit(IsSameFileType);		    break;#endif		case ft_MP3_LayerI:		    CurrentBistreamType = 0x4D504731;		    MP3Init();		    break;		case ft_MP3_LayerII:		    CurrentBistreamType = 0x4D504732;		    MP3Init();		    break;		case ft_MP3_LayerIII:		    CurrentBistreamType = 0x4D504733;			//debugStartProfiling();			MP3Init();			break;#if (0 != HAVE_AAC)		case ft_AAC:			AACInit();			break;#endif		case ft_Audio:			//debugStartProfiling();			if (IsSameFileType)				return 0;		    AudioInit();		    break;		default:			// error				break;	}		NextFileType = file_type;//	CurrentSampleRateConverterFrequency = kDecoderSampleRate_Undefined;		return 1;}/********************************************* * * ResumeDecoder() * * ******************************************/void ResumeDecoder(int flag){	decoderReturnType ret = decoderUninitilaized;	switch (CurrentFileType)	{#if (HAVE_WMA!=0)	case ft_WMA:		ret = WMADecode(flag);		break;#endif			case ft_Audio:		ret = AudioDecode(flag);		break;	case ft_MP3_LayerI:	case ft_MP3_LayerII:	case ft_MP3_LayerIII:		ret = MP3Decode(flag);		break;#if (0 != HAVE_AAC)	case ft_AAC:		ret = AACDecode(flag);		break;#endif // HAVE_AAC	}		switch (ret)	{		case decoderWaitingFBdata:		#if (DEBUG_INCLUDE_COUNTERS==1)		    countFBUnderflows++; // [RB] debug#endif			decoder_status_event.state = DECODER_STATE_WAIT_FB;			// send status event to the Controller			event_req_set_decoder(READY);			event_sleep_set_decoder(READY);			//controller_update_status(CONTROLLER_NEW_DECODER_DATA_REQUEST_EVENT);			//controller_update_status(CONTROLLER_NEW_DECODER_SLEEP_EVENT);			break;		case decoderWaitingABempty:			decoder_status_event.state = DECODER_STATE_WAIT_AB;			event_sleep_set_decoder(READY);			//controller_update_status(CONTROLLER_NEW_DECODER_SLEEP_EVENT);			break;				case decoderEOF: // natural EOF			decoder_status_event.state = DECODER_STATE_RESET_TRANSITION;			KillDecoder(closeOnly);			decoder_status_event.state = DECODER_STATE_RESET;			event_stop_set_decoder(READY);			//controller_update_status(CONTROLLER_NEW_DECODER_STOP_EVENT);			break;		case decoderEOF_immediate:					//if decoder cought stop request (decoder_immediate_EOF), cancel following			//stop request, not to perform decoder kill twice			  			event_disable_scheduling();			event_in_shedule(DECODER_CMD_EVENT);			event_in_clear(DECODER_CMD_EVENT); 			event_enable_scheduling();									// requested immediate EOF (next / stop / fseek)			decoder_status_event.state = DECODER_STATE_RESET_TRANSITION;			//KillDecoder(closeOnlyAndClearAllFB);			KillDecoder(closeOnly);				//decoder_inevent = 0;			decoder_status_event.state = DECODER_STATE_RESET;			event_stop_set_decoder(READY);			//controller_update_status(CONTROLLER_NEW_DECODER_STOP_EVENT);			break;				case decoderFatalError:			// signal upwards#if (0 != HAVE_AAC)      decoder_status_event.state = DECODER_STATE_RESET_TRANSITION;      KillDecoder(closeOnly);      decoder_status_event.state = DECODER_STATE_RESET;      event_stop_set_decoder(READY);#endif /* HAVE_AAC */			break;	}}/********************************************* * * KillDecoder() * * ******************************************/void KillDecoder(DecoderKillType killType){	switch (CurrentFileType)	{	// case MP3 LayerIII		// May use some more intelligent strategy to cleanup, i.e.	// call with closeOnly here and maybe closeAndDestroy later only if	// the next requested file to decode is not compatible with this decoder.	//WMAKill(closeAndDestroy);#if (HAVE_WMA!=0)	case ft_WMA:	  WMAKill(killType);	  break;#endif	case ft_MP3_LayerI:	case ft_MP3_LayerII:	case ft_MP3_LayerIII:	  MP3Kill(killType);	  break;#if (0 != HAVE_AAC)	case ft_AAC:		AACKill(killType);		break;#endif // HAVE_AAC	case ft_Audio:	  AudioKill(killType);	  break;	}		event_disable_scheduling();	decoder_immediate_eof = 0;	event_enable_scheduling();}/******************************************************************************//******************************************************************************//******************************************************************************/t_decoder_cmd_event  decoder_cmd_event_data[EVENT_MAX_STAGES];void *get_decoder_cmd_event_data(t_event_stage i){ // controler -> decoder  return (void *)&decoder_cmd_event_data[i];}/********************************************* * * decoder_cmd() * * ******************************************/ RETVAL decoder_task_cmd(t_decoder_cmd_event* cmd_event){	t_decoder_cmd_event* pout_event;			switch(cmd_event->command) {		case DECODER_CMD_FB_READY:	case DECODER_CMD_START:				break;							case DECODER_CMD_STOP:		decoder_immediate_eof = 1; // stop receiving AB_empty events			break;		}		pout_event = (t_decoder_cmd_event *)pevent_get_out(DECODER_CMD_EVENT);	*pout_event = *cmd_event;	event_set_out(DECODER_CMD_EVENT);     //priority dependent (semaphore signal immediatelly)	//event_cmd_set(DECODER_CMD_EVENT);       //independent from priorities	event_out_shedule(DECODER_CMD_EVENT);		return BUSY;		}void decoder_process_events(void){  uint32 reconfigure;  while (1)  {    switch (decoder_task_state)    {    case DECODER_WAIT_AB_EMPTY:      if (g_ABempty == AudioBufferElements)      {        while (CIF_CONF.field.wr_fifo_cnt); // wait for fifo to be empty        CIF_CONF.field.wr_fifo_rst = 1;        // start CIF reconfiguration:        if (NextFileType == ft_Audio)        {          CIF_CONF.field.wr_burst_len = 2;          while (CIF_CONF.field.src)            CIF_CONF.field.src = 0;        }        else        {          CIF_CONF.field.wr_burst_len = 1;          while (!CIF_CONF.field.src)            CIF_CONF.field.src = 1;        }        //since file type has changed, reconfigure DMA        ReconfigureDMA_CH0(NextFileType);        CurrentFileType = NextFileType;        decoder_status_event.state = DECODER_STATE_PLAY;        decoder_task_state = DECODER_PLAYBACK;        ResumeDecoder(DECODER_CMD_FB_READY);      }      else if(DECODER_CMD.command == DECODER_CMD_STOP)      { //waiting for audio buffer empty, but it is still not, stop cmd arrived        decoder_task_state = DECODER_PLAYBACK;		decoder_status_event.state = DECODER_STATE_RESET_TRANSITION;		KillDecoder(closeOnly);			decoder_status_event.state = DECODER_STATE_RESET;        event_stop_set_decoder(READY);      }      return;    case DECODER_PLAYBACK:      // PROCESS COMMAND EVENTS      if (IS_DECODER_CMD_EVENT)      {        if (DECODER_CMD.command == DECODER_CMD_START)        {          if (decoder_status_event.state == DECODER_STATE_RESET)          {            event_start_set_decoder(READY);            reconfigure = InitializeDecoder(DECODER_CMD.command_params.start_params.fileType);          	          	CurrentSampling_fr = DECODER_CMD.command_params.start_params.sampling_fr;	        CurrentCh_num = DECODER_CMD.command_params.start_params.ch_num;            if (reconfigure)            {              decoder_task_state = DECODER_WAIT_AB_EMPTY;              break;            }            else            {              decoder_status_event.state = DECODER_STATE_PLAY;              ResumeDecoder(DECODER_CMD_FB_READY);              return;            }          }        }        else if (DECODER_CMD.command == DECODER_CMD_FB_READY)        {          if (decoder_status_event.state == DECODER_STATE_WAIT_FB)          {            decoder_status_event.state = DECODER_STATE_PLAY;            ResumeDecoder(DECODER_CMD_FB_READY);            return;          }        }        else if (DECODER_CMD.command == DECODER_CMD_STOP)        {          if (decoder_status_event.state == DECODER_STATE_RESET)          {            event_disable_scheduling();            decoder_immediate_eof = 0;            event_enable_scheduling();            event_stop_set_decoder(READY);            return;          }          decoder_status_event.state = DECODER_STATE_RESET_TRANSITION;          KillDecoder(closeOnly);          decoder_status_event.state = DECODER_STATE_RESET;          event_stop_set_decoder(READY);          return;        }      }      if (IS_DMA0_XFER_EVENT)				{ // PROCESS STATUS EVENTS from DMA (AudioBuffer)				  if(decoder_status_event.state == DECODER_STATE_WAIT_AB)				  {				    decoder_status_event.state = DECODER_STATE_PLAY;				    ResumeDecoder(DECODER_CMD_AB_EMPTY);				  }				}								return;			default:				return;					} // switch		} // while(1)}void DecoderTask(void *unused){	while(1)	{	  OSAL_wait_thread(OSAL_THREAD_DecoderTask);	  	  event_disable_scheduling();	  event_in_shedule(DECODER_CMD_EVENT);	  event_in_shedule(DMA0_IRQ_XFER_EVENT);	  event_in_shedule(DMA0_IRQ_TIME_EVENT);	  event_enable_scheduling();	  	  // decoder_fsm:	  decoder_process_events();	  	  event_disable_scheduling();	  	  event_in_clear(DECODER_CMD_EVENT);      event_in_clear(DMA0_IRQ_XFER_EVENT);      event_in_clear(DMA0_IRQ_TIME_EVENT);	  	  //event_out_shedule(DECODER_TIME_EVENT);      event_out_shedule(DECODER_REQ_EVENT);        event_out_shedule(DECODER_SLEEP_EVENT);        event_out_shedule(DECODER_STOP_EVENT);      event_out_shedule(DECODER_START_EVENT);      event_enable_scheduling();	  	} // while(1)	}// ****************************** //uint8 decoderStopRequest(void){	uint8 retval;		event_disable_scheduling();	retval = decoder_immediate_eof;	event_enable_scheduling();	return retval;}#if 0 // [RB] commented out to reduce ROM spacevoid setDecoderPlayMode(t_PlayMode PlayMode){	decoderPlayMode = PlayMode; // seek or scan}#endif

⌨️ 快捷键说明

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