📄 sspayld.cpp
字号:
{ if ( HXR_OK != m_pCommonClassFactory->CreateInstance( IID_IHXBuffer, (void**) &pSegmentBuffer ) ) { Flush(); HX_RELEASE( pPacketBuffer ); 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;}STDMETHODIMPSimpleSegmentPayloadFormat::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;}STDMETHODIMPSimpleSegmentPayloadFormat::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 + -