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

📄 mp3ff.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                        m_pFileObj->Seek(m_ulBytesRead, FALSE);
                    }
                    else
                    {
                        m_State = Ready;
                        m_pStatus->StreamDone(0);
                    }
        
                    pPacketObj->Release();

                    if (pPacketBuffer)
                        pPacketBuffer->Release();

                    return HXR_OK;
                }
            }
            else
            {
                UINT32 ulOffset = m_ulBytesRead - pPacketData->dwBytesRemaining;
//                char szDbgStr[256];
//                sprintf(szDbgStr, "Frame of size %d found at offset %lu (%02x %02x %02x %02x) next offset = %lu\n",
//                        nSyncSize, ulOffset, pPacketData->pBuffer[0], pPacketData->pBuffer[1],
//                        pPacketData->pBuffer[2], pPacketData->pBuffer[3], ulOffset + nSyncSize);
//                OutputDebugString(szDbgStr);
            }

            // Reformat the current MP3 frame if we are streaming
            int nModFrameSize = nSyncSize;
            
#if defined (MPA_FMT_DRAFT00)
            if (m_bStreaming && !m_bRtp)
            {
                // We need 1+ audio frames
                UINT32  ulReadSize = 0;
                pModFrameStart = m_pFmtBuf->GetReadPointer(ulReadSize);

                UINT32 nSync = m_pMp3Fmt->CheckValidFrame(pModFrameStart, ulReadSize);

                if (ulReadSize >= nSync + 6 ||
                    m_bEOF)
                {
                    nModFrameSize = m_pMp3Fmt->ReformatMP3Frame(&pModFrameStart,
                                                               ulReadSize,
                                                               m_pFmtBuf->GetPrevBytes());

                    // If we did not have enough back data to reformat, skip this frame
                    // in the format buffer
                    if (!nModFrameSize)                        
                        m_pFmtBuf->AdvanceRead(nSync);
                }
                else
                    nModFrameSize = 0;
                
                if (nModFrameSize)
                    m_pFmtBuf->AdvanceRead(nSync);
                else
                {
                    // Are we advancing the buffer by some
                    // positive amount?
                    if (nSyncSize > 0)
                    {
                        // Move to next sync word
                        pPacketData->pBuffer += nSyncSize;
                        pPacketData->dwBytesRemaining -= nSyncSize;
                
                        goto TOP;
                    }
                    else
                    {
                        // If we get here, then we have gotten
                        // lost on parsing this file, and likely
                        // the file is corrupt or unsupported.
                        // If we had tried to advance the buffer
                        // by zero, we would have entered an infinite
                        // loop. Therefore, we bail out.
                        HX_RELEASE(pPacketData->pReadBuffer);
                        m_pStatus->StreamDone(0);
                        return HXR_OK;
                    }
                }
            }
