📄 play_audio.c
字号:
RMuint8 *buf = NULL; //dma buffers RMuint32 i; RMuint32 size = 0; RMascii key;#ifdef WITH_BSAC // this allow the first audio decoder to play BSAC RMuint32 bsac_frame_size; RMuint32 DMA_buf_size; RMuint32 bsac_get_info_done;#endif // WITH_BSAC #ifdef WITH_MONO /*make the mono arguments global*/ context.play_opt = mono->play_opt; context.audio_opt = mono->audio_opt; context.audioInstances = context.audio_opt[0].audioInstances; RMDBGLOG((ENABLE, "audio instances %lu, %lu\n", context.audioInstances, context.audio_opt[0].audioInstances)); print_parsed_audio_options(context.audio_opt); dcc_info.pRUA = mono->pRUA; dcc_info.pDCC = mono->pDCC; #else context.play_opt = &playback_options; context.audio_opt = audio_options; init_audio_options2(context.audio_opt, MAX_AUDIO_DECODER_INSTANCES); init_playback_options(context.play_opt); for (i = 0; i < MAX_AUDIO_DECODER_INSTANCES; i++) context.audio_opt[i].dh_info = &dh_info; parse_cmdline(&context, argc, argv, &context.audioInstances); context.audioInstances++; RMDBGLOG((ENABLE, "audio instances %lu, %lu\n", context.audioInstances, context.audio_opt[0].audioInstances)); print_parsed_audio_options(context.audio_opt); err = RUACreateInstance(&(dcc_info.pRUA), context.play_opt->chip_num); if (RMFAILED(err)) { fprintf(stderr, "Error creating RUA instance! %d\n", err); return -1; } err = DCCOpen(dcc_info.pRUA, &(dcc_info.pDCC)); if (RMFAILED(err)) { fprintf(stderr, "Error Opening DCC! %d\n", err); return -1; } if (!context.play_opt->noucode) { err = DCCInitMicroCodeEx(dcc_info.pDCC, DCCInitMode_LeaveDisplay); if (RMFAILED(err)) { fprintf(stderr, "Cannot initialize microcode %d\n", err); return -1; } } else RMDBGLOG((ENABLE, "microcode not loaded\n")); display_key_usage(KEYFLAGS);/* dcc_info.pRUA = pRUA; *//* dcc_info.pDCC = pDCC; */#endif audio_capture = EMHWLIB_MODULE(AudioCapture, context.audio_opt->AudioEngineID); /* if HD control is enabled and mode is auto, setup parameters */ if ((context.play_opt->disk_ctrl_low_level) && (context.play_opt->disk_ctrl_log2_block_size) && (context.play_opt->disk_ctrl_max_mem)) { RMuint32 bufferSize = 0; RMuint32 bufferCount = 0; RMuint32 log2BlockSize = context.play_opt->disk_ctrl_log2_block_size; RMuint32 maxBufferingMem = context.play_opt->disk_ctrl_max_mem; bufferSize = (1 << log2BlockSize); bufferCount = maxBufferingMem >> log2BlockSize; context.play_opt->dmapool_count = bufferCount; context.play_opt->dmapool_log2size = log2BlockSize; /* from #4005 videoOpt.fifo_size = 4*1024*1024; videoOpt.xfer_count = (1<<playOpt.dmapool_log2size)/1024*playOpt.dmapool_count; audioOpt.fifo_size = 1*1024*1024; audioOpt.xfer_count = (1<<playOpt.dmapool_log2size)/512*playOpt.dmapool_count; */ if (context.play_opt->disk_ctrl_low_level >= bufferCount) context.play_opt->disk_ctrl_low_level = bufferCount >> 1; context.audio_opt[0].fifo_size = 2 * (1024 * 1024); fprintf(stderr, ">> low level %lu => %lu bytes bufferized (+ bitstreamFIFO)\n", context.play_opt->disk_ctrl_low_level, context.play_opt->disk_ctrl_low_level * bufferSize); context.audio_opt[0].xfer_count = bufferCount * 2; err = setup_disk_control_parameters(&dcc_info, context.play_opt, &(context.audio_opt[0]), NULL, NULL); if (err != RM_OK) { fprintf(stderr, "Error %d trying to setup HD control params\n", err); return -1; } } /* update fifo and xfer size */ for (i = 0; i < context.audioInstances; i++) { if (!context.audio_opt[i].fifo_size) context.audio_opt[i].fifo_size = AUDIO_FIFO_SIZE; if (!context.audio_opt[i].xfer_count) context.audio_opt[i].xfer_count = XFER_FIFO_COUNT; } /* update dmapool size and count */ if (!context.play_opt->dmapool_count) context.play_opt->dmapool_count = DMA_BUFFER_COUNT; if (!context.play_opt->dmapool_log2size) context.play_opt->dmapool_log2size = DMA_BUFFER_SIZE_LOG2; for (i = 0; i < context.audioInstances; i++) { RMDBGLOG((ENABLE, "Audio[%lu]:\n\tBitstreamFIFOSize: %lu\n\tFIFOXFERCount: %lu\n", i, context.audio_opt[i].fifo_size, context.audio_opt[i].xfer_count)); } RMDBGLOG((ENABLE, "DMA Pool:\n\tSize: %ld\n\tBufferCount: %ld\n\tBufferSize: %ld\n", (context.play_opt->dmapool_count << context.play_opt->dmapool_log2size), context.play_opt->dmapool_count, (1<<context.play_opt->dmapool_log2size))); context.dmabuffer_array = (void **) NULL; context.dmabuffer_index = 0; switch (context.play_opt->disk_ctrl_state) { case DISK_CONTROL_STATE_DISABLE: break; case DISK_CONTROL_STATE_SLEEPING: case DISK_CONTROL_STATE_RUNNING: context.dmabuffer_array = (void **) RMMalloc(sizeof(void*) * context.play_opt->dmapool_count); context.dmabuffer_index = 0; if (context.dmabuffer_array == NULL) { RMDBGLOG((ENABLE, "Cannot allocate dmapool array! Disable disk control\n")); context.play_opt->disk_ctrl_state = DISK_CONTROL_STATE_DISABLE; } break; } err = apply_playback_options(&dcc_info, context.play_opt); if (RMFAILED(err)) { fprintf(stderr, "Cannot set playback options %d\n", err); return -1; } { // open first stc module struct DCCStcProfile stc_profile; RMDBGLOG((ENABLE, "using STC ID %lu\n", context.play_opt->STCid)); stc_profile.STCID = context.play_opt->STCid; stc_profile.master = Master_STC; stc_profile.stc_timer_id = 3*stc_profile.STCID+0; stc_profile.stc_time_resolution = 90000; stc_profile.video_timer_id = NO_TIMER; stc_profile.video_time_resolution = 0; stc_profile.video_offset = 0; stc_profile.audio_timer_id = 3*stc_profile.STCID+1; stc_profile.audio_time_resolution = 90000; stc_profile.audio_offset = -(context.play_opt->audio_delay_ms * (RMint32)stc_profile.audio_time_resolution / 1000); err = DCCSTCOpen(dcc_info.pDCC, &stc_profile, &dcc_info.pStcSource); if (RMFAILED(err)) { fprintf(stderr, "Cannot open stc module %d\n", err); return -1; } } if (context.audio_opt[0].AudioIn) { // Audio pass-through struct AudioEngine_STC_type ae_stc; // Start Audio STC (has to be done before opening the AudioDecoder) ae_stc.Enable = TRUE; ae_stc.time_resolution = 90000; ae_stc.time = 0; err = RUASetProperty(dcc_info.pRUA, EMHWLIB_MODULE(AudioEngine, context.audio_opt[0].AudioEngineID), RMAudioEnginePropertyID_STC, &ae_stc, sizeof(ae_stc), 0); } { struct DCCAudioProfile audio_profiles[MAX_AUDIO_DECODER_INSTANCES]; for (i = 0; i < context.audioInstances; i++) { audio_profiles[i].BitstreamFIFOSize = context.audio_opt[i].fifo_size; audio_profiles[i].XferFIFOCount = context.audio_opt[i].xfer_count; audio_profiles[i].DemuxProgramID = context.audio_opt[i].AudioEngineID * 2; audio_profiles[i].AudioEngineID = context.audio_opt[i].AudioEngineID; audio_profiles[i].AudioDecoderID = context.audio_opt[i].AudioDecoderID; audio_profiles[i].STCID = context.play_opt->STCid; } err = DCCOpenMultipleAudioDecoderSource(dcc_info.pDCC, audio_profiles, context.audioInstances, &(dcc_info.pMultipleAudioSource)); if (RMFAILED(err)) { fprintf(stderr, "Cannot open multiple audio decoder %d\n", err); goto cleanup; } } // apply the sample rate, serial out status for (i = 0; i < context.audioInstances; i++) { err = apply_audio_engine_options(&dcc_info, &(context.audio_opt[i])); if (RMFAILED(err)) { fprintf(stderr, "Error applying audio engine options %d\n", err); goto cleanup; } } apply_dvi_hdmi_audio_options(&dcc_info, &(context.audio_opt[0]), 0, FALSE, FALSE, FALSE); RMMicroSecondSleep(250 * 1000); // Give HDMI sink 1/4 Sec to set up audio, as audio-only content should be audible from the beginning on if (!context.audio_opt[0].AudioIn) { /* when capture, send buffer are not needed */ /* dmapool must be created after the module open in case we do no copy transfers */ err = RUAOpenPool(dcc_info.pRUA, 0, context.play_opt->dmapool_count, context.play_opt->dmapool_log2size, RUA_POOL_DIRECTION_SEND, &(context.pDMA)); }#ifndef WITH_BSAC#else RMDBGLOG((ENABLE, "BSAC decoding is enabled\n"));#endif //WITH_BSAC// if(context.audio_opt[0]->Codec != AudioDecoder_Codec_BSAC)// err = RUAOpenPool(dcc_info.pRUA, dcc_info.audio_decoder, DMA_BUFFER_COUNT, DMA_BUFFER_SIZE_LOG2, RUA_POOL_DIRECTION_SEND, &(context.pDMA));// else// err = RUAOpenPool(dcc_info.pRUA, 0, DMA_BUFFER_COUNT, DMA_BUFFER_SIZE_LOG2, RUA_POOL_DIRECTION_SEND, &(context.pDMA)); if (RMFAILED(err)) { RMuint32 poolSize = context.play_opt->dmapool_count << context.play_opt->dmapool_log2size; fprintf(stderr, "Error cannot open dmapool %d\n\n" "requested %lu bytes of dmapool (%lu buffers of %lu bytes), make sure you\n" "loaded llad with the right parameters. For example:\n" "max_dmapool_memory_size >= %lu max_dmabuffer_log2_size >= %lu\n\n", err, poolSize, context.play_opt->dmapool_count, (RMuint32)(1<<context.play_opt->dmapool_log2size), poolSize, context.play_opt->dmapool_log2size); goto cleanup; } /* TODO update the code with MULTIPLE AUDIO SUPPORT */#if 0 if( (context.audio_opt[0].Codec == AudioDecoder_Codec_WMA) || (context.audio_opt[0].Codec == AudioDecoder_Codec_WMAPRO) ) { // add code just for debug wma spdif - all parameters are harcoded here: struct AudioDecoder_WMAParameters_type wma_params; wma_params.VersionNumber = 0x162;// WMA PRO wma_params.SamplingFrequency = 48000; wma_params.NumberOfChannels = 6; wma_params.Bitrate = 384000; wma_params.PacketSize = 0x2000; wma_params.BitsPerSample = 24; wma_params.EncoderOptions = 0xe0; wma_params.WMAProVersionNumber = 0; wma_params.WMAProValidBitsPerSample = 24; wma_params.WMAProChannelMask = 0x3f; wma_params.OutputDualMode = context.audio_opt[0].OutputDualMode; wma_params.OutputSpdif = context.audio_opt[0].Spdif;#if 1 /* Open the file and read parameters from intermediate format */ file = open_stream(context.play_opt->filename, RM_FILE_OPEN_READ, 0); if (file == NULL) { fprintf(stderr, "Cannot open file %s\n", context.play_opt->filename); goto cleanup; } if (RMFAILED(parse_wmapro_intermediate(file, &wma_params))) { fprintf(stderr, "Cannot find sequence header!\n"); goto cleanup; } RMCloseFile(file);#endif // 1 DCCSetAudioWMAFormat(dcc_info.pAudioSource, &wma_params); // wma_params.SamplingFrequency fprintf(stdout, " set audio_freq = %ldHz (ignore any audio_freq in cmdline)\n", wma_params.SamplingFrequency); RUASetProperty(dcc_info.pRUA, EMHWLIB_MODULE(AudioEngine, context.audio_opt[0].AudioEngineID), RMAudioEnginePropertyID_SampleFrequency, &wma_params.SamplingFrequency, sizeof(wma_params.SamplingFrequency), 0); context.audio_opt[0].SampleRate = wma_params.SamplingFrequency; apply_dvi_hdmi_audio_options(&dcc_info, &(context.audio_opt[0]), wma_params.NumberOfChannels, TRUE, TRUE, FALSE); } else #endif // 0 { // apply the audio format - uninit, set codec, set specific parameters, init for (i = 0; i < context.audioInstances; i++) { err = apply_audio_decoder_options(&dcc_info, &(context.audio_opt[i])); if (RMFAILED(err)) { fprintf(stderr, "Error applying audio_decoder_options %d\n", err); goto cleanup; } } }#ifndef WITH_MONO RMTermInit(TRUE); // don't allow ctrl-C and the like ... RMSignalInit(NULL, NULL); // ... but catch other termination signals to call RMTermExit()#endif // pcm should start at the correct sample position if (context.audio_opt[0].Codec == AudioDecoder_Codec_PCM) { RMuint32 BitsPerSample = 0; RMuint32 channels = 0; if ( context.audio_opt[0].SubCodec == 0 || context.audio_opt[0].SubCodec == 3) { BitsPerSample = context.audio_opt[0].PcmCdaParams.BitsPerSample; if (context.audio_opt[0].PcmCdaParams.ChannelAssign == PcmCda1_C) channels = 1; else if (context.audio_opt[0].PcmCdaParams.ChannelAssign == PcmCda2_LR) channels = 2; else if (context.audio_opt[0].PcmCdaParams.ChannelAssign == PcmCda6_LfRfCLfeLsRs) channels = 6; else channels = 2; // choose a default value RMDBGLOG((ENABLE, "pcmcda (-pcmN_M) with M=%lu chan and N=%lu bits, subcodec %lu\n", channels, BitsPerSample, context.audio_opt[0].SubCodec)); } else if ( context.audio_opt[0].SubCodec == 1 ) { BitsPerSample = context.audio_opt[0].LpcmVobParams.BitsPerSample; if (context.audio_opt[0].LpcmVobParams.ChannelAssign == LpcmVob1_C) channels = 1; else channels = 2; RMDBGLOG((ENABLE, "lpcm with %lu chan and %lu bits, subcodec %lu\n", channels, BitsPerSample, context.audio_opt[0].SubCodec)); } else if ( context.audio_opt[0].SubCodec == 2 ) { BitsPerSample = context.audio_opt[0].LpcmAobParams.BitsPerSampleGroup1; if (context.audio_opt[0].LpcmAobParams.ChannelAssign == LpcmAob10_C) channels = 1; else channels = 2; RMDBGLOG((ENABLE, "lpcmAOB with %lu chan and %lu bits, subcodec %lu\n", channels, BitsPerSample, context.audio_opt[0].SubCodec)); } else RMDBGLOG((ENABLE, "unknown subcodec %lu\n", context.audio_opt[0].SubCodec)); context.PCMblockSize = (BitsPerSample * channels) >> 3; context.PCMblockSize *= 2; //this makes the rule generic and fixes #4434 RMDBGLOG((ENABLE, ">> audio is PCM %lu bits, %lu channels, blockSize %lu\n", BitsPerSample, channels, context.PCMblockSize)); } //////////////////////////////////////////////////////////////////////// // audio capture start when requested //////////////////////////////////////////////////////////////////////// if (context.audio_opt[0].AudioIn) { // Audio pass-through // apply the audio format - uninit, set codec, set specific parameters, init err = apply_audio_decoder_options(&dcc_info, &(context.audio_opt[0])); if (RMFAILED(err)) { fprintf(stderr, "Error applying audio_decoder_options %d\n", err); goto cleanup;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -