📄 basic_audio_render.cpp
字号:
/*
//
// INTEL CORPORATION PROPRIETARY INFORMATION
// This software is supplied under the terms of a license agreement or
// nondisclosure agreement with Intel Corporation and may not be copied
// or disclosed except in accordance with the terms of that agreement.
// Copyright(c) 2003-2007 Intel Corporation. All Rights Reserved.
//
*/
#include "basic_audio_render.h"
#include "umc_audio_codec.h"
Ipp32u VM_THREAD_CALLCONVENTION BasicAudioRenderThreadProc(void* vpParam)
{
VM_ASSERT(NULL != vpParam);
UMC::BasicAudioRender* pThis =
reinterpret_cast<UMC::BasicAudioRender*>(vpParam);
pThis->ThreadProc();
return 0;
}
UMC::BasicAudioRender::BasicAudioRender():
m_tStartTime(0),
m_tStopTime(0),
m_bStop(false),
m_bPause(false),
m_dfNorm(1)
{
m_tFreq = vm_time_get_frequency();
m_eventSyncPoint.Init(1, 1);
m_eventSyncPoint1.Init(1, 0);
m_dDynamicChannelPTS = -1;
m_wDynamicChannels = -1;
}
UMC::BasicAudioRender::~BasicAudioRender()
{
Close();
}
UMC::Status UMC::BasicAudioRender::Init(MediaReceiverParams* pInit)
{
Status umcRes = UMC_OK;
AudioRenderParams* pParams =
DynamicCast<AudioRenderParams, MediaReceiverParams>(pInit);
m_RendererIsStopped = false;
if (NULL == pParams) {
umcRes = UMC_ERR_NULL_PTR;
}
if (UMC_OK == umcRes) {
MediaBufferParams Params;
Ipp32s iSamples = 0;
sAudioStreamInfo* pAudioInfo = &pParams->info;
m_dfNorm = 1.0 / pAudioInfo->sample_frequency
/ (pAudioInfo->bitPerSample >> 3)
/ pAudioInfo->channels;
m_wInitedChannels = pAudioInfo->channels;
m_dwInitedFrequency = pAudioInfo->sample_frequency ;
switch (pAudioInfo->stream_type) {
case AC3_AUDIO:
iSamples = 256*6;
break;
case MP1L2_AUDIO:
case MP1L3_AUDIO:
iSamples = 1152;
break;
case MP2L3_AUDIO:
iSamples = 576;
break;
default: iSamples = 1024;
}
Params.m_prefInputBufferSize = //2304;
pAudioInfo->channels *
(pAudioInfo->bitPerSample >> 3) *
iSamples*2;
Params.m_numberOfFrames = 100;
Params.m_prefOutputBufferSize = Params.m_prefInputBufferSize;
//2304;//4 * 1024;
umcRes = m_DataBuffer.Init(&Params);
}
if (UMC_OK == umcRes) {
m_bStop = false;
umcRes = m_Thread.Create(BasicAudioRenderThreadProc, this);
}
return umcRes;
}
void UMC::BasicAudioRender::ThreadProc()
{
Status umcRes = UMC_OK;
AudioData data;
vm_debug_trace(VM_DEBUG_INFO, VM_STRING("BasicAudioRender::ThreadProc: Start\n"));
while (UMC_OK == umcRes && !m_bStop) {
if (UMC_OK == umcRes) {
umcRes = m_DataBuffer.LockOutputBuffer(&data);
}
if (UMC_ERR_END_OF_STREAM == umcRes) {
break;
} else
if (UMC_ERR_NOT_ENOUGH_DATA == umcRes) {
umcRes = UMC_OK;
vm_time_sleep(0);
continue;
}
if (data.GetTime() == -1) { // first frame
data.SetTime(0.0);
}
Ipp64f dfEndTime = data.GetTime() + m_dfNorm * data.GetDataSize();
VM_ASSERT(UMC_OK == umcRes || UMC_ERR_TIMEOUT == umcRes || UMC_WRN_REPOSITION_INPROGRESS == umcRes);
if (UMC_OK == umcRes) {
data.SetTime(data.GetTime(), dfEndTime);
umcRes = SendFrame(&data);
if (umcRes == UMC_ERR_FAILED) {
vm_debug_trace(VM_DEBUG_INFO, VM_STRING("BasicAudioRender::RendererIsStopped\n"));
umcRes = UMC_OK;
m_RendererIsStopped = true;
} else
if (umcRes != UMC_OK) {
vm_debug_trace(VM_DEBUG_INFO, VM_STRING("BasicAudioRender::Failed in SendFrame!!!\n"));
break;
}
}
if (UMC_OK == umcRes) {
data.SetTime(dfEndTime);
data.MoveDataPointer(data.GetDataSize());
umcRes = m_DataBuffer.UnLockOutputBuffer(&data);
}
if (m_RendererIsStopped) {
m_bStop = true;
break;
}
if (umcRes == UMC_WRN_REPOSITION_INPROGRESS) {
break;
}
}
if (!m_bStop && (umcRes == UMC_ERR_END_OF_STREAM))
{
umcRes = DrainBuffer();
m_bStop = true;
}
vm_debug_trace(VM_DEBUG_INFO, VM_STRING("BasicAudioRender::ThreadProc: Exit\n"));
}
// Audio Reference Clock
Ipp64f UMC::BasicAudioRender::GetTime()
{
m_tStartTime = vm_time_get_tick();
Ipp64f dfTime = -1.0;
if (!m_bStop) {
dfTime = GetTimeTick();
} else {
if (m_Thread.IsValid()) {
m_Thread.Wait();
}
}
m_tStopTime = vm_time_get_tick();
// we must return -1 if playback is already stopped, so zero GetDelay()
// result is required
if (-1.0 == dfTime) {
m_tStartTime = m_tStopTime;
}
return dfTime >= 0 ? dfTime : -1.0;
}
UMC::Status UMC::BasicAudioRender::GetTimeTick(Ipp64f pts)
{
Status umcRes = UMC::UMC_ERR_FAILED;
if((m_dDynamicChannelPTS > 0) && (pts >= m_dDynamicChannelPTS)) {
AudioRenderParams par;
memset(&par.info, 0, sizeof(AudioStreamInfo));
par.pModuleContext = NULL;
par.info.sample_frequency = m_dwInitedFrequency;
par.info.channels = m_wDynamicChannels;
par.info.bitPerSample = 16;
umcRes = SetParams(&par);
if(UMC_OK == umcRes) {
m_dDynamicChannelPTS = -1;
}
}
return umcRes;
}
// Estimated value of device latency
Ipp64f UMC::BasicAudioRender::GetDelay()
{
return (Ipp64f)(Ipp64s)(m_tStopTime - m_tStartTime) / (Ipp64f)(Ipp64s)m_tFreq;
}
UMC::Status
UMC::BasicAudioRender::LockInputBuffer(MediaData *in)
{
vm_debug_trace(VM_DEBUG_NONE, VM_STRING("BasicAudioRender::LockInputBuffer\n"));
if (m_RendererIsStopped) {
return UMC_ERR_FAILED;
} else
return m_DataBuffer.LockInputBuffer(in);
}
UMC::Status UMC::BasicAudioRender::UnLockInputBuffer(MediaData *in,
Status StreamStatus)
{
Status umcRes = UMC_OK;
if (UMC_OK == umcRes) {
umcRes = m_DataBuffer.UnLockInputBuffer(in, StreamStatus);
}
AudioData* pData = DynamicCast<AudioData, MediaData>(in);
if(pData) {
if(m_wInitedChannels == pData->m_info.channels &&
m_dwInitedFrequency != pData->m_info.sample_frequency) {
AudioRenderParams param;
param.info = pData->m_info;
if(UMC_OK == SetParams(¶m)) {
m_wInitedChannels = pData->m_info.channels;
m_dwInitedFrequency = pData->m_info.sample_frequency;
}
} else
if((m_wInitedChannels != pData->m_info.channels) &&
(m_dDynamicChannelPTS == -1)) {
m_dDynamicChannelPTS = in->GetTime();
m_wDynamicChannels = pData->m_info.channels;
}
}
return umcRes;
}
UMC::Status UMC::BasicAudioRender::Stop()
{
m_bStop = true;
return UMC_OK;
}
UMC::Status UMC::BasicAudioRender::Pause(bool pause)
{
if (pause)
m_bPause = true;
else
m_bPause = false;
return UMC_OK;
}
UMC::Status UMC::BasicAudioRender::Close()
{
if (m_Thread.IsValid()) {
if (m_bPause)
m_bStop = true;
m_Thread.Wait();
}
m_DataBuffer.Close();
return UMC_OK;
}
UMC::Status UMC::BasicAudioRender::Reset()
{
m_Thread.Wait();
m_DataBuffer.Reset();
return UMC_OK;
}
UMC::Status UMC::BasicAudioRender::SetParams(MediaReceiverParams *pMedia,
Ipp32u /* trickModes */)
{
Status umcRes = 0;
AudioRenderParams* pParams = DynamicCast<AudioRenderParams, MediaReceiverParams>(pMedia);
if (NULL == pParams) {
umcRes = UMC_ERR_NULL_PTR;
}
if (UMC_OK == umcRes) {
sAudioStreamInfo* info = NULL;
info = &pParams->info;
if (info->sample_frequency &&
info->bitPerSample &&
info->channels) {
m_dfNorm = 1.0 / info->sample_frequency
/ (info->bitPerSample >> 3)
/ info->channels;
m_wInitedChannels = info->channels;
m_dwInitedFrequency = info->sample_frequency;
} else {
umcRes = UMC::UMC_ERR_FAILED;
}
}
return umcRes;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -