📄 sspayld.cpp
字号:
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 + -