#endif //MPA_FMT_DRAFT00

	    // We need the pPacketBuffer here, but not before.
	    pPacketBuffer = (*m_pCreatePacketFunction)( m_pClassFactory, 
			pPacketData->pReadBuffer,
			pModFrameStart,
			nModFrameSize );

            // Set packet data
            if (nModFrameSize)
            {
#if defined (MPA_FMT_DRAFT00)
                // Copy the rtp payload header
                if (m_bRtp)
                {
                    pPacketBuffer->SetSize(nModFrameSize+m_RtpPackets.ulHeaderSize);

                    if (pPacketBuffer->GetSize() != (UINT32)nModFrameSize+m_RtpPackets.ulHeaderSize)
                    {
                        HX_RELEASE(pPacketBuffer);
                        HX_RELEASE(pPacketObj);

                        return HXR_OUTOFMEMORY;
                    }

                    memcpy(pPacketBuffer->GetBuffer(), /* Flawfinder: ignore */
                           m_RtpPackets.aHeader,
                           m_RtpPackets.ulHeaderSize);

                    memcpy(pPacketBuffer->GetBuffer()+m_RtpPackets.ulHeaderSize, /* Flawfinder: ignore */
                           pModFrameStart,
                           nModFrameSize);
                
                    // Reset rtp packet values
                    memset(&m_RtpPackets.aHeader, 0, sizeof(m_RtpPackets.aHeader));
                    m_RtpPackets.bPacketReady = 0;
                    m_RtpPackets.ulHeaders = 0;
                    m_RtpPackets.ulDataChunks = 0;
                    m_RtpPackets.ulBytesFree = RTP_PACKET_SIZE;
                }
#endif //MPA_FMT_DRAFT00
                if( m_bStreaming || m_bRtp || m_pMp3Fmt->GetMetaRepeat() )
                {
                   pPacketBuffer->Set(pModFrameStart,nModFrameSize);
                }
                
#if defined(HELIX_FEATURE_MP3FF_SHOUTCAST)
                // If this packet has meta data, left shift the mp3
                // data over the meta data.
                if (m_bMetaPacket)
                {
                    UCHAR *pTemp = pPacketBuffer->GetBuffer();
                    
                    if (m_bRtp)
                        pTemp += 4;

                    UINT32 ulBytesToTitle = m_ulNextMetaPos - 
                        (m_ulBytesRead - pPacketData->dwBytesRemaining);

                    for (UINT32 i=ulBytesToTitle; 
                         i<(UINT32)nModFrameSize - m_ulMetaLength; i++)
                        pTemp[i] = pTemp[i+m_ulMetaLength];

                    pPacketBuffer->SetSize(pPacketBuffer->GetSize()-m_ulMetaLength);

                    // Set next meta data offset
                    m_ulNextMetaPos += m_pMp3Fmt->GetMetaRepeat() + m_ulMetaLength;
                    m_ulMetaLength = 0;
                    m_bMetaPacket = 0;
                }
#endif //HELIX_FEATURE_MP3FF_SHOUTCAST

                pPacketObj->Set(pPacketBuffer, deliveryTime, streamNo,
                                ASMFlags, ASMRuleNo);
            }

            // We know we've read good data now, so clear the
            // amount of consecutive garbage bytes we've read.
            m_ulGarbageBytesRead = 0;

            // Set the delivery time for the next packet. Note that each
            // packet is stamped with a delivery time which is used to pace
            // the delivery of packets to the rendering plug-ins.
            m_dNextPts += m_Info.dTimePerFrame;
            m_ulNextPacketDeliveryTime = (UINT32)m_dNextPts;

            // Move to next sync word
            pPacketData->pBuffer += nSyncSize;
            pPacketData->dwBytesRemaining -= nSyncSize;

            // Notify the RMA core that the packet object is ready
            if (nModFrameSize)
                m_pStatus->PacketReady(status, pPacketObj);

            // Release the object since we are done with it
            pPacketObj->Release();

            if (pPacketBuffer)
                pPacketBuffer->Release();
        }
        else
            return HXR_OUTOFMEMORY;
    }
    
    // No more packets are available for this stream
    else
    {
        // Notify the RMA core that the stream is done
        m_pStatus->StreamDone(0);
    }

    return HXR_OK;
}


///////////////////////////////////////////////////////////////////////////////
//  IHXFileResponse::SeekDone                               ref:  hxfiles.h
//
//  This routine is automatically called when the Seek() operation in the
//  file is complete. Other actions are then taken dependent on the current
//  processing state.
//
STDMETHODIMP
CRnMp3Fmt::SeekDone(HX_RESULT status)
{
    switch (m_State)
    {
        case SeekSeekPending:
            // We are in the process of handling a Seek() request...
            m_State = Ready;

            // Notify the RMA core that the Seek() has completed
            m_pStatus->SeekDone(status);
            break;

        case GetId3HeaderSeekPending:

            // Return to default access
            m_pFileObj->Advise(HX_FILEADVISE_ANYACCESS);
            // If we failed,then we need to try again with
            // this new HX_FILEADVISE_ANYACCESS mode. If we
            // succeeded, then we can go ahead and read.
            if (SUCCEEDED(status))
            {
                // We successfully seeked, so now read the ID3 tags, if any
                m_State = GetId3HeaderReadPending;
                m_pFileObj->Read(ID3HeaderLen+BytesBeforeID3Header);
            }
            else
            {
                // We tried to seek to the end of the file
                // in order to get the ID3 tags, but the seek
                // failed (that can sometimes happen if we're 
                // playing via http and we have a HTTP 1.0 server)
                // If this happens, then we won't worry about getting
                // the ID3 tags - we'll simply go ahead and seek
                // back to the beginning of the file like we do
                // after we read the ID3 tags.
                m_State = GetFileHeaderSeekPending;
                m_pFileObj->Seek(MY_FILE_HEADER_START, FALSE);
            }

            break;

        case GetFileHeaderSeekPending:
            {
                m_State = GetFileHeaderReadPending;

                // Read the file header data from the file.
                // Read more when we are streaming - we need more   
                // accurate avg bitrate for vbrs when streaming.   
                UINT32 ulReadSize = MY_FILE_HEADER_LENGTH << 3;
                if (m_bLive ||
                    m_pFileObj->Advise(HX_FILEADVISE_RANDOMACCESS) == HXR_ADVISE_PREFER_LINEAR)
                {
                    ulReadSize = MY_FILE_HEADER_LENGTH;
                }
                m_pFileObj->Read(ulReadSize);
            }
            break;

        case GetStreamHeaderSeekPending:
            MyCreateStreamHeaderObj_v(HX_STATUS_OK, NULL);
            break;

        case GetPacketSeekPending:
        {
            m_State = GetPacketReadPending;
            UINT32  ulReadSize = kReadSize;
            
#if defined(HELIX_FEATURE_MP3FF_SHOUTCAST)
            if (m_ulMetaReadSize)
            {
                ulReadSize += m_ulMetaReadSize;
                m_ulMetaReadSize = 0;
            }
#endif //HELIX_FEATURE_MP3FF_SHOUTCAST

            m_pFileObj->Read(ulReadSize);

            break;
        }

        case SeekToOffsetNoRead:
            m_State = Ready;
            break;

        default:
            return HXR_UNEXPECTED;
    }

    return HXR_OK;
}


///////////////////////////////////////////////////////////////////////////////
//  IHXFileResponse::ReadDone                               ref:  hxfiles.h
//
//  This routine is automatically called when the Read() from the file is
//  done. Other actions are then taken dependent on the current processing
//  state.
//
STDMETHODIMP
CRnMp3Fmt::ReadDone(HX_RESULT   status,
                    IHXBuffer* pBufferRead)
{
    /* This may happen in HTTP streaming when the file system
     * is in still a seeking mode when the next seek is issued.
     * The file system will then call SeekDone with a status of 
     * HXR_CANCELLED for the pending seek.
     */
    if (status == HXR_CANCELLED)
    {
    return HXR_OK;
    }

    switch (m_State)
    {
        case GetId3HeaderReadPending:
        {
            if (pBufferRead)
            {
                // Try to extract ID3v1 header data
                INT32 lTemp;   
                m_pMp3Fmt->CheckForHeaders(pBufferRead->GetBuffer()+BytesBeforeID3Header,
                                           pBufferRead->GetSize()-BytesBeforeID3Header,
                                           lTemp);
            }
            
            // Go back to the beginning and init the stream
            m_State = GetFileHeaderSeekPending;
            m_pFileObj->Seek(MY_FILE_HEADER_START, FALSE);
            break;
        }

        case GetFileHeaderReadPending:
            if (!pBufferRead)
                return HXR_UNEXPECTED;

            return MyCreateFileHeaderObj_hr(status, pBufferRead);
            break;

        case GetStreamHeaderReadPending:
            if (!pBufferRead)
                return HXR_UNEXPECTED;

            MyCreateStreamHeaderObj_v(status, pBufferRead);
            break;

        case GetPacketReadPending:
        {
            // Buffer the read packet
            if (HXR_OK == status && pBufferRead && pBufferRead->GetSize())
            {
                m_ulBytesRead += pBufferRead->GetSize();

⌨️ 快捷键说明

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