amrff.cpp

来自「symbian 下的helix player源代码」· C++ 代码 · 共 914 行 · 第 1/3 页

CPP
914
字号
                        }
                        // Set some properties
                        pHdr->SetPropertyULONG32("StreamNumber",  0);
                        pHdr->SetPropertyULONG32("MaxBitRate",    ulAvgBitRate);
                        pHdr->SetPropertyULONG32("AvgBitRate",    ulAvgBitRate);
                        pHdr->SetPropertyULONG32("MaxPacketSize", AMR_IDEAL_PACKET_SIZE);
                        pHdr->SetPropertyULONG32("AvgPacketSize", AMR_IDEAL_PACKET_SIZE);
                        pHdr->SetPropertyULONG32("MinPacketSize", AMR_IDEAL_PACKET_SIZE);
                        pHdr->SetPropertyULONG32("StartTime",     0);
                        pHdr->SetPropertyULONG32("Duration",      ulDur);
                        // Pass this stream header into the payload format object
                        retVal = m_pPayloadFormat->SetStreamHeader(pHdr);
                        if (SUCCEEDED(retVal))
                        {
                            // Create a raw file packet
                            IHXPacket* pPacket = NULL;
                            retVal = MakeRawFilePacket(pBuffer, m_ulNextTimeStamp, pPacket);
                            if (SUCCEEDED(retVal))
                            {
                                // Add this packet to the payload object
                                retVal = m_pPayloadFormat->SetPacket(pPacket);
                                if (SUCCEEDED(retVal))
                                {
                                    // Update the next file offset
                                    m_ulNextFileOffset += m_pPayloadFormat->GetPacketBytesConsumed();
                                    // Update the next time stamp
                                    m_ulNextTimeStamp  += m_pPayloadFormat->GetDurationConsumed();
                                    // Set the state
                                    m_eState = StateReady;
                                    // Send the stream header
                                    retVal = m_pFormatResponse->StreamHeaderReady(HXR_OK, pHdr);
                                }
                            }
                            HX_RELEASE(pPacket);
                        }
                    }
                    HX_RELEASE(pHdr);
                }
            }
        }
        if (FAILED(retVal))
        {
            // Return to StateReady
            m_eState = StateReady;
            // Fail out to response interface
            retVal = m_pFormatResponse->StreamHeaderReady(retVal, NULL);
        }
    }
    else if (m_eState == StateGetPacketReadDonePending)
    {
        retVal = status;
        if (SUCCEEDED(retVal))
        {
            // Do we need to scan this buffer for a frame begin?
            IHXBuffer* pNewBuffer = NULL;
            UINT32     ulNewBufferOffset = 0;
            if (m_bScanForFrameBegin)
            {
#ifdef DEBUG_TEST_FRAME_SCAN
                // Force the first fifth of the buffer to be invalid
                memset(pBuffer->GetBuffer(), 0x83, pBuffer->GetSize() / 5);
#endif
                // Scan the buffer
                UINT32 ulOffset = 0;
                BYTE   bRet = CAMRFrameInfo::FindFrameBegin((m_bWideBand ? WideBand : NarrowBand),
                                                            pBuffer->GetBuffer(),
                                                            pBuffer->GetSize(),
                                                            AMR_MIN_CONSEC_FRAMES,
                                                            ulOffset);
                if (bRet)
                {
                    // If the offset is at the beginning
                    // of the buffer, then we don't have to
                    // do anything. If the offset is NOT at the
                    // beginning, then we need to create a new
                    // buffer and copy the old one into it.
                    if (ulOffset > 0 && ulOffset < pBuffer->GetSize())
                    {
                        // We have a valid offset
                        retVal = m_pCommonClassFactory->CreateInstance(CLSID_IHXBuffer,
                                                                       (void**) &pNewBuffer);
                        if (SUCCEEDED(retVal))
                        {
                            retVal = pNewBuffer->Set(pBuffer->GetBuffer() + ulOffset,
                                                     pBuffer->GetSize()   - ulOffset);
                            if (SUCCEEDED(retVal))
                            {
                                ulNewBufferOffset = ulOffset;
                            }
                        }
                    }
                    else if (ulOffset != 0)
                    {
                        // Huh? the offset was outside the buffer? Surrender!
                        retVal = HXR_FAIL;
                    }
                }
                else
                {
                    // Yikes! We didn't find a frame in this
                    // buffer at all? We surrender!
                    retVal = HXR_FAIL;
                }
                // Clear the flag
                m_bScanForFrameBegin = FALSE;
            }
            if (SUCCEEDED(retVal))
            {
                // Create a raw file packet
                IHXPacket* pRawPacket = NULL;
                retVal = MakeRawFilePacket((pNewBuffer ? pNewBuffer : pBuffer),
                                           m_ulNextTimeStamp, pRawPacket);
                if (SUCCEEDED(retVal))
                {
                    // If the buffer was less than we read, then we are 
                    // probably at the end of the file. Therefore, we want
                    // to process ALL of this buffer, regardless of the
                    // minimum packet size. So we need to tell the payload
                    // format object to Flush().
                    if (pBuffer->GetSize() < AMR_READ_SIZE)
                    {
                        m_pPayloadFormat->Flush();
                    }
                    // Add this packet to the payload object
                    retVal = m_pPayloadFormat->SetPacket(pRawPacket);
                    if (SUCCEEDED(retVal))
                    {
                        // Update the next file offset
                        m_ulNextFileOffset += m_pPayloadFormat->GetPacketBytesConsumed() + ulNewBufferOffset;
                        // Update the next time stamp
                        m_ulNextTimeStamp  += m_pPayloadFormat->GetDurationConsumed();
                        // Did we get here from a GetPacket() or a seek
                        // Now try and get a packet from the payload format object
                        IHXPacket* pPacket = NULL;
                        retVal = m_pPayloadFormat->GetPacket(pPacket);
                        if (SUCCEEDED(retVal))
                        {
                            // Set the state
                            m_eState = StateReady;
                            // We have a packet to give, so give it
                            retVal = m_pFormatResponse->PacketReady(retVal, pPacket);
                        }
                        HX_RELEASE(pPacket);
                    }
                }
                HX_RELEASE(pRawPacket);
            }
            HX_RELEASE(pNewBuffer);
        }
        if (FAILED(retVal))
        {
            // We either got here because of something bad, or because
            // we simply got to the end of the file and couldn't read
            // any more. Either way, we issue a StreamDone().
            //
            // Go back to ready
            m_eState = StateReady;
            // Issue a StreamDone
            retVal = m_pFormatResponse->StreamDone(0);
        }
    }
    else
    {
        retVal = HXR_UNEXPECTED;
    }

    return retVal;
}

STDMETHODIMP CAMRFileFormat::WriteDone(HX_RESULT status)
{
    HX_RESULT retVal = HXR_OK;

    return retVal;
}

STDMETHODIMP CAMRFileFormat::CloseDone(HX_RESULT status)
{
    HX_RESULT retVal = HXR_OK;

    return retVal;
}

STDMETHODIMP CAMRFileFormat::StatDone(HX_RESULT status, UINT32 ulSize, UINT32 ulCreationTime,
                                      UINT32 ulAccessTime, UINT32 ulModificationTime, UINT32 ulMode)
{
    HX_RESULT retVal = HXR_UNEXPECTED;

    if (m_eState == StateInitFileFormatStatDonePending)
    {
        // Did we succeed?
        if (SUCCEEDED(status))
        {
            // Save the file size
            m_ulFileSize = ulSize;
            // Now we are done with the stat interface
            HX_RELEASE(m_pFileStat);
        }
        // Set the state
        m_eState = StateReady;
        // Call back to response
        retVal = m_pFormatResponse->InitDone(status);
    }

    return retVal;
}

HX_RESULT STDAPICALLTYPE CAMRFileFormat::HXCreateInstance(IUnknown** ppIUnknown)
{
    HX_RESULT retVal = HXR_FAIL;

    if (ppIUnknown)
    {
        // Set default
        *ppIUnknown = NULL;
        // Create the object
        CAMRFileFormat *pObj = new CAMRFileFormat();
        if (pObj)
        {
            // QI for IUnknown
            retVal = pObj->QueryInterface(IID_IUnknown, (void**) ppIUnknown);
        }
        if (FAILED(retVal))
        {
            HX_DELETE(pObj);
        }
    }

    return retVal;
}

HX_RESULT STDAPICALLTYPE CAMRFileFormat::CanUnload2(void)
{
    return ((CHXBaseCountingObject::ObjectsActive() > 0) ? HXR_FAIL : HXR_OK);
}

HX_RESULT CAMRFileFormat::GetStreamInfo(IHXBuffer*  pBuffer,
                                        UINT32      ulOffset,
                                        REF(UINT32) rulAvgBitRate,
                                        REF(UINT32) rulBytesPerFrame)
{
    HX_RESULT retVal = HXR_OK;

    if (pBuffer && ulOffset < pBuffer->GetSize())
    {
        BYTE*     pBuf      = pBuffer->GetBuffer() + ulOffset;
        BYTE*     pBufLimit = pBuffer->GetBuffer() + pBuffer->GetSize();
        UINT32    ulByteSum = 0;
        UINT32    ulMSSum   = 0;
        UINT32    ulNumFr   = 0;
        CAMRFrameHdr cHdr((m_bWideBand ? WideBand : NarrowBand));
        while (1)
        {
            if (pBuf + cHdr.HdrBytes() >= pBufLimit)
            {
                break;
            }
            cHdr.Unpack(pBuf);
            if(pBuf + cHdr.DataBytes() >= pBufLimit)
            {
                break;
            }
            pBuf += cHdr.DataBytes();
            ulByteSum += cHdr.DataBytes() + cHdr.HdrBytes();
            ulMSSum   += CAMRFrameInfo::FrameDuration();
            ulNumFr++;
        }
        if (ulNumFr) rulBytesPerFrame = ulByteSum / ulNumFr;
        if (ulMSSum) rulAvgBitRate = ulByteSum * 8000 / ulMSSum;
    }
    else
    {
        retVal = HXR_FAIL;
    }

    return retVal;
}

HX_RESULT CAMRFileFormat::MakeRawFilePacket(IHXBuffer* pBuffer, UINT32 ulTimeStamp,
                                            REF(IHXPacket*) rpPacket)
{
    HX_RESULT retVal = HXR_FAIL;

    if (pBuffer && m_pCommonClassFactory)
    {
        IHXPacket* pPacket = NULL;
        retVal = m_pCommonClassFactory->CreateInstance(CLSID_IHXPacket, (void**) &pPacket);
        if (SUCCEEDED(retVal))
        {
            retVal = pPacket->Set(pBuffer, ulTimeStamp, 0, HX_ASM_SWITCH_ON, 0);
            if (SUCCEEDED(retVal))
            {
                HX_RELEASE(rpPacket);
                rpPacket = pPacket;
                rpPacket->AddRef();
            }
        }
        HX_RELEASE(pPacket);
    }

    return retVal;
}

⌨️ 快捷键说明

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