📄 raibufs.cpp
字号:
}
else
{
m_DBlockTimeRange.m_ulStart = NO_TIME_SET;
m_DBlockTimeRange.m_ulEnd = NO_TIME_SET;
}
m_IBlockTimeRange.m_ulStart = NO_TIME_SET;
m_IBlockTimeRange.m_ulEnd = NO_TIME_SET;
return HXR_OK;
}
BOOL
CInterleaveBufs::IsISuperBlockFilled(void)
{
return m_bISuperBlockDone;
}
BOOL
CInterleaveBufs::IsDSuperBlockEmpty(void)
{
return m_bDSuperBlockEmpty;
}
BOOL
CInterleaveBufs::IsStreamDone(void)
{
return (m_bEndOfPackets &&
m_bDSuperBlockEmpty &&
m_bISuperBlockEmpty);
}
HX_RESULT
CInterleaveBufs::OnPacket(Byte* pData, UINT32 ulSize, UINT32 ulSequence,
UINT32 ulTimestamp, BOOL bLost, UINT16 usFlag)
{
HX_RESULT theError = HXR_OK;
INT16 i = 0;
UINT16 j = 0;
UINT16 uBlockNum = 0;
// we got off superblock alignment here so throw away any data we
// have in the interleave buffer and start again with this packet
if ((usFlag & HX_KEYFRAME_FLAG) &&
(!m_bISuperBlockEmpty))
{
m_bISuperBlockEmpty = TRUE;
m_bISuperBlockDone = FALSE;
m_uNumIBlocks = 0;
m_bFirstPacketReceived = FALSE;
}
m_bEndOfPackets = FALSE;
if (m_bISuperBlockEmpty)
{
m_ulFirstSequenceNum = ulSequence;
m_bISuperBlockEmpty = FALSE;
}
// Calculate block location
uBlockNum = (UINT16) (ulSequence - m_ulFirstSequenceNum);
// Se if this block is in range
if (uBlockNum >= m_Param.uInterleaveFactor)
{
// We have received block from next superblock
HX_ASSERT(uBlockNum < m_Param.uInterleaveFactor);
if (!bLost)
{
// We need to make a choice to either flush the superblock data
// we have at this point or treat this packet as lost and finish
// off the current super-block.
UINT16 ulDataBlocksInSuperBlock = 0;
// Se how far away the new block is
UINT16 uNewBlockNum = (UINT16) (ulSequence -
(m_ulFirstSequenceNum +
m_Param.uInterleaveFactor));
// See how valuable the current data is
for (j = 0; j < uBlockNum; j++)
{
if (m_pIPresent[i])
{
ulDataBlocksInSuperBlock++;
}
}
// Decide whtether to keep current super-block or loose packet
if ((ulDataBlocksInSuperBlock == 0) ||
(((m_Param.uInterleaveFactor / ulDataBlocksInSuperBlock) >
SUPERBLOCK_VALUE_FACTOR) &&
(uNewBlockNum < m_Param.uInterleaveFactor)))
{
// Current superblock data is not valuable enough - flush it
uBlockNum = uNewBlockNum % m_Param.uInterleaveFactor;
m_ulFirstSequenceNum = ulSequence - uBlockNum;
// reset the present flags for the interleaved buffer
memset(m_pIPresent, 0, m_Param.uInterleaveFactor * sizeof(UINT32));
m_bISuperBlockDone = FALSE;
}
else
{
// Current superblock data is valuable enough, loose the packet
bLost = TRUE;
uBlockNum = m_Param.uInterleaveFactor - 1;
theError = HXR_BUFFER_NOT_AVAILABLE;
}
}
else
{
// Finish of the current superblock
uBlockNum = m_Param.uInterleaveFactor - 1;
}
}
HX_ASSERT(uBlockNum < m_Param.uInterleaveFactor);
m_uNumIBlocks = uBlockNum + 1;
// Copy block into place
if (!bLost)
{
#if defined(HELIX_FEATURE_AUDIO_CODEC_RAAC)
// If we are VBRS, then our sizes won't
// necessarily match up every time to the
// interleave block size, since the interleave
// block size is just an average
if (m_bIsVBRS)
{
// XXXMEH TODO: Make sanity check here for < m_ulVBRSMaxBufSize
memcpy(m_pIDataBuf, /* Flawfinder: ignore */
pData,
ulSize);
/* Since this is VBR, superblock size is
variable and changes from packet to packet */
m_ulSuperBlockSize = ulSize;
}
else
#endif /* #if defined(HELIX_FEATURE_AUDIO_CODEC_RAAC) */
{
if (ulSize != m_Param.uInterleaveBlockSize)
{
return HXR_BAD_FORMAT;
}
memcpy(m_pIDataBuf + (uBlockNum * m_Param.uInterleaveBlockSize), /* Flawfinder: ignore */
pData,
ulSize);
}
m_pIPresent[uBlockNum] = 0xffffffff;
// Timestamps:
// we are calculating the timestamps for the blocks of the superblock here
// since old non-switchable content doesn't have unique timestamps for each
// block of a superblock, we resync the timestamps at superblock boundaries
if ((uBlockNum == 0) || (!m_bFirstPacketReceived))
{
/* If this is the first non-lost packet, initialize the
* current timestamp counter, m_bFirstpacketRecieved tells us
* if we've recieved a whole packet for this superblock or the
* initial packets were lost
*/
m_fActualTimestamp = UINT32_TO_DOUBLE(ulTimestamp);
}
}
m_pIActualTimestamps[uBlockNum] = m_fActualTimestamp;
INCREMENT_FLOAT_TS(m_fActualTimestamp, m_fmsPerBlock);
// Check if superblock is done
if (uBlockNum == (m_Param.uInterleaveFactor - 1))
{
i = uBlockNum;
while ((i > 0) && (m_pIPresent[i] == 0))
{
i--;
}
// if all of the present flags are set to 0 then we lost
// the entire superblock, resync on the next block
if ((m_pIPresent[i] == 0) && (m_Param.uInterleaveFactor > 1))
{
DEBUG_OUTF(SPLICE_FILE, (s, "Lost entire superblock\t%lu\n", ulTimestamp));
m_bISuperBlockEmpty = TRUE;
m_bISuperBlockDone = FALSE;
m_uNumIBlocks = 0;
m_bFirstPacketReceived = FALSE;
}
else
{
m_bISuperBlockDone = TRUE;
m_ulFirstSequenceNum += m_Param.uInterleaveFactor;
}
}
else
{
HX_ASSERT(m_uNumIBlocks < m_Param.uInterleaveFactor);
}
// if we haven't recieved an actual packet for this superblock yet
// (i.e. the previous packets were lost) we now go back and
// give the lost blocks timestamps based on the timestamp for this
// packet
if (!m_bFirstPacketReceived)
{
if (bLost && (m_Param.uInterleaveFactor == 1))
{
// This logic prevents:
// If interleave factor is one and we seek backwards and lose
// the very first (few) packet(s), we do not know the time of
// these packets to report.
m_bISuperBlockDone = FALSE;
}
else if (!bLost)
{
// we only have to fixup the previous lost packets for this
// superblock, if this is the first block (uBlockNum == 0),
// we don't have any fixup to do.
if (uBlockNum != 0)
{
double ts;
i = uBlockNum - 1;
for (j = 2; i >= 0; i--, j++)
{
ts = m_fActualTimestamp - m_fmsPerBlock * j;
if (ts < 0.0)
{
ts = 0.0;
}
/* Mark the actual timestamps as our own computed ts */
m_pIActualTimestamps[i] = ts;
}
}
m_bFirstPacketReceived = TRUE;
}
}
// update the IBlock Time stamp range
m_IBlockTimeRange.m_ulStart = (UINT32) m_pIActualTimestamps[0];
m_IBlockTimeRange.m_ulEnd = (UINT32)
(m_pIActualTimestamps[uBlockNum] + m_fmsPerBlock);
return theError;
}
BOOL
CInterleaveBufs::DataAvailable(AUDIO_STATE audioState)
{
// We normally keep both superblocks buffered but if we are done
// or switching we only require there to be data in the
// de-interleaved superblock.
switch (audioState)
{
case AUDIO_CROSSFADE:
case AUDIO_DRYNOTIFICATION:
case AUDIO_END_OF_PACKETS:
return !m_bDSuperBlockEmpty;
break;
default:
return !m_bDSuperBlockEmpty && !m_bISuperBlockEmpty;
break;
}
}
HX_RESULT
CInterleaveBufs::NextBlock(void)
{
if (m_bDSuperBlockEmpty)
{
return HXR_NO_DATA;
}
HX_ASSERT(m_uBlockToDecode < m_Param.uInterleaveFactor);
m_uBlockToDecode++;
if (m_uBlockToDecode == m_Param.uInterleaveFactor)
{
m_bDSuperBlockEmpty = TRUE;
m_DBlockTimeRange.m_ulStart = NO_TIME_SET;
m_DBlockTimeRange.m_ulEnd = NO_TIME_SET;
if( m_bDeinterleaveInPlace == TRUE )
{
m_bISuperBlockEmpty = TRUE;
m_bISuperBlockDone = FALSE;
m_uNumIBlocks = 0;
m_uBlockToDecode = 0;
}
}
return HXR_OK;
}
HX_RESULT
CInterleaveBufs::GetBlock(Byte** hData,
UINT32* pDataSize,
UINT32* pDataFlags,
UINT32* pTimestamp,
UINT32* pActualTimestamp)
{
if (m_bDSuperBlockEmpty)
{
return HXR_NO_DATA;
}
HX_ASSERT(m_uBlockToDecode < m_Param.uInterleaveFactor);
#if defined(HELIX_FEATURE_AUDIO_CODEC_RAAC)
if (m_bIsVBRS)
{
*hData = m_pDDataBuf;
*pDataSize = m_ulVBRSDBufBytes;
}
else
#endif /* #if defined(HELIX_FEATURE_AUDIO_CODEC_RAAC) */
{
*hData = m_pDDataBuf + (m_uBlockToDecode * m_Param.uInterleaveBlockSize);
*pDataSize = m_Param.uInterleaveBlockSize;
}
*pDataFlags = m_pDPresent[m_uBlockToDecode];
*pTimestamp = (ULONG32) m_pDActualTimestamps[m_uBlockToDecode];
return HXR_OK;
}
void
CInterleaveBufs::NumDecodedBytes(UINT32 ulNumDecodedBytes)
{
if (m_bLastDecodedTimeSet)
{
INCREMENT_FLOAT_TS(m_fLastDecodedTime, CalcMs(ulNumDecodedBytes));
m_DBlockTimeRange.m_ulStart = (UINT32) m_fLastDecodedTime;
}
}
void
CInterleaveBufs::NumDecodedBytes(UINT32 ulEndingTS, UINT32 ulNumDecodedBytes)
{
m_fLastDecodedTime = UINT32_TO_DOUBLE(ulEndingTS);
m_bLastDecodedTimeSet = TRUE;
NumDecodedBytes(ulNumDecodedBytes);
}
double
CInterleaveBufs::CalcMs(UINT32 ulNumBytes)
{
return ulNumBytes * m_fMsPerByte;
}
UINT32
CInterleaveBufs::CalcBytes(double fMs)
{
return ((UINT32) (fMs / m_fMsPerByte + 0.5));
}
void
CInterleaveBufs::SwitchOff(void)
{
m_bISuperBlockEmpty = TRUE;
m_bISuperBlockDone = FALSE;
m_bFirstPacketReceived = FALSE;
m_bDSuperBlockEmpty = TRUE;
m_uNumIBlocks = 0;
m_bLastDecodedTimeSet = FALSE;
m_fLastDecodedTime = 0.0;
m_DBlockTimeRange.m_ulStart = NO_TIME_SET;
m_DBlockTimeRange.m_ulEnd = NO_TIME_SET;
m_IBlockTimeRange.m_ulStart = NO_TIME_SET;
m_IBlockTimeRange.m_ulEnd = NO_TIME_SET;
}
HX_RESULT
CInterleaveBufs::OnSeek(void)
{
DEBUG_OUTF(SPLICE_FILE, (s, "Seek\t%p\t*******\n", this));
SwitchOff();
return HXR_OK;
}
void
CInterleaveBufs::OnEndofPackets(void)
{
m_bEndOfPackets = TRUE;
if ((m_Param.uInterleaveFactor > 1) && (!m_bISuperBlockEmpty))
{
m_bISuperBlockDone = TRUE;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -