📄 dcc_audio.c
字号:
/***************************************** Copyright © 2001-2003 Sigma Designs, Inc. All Rights Reserved Proprietary and Confidential *****************************************//** @file dcc.c @brief Decoding Chain Control API @author Julien Soulier @date 2003-10-02*/// to enable or disable the debug messages of this source file, put 1 or 0 below#if 0#define LOCALDBG ENABLE#else#define LOCALDBG DISABLE#endif#include "dcc_common.h"RMstatus DCCOpenAudioDecoderSource(struct DCC *pDCC, struct DCCAudioProfile *dcc_profile, struct DCCAudioSource **ppAudioSource){ struct AudioDecoder_DRAMSize_in_type dram_in; struct AudioDecoder_DRAMSize_out_type dram_out; struct AudioDecoder_Open_type profile; RMuint32 audio_decoder, audio_engine; RMuint32 nb_audio_engines, nb_audio_decoders; RMuint32 temp, i; RMstatus err; /* Decoder shared memory is required for audio postprocessing. */ struct AudioEngine_DecoderSharedMemory_type shared; struct AudioEngine_DecoderSharedMemoryInfo_in_type info_in; struct AudioEngine_DecoderSharedMemoryInfo_out_type info_out; /* ************************* */ RMuint32 sample_rate; struct AudioEngine_Volume_type volume; /* ************************* */ *ppAudioSource = (struct DCCAudioSource *) RMMalloc(sizeof(struct DCCAudioSource)); if (*ppAudioSource == NULL) { RMDBGLOG((ENABLE, "ERROR: could not allocate 0x%08lX bytes in system memory %lu!\n", sizeof(struct DCCAudioSource))); return RM_FATALOUTOFMEMORY; } RMMemset((void*)(*ppAudioSource), 0, sizeof(struct DCCAudioSource)); (*ppAudioSource)->pRUA = pDCC->pRUA; (*ppAudioSource)->pDCC = pDCC; // Get number of audio engines and audio decoders temp = AudioEngine; err = RUAExchangeProperty(pDCC->pRUA, Enumerator, RMEnumeratorPropertyID_CategoryIDToNumberOfInstances, &temp, sizeof(temp), &nb_audio_engines, sizeof(nb_audio_engines)); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Error getting property RMEnumeratorPropertyID_CategoryIDToNumberOfInstances %s\n", RMstatusToString(err))); return err; } else { if (dcc_profile->AudioEngineID < nb_audio_engines) RMDBGLOG((LOCALDBG, "Number of audio engines: %d\n", (int) nb_audio_engines)); else { RMDBGLOG((ENABLE, "Error: audio engine index %d out of range!!! Should be < %d\n", (int) dcc_profile->AudioEngineID, (int) nb_audio_engines)); err = RM_PARAMETER_OUT_OF_RANGE; return err; } } temp = AudioDecoder; err = RUAExchangeProperty(pDCC->pRUA, Enumerator, RMEnumeratorPropertyID_CategoryIDToNumberOfInstances, &temp, sizeof(temp), &nb_audio_decoders, sizeof(nb_audio_decoders)); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Error getting property RMEnumeratorPropertyID_CategoryIDToNumberOfInstances %s\n", RMstatusToString(err))); return err; } else { if (dcc_profile->AudioDecoderID < (nb_audio_decoders / nb_audio_engines)) RMDBGLOG((LOCALDBG, "Number of audio decoders: %d\n", (int) nb_audio_decoders)); else { RMDBGLOG((ENABLE, "Error: audio decoder index %d out of range!!! Should be < %d\n", (int) dcc_profile->AudioDecoderID, (int) (nb_audio_decoders / nb_audio_engines))); err = RM_PARAMETER_OUT_OF_RANGE; return err; } } audio_engine = EMHWLIB_MODULE(AudioEngine, dcc_profile->AudioEngineID); (*ppAudioSource)->engine_moduleID = audio_engine; RMDBGLOG((LOCALDBG, "AudioEngine: 0x%08lX\n", audio_engine)); // !!Hack!! We assume there are an equal amount of decoders per engine; (nb_audio_decoders / nb_audio_engines) // gives the number of decoders per engine. This is always better then hardcoding number to 2 like before. audio_decoder = EMHWLIB_MODULE(AudioDecoder, dcc_profile->AudioEngineID * (nb_audio_decoders / nb_audio_engines) + dcc_profile->AudioDecoderID); (*ppAudioSource)->decoder_moduleID = audio_decoder; RMDBGLOG((LOCALDBG, "AudioDecoder: 0x%08lX\n", audio_decoder)); profile.DemuxProgramId = dcc_profile->DemuxProgramID; profile.TimerId = dcc_profile->STCID; (*ppAudioSource)->timer_number = profile.TimerId; for (i = 0; i <= 11; i++) { volume.Channel = i; // Now we only have master volume control. // For individual channel, use set_MixerWeight for primary decoder and secondary decoder. // Volume[i:0...7] = Weight[k][i]*channel_volume[i] volume.Volume = 0x10000000; DCCSP(pDCC->pRUA, audio_engine, RMAudioEnginePropertyID_Volume, &volume, sizeof(volume)); } sample_rate = 44100; DCCSP(pDCC->pRUA, audio_engine, RMAudioEnginePropertyID_SampleFrequency, &sample_rate, sizeof(sample_rate)); info_in.Reserved1 = 0; info_in.Reserved2 = 0; err = RUAExchangeProperty(pDCC->pRUA, audio_engine, RMAudioEnginePropertyID_DecoderSharedMemoryInfo, &info_in, sizeof(info_in), &info_out, sizeof(info_out)); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Error getting property RMAudioDecoderPropertyID_DecoderDataMemory! %s\n", RMstatusToString(err))); return err; } /* check if audio shared memory is already set in audio engine */ err = RUAGetProperty(pDCC->pRUA, audio_engine, RMAudioEnginePropertyID_DecoderSharedMemory, &shared, sizeof(shared)); if (err != RM_OK) { RMDBGLOG((ENABLE, "Cannot get DecoderSharedMemory, %s\n", RMstatusToString(err))); return err; } if (shared.Address) { RMDBGLOG((ENABLE, "=================%lx_DRAM AUDIO SHARED MEMORY is already set addr=0x%lx size=0x%lx\n", dcc_profile->AudioEngineID, shared.Address, shared.Size)); } else { /* allocate and set the shared memory used by all decoders of the same engine */ shared.Size = info_out.DecoderSharedSize; if (shared.Size) { shared.Address = pDCC->rua_malloc(pDCC->pRUA, audio_engine, pDCC->dram, RUA_DRAM_UNCACHED, shared.Size); if (!shared.Address) { RMDBGLOG((ENABLE, "ERROR: could not allocate shared 0x%08lX bytes in DRAM %lu!\n", shared.Address, 0L)); return RM_FATALOUTOFMEMORY; } RMDBGLOG((ENABLE, "===============ALLOCATING %lx_DRAM AUDIO SHARED MEMORY addr: 0x%08lX, size 0x%08lX\n", dcc_profile->AudioEngineID, shared.Address, shared.Size)); DCCSP(pDCC->pRUA, audio_engine, RMAudioEnginePropertyID_DecoderSharedMemory, &shared, sizeof(shared)); } } /* we need 8 x 0x300(0x180) for Ac3, 8 x 0xF00 for WMA, 8 x 0x400 for WMAPRO => allocate maximum=8 x 0xF00 */ dram_in.MaxChannelOutCount = 12; //10; dram_in.PCMLineCount = 0xf00; dram_in.BitstreamFIFOSize = dcc_profile->BitstreamFIFOSize; dram_in.XferFIFOCount = dcc_profile->XferFIFOCount; RMDBGLOG((LOCALDBG, "wanted fifo size %lu, xfer count %lu\n", dcc_profile->BitstreamFIFOSize, dcc_profile->XferFIFOCount)); err = RUAExchangeProperty(pDCC->pRUA, audio_decoder, RMAudioDecoderPropertyID_DRAMSize, &dram_in, sizeof(dram_in), &dram_out, sizeof(dram_out)); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Error getting property RMAudioDecoderPropertyID_DRAMSize! %s\n", RMstatusToString(err))); return err; } profile.MaxChannelOutCount = dram_in.MaxChannelOutCount; profile.PCMLineCount = dram_in.PCMLineCount; profile.BitstreamFIFOSize = dram_in.BitstreamFIFOSize; profile.XferFIFOCount = dram_in.XferFIFOCount; profile.CachedAddress = 0; profile.CachedSize = dram_out.CachedSize; if (profile.CachedSize > 0) { profile.CachedAddress = pDCC->rua_malloc(pDCC->pRUA, audio_decoder, pDCC->dram, RUA_DRAM_CACHED, profile.CachedSize); if (!profile.CachedAddress) { RMDBGLOG((ENABLE, "ERROR: could not allocate 0x%08lX bytes in cached DRAM %lu!\n", profile.CachedSize, 0L)); return RM_FATALOUTOFMEMORY; } RMDBGLOG((LOCALDBG, "(audio decoder : %lu) audio cached addr: 0x%08lX, size 0x%08lX, end: 0x%08lX\n", (*ppAudioSource)->decoder_moduleID, profile.CachedAddress, profile.CachedSize, profile.CachedAddress + profile.CachedSize)); } (*ppAudioSource)->cached_address = profile.CachedAddress; profile.UncachedAddress = 0; profile.UncachedSize = dram_out.UncachedSize; if (profile.UncachedSize > 0) { profile.UncachedAddress = pDCC->rua_malloc(pDCC->pRUA, audio_decoder, pDCC->dram, RUA_DRAM_UNCACHED, profile.UncachedSize); if (!profile.UncachedAddress) { RMDBGLOG((ENABLE, "ERROR: could not allocate 0x%08lX bytes in uncached DRAM %lu!\n", profile.UncachedSize, 0L)); return RM_FATALOUTOFMEMORY; } RMDBGLOG((LOCALDBG, "(audio decoder : %lu) audio uncached addr: 0x%08lX, size 0x%08lX, end: 0x%08lX\n", (*ppAudioSource)->decoder_moduleID, profile.UncachedAddress, profile.UncachedSize, profile.UncachedAddress + profile.UncachedSize)); } (*ppAudioSource)->uncached_address = profile.UncachedAddress; DCCSP(pDCC->pRUA, audio_decoder, RMAudioDecoderPropertyID_Open, &profile, sizeof(profile)); return RM_OK;}RMstatus DCCCloseAudioSource(struct DCCAudioSource *pAudioSource){ RMuint32 close_profile; close_profile = 0; RMDBGLOG((LOCALDBG, "closing 0x%08lx, cached 0x%08lx, uncached 0x%08lx\n", (RMuint32)pAudioSource, (RMuint32)pAudioSource->cached_address, (RMuint32)pAudioSource->uncached_address)); DCCSP(pAudioSource->pRUA, pAudioSource->decoder_moduleID, RMAudioDecoderPropertyID_Close, &close_profile, sizeof(close_profile)); if (pAudioSource->engine_moduleID != 0) { /* Free the audio shared memory per engine */ RMstatus err; RMuint32 connected_task_count; err = RUAGetProperty(pAudioSource->pRUA, pAudioSource->engine_moduleID, RMAudioEnginePropertyID_ConnectedTaskCount, &connected_task_count, sizeof(connected_task_count)); if (err != RM_OK) { RMDBGLOG((ENABLE, "Cannot get RMAudioEnginePropertyID_ConnectedTaskCount %s %lu\n", RMstatusToString(err), pAudioSource->engine_moduleID)); return err; } if (connected_task_count == 0) { struct AudioEngine_DecoderSharedMemory_type shared; RMuint32 address; err = RUAGetProperty(pAudioSource->pRUA, pAudioSource->engine_moduleID, RMAudioEnginePropertyID_DecoderSharedMemory, &shared, sizeof(shared)); if (err != RM_OK) { RMDBGLOG((ENABLE, "Cannot get DecoderSharedMemory0, %s\n", RMstatusToString(err))); return err; } if (shared.Address) { RMDBGLOG((ENABLE, "FREE %lx_DRAM AUDIO SHARED MEMORY addr=0x%lx size=0x%lx!\n", EMHWLIB_MODULE_INDEX(pAudioSource->engine_moduleID), shared.Address, shared.Size)); address = shared.Address; shared.Address = 0; shared.Size = 0; DCCSP(pAudioSource->pRUA, pAudioSource->engine_moduleID, RMAudioEnginePropertyID_DecoderSharedMemory, &shared, sizeof(shared)); /* Unlock the shared address */ err = RUASetAddressID(pAudioSource->pRUA, address, 0); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "RUASetAddressID scheduler 0 ERROR %s\n", RMstatusToString(err))); return err; } RUAFree(pAudioSource->pRUA, address); } } else { RMDBGLOG((ENABLE, "CANNOT FREE AUDIO SHARED MEMORY. There are still %lx audio tasks opened. \n", EMHWLIB_MODULE_INDEX(pAudioSource->engine_moduleID), connected_task_count)); } } if (pAudioSource->cached_address) pAudioSource->pDCC->rua_free(pAudioSource->pRUA, pAudioSource->cached_address); if (pAudioSource->uncached_address) pAudioSource->pDCC->rua_free(pAudioSource->pRUA, pAudioSource->uncached_address); RMFree(pAudioSource); return RM_OK;}RMstatus DCCGetAudioDecoderSourceInfo(struct DCCAudioSource *pAudioSource, RMuint32 *decoder, RMuint32 *engine, RMuint32 *timer){ *decoder = pAudioSource->decoder_moduleID; *timer = pAudioSource->timer_number; *engine = pAudioSource->engine_moduleID; return RM_OK;}static RMstatus send_audio_command(struct RUA *pRUA, RMuint32 audio_decoder, enum AudioDecoder_Command_type a_command) { struct RUAEvent evt; enum AudioDecoder_State_type state; RMuint32 index; RMstatus err; evt.ModuleID = audio_decoder; evt.Mask = RUAEVENT_COMMANDCOMPLETION; err = RUAResetEvent(pRUA, &evt); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot reset audio command completion event, %s\n", RMstatusToString(err))); return err; } err = RUASetProperty(pRUA, audio_decoder, RMAudioDecoderPropertyID_Command, &a_command, sizeof(a_command), 0); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot send audio command, %s\n", RMstatusToString(err))); return err; } evt.ModuleID = audio_decoder; evt.Mask = RUAEVENT_COMMANDCOMPLETION; err = RUAWaitForMultipleEvents(pRUA, &evt, 1, WAIT_COMMAND_TIMEOUT_US, &index); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "wait for audio command completion %d failed, %s\n", a_command, RMstatusToString(err))); return err; } err = RUAGetProperty(pRUA, audio_decoder, RMAudioDecoderPropertyID_State, &state, sizeof(state)); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot get audio state, %s\n", RMstatusToString(err))); return err; } RMDBGLOG((LOCALDBG, "(audio decoder : %lu) Now AUDIO state = %s\n", audio_decoder, AUDIO_STATE_TO_STRING(state))); return RM_OK;}RMstatus DCCSetAudioDecoderSourceFormat(struct DCCAudioSource *pAudioSource, struct DCCAudioDecoderFormat *pFormat){ RMstatus err; enum AudioDecoder_Codec_type codec; err = send_audio_command(pAudioSource->pRUA, pAudioSource->decoder_moduleID, AudioDecoder_Command_Uninit); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot send AudioDecoder_Command_Uninit, %s\n", RMstatusToString(err))); return err; } codec = pFormat->Codec; DCCSP(pAudioSource->pRUA, pAudioSource->decoder_moduleID, RMAudioDecoderPropertyID_Codec, &codec, sizeof(codec)); return send_audio_command(pAudioSource->pRUA, pAudioSource->decoder_moduleID, AudioDecoder_Command_Init);}RMstatus DCCSetAudioBtsThreshold(struct DCCAudioSource *pAudioSource, RMuint32 level){ RMDBGLOG((LOCALDBG," >>>>>> Set AudioBtsThreshold %lu\n", level)); DCCSP(pAudioSource->pRUA, pAudioSource->decoder_moduleID, RMAudioDecoderPropertyID_AudioBtsThreshold, &level, sizeof(RMuint32)); return RM_OK;}RMstatus DCCSetAudioBSACFormat(struct DCCAudioSource *pAudioSource, struct AudioDecoder_BSACParameters_type *pFormat){ RMstatus err; enum AudioDecoder_Codec_type codec = AudioDecoder_Codec_BSAC; RMDBGLOG((ENABLE, "Set MPEG-4 BSAC audio format\n")); err = send_audio_command(pAudioSource->pRUA, pAudioSource->decoder_moduleID, AudioDecoder_Command_Uninit); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot AudioDecoder_Command_Uninit, %s\n", RMstatusToString(err))); return err; } DCCSP(pAudioSource->pRUA, pAudioSource->decoder_moduleID, RMAudioDecoderPropertyID_Codec, &codec, sizeof(codec)); DCCSP(pAudioSource->pRUA, pAudioSource->decoder_moduleID, RMAudioDecoderPropertyID_BSACParameters, pFormat, sizeof(struct AudioDecoder_BSACParameters_type)); return send_audio_command(pAudioSource->pRUA, pAudioSource->decoder_moduleID, AudioDecoder_Command_Init);}RMstatus DCCSetAudioAc3Format(struct DCCAudioSource *pAudioSource, struct AudioDecoder_Ac3Parameters_type *pFormat){ RMstatus err; enum AudioDecoder_Codec_type codec = AudioDecoder_Codec_AC3; RMDBGLOG((ENABLE, "Set AC3 audio\n")); err = send_audio_command(pAudioSource->pRUA, pAudioSource->decoder_moduleID, AudioDecoder_Command_Uninit);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -