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

📄 sspayld.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
                return HXR_OUTOFMEMORY;
            }

            if ( HXR_OK != m_pCommonClassFactory->CreateInstance( IID_IHXPacket,
                                                                  (void**) &pSegmentPacket )
               )
            {
                Flush();
                HX_RELEASE( pSegmentBuffer );
                HX_RELEASE( pPacketBuffer );
                return HXR_OUTOFMEMORY;
            }

            pSegmentBuffer->SetSize( sizeof(SEGMENTHEADER) + (uiBytesRemaining > m_ulMaxSegmentSize) ? m_ulMaxSegmentSize : uiBytesRemaining );
            LPSEGMENTHEADER pSegmentHeader = (LPSEGMENTHEADER) pSegmentBuffer->GetBuffer();

            pSegmentHeader->ulOffset = i * ( m_ulMaxSegmentSize );
            pSegmentHeader->usIndex = i;
            pSegmentHeader->usTotalSegments = m_ulTotalSegments;

            if ( !m_bBigEndian )
            {
                SwapDWordBytes(&pSegmentHeader->ulOffset, 1);
                SwapWordBytes(&pSegmentHeader->usIndex, 1);
                SwapWordBytes(&pSegmentHeader->usTotalSegments, 1);
            }

            memcpy( (UCHAR*) pSegmentHeader + sizeof(SEGMENTHEADER), /* Flawfinder: ignore */
                    pPacketBufferData + pSegmentHeader->ulOffset,
                    pSegmentBuffer->GetSize() - sizeof(SEGMENTHEADER)
                  );

            uiBytesRemaining -= pSegmentBuffer->GetSize() - sizeof(SEGMENTHEADER);;

            pSegmentPacket->Set( pSegmentBuffer,
                                 pPacket->GetTime(),
                                 pPacket->GetStreamNumber(),
                                 pPacket->GetASMFlags(),
                                 pPacket->GetASMRuleNumber()
                               );
            HX_RELEASE( pSegmentBuffer );

            m_pSegmentedPackets->AddTail( pSegmentPacket );
        }

        HX_RELEASE( pPacketBuffer );
    }
    else
    {
        // This PayloadFormat does not return incomplete data;
        // The client is assumed to be able to deal with lost data quantums
        // of the size of m_ulPacketSize:
        if ( pPacket->IsLost() )
        {
            Flush();
            return HXR_OK;
        }

        IHXBuffer* pPacketBuffer = pPacket->GetBuffer();
        UINT16 usSegment = ( (LPSEGMENTHEADER) pPacketBuffer->GetBuffer() )->usIndex;
        if ( !m_bBigEndian )
        {
            SwapWordBytes( &usSegment, 1 );
        }
        HX_RELEASE( pPacketBuffer );

        // Missing/lost segments?
        if (usSegment != m_pSegmentedPackets->GetCount())
        {
            // Since we flush on lost packets, a non-zero segment list
            // indicates a *missing* packet (bug in the core)
            HX_ASSERT(m_pSegmentedPackets->GetCount() == 0 && "Missing segments!");
            Flush();
            return HXR_OK;
        }

        pPacket->AddRef();
        m_pSegmentedPackets->AddTail( pPacket );

        // New frame?
        if ( usSegment == 0 )
        {
            IHXBuffer* pFirstBuffer = pPacket->GetBuffer();
            HX_ASSERT( pFirstBuffer );

            m_ulTotalSegments = ( (LPSEGMENTHEADER) pFirstBuffer->GetBuffer() )->usTotalSegments;
            if ( !m_bBigEndian )
            {
                SwapWordBytes( &m_ulTotalSegments, 1 );
            }
            HX_RELEASE( pFirstBuffer );

            if (m_ulTotalSegments == 0)
            {
                // No segments, eh?
                HX_ASSERT(FALSE && "Segment count zero - packetizer error!");
                Flush();
                return HXR_OK;
            }
        }

        // Sort and reconstruct the packet here, rather than in GetPacket(), on
        // the assumption that GetPacket() is a time sensitive function:
        if ( m_pSegmentedPackets->GetCount() == m_ulTotalSegments )
        {
            // We use a simple O(n) reconstruction here (no sorting)
            UINT32 uiPacketSize = 0;

            IHXBuffer* pSegmentBuffer = NULL;
            UCHAR* pSegmentBufferData = NULL;

            // Find packet size and swap headers:
            for ( CHXSimpleList::Iterator maxIterator = m_pSegmentedPackets->Begin();
                maxIterator != m_pSegmentedPackets->End();
                ++maxIterator )
            {
                pSegmentBuffer = ( (IHXPacket*) *maxIterator )->GetBuffer();
                pSegmentBufferData = pSegmentBuffer->GetBuffer();

                if ( !m_bBigEndian )
                {
                    SwapDWordBytes( &( (LPSEGMENTHEADER) pSegmentBufferData )->ulOffset, 1 );
                }

                if ( ( (LPSEGMENTHEADER) pSegmentBufferData )->ulOffset + pSegmentBuffer->GetSize() > uiPacketSize )
                {
                    uiPacketSize = ( (LPSEGMENTHEADER) pSegmentBufferData )->ulOffset + pSegmentBuffer->GetSize();
                }
                HX_RELEASE(pSegmentBuffer);
            }
            uiPacketSize -= sizeof( SEGMENTHEADER );

            // An assembled packet should have been collected by this point; we only assemble
            // one packet at a time, for now, for simplicity.
            HX_ASSERT( !m_pAssembledPacket );
            HX_RELEASE( m_pAssembledPacket );
            m_pAssembledPacket = NULL;

            // Create our assembled packet, buffer:
            IHXBuffer* pPacketBuffer = NULL;
            if ( HXR_OK != m_pCommonClassFactory->CreateInstance( IID_IHXBuffer,
                                                                  (void**) &pPacketBuffer )
               )
            {
                Flush();
                return HXR_FAIL;
            }

            if ( HXR_OK != m_pCommonClassFactory->CreateInstance( IID_IHXPacket,
                                                                  (void**) &m_pAssembledPacket )
               )
            {
                Flush();
                HX_RELEASE( pPacketBuffer );
                return HXR_FAIL;
            }

            pPacketBuffer->SetSize( uiPacketSize );
            IHXPacket* pPacketDetails = ( (IHXPacket*) m_pSegmentedPackets->GetHead() );
            m_pAssembledPacket->Set(pPacketBuffer,
                                    pPacketDetails->GetTime(),
                                    pPacketDetails->GetStreamNumber(),
                                    pPacketDetails->GetASMFlags(),
                                    pPacketDetails->GetASMRuleNumber()
                                   );

            // This reconstruction approach may not assemble in segment order, but the
            // performance penalty is small, and it keeps the code simple.  Using ulOffset
            // also allows clever datatypes/compatible payload formatters to insert gaps in
            // the buffer in which the renders could write data for their own bizzare
            // purposes (use at your own peril).
            UCHAR* pPacketBufferData = pPacketBuffer->GetBuffer();
            UINT32 ulPacketBufferSize = pPacketBuffer->GetSize();
            HX_RELEASE(pPacketBuffer);
            IHXPacket* pSegmentPacket = NULL;
            while ( !m_pSegmentedPackets->IsEmpty() )
            {
                pSegmentPacket = (IHXPacket*) m_pSegmentedPackets->RemoveHead();
                HX_ASSERT( pSegmentPacket );
                pSegmentBuffer = pSegmentPacket->GetBuffer();
                HX_ASSERT( pSegmentBuffer );
                pSegmentBufferData = pSegmentBuffer->GetBuffer();
                UINT32 ulMaxCopyBytes = ulPacketBufferSize - ( (LPSEGMENTHEADER) pSegmentBufferData )->ulOffset;
                UINT32 ulBytesToCopy = pSegmentBuffer->GetSize() - sizeof(SEGMENTHEADER);
                if (ulBytesToCopy > ulMaxCopyBytes) ulBytesToCopy = ulMaxCopyBytes;
                memcpy( pPacketBufferData + ( (LPSEGMENTHEADER) pSegmentBufferData )->ulOffset, /* Flawfinder: ignore */
                        pSegmentBufferData + sizeof(SEGMENTHEADER),
                        ulBytesToCopy);
                HX_RELEASE( pSegmentBuffer );
                HX_RELEASE( pSegmentPacket );
            }
        }
    }

    return HXR_OK;
}

STDMETHODIMP
SimpleSegmentPayloadFormat::GetPacket( REF(IHXPacket*) pPacket )
{
    pPacket = NULL;

    if ( m_bPacketize )
    {
        if ( m_pSegmentedPackets->IsEmpty() )
        {
            return HXR_UNEXPECTED;
        }
        else
        {
            pPacket = (IHXPacket*) m_pSegmentedPackets->RemoveHead();
        }
    }
    else
    {
        if ( m_pAssembledPacket )
        {
            pPacket = m_pAssembledPacket;
            m_pAssembledPacket = NULL;
        }
        else
        {
            return HXR_INCOMPLETE;
        }
    }

    return HXR_OK;
}

STDMETHODIMP
SimpleSegmentPayloadFormat::Flush()
{
    // Release all of our segment packets; but keep any assembled
    while ( !m_pSegmentedPackets->IsEmpty() )
    {
        IHXPacket* pPacket = (IHXPacket*) m_pSegmentedPackets->RemoveHead();
        HX_RELEASE(pPacket);
    }
    m_ulTotalSegments = 0;

    return HXR_OK;
}

⌨️ 快捷键说明

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