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

📄 raformat.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
     *		0     1    2       3	4
     *
     */
    BOOL bDone = FALSE;
    ulTimestamp = UnAdjustTimestamp(ulTimestamp, m_lTimeOffset);

    m_ulCrossFadeEndTime = ulTimestamp;

    // see if it's at #3
    bDone = m_pPacketFeeder->SetCrossFadeEndTime(ulTimestamp);

    // see if it's at #2
    if (!bDone)
    {
	if (!m_IBufs.m_IBlockTimeRange.IsEmpty())
	{
	    if (m_IBufs.m_IBlockTimeRange.TimeInRange(ulTimestamp))
	    {
		DEBUG_OUTF(XFADE_FILE, (s, "SetXFadeEndTime Pos(2)\t%lu\t%lu\n", ulTimestamp, (UINT32)GetMSPerBlock()));
		bDone = TRUE;
	    }
	    else
	    {
	        // check for the #4 position
		if (IsTimeGreater(ulTimestamp, m_IBufs.m_IBlockTimeRange.m_ulEnd))
		{
		    // position #4 and we're done
		    bDone = TRUE;
		    DEBUG_OUTF(XFADE_FILE, (s, "SetXFadeEndTime Pos(4 after 2)\t%lu\t%lu\n", ulTimestamp, (UINT32)GetMSPerBlock()));
		}
		else
		{
		    // either 1 or 0 so flush 2
		    m_IBufs.FlushIBlock();
		}
	    }
	}
    }

    // see if it's #1
    if (!bDone)
    {
	if (!m_IBufs.m_DBlockTimeRange.IsEmpty())
	{
	    if (m_IBufs.m_DBlockTimeRange.TimeInRange(ulTimestamp))
	    {
		DEBUG_OUTF(XFADE_FILE, (s, "SetXFadeEndTime Pos(1)\t%lu\t%lu\n", ulTimestamp, (UINT32)GetMSPerBlock()));
		bDone = TRUE;
	    }
	    else
	    {
	        // check for the #4 position
		if (IsTimeGreater(ulTimestamp, m_IBufs.m_DBlockTimeRange.m_ulEnd))
		{
		    // position #4 and we're done
		    DEBUG_OUTF(XFADE_FILE, (s, "SetXFadeEndTime Pos(4 after 1)\t%lu\t%lu\n", ulTimestamp, (UINT32)GetMSPerBlock()));
		    bDone = TRUE;
		}
		else
		{
		    //it's 0, flush the I bufs now
		    DEBUG_OUTF(XFADE_FILE, (s, "SetXFadeEndTime Pos(0), flushing format\t%lu\t%lu\n", ulTimestamp, (UINT32)GetMSPerBlock()));
		    SetupForNextTimeRange();
		}
	    }
	}
	else
	{
	    //it's 0, flush the I bufs now
	    DEBUG_OUTF(XFADE_FILE, (s, "SetXFadeEndTime Pos(0), flushing format\t%lu\t%lu\n", ulTimestamp, (UINT32)GetMSPerBlock()));
	    SetupForNextTimeRange();
	}
    }
}

void
CRaFormat::DiscardTillEndOfCrossFade(UINT32 ulTimestamp)
{
    /*
     *	The ulTimestamp can be in one of these 5 positions.
     *	We start from 0 and go to 4 looking for some data that's
     *	greater than the ulTimestamp time.
     *
     *		    [DDD][III] {_,_,_,_,_,_,_,}
     *		^     ^    ^       ^            ^
     *		|     |    |       |            |
     *		0     1    2       3            4
     *
     */
    BOOL bDone = FALSE;
    ulTimestamp = UnAdjustTimestamp(ulTimestamp, m_lTimeOffset);

    // cannot equal NO_TIME_SET so we bump it up one
    if (ulTimestamp == NO_TIME_SET)
    {
	ulTimestamp += 1;
    }

    m_ulForceDiscardUntilTime = ulTimestamp;

    // start looking to see if it's #0 or #1
    if (!m_IBufs.m_DBlockTimeRange.IsEmpty())
    {
	if (IsTimeGreater(m_IBufs.m_DBlockTimeRange.m_ulStart, ulTimestamp))
	{
	    DEBUG_OUTF(DISCARDUNTIL_FILE, (s, "DiscardUntil Pos(0),\t%lu\t%lu\n", ulTimestamp, (UINT32)GetMSPerBlock()));
	    // time is in past and we're done, reset state variables
	    m_ulForceDiscardUntilTime = NO_TIME_SET;
	    bDone = TRUE;
	}
	else if (m_IBufs.m_DBlockTimeRange.TimeInRange(ulTimestamp))
	{
	    DEBUG_OUTF(DISCARDUNTIL_FILE, (s, "DiscardUntil Pos(1),\t%lu\t%lu\n", ulTimestamp, (UINT32)GetMSPerBlock()));
	    bDone = TRUE;
	}
	else
	{
	    DEBUG_OUTF(DISCARDUNTIL_FILE, (s, "FlushDBlock\t%lu\t%lu\t%lu\n", ulTimestamp, (UINT32)GetMSPerBlock(), m_IBufs.m_DBlockTimeRange.m_ulStart));
	    m_IBufs.FlushDBlock();
	}
    }
    
    // see if it's at #2
    if (!bDone)
    {
	// fill the IBlock if we can
	if (!m_IBufs.IsISuperBlockFilled())
	{
	    m_pPacketFeeder->FillISuperBlock();
	}
    
	if (!m_IBufs.m_IBlockTimeRange.IsEmpty())
	{
	    if (IsTimeGreater(m_IBufs.m_IBlockTimeRange.m_ulStart, ulTimestamp))
	    {
		DEBUG_OUTF(DISCARDUNTIL_FILE, (s, "DiscardUntil Pos(0),\t%lu\t%lu\n", ulTimestamp, (UINT32)GetMSPerBlock()));
		// time is in past and we're done, reset state variables
		m_ulForceDiscardUntilTime = NO_TIME_SET;
		bDone = TRUE;
	    }
	    else if (m_IBufs.m_IBlockTimeRange.TimeInRange(ulTimestamp))
	    {
		bDone = TRUE;
		DEBUG_OUTF(DISCARDUNTIL_FILE, (s, "DiscardUntil Pos(2),\t%lu\t%lu\n", ulTimestamp, (UINT32)GetMSPerBlock()));
	    }
	    else
	    {
		DEBUG_OUTF(DISCARDUNTIL_FILE, (s, "FlushIBlock\t%lu\t%lu\t%lu\n", ulTimestamp, (UINT32)GetMSPerBlock(), m_IBufs.m_IBlockTimeRange.m_ulStart));
		m_IBufs.FlushIBlock();
	    }
	}
    }

    bDone = m_pPacketFeeder->DiscardTillEndOfCrossFade(ulTimestamp, bDone);

    // if still not done, it's at #4, else we found it before #4
    if (!bDone)
    {
	m_ulForceDiscardUntilTime = NO_TIME_SET;
    }
}

HX_RESULT
CRaFormat::GetNextAudioDataTime(UINT32& ulStart, UINT32& ulEnd)
{
    UINT32	ulIterationCounter = 0;
    HX_RESULT	theError = HXR_OK;
    BOOL	bSuccess = FALSE;
    
    ulStart = ulEnd = 0;

    // move any data from the time range queue into the IBufs
    m_pPacketFeeder->FillISuperBlock();
    
    if (m_bEndOfPackets)
    {
	if (!m_IBufs.DataAvailable(AUDIO_END_OF_PACKETS))
	{	 
	    // this is an "emergency" state so do this even
	    // if the IBlock isn't quite full
	    m_IBufs.DeInterleaveData();
	}
    }

    do
    {
	// move any data from the time range queue into the IBufs
	m_pPacketFeeder->FillISuperBlock();

	// Here we always want to know the full time range of available
	// time so we always ask for the crossfade time
	if (m_IBufs.DataAvailable(AUDIO_CROSSFADE))
	{
	    if (m_ulForceDiscardUntilTime != NO_TIME_SET)
	    {
		// this will be the actual start time of 
		// the data returned from GetAudioData
		ulStart = m_ulForceDiscardUntilTime;
		DEBUG_OUTF(TIME_FILE, (s, "Force Discard Time Reported\t%lu\t%lu\n", 
		    ulStart, (UINT32)GetMSPerBlock()));
	    }
	    else
	    {
		ulStart = m_IBufs.m_DBlockTimeRange.m_ulStart;
		
		// we may have data before the track start time but we will
		// not return audio data prior to the track start time
		if (m_bForceStartTrackTime && IsTimeLess(ulStart, m_ulTrackStartTime))
		{
		    ulStart = m_ulTrackStartTime;
		}

		DEBUG_OUTF(TIME_FILE, (s, "DBlock start Time Reported\t%lu\t%lu\n", 
		    ulStart, (UINT32)GetMSPerBlock()));
		HX_ASSERT(ulStart != NO_TIME_SET);
	    }

	    ulEnd = ulStart + (UINT32)GetMSPerBlock();

	    if (m_bForceEndTrackTime && ulEnd > m_ulTrackEndTime)
	    {
		ulEnd = m_ulTrackEndTime;
		HX_ASSERT(ulEnd >= ulStart);
	    }

            ulStart = AdjustTimestamp(ulStart, m_lTimeOffset);
            ulEnd   = AdjustTimestamp(ulEnd,   m_lTimeOffset);

	    bSuccess = TRUE;
	    break;
	}
	else 
	{
	    // if there is a current time range, ask it if it's 
	    // ended.  We assume it's not ended.
	    BOOL bTimeRangeEnded = m_pPacketFeeder->IsCurrentTimeRangeEnded();
	    BOOL bDataInTimeRange = !m_pPacketFeeder->IsCurrentTimeRangeEmpty();

	    // If the D superblock is empty and there's more data to decode
	    // we give it a try to move the data into the D superblock to
	    // decode it.
	    if (m_IBufs.IsDSuperBlockEmpty() &&
		(!m_IBufs.IsISuperBlockEmpty() || bDataInTimeRange))
	    {
		if (m_IBufs.IsISuperBlockFilled())
		{
		    m_IBufs.DeInterleaveData();
		}

		// if we don't have any data in the De-interleaved superblock
		// and we failed to fill the Interleaved superblock, we
		// must be out of data and we should break out of the while loop
		if (m_IBufs.IsDSuperBlockEmpty() && 
		    (!m_pPacketFeeder->FillISuperBlock()))
		{
		    DEBUG_OUTF(DOAUDIO_FILE, (s, "GetNextAudioDataTime\t%d\t%d\t%d\t%d\t%lu\n", 
			m_IBufs.IsDSuperBlockEmpty(), m_IBufs.IsISuperBlockEmpty(), m_IBufs.IsISuperBlockFilled(), bTimeRangeEnded, (UINT32)GetMSPerBlock()));
		    break;
		}
	    }
	    else
	    {
		// if we get here, there's no in the IBuf or the 
		// current time range.
		HX_ASSERT(!bDataInTimeRange);

		if (bTimeRangeEnded)
		{
		    // the Time range has ended and the data from it is
		    // gone from the IBufs so setup the next time range
		    // now
		    SetupForNextTimeRange();
		}
		else
		{
		    DEBUG_OUTF(DOAUDIO_FILE, (s, "GetNextAudioDataTime\t%d\t%d\t%d\t%d\t%lu\n", 
			m_IBufs.IsDSuperBlockEmpty(), m_IBufs.IsISuperBlockEmpty(), m_IBufs.IsISuperBlockFilled(), bTimeRangeEnded, (UINT32)GetMSPerBlock()));
		    break;
		}
	    }
	}
    
	ulIterationCounter++;
    } while (ulIterationCounter < MAX_AUDIO_DATA_ATTEMPTS);

    if (bSuccess)
    {
	return HXR_OK;
    }
    else
    {
	return HXR_NO_DATA;
    }
}

UINT32
CRaFormat::GetCurrentTimeRangeEnd()
{
    UINT32 ulRet = m_pPacketFeeder->GetCurrentTimeRangeEnd();

    if (ulRet == NO_TIME_SET)
    {
	if (!m_IBufs.m_IBlockTimeRange.IsEmpty())
	{
	    // it will be in the IBufs
	    ulRet = m_IBufs.m_IBlockTimeRange.m_ulEnd;
	}
	else
	{
	    ulRet = m_IBufs.m_DBlockTimeRange.m_ulEnd;
	}
    }

    DEBUG_OUTF(TREND_FILE, (s, "%lu\t%lu\n", (UINT32)GetMSPerBlock(), ulRet));

    ulRet = AdjustTimestamp(ulRet, m_lTimeOffset);

    return ulRet;
}

void CRaFormat::ThrowUpgrade(const char* pszStr)
{
    if (m_pCommonClassFactory && pszStr)
    {
        IHXBuffer* pBuffer = NULL;
        m_pCommonClassFactory->CreateInstance(CLSID_IHXBuffer, (void**) &pBuffer);
        if (pBuffer)
        {
            pBuffer->Set((BYTE*) pszStr, strlen(pszStr) + 1);
            if (m_pUpgradeCollection)
            {
                m_pUpgradeCollection->Add(eUT_Required, pBuffer, 0, 0);
            }
        }
        HX_RELEASE(pBuffer);
    }
}

HX_RESULT 
CRaFormat::OnSeek (UINT32 ulOldTime, UINT32 ulNewTime)
{
    m_IBufs.OnSeek();

    m_bFirstPacket = TRUE;
    m_bEndOfPackets = FALSE;
    m_ulCodecDelay = 0;
    m_fCodecDelay = 0.0;
    m_bPCMStreamStart = TRUE;
    
    SetupForNextTimeRange();
    m_pPacketFeeder->Reset();

    return HXR_OK;
}

BOOL
CRaFormat::IsStreamDone()
{
    if( !m_pPacketFeeder )
    {
        return TRUE;
    }
    return ((!m_pPacketFeeder->IsActive()) && m_IBufs.IsStreamDone());
}

void
CRaFormat::SetupForNextTimeRange()
{
    m_pPacketFeeder->SetupForNextTimeRange();

    if (m_pCodec != NULL)
    {
        UINT32 ulOutSize = m_ulAudioBufSize;
        IHXBuffer * pBuffer = NULL;
	m_pCommonClassFactory->CreateInstance(CLSID_IHXBuffer, (void**) &pBuffer);
	if( pBuffer )
	{
	   if( pBuffer->GetSize() != m_ulAudioBufSize )
	   {
              // Yikes! This can fail if heap is low: no check!
	      pBuffer->SetSize( ulOutSize );
	   }
    	   m_pCodec->Flush( pBuffer->GetBuffer(), &ulOutSize );
	   HX_RELEASE( pBuffer );
	}
    }

    m_ulCodecDelay = 0;
    m_fCodecDelay = 0.0;
    m_bPCMStreamStart = TRUE;
    m_ulCrossFadeEndTime = NO_TIME_SET;
    m_ulForceDiscardUntilTime = NO_TIME_SET;
    m_IBufs.SwitchOff();
}

void 
CRaFormat::OnEndofPackets(void)
{
    if( !m_pPacketFeeder )
    {
        m_bEndOfPackets = TRUE;
        return;
    }
    m_pPacketFeeder->OnEndOfPackets();
    m_bEndOfPackets = TRUE;
    
    // if we've already given all of the packets to the ibufs,
    // we can tell them we are done now, otherwise wait till
    // we do finish the packets
    if (!m_pPacketFeeder->IsActive())
    {
	m_IBufs.OnEndofPackets();
    }
}

HX_RESULT
CRaFormat::UpdatePacketTimeOffset(INT32 lTimeOffset)
{
    m_lTimeOffset -= lTimeOffset;
    return HXR_OK;
}

HX_RESULT
CRaFormat::UpdatePlayTimes(IHXValues* pProps)
{
    UINT32 ulStart = 0;
    UINT32 ulEnd = 0;

    if (HXR_OK == pProps->GetPropertyULONG32("Start", ulStart))
    {
	m_ulTrackStartTime = ulStart;
	m_bForceStartTrackTime = TRUE;
    }

    if (HXR_OK == pProps->GetPropertyULONG32("End", ulEnd))
    {
	m_ulTrackEndTime = ulEnd;
	m_bForceEndTrackTime = TRUE;
    }

    return HXR_OK;
}


// statistics
#if defined(HELIX_FEATURE_STATS)
HX_RESULT CRaFormat::UpdateStatistics (IHXRegistry* pRegistry, UINT32 ulRegistryID,
				       UINT32& ulCodecRegID, UINT32& ulCodecTextRegID,
				       UINT32& ulCodec4CCRegID, UINT32& ulRateRegID,
				       UINT32& ulChannelsRegID, UINT32& ulSurroundRegID)
{
    char	    szRegistryEntry[MAX_DISPLAY_NAME] = {0}; /* Flawfinder: ignore */
    IHXBuffer*	    pszRegistryName = NULL;
    IHXBuffer*	    pValue = NULL;
    CStreamParam*    pParam;
    HX_RESULT retVal = HXR_OK;

    if (!pRegistry || !ulRegistryID || m_pCodec == NULL)
    {
	return HXR_FAILED;
    }

    pParam = &m_StreamParam;

    if (!ulCodecRegID)
    {
	// Get the current registry key name
	if (!ulCodecRegID && (HXR_OK == pRegistry->GetPropName(ulRegistryID, pszRegistryName)))
	{
	    SafeSprintf (szRegistryEntry, MAX_DISPLAY_NAME, "%s.Codec", pszRegistryName->GetBuffer());
	    if (pParam->codecID)
	    {
		m_pCommonClassFactory->CreateInstance(CLSID_IHXBuffer, 
		    (void**) &pValue);

		//
		UINT16	uPropSize = 0;
		void*	pProp = m_pCodec->GetFlavorProperty(m_StreamParam.uFlavorIndex, FLV_PROP_NAME, &uPropSize);

		if (uPropSize)
		{
		    pValue->Set((const UCHAR*)pProp, uPropSize);
		    ulCodecRegID = pRegistry->AddStr(szRegistryEntry, pValue);
		}
		pValue->Release();
	    }
	    pszRegistryName->Release();
	    pszRegistryName = NULL;
	}
    }
    else
    {
	if (pParam->codecID)
	{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -