📄 vbrdepack.cpp
字号:
if (SUCCEEDED(retVal))
{
retVal = pBuffer->Set(pBuf, ulSize);
}
}
}
else
{
// This is a lost packet, so it's OK not
// to have a buffer
retVal = HXR_OK;
}
if (SUCCEEDED(retVal))
{
// Create an IHXPacket
IHXPacket* pPacket = NULL;
retVal = m_pCommonClassFactory->CreateInstance(CLSID_IHXPacket, (void**) &pPacket);
if (SUCCEEDED(retVal))
{
// Set the packet parameters
retVal = pPacket->Set(pBuffer,
ulTime,
m_usStreamNum,
HX_ASM_SWITCH_ON,
m_usKeyFrameRuleNum);
if (SUCCEEDED(retVal))
{
// If this is a lost packet, then set
// the lost flag
if (bLost)
{
pPacket->SetAsLost();
}
// Set the out parameter
HX_RELEASE(rpPacket);
rpPacket = pPacket;
rpPacket->AddRef();
}
}
HX_RELEASE(pPacket);
}
HX_RELEASE(pBuffer);
}
return retVal;
}
HX_RESULT CVBRSimpleDepacketizer::GenerateAndQueueLossPackets(UINT32 ulFirstPacketStartTime,
UINT32 ulLastPacketEndTime)
{
HX_RESULT retVal = HXR_FAIL;
if (ulLastPacketEndTime > ulFirstPacketStartTime)
{
// Compute the difference
UINT32 ulDiff = ulLastPacketEndTime - ulFirstPacketStartTime;
// Compute the number of packets
UINT32 ulNumLossPackets = 0;
if (m_dAUDuration != 0.0)
{
ulNumLossPackets = (UINT32) (ulDiff / m_dAUDuration);
}
// Generate loss packets
retVal = HXR_OK;
for (UINT32 i = 0; i < ulNumLossPackets && SUCCEEDED(retVal); i++)
{
UINT32 ulTSOffset = (UINT32) (i * m_dAUDuration);
UINT32 ulTime = ulFirstPacketStartTime + ulTSOffset;
IHXPacket* pPacket = NULL;
retVal = CreatePacket(NULL, 0, ulTime, TRUE, pPacket);
if (SUCCEEDED(retVal))
{
retVal = AddToQueue(m_pOutputQueue, pPacket);
}
HX_RELEASE(pPacket);
}
}
return retVal;
}
HX_RESULT CVBRSimpleDepacketizer::AddToQueue(REF(CHXSimpleList*) rpList, IHXPacket* pPacket)
{
HX_RESULT retVal = HXR_FAIL;
if (!rpList)
{
rpList = new CHXSimpleList();
}
if (rpList)
{
// AddRef the packet before going on the list
pPacket->AddRef();
// Put the packet on the list
rpList->AddTail((void*) pPacket);
// Clear the return value
retVal = HXR_OK;
}
return retVal;
}
HX_RESULT CVBRSimpleDepacketizer::ParseVBRPacket(BYTE* pBuf,
UINT32 ulSize,
REF(UINT32) rulNumAU,
REF(BOOL) rbFragmented)
{
HX_RESULT retVal = HXR_FAIL;
if (pBuf && ulSize)
{
// Compute the buf limit (for safety)
BYTE* pBufLimit = pBuf + ulSize;
HX_ASSERT(pBuf + 2 <= pBufLimit);
if (pBuf + 2 <= pBufLimit)
{
// Get the AU header size in bits
UINT32 ulAUHeaderSizeBits = UnPackUINT16(pBuf);
// Convert to bytes (rounding up to next byte)
UINT32 ulAUHeaderSize = (ulAUHeaderSizeBits + 7) >> 3;
// Sanity check to make sure that the AU header size is
// greater than 0 and a multiple of 2 bytes
HX_ASSERT(ulAUHeaderSize && !(ulAUHeaderSize & 1));
if (ulAUHeaderSize && !(ulAUHeaderSize & 1))
{
// Since we know that each AU header is 2 bytes, then
// we know that the number of AU's in this packet is
// ulAUHeaderSize / 2.
rulNumAU = ulAUHeaderSize >> 1;
// The audio/mpeg-generic spec says that each packet
// can either have a complete AU, a fragment of a single
// AU, or multiple complete AUs. Therefore, if the
// number of AUs is greater than 1, then we know we
// have ulNumAU *complete* AUs. Therefore, for more
// than one AU, we know what the exact size of the
// packet should be, and that should match up with
// the data size of the packet.
BYTE* pAUSize = pBuf + 2;
UINT32 ulAUDataSize = 0;
for (UINT32 i = 0; i < rulNumAU; i++)
{
HX_ASSERT(pAUSize + 2 <= pBufLimit);
if (pAUSize + 2 <= pBufLimit)
{
UINT32 ulAUSize = UnPackUINT16(pAUSize);
ulAUDataSize += ulAUSize;
pAUSize += 2;
}
}
// Compute the expected size of the packet
UINT32 ulExpectedSize = 2 + // AU header size (16 bits)
rulNumAU * 2 + // AU sizes
ulAUDataSize; // the AU's themselves
// Check this against the actual size. If we have
// 1 AU, then the expected size can be greater than
// the actual size due to fragmentation. If we have
// more than more AU, then the expected size MUST
// match the actual size.
if (rulNumAU > 1)
{
if (ulExpectedSize == ulSize)
{
// Multiple AUs, no fragmentation
rbFragmented = FALSE;
retVal = HXR_OK;
}
}
else if (rulNumAU == 1)
{
if (ulExpectedSize > ulSize)
{
// Fragmented single AU
rbFragmented = TRUE;
retVal = HXR_OK;
}
else
{
// Single AU, no fragmentation
rbFragmented = FALSE;
retVal = HXR_OK;
}
}
}
}
}
HX_ASSERT(SUCCEEDED(retVal));
return retVal;
}
UINT32 CVBRSimpleDepacketizer::UnPackUINT16(BYTE* pBuf)
{
return (pBuf[0] << 8) | pBuf[1];
}
void CVBRSimpleDepacketizer::RemoveDifferingPackets(UINT32 ulTime)
{
if (m_pFragQueue && m_pFragQueue->GetCount() > 0)
{
IHXPacket* pPacket = (IHXPacket*) m_pFragQueue->GetHead();
if (pPacket && pPacket->GetTime() < ulTime)
{
// There are packets on the frag queue with
// timestamps less than this one. Therefore,
// we need to clear the queue
ClearQueue(m_pFragQueue);
}
}
}
BOOL CVBRSimpleDepacketizer::CanDefrag()
{
BOOL bRet = FALSE;
if (m_pFragQueue && m_pFragQueue->GetCount() > 0)
{
IHXPacket* pPacket = (IHXPacket*) m_pFragQueue->GetHead();
UINT32 ulActualAUDataSize = 0;
UINT32 ulAUDataSize = GetAUSize(pPacket, ulActualAUDataSize);
UINT32 ulActualAUDataSizeSum = 0;
LISTPOSITION pos = m_pFragQueue->GetHeadPosition();
while (pos)
{
pPacket = (IHXPacket*) m_pFragQueue->GetNext(pos);
GetAUSize(pPacket, ulActualAUDataSize);
ulActualAUDataSizeSum += ulActualAUDataSize;
}
// Check that the stated size of the AU
// is the same as the sum of the actual
// AU data sizes across all the fragmented packets
if (ulAUDataSize == ulActualAUDataSizeSum)
{
bRet = TRUE;
}
}
return bRet;
}
HX_RESULT CVBRSimpleDepacketizer::Defrag(REF(IHXPacket*) rpPacket)
{
HX_RESULT retVal = HXR_FAIL;
if (m_pCommonClassFactory && m_pFragQueue && m_pFragQueue->GetCount() > 0)
{
// Get the stated size of the AU
IHXPacket* pFragPacket = (IHXPacket*) m_pFragQueue->GetHead();
UINT32 ulTmp = 0;
UINT32 ulAUSize = GetAUSize(pFragPacket, ulTmp);
UINT32 ulTime = pFragPacket->GetTime();
// Sanity check
if (ulAUSize > 0)
{
// Create a buffer of this size
BYTE* pBuf = new BYTE [ulAUSize];
if (pBuf)
{
// Copy all the fragmented packets into this buffer
UINT32 ulFragSizeSum = 0;
LISTPOSITION pos = m_pFragQueue->GetHeadPosition();
while (pos)
{
pFragPacket = (IHXPacket*) m_pFragQueue->GetNext(pos);
if (pFragPacket)
{
IHXBuffer* pFragBuffer = pFragPacket->GetBuffer();
if (pFragBuffer)
{
memcpy(pBuf + ulFragSizeSum,
pFragBuffer->GetBuffer() + 4,
pFragBuffer->GetSize() - 4);
ulFragSizeSum += pFragBuffer->GetSize() - 4;
}
HX_RELEASE(pFragBuffer);
}
}
// Create the packet
HX_RELEASE(rpPacket);
retVal = CreatePacket(pBuf, ulAUSize, ulTime, FALSE, rpPacket);
}
HX_VECTOR_DELETE(pBuf);
}
}
return retVal;
}
UINT32 CVBRSimpleDepacketizer::GetAUSize(IHXPacket* pPacket, REF(UINT32) rulActualAUDataSize)
{
UINT32 ulRet = 0;
if (pPacket)
{
IHXBuffer* pBuffer = pPacket->GetBuffer();
if (pBuffer)
{
ulRet = UnPackUINT16(pBuffer->GetBuffer() + 2);
rulActualAUDataSize = pBuffer->GetSize() - 4;
}
HX_RELEASE(pBuffer);
}
return ulRet;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -