⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 raibufs.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    }
    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 + -