⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hxaudply.cpp

📁 linux下的一款播放器
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/************************************************************************ *  Method: *		CHXAudioPlayer::GetStreamCount *	Purpose: *		Get the number of streams associated with this player. */UINT16 CHXAudioPlayer::GetStreamCount(){    return m_pStreamList->GetCount();}/************************************************************************ *  Method: *		CHXAudioPlayer::SetStreamInfoResponse *	Purpose: *		Add the stream info response interface to our list. */STDMETHODIMP CHXAudioPlayer::SetStreamInfoResponse(    IHXAudioStreamInfoResponse*    pResponse){    if (!pResponse || !m_pStreamRespList)    {	return HXR_FAILED;    }    /* Add to the stream response list */    LISTPOSITION lPos = m_pStreamRespList->Find(pResponse);    if (lPos)    {	return HXR_FAILED;    }    m_pStreamRespList->AddTail((void*) pResponse);    pResponse->AddRef();         // Released in destructor    return HXR_OK;}/************************************************************************ *  Method: *  CHXAudioPlayer::RemoveStreamInfoResponse *  Purpose: *  Remove stream info response that was added earlier */STDMETHODIMP CHXAudioPlayer::RemoveStreamInfoResponse(    IHXAudioStreamInfoResponse*    pResponse){    /* Add to the stream response list */    if (pResponse && m_pStreamRespList)    {	LISTPOSITION lPos = m_pStreamRespList->Find(pResponse);	if (lPos)	{	    m_pStreamRespList->RemoveAt(lPos);	    pResponse->Release();         // Released in destructor	    return HXR_OK;	}    }    return HXR_FAILED;}UINT16CHXAudioPlayer::NumberOfResumedStreams(void){    UINT16 uNumActive = 0;    if (m_pStreamList && m_pStreamList->GetCount() > 0)    {	CHXAudioStream* pStream = 0;	CHXSimpleList::Iterator lIter = m_pStreamList->Begin();	for (; lIter != m_pStreamList->End(); ++lIter)	{	    pStream = (CHXAudioStream*) (*lIter);	    if (pStream->GetState() == E_PLAYING)	    {		uNumActive++;	    }	}    }    return uNumActive;}void CHXAudioPlayer::StreamInitialized(CHXAudioStream* pAudioStream){    /* If we are already initialized, it means this stream was added mid-     * presentation and gogt initialized later. In this case, report arrival     * of this stream to all StreamInfoResponse objects registered with the     * player     */    if (m_pStreamRespList && m_bInited)    {	IHXAudioStreamInfoResponse* pAudioStreamInfoResponse = 0;	CHXSimpleList::Iterator lIter = m_pStreamRespList->Begin();	for (; lIter != m_pStreamRespList->End(); ++lIter) 	{	    pAudioStreamInfoResponse = (IHXAudioStreamInfoResponse*) (*lIter);	    pAudioStreamInfoResponse->OnStream(pAudioStream);	}    }    m_bHasStreams = TRUE;}ULONG32	CHXAudioPlayer::GetInitialPushdown(BOOL bAtStart /* = FALSE*/){    /* If there are any audio streams, initial pushdown is session's     * initial pushdown     */    if (m_pStreamList->GetCount() > 0)    {        ULONG32 ulRet =             m_Owner->GetInitialPushdown(bAtStart) + m_ulGranularity;#ifdef HELIX_FEATURE_MIN_HEAP        // The MIN_HEAP code seems to need 1 extra block's worth        // of data to avoid rebuffers during playback. This        // is a low impact temporary solution that fixes the problem.        ulRet += m_ulGranularity;#endif /* HELIX_FEATURE_MIN_HEAP */        return ulRet;    }    else    {	return 0;    }}/************************************************************************ *  Method: *      CHXAudioPlayer::OnTimerCallback *  Purpose: *      Timer callback when implementing fake timeline. */void	CHXAudioPlayer::OnTimerCallback(){    ULONG32 ulCurrentTime	= HX_GET_TICKCOUNT();    m_ulIncreasingTimer		+= CALCULATE_ELAPSED_TICKS(m_ulLastFakeCallbackTime, ulCurrentTime);    m_ulLastFakeCallbackTime    = ulCurrentTime;    OnTimeSync(m_ulIncreasingTimer);    /* A call to timesync may result in stopping     * playback and we do not want to have any more     * time syncs.     */    /* Put this back in the scheduler.     */    if (m_bInited && m_eState == E_PLAYING && !m_ulCallbackID)    {	*m_pFakeAudioCBTime += (int) (m_ulGranularity*1000);	m_ulCallbackID = m_pScheduler->AbsoluteEnter( this,                                                      *((HXTimeval*)m_pFakeAudioCBTime));    }}voidCHXAudioPlayer::SetLive(BOOL bIsLive){    m_bIsLive = bIsLive;    CHXAudioStream* s = 0;    CHXSimpleList::Iterator lIter = m_pStreamList->Begin();    for (; lIter != m_pStreamList->End(); ++lIter)    {	s = (CHXAudioStream*) (*lIter);	s->SetLive(m_bIsLive);    }}voidCHXAudioPlayer::AudioFormatNowKnown(void){    HX_ASSERT(m_bInited);    /* When : More than one audio stream created after initialization     * and one of them already called this function earlier     */    if (m_bHasStreams)    {	return;    }    m_bHasStreams   = TRUE;    m_bInited	= FALSE;    /* internal setup */    HX_RESULT theErr = Setup(m_ulGranularity);    if (theErr != HXR_OK)    {	IHXErrorMessages* pErrorMessage = NULL;	m_pContext->QueryInterface(IID_IHXErrorMessages, (void**) &pErrorMessage);	if (pErrorMessage)	{	    pErrorMessage->Report(HXLOG_ERR, theErr, 0, NULL, NULL);	    pErrorMessage->Release();	}	return;    }    HX_ASSERT(m_bInited);    /* If we have not yet resumed, it is simply setting the audio     * player from fake timeline mode to audio timeline mode.     * Instead if we have already been resumed and are acting as a     * fake timeline, we need to kinda pause from being a fake timeline to     * an audio timeline, In this process, we may have to seek the audio     * device to generate right timesyncs.     */    /* If we are already resumed, we need to call resume again internally */    if (m_bIsResumed)    {	StopFakeTimeline();	Seek(m_ulCurrentTime);	// only resume the owner if we are in a play state...	// otherwise owner will be resumed when the player gets resumed.	if (m_eState == E_PLAYING)	{	    m_Owner->Resume();	}    }    else    {	/* Cool! HXPlayer will call resume later */    }}voidCHXAudioPlayer::RegisterRealAudioStream(CHXAudioStream* pAudioStream){    if (!m_pRealAudioStreamList)    {	m_pRealAudioStreamList = new CHXSimpleList;    }    m_pRealAudioStreamList->AddTail((void*) pAudioStream);    m_bAdjustForRealAudio = TRUE;}voidCHXAudioPlayer::UnRegisterRealAudioStream(CHXAudioStream* pAudioStream){    if (!m_pRealAudioStreamList)    {	return;    }    LISTPOSITION posStream = m_pRealAudioStreamList->Find((void*) pAudioStream);    if (posStream)    {	m_pRealAudioStreamList->RemoveAt(posStream);    }    /* Check if there are any more RealAudio Streams registered */    if (m_pRealAudioStreamList->GetCount() == 0)    {	m_bAdjustForRealAudio = FALSE;    }}BOOLCHXAudioPlayer::IsAudioOnlyTrue(void){    BOOL bRetValue = TRUE;    IHXPlayer* pPlayer = NULL;    m_pContext->QueryInterface(IID_IHXPlayer, (void**)&pPlayer);    HX_ASSERT(pPlayer);    UINT16 uNumSources = pPlayer->GetSourceCount();    IUnknown*		pUnknown	= NULL;    IHXStreamSource*	pStreamSource	= NULL;    IHXStream*		pStream		= NULL;    for (UINT16 i=0; bRetValue && i < uNumSources; i++)    {	pPlayer->GetSource(i, pUnknown);	pUnknown->QueryInterface(IID_IHXStreamSource,				 (void**) &pStreamSource);	HX_RELEASE(pUnknown);	HX_ASSERT(pStreamSource);	UINT16 uNumStreams = pStreamSource->GetStreamCount();	for (UINT16 j=0; bRetValue && j < uNumStreams; j++)	{	    pStreamSource->GetStream(j, pUnknown);	    pUnknown->QueryInterface(IID_IHXStream,				     (void**) &pStream);	    HX_RELEASE(pUnknown);	    HX_ASSERT(pStream);	    IHXValues* pHeader = pStream->GetHeader();	    if (pHeader)	    {		if (!IsThisAudioStream(pHeader))		{		    bRetValue = FALSE;		}		pHeader->Release();	    }	    pStream->Release();	}	HX_RELEASE(pStreamSource);    }    HX_RELEASE(pPlayer);    return bRetValue;}BOOLCHXAudioPlayer::IsThisAudioStream(IHXValues* pHeader){    CHXSimpleList::Iterator ndxStream = m_pStreamList->Begin();    for(; ndxStream != m_pStreamList->End(); ++ndxStream)    {	CHXAudioStream* pAudioStream = (CHXAudioStream*) (*ndxStream);	IHXValues* pAudioHeader = pAudioStream->GetStreamInfo();	if (pAudioHeader == pHeader)	{	    HX_RELEASE(pAudioHeader);	    return TRUE;	}	HX_RELEASE(pAudioHeader);    }    return FALSE;}voidCHXAudioPlayer::AdjustForRealAudio(){    UINT32 ulCurrentDeviceTime = m_ulCurrentTime;#if defined(HELIX_FEATURE_AUDIO_INACCURATESAMPLING)    if (m_bAdjustForRealAudio)    {	CHXAudioStream* pAudioStream = NULL;        // Only use a playing audio stream for time adjustment:        for (CHXSimpleList::Iterator streamIterator = m_pRealAudioStreamList->Begin();             streamIterator != m_pRealAudioStreamList->End();             ++streamIterator)        {            if ( ((CHXAudioStream*) (*streamIterator))->GetState() == E_PLAYING)            {                pAudioStream = (CHXAudioStream*) *streamIterator;                break;            }        }        if (pAudioStream)        {            UINT32 ulAdjustedTime = 0L;            double dBytesPlayed = m_Owner->GetNumBytesPlayed();            if (HXR_OK == pAudioStream->ConvertCurrentTime( dBytesPlayed,                                                            m_ulCurrentTime,                                                            ulAdjustedTime))            {                UINT32 ulTickCount = HX_GET_TICKCOUNT();                /* This is to avoid stall at end of the presentation */                /* The RA stream may have a duration of say 30 seconds                 * but the actual data may be only for 29.9                 * seconds. In this case, audio stream will never                 * return time more than 29.9 seconds and we will get                 * stalled.  To avoid this, we wait for atmost                 * MAX_WAIT_AT_SAME_TIME (== max granularity+50 ms) at                 * the same timestamp. If we find that we are pushing                 * more data in the audio device but the audio stream                 * is reporting the same time for the past                 * MAX_WAIT_AT_SAME_TIME, we increment our timestamp                 * by the real time elapsed since the last update.                 * This code will only trigger when we are near the                 * end of presentation.                 */                if (m_bTimeReturned &&                    ulAdjustedTime <= m_ulLastCurrentTimeReturned &&                    ulCurrentDeviceTime > m_ulLastDeviceTimeAdjusted &&                    ulCurrentDeviceTime - m_ulLastDeviceTimeAdjusted > MAX_WAIT_AT_SAME_TIME)                {                    UINT32 ulElapsedTime = CALCULATE_ELAPSED_TICKS(m_ulTimeAdjustDoneAt,                                                                   ulTickCount);                    if (ulElapsedTime >= MAX_WAIT_AT_SAME_TIME)                    {                        m_ulCurrentTime = m_ulLastCurrentTimeReturned + ulElapsedTime;                        m_ulTimeAdjustDoneAt	    = ulTickCount;                        m_ulLastDeviceTimeAdjusted  = ulCurrentDeviceTime;                    }                    else                    {                        m_ulCurrentTime = ulAdjustedTime;                    }                }                else                {                    m_ulTimeAdjustDoneAt = ulTickCount;                    m_ulCurrentTime      = ulAdjustedTime;                }            }        }    }#endif /* HELIX_FEATURE_AUDIO_INACCURATESAMPLING */    /* Never go back in time */    if (!m_bTimeReturned)    {	m_bTimeReturned		    = TRUE;	m_ulLastCurrentTimeReturned = m_ulCurrentTime;	m_ulTimeAdjustDoneAt	    = HX_GET_TICKCOUNT();	m_ulLastDeviceTimeAdjusted  = ulCurrentDeviceTime;    }    else if (m_ulCurrentTime <= m_ulLastCurrentTimeReturned)    {	m_ulCurrentTime = m_ulLastCurrentTimeReturned;    }    else    {	m_ulLastDeviceTimeAdjusted  = ulCurrentDeviceTime;	m_ulLastCurrentTimeReturned = m_ulCurrentTime;    }}HX_RESULTCHXAudioPlayer::ResumeFakeTimeline(void){    HX_RESULT	rc = HXR_OK;    HX_ASSERT(!m_bHasStreams);    HXTimeval lTime = m_pScheduler->GetCurrentSchedulerTime();    m_pFakeAudioCBTime->tv_sec = lTime.tv_sec;    m_pFakeAudioCBTime->tv_usec = lTime.tv_usec;    m_ulIncreasingTimer = m_ulCurrentTime;    m_ulLastFakeCallbackTime = HX_GET_TICKCOUNT();    *m_pFakeAudioCBTime += (int) (m_ulGranularity*1000);    m_ulCallbackID = m_pScheduler->AbsoluteEnter(this,                                                 *((HXTimeval*) m_pFakeAudioCBTime));    return rc;}HX_RESULT CHXAudioPlayer::Func(){    m_ulCallbackID = 0;    OnTimerCallback();    return HXR_OK;}HX_RESULT CHXAudioPlayer::StopFakeTimeline(void){    HX_RESULT	rc = HXR_OK;    if(m_ulCallbackID && m_pScheduler)    {        m_pScheduler->Remove(m_ulCallbackID);    }    return rc;}doubleCHXAudioPlayer::NumberOfBytesWritten(){    return m_Owner->NumberOfBytesWritten();}doubleCHXAudioPlayer::ConvertMsToBytes(UINT32 ulTime){    return m_Owner->ConvertMsToBytes(ulTime);}voidCHXAudioPlayer::UpdateStreamLastWriteTime(){    // Make each stream seek, too, since they own the resampling buffers.    CHXAudioStream* s = 0;    CHXSimpleList::Iterator lIter = m_pStreamList->Begin();    for (; lIter != m_pStreamList->End(); ++lIter)    {	s = (CHXAudioStream*) (*lIter);	s->UpdateStreamLastWriteTime();    }}voidCHXAudioPlayer::SaveLastNMilliSeconds(BOOL bSave, UINT32 ulNMilliSeconds){    // Make each stream seek, too, since they own the resampling buffers.    CHXAudioStream* s = 0;    CHXSimpleList::Iterator lIter = m_pStreamList->Begin();    for (; lIter != m_pStreamList->End(); ++lIter)    {	s = (CHXAudioStream*) (*lIter);	s->SaveLastNMilliSeconds(bSave, ulNMilliSeconds);    }}voidCHXAudioPlayer::RewindPlayer(UINT32 ulTimeToRewind){    if (m_pStreamList->GetCount() == 0	|| !m_bCanBeRewound)    {	return;    }    // Make each stream seek, too, since they own the resampling buffers.    CHXAudioStream* s = 0;    CHXSimpleList::Iterator lIter = m_pStreamList->Begin();    for (; lIter != m_pStreamList->End(); ++lIter)    {	s = (CHXAudioStream*) (*lIter);	s->RewindStream(ulTimeToRewind);    }    HX_ASSERT(m_llLastWriteTime >= ulTimeToRewind);    if (m_llLastWriteTime >= ulTimeToRewind)    {	m_llLastWriteTime -= ulTimeToRewind;    }}HX_RESULTCHXAudioPlayer::ProcessAudioHook(PROCESS_ACTION action,				 IHXAudioHook* pAudioHook){    return HXR_OK;}STDMETHODIMP CHXAudioPlayer::SetError( HX_RESULT theErr ){    if (theErr != HXR_OK)    {	IHXErrorMessages* pErrorMessage = NULL;	m_pContext->QueryInterface(IID_IHXErrorMessages, (void**) &pErrorMessage);	if (pErrorMessage)	{	    pErrorMessage->Report(HXLOG_ERR, theErr, 0, NULL, NULL);	    pErrorMessage->Release();	}    }    return HXR_OK;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -