📄 mpapayld.cpp
字号:
// Set the 4-Byte audio header for this packet
// (as dictated by RFC 2250)
putshort(pBuf, 0);
pBuf += 2;
putshort(pBuf, 0);
pBuf += 2;
// Copy the data from the input packet list
// into the new packet buffer
CopyInput(pBuf, ulBufSize - 4);
// Finalize the new packet
pNewPacket->Set(pNewBuffer, ulNewTimestamp,
(UINT16)m_ulStreamNum, HX_ASM_SWITCH_ON, 0);
HX_RELEASE(pNewBuffer);
pPacket = pNewPacket;
}
return hResult;
}
HX_RESULT
MPAPayloadFormat::CreateFragmentedPacket(REF(IHXPacket*) pPacket)
{
HX_RESULT hResult = HXR_OK;
UINT32 ulBufSize = 0;
UCHAR* pBuf = NULL;
IHXPacket* pNewPacket = NULL;
IHXBuffer* pNewBuffer = NULL;
// Figure out how much we want to put in this packet, based on the
// frame size, frame offset, and max packet size
ulBufSize = m_ulFrameSize - m_ulFrameOffset;
if (ulBufSize > m_ulMaxPacketSize)
{
ulBufSize = m_ulMaxPacketSize;
}
if ((m_ulInputSize < ulBufSize) &&
!m_bFlushed)
{
// We don't have enough input
// data to produce a full packet
hResult = HXR_INCOMPLETE;
}
else
{
// Create a new packet
m_pClassFactory->CreateInstance(CLSID_IHXPacket,
(void**)&pNewPacket);
// Create a new buffer
m_pClassFactory->CreateInstance(CLSID_IHXBuffer,
(void**)&pNewBuffer);
// Figure out what the timestamp should be
UINT32 ulNewTimestamp = GetNextTimestamp();
// Set the size of the buffer appropriately
if (m_ulInputSize < ulBufSize)
{
// We must have been flushed, so fill the packet
// with whatever remaining data we have
HX_ASSERT(m_bFlushed);
ulBufSize = m_ulInputSize;
}
ulBufSize += 4;
pNewBuffer->SetSize(ulBufSize);
pBuf = pNewBuffer->GetBuffer();
// Set the 4-Byte audio header for this packet
// (as dictated by RFC 2250)
putshort(pBuf, 0);
pBuf += 2;
putshort(pBuf, (UINT16)m_ulFrameOffset);
pBuf += 2;
// Update the current frame offset
m_ulFrameOffset += ulBufSize - 4;
if (m_ulFrameOffset == m_ulFrameSize)
{
// We finished a frame, so reset our offset
m_ulFrameOffset = 0;
}
// Copy the data from the input packet list
// into the new packet buffer
CopyInput(pBuf, ulBufSize - 4);
// Finalize the new packet
pNewPacket->Set(pNewBuffer, ulNewTimestamp,
(UINT16)m_ulStreamNum, HX_ASM_SWITCH_ON, 0);
HX_RELEASE(pNewBuffer);
pPacket = pNewPacket;
}
return hResult;
}
HX_RESULT
MPAPayloadFormat::UnformatRTPPacket(REF(IHXPacket*) pPacket)
{
HX_RESULT hResult = HXR_OK;
BOOL bDone = FALSE;
while (!bDone)
{
if (m_pPartialPacket)
{
// We've already unformatted part of an audio frame,
// so grab then next packet and add it to the end
hResult = UnformatNextPacket(pPacket, bDone);
}
else
{
// We don't have any partially unformatted data,
// so just grab the first packet and deal with it
hResult = UnformatFirstPacket(pPacket, bDone);
}
}
return hResult;
}
HX_RESULT
MPAPayloadFormat::UnformatFirstPacket(REF(IHXPacket*) pPacket,
REF(BOOL) bDone)
{
IHXPacket* pNextPacket = NULL;
IHXBuffer* pNextBuffer = NULL;
bDone = FALSE;
// Get the next input packet
pNextPacket = (IHXPacket*)m_pInputPackets->RemoveHead();
HX_ASSERT(pNextPacket);
// If this is a lost packet, give it
// straight back to the caller
if (pNextPacket->IsLost())
{
pPacket = pNextPacket;
bDone = TRUE;
return HXR_OK;
}
pNextBuffer = pNextPacket->GetBuffer();
HX_ASSERT(pNextBuffer);
// Create a new packet
m_pClassFactory->CreateInstance(CLSID_IHXPacket,
(void**)&m_pPartialPacket);
HX_ASSERT(m_pPartialPacket);
// Create a new buffer
m_pClassFactory->CreateInstance(CLSID_IHXBuffer,
(void**)&m_pPartialBuffer);
HX_ASSERT(m_pPartialBuffer);
// Add this onto the new packet
m_pPartialBuffer->SetSize(pNextBuffer->GetSize() - 4);
memcpy(m_pPartialBuffer->GetBuffer(), /* Flawfinder: ignore */
pNextBuffer->GetBuffer() + 4,
pNextBuffer->GetSize() - 4);
// Set all properties except buffer from this packet
m_pPartialPacket->Set(m_pPartialBuffer,
pNextPacket->GetTime(),
pNextPacket->GetStreamNumber(),
pNextPacket->GetASMFlags(),
pNextPacket->GetASMRuleNumber());
// Find out if this packet contains an integral number
// of full frames or a fragment of a single large frame
UINT32 ulOffset = GetFrameOffset(pNextBuffer);
if (!ulOffset && !m_ulFrameSize)
{
UINT32 ulBytesSkipped = 0;
m_ulFrameSize = GetFrameSize(pNextBuffer->GetBuffer() + 4,
pNextBuffer->GetSize() - 4, ulBytesSkipped);
HX_ASSERT(m_ulFrameSize);
if (ulBytesSkipped)
{
// If we had to skip any Bytes to find the header
// info, discard those leading Bytes as garbage
m_ulInputUsed = ulBytesSkipped;
m_ulInputSize -= ulBytesSkipped;
}
}
if (ulOffset)
{
// We must have lost the previous packet in this
// frame, so toss out the rest for now
//
// XXXDPS - If we can actually make some use of a
// partial audio frame, we may want to do something
// more intelligent here...
HX_RELEASE(m_pPartialBuffer);
HX_RELEASE(m_pPartialPacket);
bDone = FALSE;
}
else
{
if (m_ulFrameSize <= (pNextBuffer->GetSize() - 4))
{
// The packet contains an integral number of full frames
// Return the packet we've constructed
pPacket = m_pPartialPacket;
pPacket->AddRef();
HX_RELEASE(m_pPartialBuffer);
HX_RELEASE(m_pPartialPacket);
bDone = TRUE;
}
else
{
// The packet contains the first fragment of a large
// frame that spans several packets
// We will keep looping and adding data to this buffer
// until we have constructed an entire frame of audio...
}
}
HX_RELEASE(pNextBuffer);
HX_RELEASE(pNextPacket);
return HXR_OK;
}
HX_RESULT
MPAPayloadFormat::UnformatNextPacket(REF(IHXPacket*) pPacket,
REF(BOOL) bDone)
{
HX_RESULT hResult = HXR_OK;
IHXPacket* pNextPacket = NULL;
IHXBuffer* pNextBuffer = NULL;
bDone = FALSE;
if (m_pInputPackets->IsEmpty())
{
if (!m_bFlushed)
{
// We don't have enough input
// data to produce a full packet
hResult = HXR_INCOMPLETE;
}
else
{
// Return the (partial) packet we've constructed
pPacket = m_pPartialPacket;
pPacket->AddRef();
HX_RELEASE(m_pPartialBuffer);
HX_RELEASE(m_pPartialPacket);
}
bDone = TRUE;
}
else
{
// Get the next input packet
pNextPacket = (IHXPacket*)m_pInputPackets->RemoveHead();
HX_ASSERT(pNextPacket);
if (pNextPacket->IsLost())
{
// If the packet is a lost packet, discard any
// partial packet we may have been building and
// forward this lost packet back to the caller
pPacket = pNextPacket;
pPacket->AddRef();
HX_RELEASE(m_pPartialBuffer);
HX_RELEASE(m_pPartialPacket);
bDone = TRUE;
}
else
{
pNextBuffer = pNextPacket->GetBuffer();
HX_ASSERT(pNextBuffer);
// Add the data from this packet onto our cumulative buffer
// Temporarily Release() our references on the buffer, since
// m_pPartialPacket has a reference on it and we can't set a
// buffer with 2 references. We will re-AddRef() it in a sec.
m_pPartialBuffer->Release();
UINT32 ulPrevSize = m_pPartialBuffer->GetSize();
m_pPartialBuffer->SetSize(ulPrevSize +
pNextBuffer->GetSize() - 4);
memcpy(m_pPartialBuffer->GetBuffer() + ulPrevSize, /* Flawfinder: ignore */
pNextBuffer->GetBuffer() + 4,
pNextBuffer->GetSize() - 4);
// Re-AddRef() the buffer now that we have set it
m_pPartialBuffer->AddRef();
m_pPartialPacket->Set(m_pPartialBuffer,
m_pPartialPacket->GetTime(),
m_pPartialPacket->GetStreamNumber(),
m_pPartialPacket->GetASMFlags(),
m_pPartialPacket->GetASMRuleNumber());
if (m_pPartialBuffer->GetSize() >= m_ulFrameSize)
{
// Return the (full) packet we've constructed
pPacket = m_pPartialPacket;
pPacket->AddRef();
HX_RELEASE(m_pPartialBuffer);
HX_RELEASE(m_pPartialPacket);
bDone = TRUE;
}
HX_RELEASE(pNextBuffer);
}
HX_RELEASE(pNextPacket);
}
return hResult;
}
HX_RESULT
MPAPayloadFormat::CreateLostPacket(IHXPacket* pOldPacket,
REF(IHXPacket*) pNewPacket)
{
// Create a new packet
m_pClassFactory->CreateInstance(CLSID_IHXPacket,
(void**)&pNewPacket);
HX_ASSERT(pNewPacket);
// Set all properties except buffer and time from
// the old packet
pNewPacket->Set(NULL,
0,
pOldPacket->GetStreamNumber(),
pOldPacket->GetASMFlags(),
pOldPacket->GetASMRuleNumber());
pNewPacket->SetAsLost();
return HXR_OK;
}
UINT32
MPAPayloadFormat::GetNextTimestamp()
{
if (m_pInputPackets->IsEmpty())
{
return 0;
}
else
{
IHXPacket* pPacket = (IHXPacket*)m_pInputPackets->GetHead();
HX_ASSERT(pPacket);
return pPacket->GetTime();
}
}
void
MPAPayloadFormat::CopyInput(UCHAR* pDest, UINT32 ulSize)
{
UINT32 ulBytesCopied = 0;
while (ulBytesCopied < ulSize)
{
IHXPacket* pPacket = (IHXPacket*)m_pInputPackets->RemoveHead();
HX_ASSERT(pPacket);
IHXBuffer* pBuffer = pPacket->GetBuffer();
HX_ASSERT(pBuffer);
UCHAR* pSrc = pBuffer->GetBuffer();
HX_ASSERT(pSrc);
UINT32 ulSrcSize = pBuffer->GetSize();
HX_ASSERT(ulSrcSize);
// Offset the input buffer based on
// how much we have previously used
pSrc += m_ulInputUsed;
ulSrcSize -= m_ulInputUsed;
if (ulSrcSize < ulSize - ulBytesCopied)
{
memcpy(pDest, pSrc, ulSrcSize); /* Flawfinder: ignore */
pDest += ulSrcSize;
ulBytesCopied += ulSrcSize;
m_ulInputUsed = 0;
}
else if (ulSrcSize > ulSize - ulBytesCopied)
{
// This packet is more than big enough
// to fill our requested size
UINT32 ulBytesToCopy = ulSize - ulBytesCopied;
memcpy(pDest, pSrc, ulBytesToCopy); /* Flawfinder: ignore */
pDest += ulBytesToCopy;
ulBytesCopied += ulBytesToCopy;
// Add this packet back onto the list
pPacket->AddRef();
m_pInputPackets->AddHead(pPacket);
// Remember how much of it we have used
m_ulInputUsed += ulBytesToCopy;
}
else
{
// An exact match!
memcpy(pDest, pSrc, ulSrcSize); /* Flawfinder: ignore */
pDest += ulSrcSize;
ulBytesCopied += ulSrcSize;
m_ulInputUsed = 0;
}
HX_RELEASE(pBuffer);
HX_RELEASE(pPacket);
}
m_ulInputSize -= ulBytesCopied;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -