📄 play_multiple_audio.c
字号:
} wma_params->OutputDualMode = asf_audio_opt->OutputDualMode; wma_params->OutputSpdif = asf_audio_opt->Spdif; pSendContext->audio_stream_index = Stream_Number; RMDBGLOG((ENABLE, "audioStreamTable[%ld]=%ld\n", audioStreams-1, Stream_Number)); if (!pSendContext->SendAudioData) { RMDBGLOG((ENABLE, ">>> audio stream found, enabling audio playback\n")); pSendContext->AudioStreamFound = TRUE; status = setup_audio_decoder(pSendContext); if (RMFAILED(status)){ RMDBGLOG((ENABLE,"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); } } }}///////////////////YYYYstatic 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((ENABLE, "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((ENABLE, "initAudioDecoder\n")); codec = (RMuint32)wma_params->VersionNumber; switch (codec) { case 0x161: case 0x7A21: case 0x7A22: // WMA if (context->compressed_audio) { fprintf(stderr, ">>> Error: audio specified is WMAPro while detected is WMA\n"); context->compressed_audio = FALSE; return RM_ERROR; } break; case 0x162: // WMAPro if (!context->compressed_audio) { fprintf(stderr, ">>> Error: audio specified is WMA while detected is WMAPro\n"); context->compressed_audio = TRUE; return RM_ERROR; } break; case 0x163: // WMALSL RMDBGLOG((ENABLE, "initAudioDecoder: WMALSL\n")); if (!context->compressed_audio) { fprintf(stderr, ">>> Error: audio specified is WMA while detected is WMALSL\n"); context->compressed_audio = TRUE; return RM_ERROR; } break; default: // wrong codec fprintf(stderr, "error wrong codec %lx, disabling audio\n", codec); context->compressed_audio = FALSE; context->SendAudioData = FALSE; return RM_ERROR; break; } if (context->compressed_audio) { RMstatus err; RMMetaWMAParameters temp_wmaparams; temp_wmaparams.VersionNumber = wma_params->VersionNumber; temp_wmaparams.SamplingFrequency = wma_params->SamplingFrequency; temp_wmaparams.NumberOfChannels = wma_params->NumberOfChannels; temp_wmaparams.Bitrate = wma_params->Bitrate; temp_wmaparams.PacketSize = wma_params->PacketSize; temp_wmaparams.EncoderOptions = wma_params->EncoderOptions; temp_wmaparams.BitsPerSample = wma_params->BitsPerSample; temp_wmaparams.WMAProValidBitsPerSample = wma_params->WMAProValidBitsPerSample; temp_wmaparams.WMAProChannelMask = wma_params->WMAProChannelMask; temp_wmaparams.WMAProVersionNumber = wma_params->WMAProVersionNumber; temp_wmaparams.OutputChannels = wma_params->OutputChannels; if(context->vDecoder == (void *)NULL) { RMDBGLOG((ENABLE,"******** using RMF's WMAPRO decoder ********\n")); err = RMCreateWMAProVDecoder(&(context->vDecoder)); if (err != RM_OK) { RMDBGLOG((ENABLE,"error: cant create wmaproVdecoder!\n")); return RM_ERROR; } err = RMWMAProVDecoderOpen(context->vDecoder); if (err != RM_OK) { RMDBGLOG((ENABLE,"error: cant open wmaproVdecoder!\n")); return RM_ERROR; } } if (context->vDecoder != (void *)NULL) { err = RMWMAProVDecoderInit(context->vDecoder, wma_params->EncoderOptions, wma_params->PacketSize, &temp_wmaparams); if (err != RM_OK) RMDBGLOG((ENABLE, "wmaprodecoder init error\n")); } else { RMDBGLOG((ENABLE, "calling wmaprodecoder init before open!\n")); } } if(codec != 0x163) { status = DCCSetAudioWMAFormat(context->dcc_info->pAudioSource, wma_params); if(status == RM_OK){ // wma_params->SamplingFrequency RMDBGLOG((ENABLE, " set audio_freq = %ldHz (ignore any audio_freq in cmdline)\n", wma_params->SamplingFrequency)); status = RUASetProperty(context->dcc_info->pRUA, context->dcc_info->audio_engine, RMAudioEnginePropertyID_SampleFrequency, &wma_params->SamplingFrequency, sizeof(wma_params->SamplingFrequency), 0); asf_audio_opt->SampleRate = wma_params->SamplingFrequency; apply_dvi_hdmi_audio_options(context->dcc_info, asf_audio_opt, wma_params->NumberOfChannels, TRUE, TRUE, FALSE); } } else { asf_audio_opt->Codec = AudioDecoder_Codec_PCM; asf_audio_opt->SubCodec = 0; asf_audio_opt->SampleRate = wma_params->SamplingFrequency; asf_audio_opt->PcmCdaParams.ChannelAssign = PcmCda2_LR; asf_audio_opt->PcmCdaParams.BitsPerSample = wma_params->BitsPerSample; asf_audio_opt->PcmCdaParams.MsbFirst = FALSE; // apply the sample rate, serial out status status = apply_audio_engine_options(context->dcc_info, asf_audio_opt); if(status != RM_OK){ RMDBGLOG((ENABLE, "Cannot apply audio engine options ... disabling audio, error = %d\n", status)); context->SendAudioData = FALSE; } status = apply_audio_decoder_options(context->dcc_info, asf_audio_opt); RMDBGLOG((ENABLE, " set PCM codec for WMALSL, Sampling Freq=%lu\n", asf_audio_opt->SampleRate)); DCCSTCSetTimeResolution(context->dcc_info->pStcSource, DCC_Audio, 90000); } if(status != RM_OK){ RMDBGLOG((ENABLE, "Cannot set audio codec ... disabling audio, error = %d\n", status)); context->SendAudioData = FALSE; } context->audio_decoder_initialized = TRUE; } return RM_OK;}static RMbool SwitchAudio(struct asf_context *pSendContext, RMuint32 Media_Object_Number){ RMDBGLOG((ENABLE, "got audio stream change command\n")); pSendContext->dcc_info->state = RM_PLAYING; if ((pSendContext->dcc_info->selectAudioStream > (RMint32)audioStreams) || (pSendContext->dcc_info->selectAudioStream == 0) || (audioStreams <= 1) || (pSendContext->dcc_info->selectAudioStream == (RMint32)pSendContext->audio_stream_index)) { RMDBGLOG((ENABLE, "audio stream change ignored (total audioStreams %lu, selected %ld, current %lu)\n", audioStreams, pSendContext->dcc_info->selectAudioStream, pSendContext->audio_stream_index)); return FALSE; } asfStop(pSendContext, RM_DEVICES_AUDIO); if (pSendContext->compressed_audio) { RMDBGLOG((ENABLE, "close wmapro decoder\n")); RMWMAProVDecoderClose(pSendContext->vDecoder); RMDBGLOG((ENABLE, "open wmapro decoder\n")); RMWMAProVDecoderOpen(pSendContext->vDecoder); } pSendContext->dcc_info->state = RM_PLAYING; pSendContext->audio_decoder_initialized = FALSE; pSendContext->prev_audio_media_object_number = Media_Object_Number; RMDBGLOG((ENABLE, "total audio streams %lu\n", audioStreams)); if (pSendContext->dcc_info->selectAudioStream == -1) { RMuint32 i; for (i = 0; i < audioStreams ; i++) { if (audioStreamTable[i] != pSendContext->audio_stream_index) break; } RMDBGLOG((ENABLE, "current stream %lu, switch to %lu\n", pSendContext->audio_stream_index, audioStreamTable[i])); pSendContext->audio_stream_index = audioStreamTable[i]; } else { RMDBGLOG((ENABLE, "current stream %lu, switch to %lu\n", pSendContext->audio_stream_index, pSendContext->dcc_info->selectAudioStream)); pSendContext->audio_stream_index = pSendContext->dcc_info->selectAudioStream; } asfPlay(pSendContext, RM_DEVICES_AUDIO, 0); return TRUE;}static void try_decode_wmapro(struct asf_context *pSendContext, RMbool EOS){ /* wmapro decoding and senddata */ RMstatus status; RMuint32 rd1, size1, rd2; struct wmapro_buffer_info *buf_info; RMuint32 size_audio = 0, size_info; RMuint8 *buf_audio; struct emhwlib_info *pInfo; RMuint32 broken_frame; while (RMfifo_get_readable_size(pSendContext->wmapro_fifo, &rd1, &size1, &rd2) >= sizeof(struct wmapro_buffer_info)) { buf_info = (struct wmapro_buffer_info *) rd1; if (buf_info->new_buffer) { RMDBGLOG((WMAPRODBG, "Reset WMAPRO decoder with buffer(%p) size(%lu)\n", buf_info->ptr, buf_info->size)); status = RMWMAProVDecoderResetParser(pSendContext->vDecoder, buf_info->ptr, buf_info->size); if (status != RM_OK) { RMDBGLOG((WMAPRODBG, "Cannot reset wmapro parser\n")); pSendContext->prev_Audio_Presentaion_time = buf_info->Info.TimeStamp; goto next_wmapro_packet; } if((RMuint32)buf_info->Info.TimeStamp > 0) { if (ResyncAudio(pSendContext, buf_info->Info.TimeStamp) == RM_SKIP_TO_RESYNC) { RMDBGLOG((ENABLE, "Skip to resync\n")); goto next_wmapro_packet; } pSendContext->prev_Audio_Presentaion_time = buf_info->Info.TimeStamp; } else { buf_info->Info.TimeStamp = pSendContext->prev_Audio_Presentaion_time; } pSendContext->packet_counter ++; buf_info->new_buffer = FALSE; buf_info->pBuffer = NULL; } while (1) { RMbool fHaveNewBuffer = FALSE; if (buf_info->pBuffer == NULL) { status = RMWMAProVDecoderGetFrame(pSendContext->vDecoder, &(buf_info->pBuffer)); if (status == RM_WMAPRO_SKIPFRAME) { buf_info->pBuffer = NULL; RMDBGLOG((WMAPRODBG, "SKIP FRAME\n")); continue; } else if (status != RM_OK) { RMDBGLOG((WMAPRODBG, "Error get frame\n")); break; } } if (pSendContext->UncompressedBuffer != NULL) { RUAReleaseBuffer(pSendContext->pDMAuncompressed, pSendContext->UncompressedBuffer); pSendContext->UncompressedBuffer = NULL; } if (EOS) { while (1) { if (RUAGetBuffer(pSendContext->pDMAuncompressed, &pSendContext->UncompressedBuffer, GETBUFFER_TIMEOUT_US) == RM_OK) break; } } else { if (RUAGetBuffer(pSendContext->pDMAuncompressed, &pSendContext->UncompressedBuffer, 0) != RM_OK) { RMDBGLOG((WMAPRODBG, "Cannot get buffer\n")); return; } } fHaveNewBuffer = TRUE; buf_audio = pSendContext->UncompressedBuffer; status = RMWMAProVDecoderDecode(pSendContext->vDecoder, buf_info->pBuffer, buf_audio, &size_audio); buf_info->pBuffer = NULL; RMDBGLOG((WMAPRODBG, "size_audio = %d on buffer %p\n", size_audio, buf_audio)); if (size_audio > (1<<AUDIO_DMA_BUFFER_SIZE_LOG2)) { RMDBGLOG((ENABLE, "size_audio (%ld) > dmabuffersize (%ld), disabling audio\n", size_audio, (1<<AUDIO_DMA_BUFFER_SIZE_LOG2))); pSendContext->SendAudioData = FALSE; break; } if(size_audio > 0) { pInfo = NULL; size_info = 0; /* need to be the first test to do it every time */ broken_frame = RMWMAProVDecodeGetFlag(pSendContext->vDecoder, INQUIRE_BROKEN_FRAME_FLAG); RMDBGLOG((WMAPRODBG, "broken %lu, sendpts %lu, audiopts %lu\n", broken_frame, buf_info->fSendPTS, pSendContext->SendAudioPts)); if (buf_info->fSendPTS && pSendContext->SendAudioPts && !broken_frame) { pInfo = &(buf_info->Info); size_info = sizeof(buf_info->Info); buf_info->fSendPTS = 0; } if ((pInfo != NULL) && (pInfo->ValidFields != 0)) RMDBGLOG((WMAPRODBG, "sending wmapro audio %d, MON %d, %ld bytes, pts %llu\n", (int)buf_info->Stream_Number, (int)buf_info->Media_Object_Number, size_audio, pInfo == NULL ? 0:pInfo->TimeStamp)); if (RUASendData(pSendContext->pRUA, pSendContext->dcc_info->audio_decoder, pSendContext->pDMAuncompressed, buf_audio, size_audio, pInfo, size_info) != RM_OK) { RMDBGLOG((ENABLE, "WmaPro Xfer task too small\n")); break; } pSendContext->AudioByteCounter += size_audio; } else { printf("Flush WMAPRO decoder due to error\n"); RMWMAProVDecoderFlushParser(pSendContext->vDecoder); break; } if (status != RM_OK) break; } next_wmapro_packet: RUAReleaseBuffer(pSendContext->pDMA, buf_info->ptr); RMfifo_incr_read_ptr(pSendContext->wmapro_fifo, sizeof(struct wmapro_buffer_info)); }}static void play_Payload( void *context, unsigned char Stream_Number, unsigned char *buf, unsigned long size, unsigned long bytes_left, unsigned char Is_Key_Frame, unsigned long Media_Object_Number, unsigned char Media_Object_Number_valid, unsigned long Presentation_Time, unsigned char Presentation_Time_valid, unsigned long Offset_Into_Media_Object ){ struct asf_context *pSendContext = (struct asf_context *) context; struct emhwlib_info Info; struct emhwlib_info *pInfo; RMuint32 size_info; RMint32 diff; RMstatus err;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -