📄 avsync.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 <math.h>
#include "avsync.h"
#include "codec_pipeline.h"
#include "umc_media_data_ex.h"
#include "null_audio_render.h"
#include "umc_module_context.h"
#include "umc_audio_codec.h"
#if !defined(ARM) && !defined(_ARM_)
#define TASK_SWITCH() vm_time_sleep(0);
#else
#define TASK_SWITCH()
#endif
#undef CLASSNAME
#define CLASSNAME VM_STRING("AVSync")
#define REPOSITION_AVSYNC_PRECISION 0.99
AVSync::CommonCtl::CommonCtl():
cformat(UMC::NONE), // YUV color format
ulSplitterFlags(UMC::UNDEF_SPLITTER), // Splitter Flags
ulVideoDecoderFlags(0), // Video Decoder Flags
ulAudioDecoderFlags(0), // Audio Decoder Flags
ulVideoRenderFlags(0), // Video Render Flags
ulAudioRenderFlags(0), // Audio Render Flags
pRenContext(NULL), // Module context (HWND or some other)
pReadContext(NULL), // Module context (local or remote)
lInterpolation(UMC::FLAG_CCNV_NONE), // Interpolation Flags
uiPrefVideoRender(UMC::DEF_VIDEO_RENDER),// Prefered video render
uiPrefDataReader(DEF_DATA_READER), // Prefered data reader
lDeinterlacing(0), // Deinterlacing Flags
pExternalInfo(NULL),
terminate(false), // terminate the program after playback
performance(false), // Performance statistic
repeat(false), // repeatedly playback
fullscr(false), // turn on full screen
stick(true), // stick to the window size
debug(true), // enable step & fast forward, sound disabled
step(false), // enable step & fast forward, sound disabled
bSync(true), // Play synchronously even if no sound
uiLimitVideoDecodeThreads(1),
uiSelectedVideoID(0), //zero is default value to select any video stream
uiSelectedAudioID(0), //zero is default value to select any audio stream
uiTrickMode(UMC::UMC_TRICK_MODES_NO),
iBitDepth(8)
{
memset(szOutputVideo, 0, sizeof(szOutputVideo));
memset(szOutputAudio, 0, sizeof(szOutputAudio));
}
AVSync::AVSync():
m_pDataReader(NULL),
m_pSplitter(NULL),
m_pAudioDecoder(NULL),
m_pDSAudioCodec(NULL),
m_pMediaBuffer(NULL),
m_pAudioRender(NULL),
m_pVideoDecoder(NULL),
m_pVideoRender(NULL),
m_bStopFlag(false),
m_bAudioPlaying(false),
m_bVideoPlaying(false),
m_bPaused(false),
m_bSync(false),
m_dfFrameRate(1),
m_SystemType(UMC::UNDEF_STREAM),
m_pAudioInfo(0),
m_pVideoInfo(0),
m_nAudioTrack(0),
m_nVideoTrack(0),
m_pVideoDecSpecInfo(0),
m_pAudioDecSpecInfo(0)
{
vm_debug_trace_withfunc(VM_DEBUG_FILE, VM_STRING("AVSync::AVSync()"), VM_STRING("AVSync,+"));
m_DecodedFrameSize.width = 0;
m_DecodedFrameSize.height = 0;
m_lliFreq = vm_time_get_frequency();
m_cFormat = UMC::YV12;
vm_debug_trace_withfunc(VM_DEBUG_FILE, VM_STRING("AVSync::AVSync()"), VM_STRING("AVSync,-"));
}
void AVSync::GetAVInfo (UMC::SplitterInfo* pSplitterInfo)
{
Ipp32u i;
m_pVideoInfo = 0;
m_pAudioInfo = 0;
m_pAudioDecSpecInfo = 0;
m_pVideoDecSpecInfo = 0;
for (i=0; i< pSplitterInfo->m_nOfTracks; i++)
{
if (pSplitterInfo->m_ppTrackInfo[i]->m_isSelected)
{
if (pSplitterInfo->m_ppTrackInfo[i]->m_Type & UMC::TRACK_ANY_VIDEO)
{
VM_ASSERT(!m_pVideoInfo);
m_nVideoTrack = i;
m_pVideoInfo = (UMC::VideoStreamInfo*)pSplitterInfo->m_ppTrackInfo[i]->m_pStreamInfo;
m_pVideoDecSpecInfo = pSplitterInfo->m_ppTrackInfo[i]->m_pDecSpecInfo;
}
else if (pSplitterInfo->m_ppTrackInfo[i]->m_Type & UMC::TRACK_ANY_AUDIO)
{
VM_ASSERT(!m_pAudioInfo);
m_nAudioTrack = i;
m_pAudioInfo = (UMC::AudioStreamInfo*)pSplitterInfo->m_ppTrackInfo[i]->m_pStreamInfo;
m_pAudioDecSpecInfo = pSplitterInfo->m_ppTrackInfo[i]->m_pDecSpecInfo;
}
}//if
}//for
}
UMC::Status
AVSync::Init(CommonCtl& rControlParams)
{
UMC::Status umcRes = UMC::UMC_OK;
UMC::MediaData FirstFrameA;
ExternalInfo* pExtInf = rControlParams.pExternalInfo;
UMC::SplitterInfo* pSplitterInfo=0;
vm_debug_trace_withfunc(VM_DEBUG_FILE, VM_STRING("AVSync::Init"), VM_STRING("Init,+"));
m_MutAccess.Lock();
m_ccParams = rControlParams;
m_cFormat = rControlParams.cformat;
if (UMC::UMC_OK == umcRes)
{
if(pExtInf && pExtInf->m_pDataReader)
{
m_pDataReader = pExtInf->m_pDataReader;
}
else
{
umcRes = CodecPipeline::SelectDataReader(*rControlParams.pReadContext,
m_pDataReader,
rControlParams.uiPrefDataReader);
}
}
if (UMC::UMC_OK == umcRes)
{
if(pExtInf && pExtInf->m_pSplitter)
{
m_pSplitter = pExtInf->m_pSplitter;
}
else
{
umcRes = CodecPipeline::SelectSplitter(m_pDataReader,
rControlParams.ulSplitterFlags,
m_pSplitter,
rControlParams.uiSelectedVideoID,
rControlParams.uiSelectedAudioID);
}
}
if (UMC::UMC_OK == umcRes)
{
umcRes = m_pSplitter->GetInfo(&pSplitterInfo);
if (UMC::UMC_OK != umcRes)
{
vm_debug_trace(VM_DEBUG_NONE, VM_STRING("Failed to get splitter info\n"));
}
else
{
GetAVInfo (pSplitterInfo);
m_SystemType = pSplitterInfo->m_SystemType;
}
}
if (UMC::UMC_OK == umcRes && m_pAudioInfo)
{
// Get splitter some time to read out at least one audio frame
vm_time_sleep(0);
/* if (UMC::UMC_OK == umcRes &&
UMC::TRACK_PCM !=m_pAudioInfo->stream_type &&
UMC::TRACK_LPCM !=m_pAudioInfo->stream_type)
{
while (((umcRes = m_pSplitter->GetNextData(&FirstFrameA,m_nAudioTrack))==UMC::UMC_ERR_NOT_ENOUGH_DATA)&&!m_bStopFlag)
vm_time_sleep(5);
}*/
if (UMC::UMC_OK == umcRes)
{
umcRes = CodecPipeline::SelectDTAudioDecoder(*m_pAudioInfo,
m_pAudioDecoder,
m_pDSAudioCodec,
m_pMediaBuffer,
m_pAudioDecSpecInfo);
}
if (UMC::UMC_OK == umcRes && m_pAudioInfo)
{
if (UMC::FLAG_AREN_VOID & rControlParams.ulAudioRenderFlags)
{
rControlParams.uiPrefAudioRender = UMC::NULL_AUDIO_RENDER;
}
umcRes = CodecPipeline::SelectAudioRender(*m_pAudioInfo,
*rControlParams.pRenContext,
m_pAudioRender,
rControlParams.uiPrefAudioRender,
rControlParams.szOutputAudio);
}
else if (UMC::UMC_ERR_INVALID_STREAM == umcRes)
{
m_pAudioInfo = 0;
umcRes = UMC::UMC_OK;
}
}
if (UMC::UMC_OK == umcRes && m_pVideoInfo)
{
UMC::BaseCodec *pColorConverter = ((UMC::NONE == rControlParams.cformat) ?
((UMC::BaseCodec *) &m_DataPointersCopy) :
((UMC::BaseCodec *) &m_ColorConverter));
umcRes = CodecPipeline::SelectVideoDecoder(*m_pVideoInfo,
m_pVideoDecSpecInfo,
rControlParams.lInterpolation,
rControlParams.lDeinterlacing,
rControlParams.uiLimitVideoDecodeThreads,
rControlParams.ulVideoDecoderFlags,
*pColorConverter,
m_pVideoDecoder);
if (UMC::UMC_OK == umcRes)
{
UMC::VideoDecoderParams vParams;
/*umcRes = */m_pVideoDecoder->GetInfo(&vParams);
if(!(Ipp32s)m_pVideoInfo->framerate)
m_pVideoInfo->framerate = vParams.info.framerate;
if(!m_pVideoInfo->clip_info.width)
m_pVideoInfo->clip_info.width = vParams.info.clip_info.width;
if(!m_pVideoInfo->clip_info.height)
m_pVideoInfo->clip_info.height = vParams.info.clip_info.height;
m_DecodedFrameSize = m_pVideoInfo->clip_info;
}
if (UMC::UMC_OK == umcRes)
{
if(pExtInf && pExtInf->m_pVideoRender)
{
m_pVideoRender = pExtInf->m_pVideoRender;
}
else
{
if (UMC::DEF_VIDEO_RENDER == rControlParams.uiPrefVideoRender)
{
rControlParams.uiPrefVideoRender =
#if defined(USE_FW_RENDERER)
UMC::FW_VIDEO_RENDERER;
#elif defined(USE_NULL_RENDERER)
UMC::NULL_VIDEO_RENDERER;
#elif defined(_WIN32_WINNT)
UMC::BLT_VIDEO_RENDER;
#else
UMC::DEF_VIDEO_RENDER;
#endif
}
umcRes = CodecPipeline::SelectVideoRender(*rControlParams.pRenContext,
m_DecodedFrameSize,
rControlParams.rectDisp,
rControlParams.rectDisp,
rControlParams.cformat,
rControlParams.ulVideoRenderFlags,
m_pVideoRender,
rControlParams.uiPrefVideoRender,
rControlParams.szOutputVideo);
}
if (UMC::UMC_OK != umcRes)
{
vm_debug_message(VM_STRING("Failed to intialize video render\n"));
}
}
if (UMC::UMC_OK == umcRes)
{ umcRes = m_StepEvent.Init(1,1); }
if (UMC::UMC_OK == umcRes &&
m_pVideoInfo)
{
if(rControlParams.step)
umcRes = m_StepEvent.Reset();
else
umcRes = m_StepEvent.Set();
}
if (UMC::UMC_OK == umcRes)
{
m_bSync = rControlParams.bSync;
m_dfFrameRate = m_pVideoInfo->framerate;
m_Stat.Reset();
m_bStopFlag = false;
m_Stat.dfFrameRate = m_dfFrameRate;
if (m_pAudioInfo)
{
m_Stat.dfDuration = (m_pVideoInfo->duration < m_pAudioInfo->duration) ?
m_pAudioInfo->duration: m_pVideoInfo->duration;
}
else
{
m_Stat.dfDuration = m_pVideoInfo->duration;
}
}
}
if (UMC::UMC_OK == umcRes)
{
vm_string_printf(VM_STRING("\n"));
if (pSplitterInfo)
{
vm_string_printf(VM_STRING("Stream Type :\t\t%s\n"), UMC::GetStreamTypeString(m_SystemType));
}
if (m_pVideoInfo)
{
vm_string_printf(VM_STRING("Video Info :\n"));
vm_string_printf(VM_STRING("-Video Type :\t\t%s\n"), UMC::GetVideoTypeString((UMC::VideoStreamType)m_pVideoInfo->stream_type));
vm_string_printf(VM_STRING("-Resolution :\t\t%dx%d\n"), m_pVideoInfo->clip_info.width,m_pVideoInfo->clip_info.height);
vm_string_printf(VM_STRING("-Frame Rate :\t\t%.2lf\n"), m_pVideoInfo->framerate);
}
if (m_pAudioInfo)
{
vm_string_printf(VM_STRING("Audio Info :\n"));
vm_string_printf(VM_STRING("-Audio Type :\t\t%s\n"), UMC::GetAudioTypeString((UMC::AudioStreamType)m_pAudioInfo->stream_type));
vm_string_printf(VM_STRING("-S.Frequency :\t\t%d\n"), m_pAudioInfo->sample_frequency);
vm_string_printf(VM_STRING("-Num.Channel :\t\t%d\n"), m_pAudioInfo->channels);
vm_string_printf(VM_STRING("-BitPerSample:\t\t%d\n"), m_pAudioInfo->bitPerSample);
vm_string_printf(VM_STRING("\n"));
}
}
m_MutAccess.Unlock();
vm_debug_trace_withfunc(VM_DEBUG_FILE, VM_STRING("AVSync::Init"), VM_STRING("Init,-"));
return umcRes;
}
UMC::Status
AVSync::Start()
{
UMC::Status umcRes = UMC::UMC_OK;
vm_debug_trace_withfunc(VM_DEBUG_FILE, VM_STRING("AVSync::Start"), VM_STRING("Start,+"));
m_MutAccess.Lock();
m_bStopFlag = false;
m_bAudioPlaying = false;
m_bVideoPlaying = false;
m_Stat.Reset();
if (UMC::UMC_OK == umcRes && m_pVideoInfo)
{
VM_ASSERT(NULL != m_pVideoRender);
vm_debug_trace(VM_DEBUG_INFO, VM_STRING("Start: VideoProc start:\n"));
umcRes = m_VideoThread.Create(VideoThreadProc,
static_cast<AVSync*>(this));
}
if (UMC::UMC_OK == umcRes && m_pAudioInfo)
{
VM_ASSERT(NULL != m_pAudioRender);
VM_ASSERT(m_pAudioInfo);
vm_debug_trace(VM_DEBUG_INFO, VM_STRING("Start: AudioThread start:\n"));
umcRes = m_AudioThread.Create(AudioThreadProc,
static_cast<AVSync*>(this));
}
if (UMC::UMC_OK == umcRes &&
(NULL != m_pVideoRender))
// (NULL != m_pVideoRender || NULL != m_pAudioRender))
{
vm_debug_trace(VM_DEBUG_INFO, VM_STRING("Start: SyncThread start\n"));
umcRes = m_SyncThread.Create(SyncThreadProc,
static_cast<AVSync*>(this));
}
if (UMC::UMC_OK == umcRes && NULL != m_pVideoRender)
{
vm_debug_trace(VM_DEBUG_INFO, VM_STRING("Start: Video Render ShowSurface:\n"));
m_pVideoRender->ShowSurface();
}
if (UMC::UMC_OK == umcRes)
{
vm_time_sleep(1);
#if defined (ARM) || defined (_ARM_)
m_SyncThread.SetPriority(VM_THREAD_PRIORITY_NORMAL);
m_AudioThread.SetPriority(VM_THREAD_PRIORITY_NORMAL);
m_VideoThread.SetPriority(VM_THREAD_PRIORITY_NORMAL);
#else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -