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

📄 hxaudses.cpp

📁 linux下的一款播放器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        HXAudioData audioData;        CHXAudioPlayer* pPlayer = 0;        CHXAudioStream* pStream = 0;        CHXSimpleList*  pStreamList = 0;#if defined(HELIX_FEATURE_VOLUME) || defined(HELIX_FEATURE_MIXER)        UINT16  uPlayerVolume = HX_INIT_VOLUME;#endif        UCHAR*  pMixBuffer = 0;        UCHAR*  pPlayerBuf = NULL;        UCHAR*  pSessionBuf = NULL;        IHXBuffer* pMixIHXBuffer = NULL;        BufType bufType = BUFFER_NONE;        for (UINT16 i = 0; !theErr && i < uPush; i++ )        {            m_uNumToBePushed = uPush - i;            m_bSessionBufferDirty = FALSE; // only used for multi-player case            UINT32  ulNumBytesWritten = m_ulBytesPerGran;            BOOL    bAtLeastOnePlayerActive = FALSE;            theErr = m_pSessionBuf->SetSize(m_ulBytesPerGran);            if( theErr == HXR_OUTOFMEMORY )            {                theErr = HXR_OUTOFMEMORY;                goto exit;            }            pSessionBuf = m_pSessionBuf->GetBuffer();            // Zero session buffer.            //memset(pSessionBuf, 0, HX_SAFESIZE_T(m_ulBytesPerGran));            // Get each player            pPlayer = 0;            CHXSimpleList::Iterator lIter = m_pPlayerList->Begin();            for (; lIter != m_pPlayerList->End(); ++lIter)            {                BOOL bStalled = FALSE;                pPlayer = (CHXAudioPlayer*) (*lIter);                if (pPlayer->GetStreamCount() == 0 ||                    pPlayer->IsDonePlayback() ||                    pPlayer->GetState() != E_PLAYING)                {                    continue;                }                bAtLeastOnePlayerActive = TRUE;                if (m_pPlayerList->GetCount() == 1)                {                    pMixIHXBuffer = m_pSessionBuf;                    bufType = BUFFER_SESSION;                }                else                {                    if (!m_pPlayerBuf)                    {                        m_pPlayerBuf = new CHXBuffer;                        m_pPlayerBuf->AddRef();                    }                    m_pPlayerBuf->SetSize(m_ulBytesPerGran);                    pPlayerBuf = m_pPlayerBuf->GetBuffer();                    // Zero play buffer.//                  memset(pPlayerBuf, 0, HX_SAFESIZE_T(m_ulBytesPerGran));                    pMixIHXBuffer = m_pPlayerBuf;                    bufType = BUFFER_PLAYER;                }                pMixBuffer = pMixIHXBuffer->GetBuffer();                BOOL bIsMixBufferDirty = FALSE;                BOOL bMayNeedToRollbackTimestamp = FALSE;                if (pPlayer->GetState() == E_PLAYING)                {                    UINT32  ulBufTime = 0;                    // Get each stream associated with this player                    pStreamList = pPlayer->GetStreamList();                    if (pStreamList)                    {                    CHXSimpleList::Iterator lIter = pStreamList->Begin();                    for (; lIter != pStreamList->End(); ++lIter)                    {                        pStream = (CHXAudioStream*) (*lIter);                        pStream->m_bMayNeedToRollbackTimestamp = FALSE;                        // don't mix paused audio streams                        if (pStream->GetState() != E_PAUSED)                        {                            theErr = pStream->MixIntoBuffer( pMixBuffer, m_ulBytesPerGran, ulBufTime, bIsMixBufferDirty);                            // so as not to trigger ReallyNeedData                            // since one of the streams internal m_llLastwritetime                            // has been updated even though this flag is set to FALSE.#if 0                            if (!bIsMixBufferDirty &&                                (theErr == HXR_OK || theErr == HXR_NO_DATA))                            {                                bIsMixBufferDirty = TRUE;                                ::memset(pMixBuffer, 0, HX_SAFESIZE_T(m_ulBytesPerGran));                            }#endif                            if (theErr == HXR_NO_DATA)                            {                                pStream->m_bMayNeedToRollbackTimestamp = TRUE;                                bMayNeedToRollbackTimestamp = TRUE;                                theErr = HXR_OK;                                continue;                            }                            if (theErr == HXR_FAIL)                            {                                theErr = HXR_OK;                                goto exit;                            }                            if (theErr == HXR_OUTOFMEMORY)                            {                                goto exit;                            }                            if (theErr == HXR_WOULD_BLOCK)                            {#ifdef _RAHULDEBUG                                {                                    char str[255]; /* Flawfinder: ignore */                                    ::sprintf(str, "Num to be pushed remaining: %lu\n", m_uNumToBePushed); /* Flawfinder: ignore */                                    OutputDebugString(str);                                }#endif                                if (bMayNeedToRollbackTimestamp)                                {                                    bMayNeedToRollbackTimestamp = FALSE;                                    lIter = pStreamList->Begin();                                    for (; lIter != pStreamList->End(); ++lIter)                                    {                                        pStream = (CHXAudioStream*) (*lIter);                                        if (pStream->m_bMayNeedToRollbackTimestamp)                                        {                                            pStream->m_bMayNeedToRollbackTimestamp = FALSE;                                            pStream->RollBackTimestamp();                                        }                                    }                                }                                goto handlewouldblock;                            }                        }                        if (pPlayer->GetState() != E_PLAYING)                        {                            /* We should keep the last buffer around and the last stream                             * to be mixed again...TBD XXX Rahul                             */                            //pPlayer->SetLastMixedBuffer(pMixBuffer, pStream);                            bStalled = TRUE;                            break;                        }                    }                    } //if (pStreamList)                    /* This pause may have happended due to ondrynotification */                    if (m_bPaused || m_bStoppedDuringPause)                    {                        /* This would happen ONLY IF THERE IS ONE AUDIO PLAYER                         * and that has been paused. So simply break                         */                        goto exit;                        //break;                    }                    /* hmmm... looks like there are more than one audio player.                     * continue with the next one                     */                    if (bStalled)                    {                        continue;                    }                    /* If the mixer buffer was not used, make sure it is initialized                     * to silence since we pass it to post process hooks                     */                    if (!bIsMixBufferDirty)                    {//{FILE* f1 = ::fopen("e:\\audioses.txt", "a+"); ::fprintf(f1, "%lu\t%p\tsilence in mix buffer\n", HX_GET_BETTERTICKCOUNT(), this);::fclose(f1);}                        ::memset(pMixBuffer, 0, HX_SAFESIZE_T(m_ulBytesPerGran));                    }#if defined(HELIX_FEATURE_VOLUME) && defined(HELIX_FEATURE_MIXER)                    // Apply Player volume to buffer; do this before we call                    // the post mix hooks.                    uPlayerVolume = pPlayer->GetVolume();                    if (uPlayerVolume != 100 && bIsMixBufferDirty)                    {                        CHXMixer::ApplyVolume(pMixBuffer, m_ulBytesPerGran, uPlayerVolume, m_DeviceFmt.uBitsPerSample);                    }#endif /* HELIX_FEATURE_VOLUME && HELIX_FEATURE_MIXER */                    // Give data to this AudioPlayer's post mix hooks                    // (do they want 8 or 16 bit?)                    BOOL bChanged = FALSE;                    ProcessPostMixHooks(pPlayer, pMixIHXBuffer, &bDisableWrite, ulBufTime, bChanged);                    /*                     * If the mixer buffer changed (because of a post mix hook)                     * make sure to point the player/session buffer to this                     * modified buffer                     */                    if (bChanged)                    {                        pMixBuffer = pMixIHXBuffer->GetBuffer();                        if (bufType == BUFFER_PLAYER)                        {                            m_pPlayerBuf = pMixIHXBuffer;                            pPlayerBuf = pMixIHXBuffer->GetBuffer();                        }                        else                        {                            m_pSessionBuf = pMixIHXBuffer;                            pSessionBuf = pMixIHXBuffer->GetBuffer();                        }                    }                }#if defined(HELIX_FEATURE_MIXER)                // Don't mix if volume is 0.                // Don't mix if this player has disabled device write.                // Don't mix if there is only one player since we would have                // written data into session buf instead of player buffer                if (m_pPlayerList->GetCount() > 1 && uPlayerVolume > 0 && !bDisableWrite)                {                    /* We always set a volume of 100 since we have already applied volume                     * to player buffer                     */                    CHXMixer::MixBuffer( pPlayerBuf, pSessionBuf,                                m_ulBytesPerGran, FALSE, 100, m_DeviceFmt.uBitsPerSample, m_bSessionBufferDirty);                }#endif /* HELIX_FEATURE_MIXER */                pPlayer->UpdateLastWriteTime(m_ulGranularity);            }            if (!bAtLeastOnePlayerActive)            {                goto exit;            }            /* did we ever write to the session buffer ? */            if (m_pPlayerList->GetCount() > 1 && !m_bSessionBufferDirty)            {//{FILE* f1 = ::fopen("e:\\audioses.txt", "a+"); ::fprintf(f1, "%lu\t%p\tsilence in session buffer\n", HX_GET_BETTERTICKCOUNT(), this);::fclose(f1);}                ::memset(pSessionBuf, 0, HX_SAFESIZE_T(m_ulBytesPerGran));            }            // This increments with each buffered played.            m_dBufEndTime   += m_dGranularity;            // Set the session buffer to the IRMA buffer.            audioData.pData       = m_pSessionBuf;            audioData.ulAudioTime = (ULONG32)m_dBufEndTime;            if (m_pAudioDev && !m_bDisableWrite)            {                /* are we dealing with a f*%$'ed up sound card */                if ((m_BeforeHookDeviceFmt.uChannels == 1 && m_DeviceFmt.uChannels == 2)||                    m_BeforeHookDeviceFmt.uBitsPerSample == 8)                {                    ConvertTo8BitAndOrMono(&audioData);                }                if (m_pFinalHook && m_bUseFinalHook)                {                    if (HXR_OK == ProcessAudioHook(ACTION_CHECK, m_pFinalHook))                    {                        m_pOutDataPtr->pData        = NULL;                        m_pOutDataPtr->ulAudioTime          = audioData.ulAudioTime;                        m_pOutDataPtr->uAudioStreamType = audioData.uAudioStreamType;                        m_pFinalHook->OnBuffer(&audioData, m_pOutDataPtr);                        HX_ASSERT(m_pOutDataPtr->pData);                        if (m_pOutDataPtr->pData)                        {                            HX_RELEASE(audioData.pData);                            m_pSessionBuf = audioData.pData = m_pOutDataPtr->pData;                        }                        else                        {                            /* This is a screwed up Hook. Disable it */                            m_bUseFinalHook = FALSE;                        }                    }                }                if (m_pHookList)                {                    ProcessHooks(&audioData);                }                ulNumBytesWritten    = audioData.pData->GetSize();                if (HXR_OK == ProcessAudioDevice(ACTION_CHECK, m_pAudioDev))                {                    // Write session audio data to device.                    theErr = m_pAudioDev->Write(&audioData);                    if( theErr == HXR_OUTOFMEMORY )                    {                        goto exit;                    }                }                if (theErr == HXR_WOULD_BLOCK)                {                    HXAudioData* pAudioData     = new HXAudioData;                    pAudioData->pData           = audioData.pData;                    pAudioData->pData->AddRef();                    pAudioData->ulAudioTime     = audioData.ulAudioTime;                    pAudioData->uAudioStreamType= audioData.uAudioStreamType;                    // Create auxiliary buffer list, if one is not already created                    if (!m_pAuxiliaryAudioBuffers)                    {                        m_pAuxiliaryAudioBuffers = new CHXSimpleList;                    }                    if( NULL == m_pAuxiliaryAudioBuffers->AddTail(pAudioData) )                    {                        theErr = HXR_OUTOFMEMORY;                        goto exit;                    }                    HX_RELEASE(m_pSessionBuf);                }                /* Any error from audio device other than memory error is                 * returned as HXR_AUDIO_DRIVER                 */                if (theErr != HXR_OK && theErr != HXR_WOULD_BLOCK &&                    theErr != HXR_OUTOFMEMORY)                {                    theErr = HXR_AUDIO_DRIVER;                }            }            if (!theErr)            {                m_ulBlocksWritten++;                m_dNumBytesWritten  += ulNumBytesWritten;            }            // So this function is good in theory, but in practice we find in            // heap-optimized mode it is not necessary, and it leads to            // unnecessary heap fragmentation.#if !defined(HELIX_CONFIG_MIN_HEAP_FRAG)            theErr = CheckForBufferReuse();#endif        }  // for loop    }     //  end if we have audio streamshandlewouldblock:    // mask this error    if (theErr == HXR_WOULD_BLOCK)    {        theErr = HXR_OK;    }    // If we do not have audio.. OR  if we do have audio but    // we have disabled writing to the device, then we need to    // fake the timeline.    if (!theErr && !m_ulCallbackID && (!m_bHasStreams || m_bDisableWrite))    {        if (m_bFirstPlayAudio)        {            // First time thru, we initialize callback time.            HXTimeval lTime = m_pScheduler->GetCurrentSchedulerTime();            m_pFakeAudioCBTime->tv_sec = lTime.tv_sec;            m_pFakeAudioCBTime->tv_usec = lTime.tv_usec;            m_ulIncreasingTimer = 0;            m_ulLastFakeCallbackTime    = HX_GET_TICKCOUNT();            *m_pFakeAudioCBTime += (int) (m_ulGranularity*1000);        }        m_bFakeAudioTimeline =  TRUE;        m_ulCallbackID = m_pScheduler->RelativeEnter( this, m_ulGranularity);        if (m_bFirstPlayAudio)        {            OnTimeSync(m_ulIncreasingTimer);        }    }    else if (!theErr && !m_ulCallbackID && m_bHasStreams && !m_bDisableWrite)    {        m_bFakeAudioTimeline =  FALSE;        m_ulCallbackID = m_pScheduler->RelativeEnter(this, m_ulGranularity*9/10);#if 0   // XXX HP don't send OnTimeSync() untill we resume the audio device        // the following logic caused OnTimeSync() sent to video renderer before the audio        // timeline is started after seeking, as a consequence, the A/V could be out of        // sync, video could be frozen for short period time in order to wait the audio        // timeline to catch up        if (m_bFirstPlayAudio)        {            OnTimeSync(m_ulIncreasingTimer);        }#endif    }exit:    m_bInPlayAudio      = FALSE;    // can only happen in multi-player pause/resume/stop case    if (m_bDeferActualResume && theErr != HXR_OUTOFMEMORY)

⌨️ 快捷键说明

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