📄 play_multiple_audio.c
字号:
/* * * Copyright (c) Sigma Designs, Inc. 2002, 2007 All rights reserved. * Cleanup version *//*** * @file play_multiple_audio.c* @brief sample application to test audio mixing* * * @ingroup samplecode* * $Revision: 1.46 $ $Date: 2007-10-31 01:11:03 $*/#include <ctype.h>#include "../samples/sample_os.h"#define ALLOW_OS_CODE 1#include "../dcc/include/dcc.h"#include "../samples/common.h"//--------WMA#include "../rmasfdemux/include/rmasfdemuxapi.h"#include "../rmasfdemux/include/wmdrm.h"#include "../rmasfdemux/include/wmdrmopl.h"#include "../rmwmaprodecoder/include/rmwmaprodefine.h"#include "../rmwmaprodecoder/include/rmwmaprodecoderapi.h"#include "play_multiple_audio.h"//-------//#define DBX#include "../dcc/src/dcc_common.h"#if 1#define TMP_FIX_MIX_WEIGHT_KEYS 0 //Temporary fix the key pressing features of Weight Mixing#else#define TMP_FIX_MIX_WEIGHT_KEYS 1 //Temporary fix the key pressing features of Weight Mixing#endif#if 1 // Define 1 if using audio mixing, 0 without.#define TMP_MIX_AUDIO_ENGINES 1 // for testing mixing of audio engines#else#undef TMP_MIX_AUDIO_ENGINES // for testing mixing of audio engines#endif#define AUDIOSTRMDBG ENABLE#define PAYLOADDBG DISABLE#define TRICKDBG DISABLE#define SENDDBG DISABLE#define WMAPRODBG DISABLE#define RESET_EOF (0x00)#define MARK_EOF (0x01)#define GETBUFFER_TIMEOUT_US (0) //1000000#define WAIT_EOS_TIMEOUT_US (10000) //Reduce from 1 min to 10000us to avoid silence at waiting EOS, //application will keep waiting even its timeout till an EOS event occured#define DMA_BUFFER_SIZE_LOG2 (17) //16 //15#define DMA_BUFFER_COUNT (8) //16 //32#define DMA_PCMX_BUFFER_SIZE_LOG2 (17) //16 //15#define DMA_PCMX_BUFFER_COUNT (2) //4 //8#define SENDDATA_TIMEOUT_US 1000000#define REPACK_SIZE (4096)#define AUDIO_FIFO_SIZE (1024*1024)#define XFER_FIFO_COUNT (32)#define AUDIO_PCMX_FIFO_SIZE (512*1024)#define XFER_PCMX_FIFO_COUNT (32)#define KEYFLAGS (SET_KEY_PLAYBACK | SET_KEY_AUDIO)#define RM_DEVICES_STC (0x1)#define RM_DEVICES_AUDIO (0x4)#define MAX_WMAPRO_INFO (128)//PLAY MUL AUDIO STATUS#define ASF_DMA_BUFFER_SIZE_LOG2 (15) // 32kB#define ASF_DMA_BUFFER_COUNT (16) // 16*32kB ~= 512KB#ifdef WMAPRO_V1#define AUDIO_DMA_BUFFER_SIZE_LOG2 (16 // 64kB#define AUDIO_DMA_BUFFER_COUNT (2) // 2*64kB ~= 128KB#else#define AUDIO_DMA_BUFFER_SIZE_LOG2 (17) // 128kB#define AUDIO_DMA_BUFFER_COUNT (2) // 2*128kB ~= 256KB#endif // average video packet size = 2k#define VIDEO_XFER_FIFO_COUNT (ASF_DMA_BUFFER_COUNT * (1 << ASF_DMA_BUFFER_SIZE_LOG2) / 2048) // average audio packet size = 2k#define AUDIO_XFER_FIFO_COUNT (AUDIO_DMA_BUFFER_COUNT * (1 << AUDIO_DMA_BUFFER_SIZE_LOG2) / 2048)/* do NOT increase these values unless you have a reason to, otherwise, curacao wont be able to run due to lack of memory */#define ASF_VIDEO_FIFO_SIZE (3 * 1024 * 1024) // 3s @ 1MB/s#define ASF_AUDIO_FIFO_SIZE (5 * 1024 * 1024) // 5s @ 1MB/s#define ASF_KEYFLAGS (SET_KEY_DISPLAY | SET_KEY_PLAYBACK | SET_KEY_AUDIO | SET_KEY_DEBUG | SET_KEY_SPI)#define MAX_INDEX_NUMBER (5)#define INDEX_BUFFER_SIZE (200 * 1024)#define RM_DEVICES_VIDEO (0x2)#define RM_STREAM_VIDEO (0x1)#define RM_STREAM_AUDIO (0x2)#define RM_SKIP_TO_RESYNC (0x1)#define ALL_ON (0x03)#define MAX_NUMBER_OF_AUDIO_STREAMS (16)#define RMAUDIO_4_28_CONVERT (1<<28)#define DELTA_PTS (100) // 1 sec#define CONTIGUOUS_LENGHT (0x100000) // 1 MB#define MAX_TASK_COUNT (4)#define MAX_ENGINE_COUNT (2)#define MAX_DECODER_COUNT (4)/* * Globals, should be explicitely initialized in init_globals */static RMbool bypass_drm;static RMuint32 audioStreams;static RMuint32 audioStreamTable[10];static struct audio_cmdline *asf_audio_opt;static struct playback_cmdline *asf_play_opt;static struct priv_cmdline priv_opt;// Support Multiple Audio Decoder PlayBackstatic RMbool rptpcmx = FALSE;#if (TMP_FIX_MIX_WEIGHT_KEYS) // Used for weighted audio output static struct AudioDecoder_MixerWeight_type cmdblock;static RMuint32 weight[MAX_TASK_COUNT][8]={ {100,100,100,100,100,100,100,100}, {100,100,100,100,100,100,100,100}, {100,100,100,100,100,100,100,100}, {100,100,100,100,100,100,100,100}};#endifstatic struct RUAEvent e[MAX_TASK_COUNT];static RMuint32 nEvents = 0;static RMuint32 pcmx_rcnt = 0;static RMbool nEOS[MAX_TASK_COUNT] = { FALSE, FALSE, FALSE, FALSE};static RMuint32 nStatus[MAX_TASK_COUNT]={ 0x02,0x02,0x02,0x02};static enum EMhwlibAudioEngineMixMode MixingMode = EMhwlibAudioEngineMixMode_None;static RMuint32 MixingEngineMaster = 0;// Task list similar to ply_mul_videostatic struct audio_context context[MAX_TASK_COUNT];static struct dcc_context dcc_info[MAX_TASK_COUNT] = {{0,},{0,},{0,},{0,}};static struct dcc_context *pdcc_info[MAX_TASK_COUNT]; /*access through play_opt*/static struct playback_cmdline playback_options[MAX_TASK_COUNT]; /*access through disp_opt*/static struct audio_cmdline audio_options[MAX_TASK_COUNT];static struct playback_cmdline *play_opt;static struct audio_cmdline *audio_opt;static struct RM_PSM_Context PSMcontext;static struct RM_PSM_Actions actions;static struct asf_context SendContext[MAX_TASK_COUNT] = {{0,},{0,},{0,},{0,}};static struct stream_options_s stream_options[MAX_TASK_COUNT];static struct RMfifo wmapro_fifo[MAX_TASK_COUNT];static struct wmapro_buffer_info wmapro_info_array[MAX_TASK_COUNT][MAX_WMAPRO_INFO];#define db(txt) fprintf(stderr,txt);/* PMA protoypes */static void PMAAddEvents(struct RUAEvent e[], RMuint32* nEvents, RMuint32 mask, RMuint32 decoder);static int PMAConfigEngine(int decoder,struct DCC* pDCC, struct RUA* pRUA);static int PMAConfigDecoder(int decoder,struct DCC* pDCC, struct RUA* pRUA);static int PMAAsfDemuxConfig ( int decoder, struct DCC* pDCC, struct RUA* pRUA);/* prototypes */static RMstatus asfStop(struct asf_context *pSendContext, RMuint32 devices);static RMstatus asfPlay(struct asf_context * pSendContext, RMuint32 devices, enum DCCVideoPlayCommand mode);static RMstatus setup_audio_decoder(struct asf_context *pSendContext);static RMstatus init_private_options(struct priv_cmdline *options){ return RM_OK;}static void print_Audio_Stream_Properties ( void *context, unsigned char Stream_Number, unsigned short Codec_ID, unsigned short Number_of_Channels, unsigned long Samples_Per_Second, unsigned long Average_Number_of_Bytes_Per_Second, unsigned short Block_Alignment, unsigned short Bits_Per_Sample, unsigned char *Codec_Specific_Data, unsigned long Partial_Codec_Specific_Data_Size, unsigned long Codec_Specific_Data_Size ){ struct asf_context *pSendContext = (struct asf_context *) context; struct AudioDecoder_WMAParameters_type *wma_params = &(pSendContext->wma_params); RMstatus status; pSendContext->WMAPROBitsPacketLength = 0; pSendContext->Audio_Codec_Specific_Data_Received += Partial_Codec_Specific_Data_Size; RMDBGLOG((AUDIOSTRMDBG,"print_Audio_Stream_Properties %lu, %lu, %lu\n", pSendContext->Audio_Codec_Specific_Data_Received, Partial_Codec_Specific_Data_Size, Codec_Specific_Data_Size)); if (Partial_Codec_Specific_Data_Size == Codec_Specific_Data_Size) pSendContext->Audio_Codec_Specific_Data_Received = Codec_Specific_Data_Size; if (pSendContext->Audio_Codec_Specific_Data_Received == Codec_Specific_Data_Size) { audioStreamTable[audioStreams++] = Stream_Number; RMDBGLOG((AUDIOSTRMDBG, "Stream #%hu - Audio - \n", Stream_Number)); RMDBGLOG((AUDIOSTRMDBG, "%hu channel(s), %lu samples/second, %hu bits/sample\n", Number_of_Channels, Samples_Per_Second, Bits_Per_Sample)); RMDBGLOG((AUDIOSTRMDBG, " Bitrate: %lu bit/s, Block size is 0x%04x bytes [0x%05x bits]\n", Average_Number_of_Bytes_Per_Second * 8, Block_Alignment, Block_Alignment * 8)); wma_params->VersionNumber = Codec_ID; wma_params->SamplingFrequency = Samples_Per_Second; wma_params->NumberOfChannels = Number_of_Channels; wma_params->Bitrate = Average_Number_of_Bytes_Per_Second * 8; wma_params->PacketSize = Block_Alignment * 8; wma_params->EncoderOptions = 0; wma_params->BitsPerSample = Bits_Per_Sample; wma_params->WMAProValidBitsPerSample = Bits_Per_Sample; wma_params->WMAProChannelMask = 0; wma_params->WMAProVersionNumber = 0; wma_params->OutputChannels = asf_audio_opt->WmaParams.OutputChannels; if (Codec_ID == 0x160) { // WMA Audio Version 1 RMDBGLOG((AUDIOSTRMDBG, "error, codec WMA Audio Version 1 not supported, disable audio\n")); pSendContext->SendAudioData = FALSE; return; } // Audio Codec Type Specific data in ASF if ( (Codec_ID == 0x161) || // WMA Audio Version 2 (Codec_ID == 0x7A21) || (Codec_ID == 0x7A22) ) { // 4 + 2 + 4 if (10 == Codec_Specific_Data_Size) { RMuint32 dwSamplesPerBlock; RMuint16 wEncodeOptions; RMuint32 dwSuperBlockAlign; dwSamplesPerBlock = (((RMuint32) Codec_Specific_Data[3]) << 24) + (((RMuint32) Codec_Specific_Data[2]) << 16) + (((RMuint32) Codec_Specific_Data[1]) << 8) + ((RMuint32) Codec_Specific_Data[0]); wEncodeOptions = + (((RMuint16) Codec_Specific_Data[5]) << 8) + ((RMuint16) Codec_Specific_Data[4]); dwSuperBlockAlign = (((RMuint32) Codec_Specific_Data[9]) << 24) + (((RMuint32) Codec_Specific_Data[8]) << 16) + (((RMuint32) Codec_Specific_Data[7]) << 8) + ((RMuint32) Codec_Specific_Data[6]); RMDBGLOG((AUDIOSTRMDBG, " Audio codec ID: %04x,\n" " Bits per block: 0x%04x\n" " Encode option: 0x%04x \n", (int) Codec_ID, (int) dwSamplesPerBlock, (int) wEncodeOptions)); wma_params->EncoderOptions = wEncodeOptions; } else { RMDBGLOG((AUDIOSTRMDBG, "Error: audio specific data has invalid size (%d)\n", (int) Codec_Specific_Data_Size)); } } // WMA pro type specific data (untested yet..) // WMA Audio Pro or WMALSL if ((Codec_ID == 0x162) || (Codec_ID == 0x163)) { RMuint16 wValidBitsPerSample; RMuint32 dwChannelMask; RMuint16 wEncodeOptions; wValidBitsPerSample = + (((RMuint16) Codec_Specific_Data[1]) << 8) + ((RMuint16) Codec_Specific_Data[0]); dwChannelMask = (((RMuint32) Codec_Specific_Data[5]) << 24) + (((RMuint32) Codec_Specific_Data[4]) << 16) + (((RMuint32) Codec_Specific_Data[3]) << 8) + ((RMuint32) Codec_Specific_Data[2]); wEncodeOptions = + (((RMuint16) Codec_Specific_Data[15]) << 8) + ((RMuint16) Codec_Specific_Data[14]); RMDBGLOG((AUDIOSTRMDBG, " Audio codec ID: %04x,\n" " %u valid bits/sample, %08X channel mask\n" " 0x%04x encode options\n", (int) Codec_ID, (int) wValidBitsPerSample, (int) dwChannelMask, (int) wEncodeOptions)); wma_params->EncoderOptions = wEncodeOptions; wma_params->WMAProValidBitsPerSample = wValidBitsPerSample; wma_params->WMAProChannelMask = dwChannelMask; } wma_params->OutputDualMode = asf_audio_opt->OutputDualMode; wma_params->OutputSpdif = asf_audio_opt->Spdif; pSendContext->audio_stream_index = Stream_Number; RMDBGLOG((AUDIOSTRMDBG, "audioStreamTable[%ld]=%ld\n", audioStreams-1, Stream_Number)); if (!pSendContext->SendAudioData) { RMDBGLOG((AUDIOSTRMDBG, ">>> audio stream found, enabling audio playback\n")); pSendContext->AudioStreamFound = TRUE; status = setup_audio_decoder(pSendContext); if (RMFAILED(status)) { RMDBGLOG((AUDIOSTRMDBG,"Error initializing audio\n")); pSendContext->SendAudioData = FALSE; } else { pSendContext->SendAudioData = asf_play_opt->send_audio; if (!(pSendContext->dcc_info->seek_supported)) /* Seek is not supported, do play now */ asfPlay(pSendContext, RM_DEVICES_AUDIO, DCCVideoPlayFwd); } } }}static RMuint32 ResyncAudio(struct asf_context *pSendContext, RMuint32 Presentation_Time){ RMuint64 CurrentSTC; RMint32 CutSTC; struct AudioDecoder_WMAParameters_type *wma_params = &(pSendContext->wma_params); RMuint32 codec = (RMuint32)wma_params->VersionNumber; if (!pSendContext->FirstSystemTimeStamp) { DCCSTCGetTime(pSendContext->dcc_info->pStcSource, &CurrentSTC, pSendContext->video_vop_tir); CutSTC = CurrentSTC & 0xffffffff; if ( (RMint32)(Presentation_Time - CutSTC) <= 0) { RMDBGLOG((AUDIOSTRMDBG, "Current STC = %lld PTS=%lu skipping to resync\n", CurrentSTC, Presentation_Time)); if (pSendContext->compressed_audio) { RMWMAProVDecoderFlushParser(pSendContext->vDecoder); } if (codec != 0x161) return RM_SKIP_TO_RESYNC; } } return 0;}static RMstatus initAudioDecoder(struct asf_context * context){ if (context->audio_decoder_initialized == FALSE) { RMstatus status = RM_ERROR; struct AudioDecoder_WMAParameters_type *wma_params = &(context->wma_params); RMuint32 codec; RMDBGLOG((AUDIOSTRMDBG, "initAudioDecoder\n")); codec = (RMuint32)wma_params->VersionNumber; switch (codec) { case 0x161: case 0x7A21: case 0x7A22:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -