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

📄 rvorbis.cpp

📁 linux下的一款播放器
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    ogg_int64_t den = m_audioFmt.ulSamplesPerSec;    ogg_int64_t q = m_totalSamples / den;    ogg_int64_t r = m_totalSamples - q * den;    return (UINT32)(q * 1000 + (r * 1000) / den);}UINT32 CVorbisRenderer::BytesToMs(UINT32 ulNumBytes){    UINT32 q = ulNumBytes / m_ulBytesPerSec;    UINT32 r = ulNumBytes - q * m_ulBytesPerSec;    return q * 1000 + (r * 1000) / m_ulBytesPerSec;}UINT32 CVorbisRenderer::MsToBytes(UINT32 ulMs){    UINT32 q = ulMs / 1000;    UINT32 r = ulMs - q * 1000;    return q * m_ulBytesPerSec + (r * m_ulBytesPerSec) / 1000;}STDMETHODIMP CVorbisRenderer::OnDryNotification(UINT32 ulCurrentStreamTime,                                                 UINT32 ulMinimumDurationRequired){    HX_RESULT res = HXR_UNEXPECTED;    DPRINTF(D_VORBIS,("OnDryNotification(%u %u)\n",                       ulCurrentStreamTime, ulMinimumDurationRequired));    if (VorbisPlay != m_VorbisState)    {        res = HXR_OK;       }    else if (m_pDepack)    {        BOOL bDone = FALSE;        UINT32 ulEndTime = ulCurrentStreamTime + ulMinimumDurationRequired;        BOOL bWroteData = FALSE;        UINT32 ulLastWriteTime = 0;        BOOL bAudioParamsChanged = FALSE;        BOOL bEOS = FALSE;                while (!bDone)        {            ogg_packet* pPkt = NULL;            HX_RESULT err = m_pDepack->GetVorbisPacket(pPkt);                        if (HXR_OK == err)            {                if (pPkt->b_o_s)                {                    gotoInitialHeaderState();                }                else if (pPkt->e_o_s)                {                    bEOS = TRUE;                }                else                {                    HX_ASSERT(!bEOS);                }                switch (m_VorbisState) {                case VorbisInitialHeader:                    res = handleInitialHeader(pPkt);                    bEOS = FALSE;                    break;                                    case VorbisCommentHeader:                    if (vorbis_synthesis_headerin(&m_vi, &m_vc, pPkt) >= 0)                    {                        DPRINTF(D_VORBIS,("Got Comment Header\n"));                        updateTACInfo(&m_vc);                        m_VorbisState = VorbisCodebookHeader;                    }                    break;                                    case VorbisCodebookHeader:                    vorbis_synthesis_headerin(&m_vi, &m_vc, pPkt);                    vorbis_synthesis_init(&m_vd, &m_vi);                    vorbis_block_init(&m_vd, &m_vb);                                        m_VorbisState = VorbisPlay;                            DPRINTF(D_VORBIS,("Got Codebooks\n"));                    break;                case VorbisPlay:                    DPRINTF(D_VORBIS,("calling DecodeAndRender\n"));                    ulLastWriteTime = DecodeAndRender(pPkt);                    bWroteData = TRUE;                    bDone =  IsTimeGreaterOrEqual(ulLastWriteTime,ulEndTime);                    break;                default:                    HX_ASSERT(!"Unexpected state!");                    bDone = TRUE;                    break;                };                _ogg_free(pPkt);            }            else             {                 bDone = TRUE;            }        }        if (!bWroteData ||             IsTimeLess(ulLastWriteTime, ulEndTime) &&            !IsRebuffering() && !bEOS)        {            /* We ran out of data and we didn't satisfy what             * is needed. Initiate a rebuffer so we get more             * packets             */            StartRebuffer();        }        else if (bWroteData &&                  IsTimeGreaterOrEqual(ulLastWriteTime,ulEndTime) &&                 IsRebuffering())        {            /* We wrote data, satisfied what was needed and             * were rebuffering. Time to end the rebuffer.             */            EndRebuffer();        }                if (bEOS)        {            /* We don't have any more data and we've seen an             * end of stream packet. This could be the start             * of a video only stream group. Disable ODN             * calls for now so we don't rebuffer and             * transition to the VorbisInitialHeader state so              * that we are ready for the next stream  and so             * OnPacket will process the packets.              */            m_pCurrentStream->SetDryNotification(NULL);            gotoInitialHeaderState();        }        DPRINTF(D_VORBIS,("needed %ldms sent %ldms...\n",                           ulMinimumDurationRequired,                           (bWroteData) ? (ulLastWriteTime - ulCurrentStreamTime) : 0));        res = HXR_OK;    }    DPRINTF(D_VORBIS,("OnDryNotification() : res %08x\n", res));    return res;}STDMETHODIMP CVorbisRenderer::OnTimeSync(UINT32 currentPlayBackTime){    DPRINTF(D_VORBIS,("OnTimeSync(%u)\n", currentPlayBackTime));    return HXR_OK;}STDMETHODIMP CVorbisRenderer::OnPreSeek(UINT32 timeBeforeSeek, UINT32 timeAfterSeek){    DPRINTF(D_VORBIS,("OnPreSeek(%u, %u)\n", timeBeforeSeek, timeAfterSeek));    m_bInSeekMode = TRUE;    return HXR_OK;}STDMETHODIMP CVorbisRenderer::OnPostSeek(UINT32 timeBeforeSeek, UINT32 timeAfterSeek){    DPRINTF(D_VORBIS,("OnPostSeek(%u, %u)\n", timeBeforeSeek, timeAfterSeek));    m_bInSeekMode = FALSE;        m_bIsFirstPacket = TRUE;    if (m_pDepack)    {        m_pDepack->Reset();    }            return HXR_OK;}STDMETHODIMP CVorbisRenderer::OnPause(UINT32 timeBeforePause){    DPRINTF(D_VORBIS,("CVorbisRenderer::OnPause(%u)\n", timeBeforePause));    return HXR_OK;}STDMETHODIMP CVorbisRenderer::OnBuffering(UINT32 reason, UINT16 percentComplete){    return HXR_OK;}STDMETHODIMP CVorbisRenderer::OnEndofPackets(void){    DPRINTF(D_VORBIS,("CVorbisRenderer::OnEndofPackets()\n"));    if (m_pDepack)    {        m_pDepack->EndOfStream();    }    m_bEndOfPackets = TRUE;    if (IsRebuffering())    {        EndRebuffer();    }    return HXR_OK;}STDMETHODIMP CVorbisRenderer::EndStream(void){    DPRINTF(D_VORBIS,("CVorbisRenderer::EndStream()\n"));    Shutdown();            return HXR_OK;}CVorbisRenderer::~CVorbisRenderer(void){        Shutdown();}STDMETHODIMP_(UINT32) CVorbisRenderer::AddRef(void){    return InterlockedIncrement(&m_RefCount);}STDMETHODIMP_(UINT32) CVorbisRenderer::Release(void){    if (InterlockedDecrement(&m_RefCount) > 0)        return m_RefCount;    delete this;    return 0;}STDMETHODIMP CVorbisRenderer::QueryInterface(REFIID interfaceID, void **ppInterfaceObj){    if (IsEqualIID(interfaceID, IID_IUnknown)) {        AddRef();        *ppInterfaceObj = (IUnknown *)(IHXPlugin *)this;        return HXR_OK;    } else if (IsEqualIID(interfaceID, IID_IHXPlugin)) {        AddRef();        *ppInterfaceObj = (IHXPlugin *)this;        return HXR_OK;    } else if (IsEqualIID(interfaceID, IID_IHXRenderer)) {        AddRef();        *ppInterfaceObj = (IHXRenderer *)this;        return HXR_OK;    }    *ppInterfaceObj = NULL;    return HXR_NOINTERFACE;}HX_RESULT CVorbisRenderer::InitAudioStream(UINT32 ulSampleRate, UINT16 usChannels){    HX_RESULT res = HXR_OK;    DPRINTF(D_VORBIS,("InitAudioStream(%u, %u)\n", ulSampleRate, usChannels));    UINT32 uCurrentSampleRate = 0;    UINT32 uCurrentChannels = 0;    if (m_pCurrentStream)    {        res = m_pCurrentStream->GetStreamInfo(uCurrentSampleRate,                                              uCurrentChannels);        m_pCurrentStream->SetDryNotification(NULL);        m_pCurrentStream = NULL;    }    if ((uCurrentSampleRate != ulSampleRate) &&        m_totalSamples && uCurrentSampleRate)    {        ogg_int64_t q = m_totalSamples / uCurrentSampleRate;        ogg_int64_t r = m_totalSamples - q * uCurrentSampleRate;        m_totalSamples =             q * ulSampleRate + (r * ulSampleRate) / uCurrentSampleRate;    }    m_audioFmt.ulSamplesPerSec = ulSampleRate;    m_audioFmt.uChannels = usChannels;    m_audioFmt.uBitsPerSample = 16;    m_audioFmt.ulSamplesPerSec = ulSampleRate;    m_audioFmt.uMaxBlockSize = 4096;        m_ulBytesPerSec = (m_audioFmt.uChannels *                        (m_audioFmt.uBitsPerSample / 8) *                        m_audioFmt.ulSamplesPerSec);        m_pCurrentStream = findAudioStream(m_audioFmt.ulSamplesPerSec,                                       m_audioFmt.uChannels);    if (m_pCurrentStream)    {        m_pCurrentStream->SetDryNotification(this);    }    else    {        res = HXR_UNEXPECTED;    }    return res;}COggAudioStreamHelper* CVorbisRenderer::findAudioStream(UINT32 ulSampleRate,                                  UINT16 usChannels){    COggAudioStreamHelper* pRet = NULL;    CHXSimpleList::Iterator itr = m_audioStreams.Begin();    for (;!pRet && (itr != m_audioStreams.End()); ++itr)    {        COggAudioStreamHelper* pHlpr =             (COggAudioStreamHelper*)*itr;                UINT32 uSampRate;        UINT32 uChannels;        if ((HXR_OK == pHlpr->GetStreamInfo(uSampRate, uChannels)) &&            (uSampRate == ulSampleRate) &&            (usChannels == uChannels))        {            pRet = pHlpr;            pRet->AddRef();        }    }    if (!pRet)    {        IHXAudioStream* pAudioStream = NULL;        HX_RESULT res = m_pAudioPlayer->CreateAudioStream(&pAudioStream);        if (HXR_OK == res)        {            pRet = new COggAudioStreamHelper;            if (pRet)            {                pRet->AddRef(); // For return value                res = pRet->Init(pAudioStream);                if (HXR_OK == res)                {                    if (m_audioStreams.AddTail(pRet))                    {                        pRet->AddRef(); // For list                        res = pAudioStream->Init(&m_audioFmt,                                                  m_pStreamHeaderObj);                        if (HXR_OK != res)                        {                            pRet->Release(); // For list                            m_audioStreams.RemoveTail();                        }                    }                    else                    {                        res = HXR_OUTOFMEMORY;                    }                }                                            if (HXR_OK != res)                {                    HX_RELEASE(pRet); // For return value                }            }        }        HX_RELEASE(pAudioStream);    }    return pRet;}UINT32 CVorbisRenderer::DecodeAndRender(ogg_packet* pOp){    UINT32 ulLastWriteTime = 0;    // we have a packet to decode    float **pcm;    int samples;    int convsize = m_audioFmt.uMaxBlockSize / m_vi.channels;    if (vorbis_synthesis(&m_vb, pOp) == 0)        vorbis_synthesis_blockin(&m_vd, &m_vb);    else {        DPRINTF(D_VORBIS,("ERROR ? HMMMMMMM\n"));    }    UINT32 ulAudioTime = CurrentTime();    while ((samples = vorbis_synthesis_pcmout(&m_vd, &pcm)) > 0) {        int i, j;        int clipflag = 0;        int bout = (samples < convsize ? samples : convsize);        int audioByteCt = bout * m_vi.channels * 2;        HXAudioData audioData;        audioData.pData = NULL;        audioData.ulAudioTime = ulAudioTime;                if ((HXR_OK == m_pClassFactory->CreateInstance(CLSID_IHXBuffer,                                                (void **)&audioData.pData)) &&            (HXR_OK == audioData.pData->SetSize(audioByteCt)))        {

⌨️ 快捷键说明

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