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

📄 hxflsrc.cpp

📁 symbian 下的helix player源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    }

    seekTime	+= m_ulStartTime;

    /* Are we seeking past the last expected packet time?
     * If so, don't bother... and mark this source as done
     */
    HX_ASSERT(m_llLastExpectedPacketTime < MAX_UINT32);
    // XXX HP make sure the source has been initialized otherwise
    // m_llLastExpectedPacketTime could be 0 and we could falsely
    // mark the source ended
    if (m_bInitialized && !mLiveStream && seekTime >= INT64_TO_UINT32(m_llLastExpectedPacketTime))
    {
	if (m_pSourceInfo && m_pSourceInfo->m_bSeekToLastFrame)
	{
	    seekTime = INT64_TO_UINT32(m_llLastExpectedPacketTime);
	}
	else
	{
	    m_bSourceEnd = TRUE;
	    m_bForcedSourceEnd = TRUE;
	    AdjustClipBandwidthStats(FALSE);
	    goto cleanup;
	}
    }

    m_bInitialBuffering = TRUE;
    m_bForcedSourceEnd	= FALSE;
    m_uActiveStreams	= m_uNumStreams; 
    m_bIsPreBufferingStarted	= FALSE;
    m_bIsPreBufferingDone	= FALSE;

    if (m_nSeeking == 0)
    {
	m_nSeeking++;
    }

#if defined(HELIX_FEATURE_RECORDCONTROL)
    if (m_pRecordControl && m_pRecordControl->Seek(seekTime) == HXR_OK &&
	m_bPlayFromRecordControl)
    {
	m_pBufferManager->DoSeek(seekTime, TRUE);
	SeekDone(HXR_OK);
    }
    else
#endif /* HELIX_FEATURE_RECORDCONTROL */
    {
	m_bSourceEnd = FALSE;

	m_pBufferManager->DoSeek(seekTime, FALSE);

	if (HXR_OK != m_pFFObject->Seek(seekTime))
	{
	    if (m_nSeeking)
	    {
		m_nSeeking--;
	    }
	}
    }

    m_llLastFillEndTime = 0;   

cleanup:

    return HXR_OK;
}

	
HX_RESULT	
HXFileSource::DoPause(void)
{
    if (m_bPaused)
    {
	return HXR_OK;
    }

    /* Only if it is an external pause */
    if (!m_bSourceEnd && !m_bDelayed && m_pBufferManager)
    {
	m_pBufferManager->DoPause();
    }

    m_bPaused = TRUE;

    return HXR_OK;
}


HX_RESULT   
HXFileSource::StartInitialization(void)
{
    m_bFastStartInProgress = TRUE;
    m_pBufferManager->DoResume();
    if (m_pSourceInfo)
    {
	m_pSourceInfo->Resumed();
    }
    return HXR_OK;
}

HX_RESULT   
HXFileSource::DoResume(void)
{
    HX_RESULT theErr = HXR_OK;

    m_bFastStartInProgress = FALSE;

    /* This may happen if a new source is added from SMIL renderer during 
     * initialization of exisitng sources. We will eventually call Resume 
     * on this source once it is initialized in SourceInfo::ProcessIdle
     */
    if (!m_bInitialized || (m_pSourceInfo && !m_pSourceInfo->IsInitialized()))
    {
	return HXR_OK;
    }

    if (m_bSourceEnd || CanBeResumed())
    {
	m_bResumePending = FALSE;

	if (!m_bSourceEnd)
	{
	    m_pBufferManager->DoResume();
	}

	// resume the audio streams if the source is added
	// while the player is in play mode
	// CAUTION: this will cause rewind in audio service
	if (m_bFirstResume && m_pPlayer->IsPlaying() &&
	    m_ulDelay <= m_pPlayer->GetInternalCurrentPlayTime())
	{
	    ResumeAudioStreams();
	}

	m_bFirstResume = FALSE;
	m_bPaused = FALSE;

	if (m_pSourceInfo)
	{
	    m_pSourceInfo->Resumed();
	}

	if (!m_bSourceEnd)
	{
	    theErr = FillBuffers();
	}
    }

    if (!theErr && !m_bIsActive && !m_bDelayed &&
	m_pPlayer->GetInternalCurrentPlayTime() >= m_ulDelay)
    {
	AdjustClipBandwidthStats(TRUE);
    }

    if (theErr == HXR_AT_END)
    {
	SetEndOfClip();
	theErr = HXR_OK;
    }

    return theErr;
}

/************************************************************************
 *	Method:
 *	    IHXPendingStatus::GetStatus
 *	Purpose:
 *	    Called by the user to get the current pending status from an object
 */
STDMETHODIMP
HXFileSource::GetStatus
(
    REF(UINT16) uStatusCode, 
    REF(IHXBuffer*) pStatusDesc, 
    REF(UINT16) ulPercentDone
)
{
    HX_RESULT hResult = HXR_OK;
    IHXPendingStatus* pStatus = NULL;

    UINT16  buffer	= 100;
    UINT16  statusCode	= HX_STATUS_READY;
    UINT16  percentDone = 0;

    uStatusCode	    = HX_STATUS_READY;
    pStatusDesc	    = 0;
    ulPercentDone   = 0;
    
    if (m_bDelayed)
    {
	return HXR_OK;
    }

    if (m_bSourceEnd)
    {
	if (!IsRebufferDone())
	{
	    uStatusCode = HX_STATUS_BUFFERING;
	    ulPercentDone = 99;
	}
	else
	{
	    if (m_bInitialBuffering)
	    {
		InitialBufferingDone();
	    }

	    m_ulLastBufferingReturned = 100;
	    uStatusCode = HX_STATUS_READY;
	}

	return HXR_OK;
    }

    if (m_bInitialized)
    {
	if (m_bFirstResume)
	{
	    uStatusCode	    = HX_STATUS_INITIALIZING;
	    return HXR_OK;
	}

	m_pBufferManager->GetStatus(uStatusCode, 
				    pStatusDesc,
				    ulPercentDone);

	buffer = ulPercentDone;

	/* We only aggregate buffering from a lower level if we are in a buffering mode.
	 * Reason: Once the initial bufering is done, we go in buffering more ONLY IF the
	 * renderer tells us that it is in a panic state and we run out of packets.
	 */
	if (buffer == 100 && !m_bInitialBuffering)
	{	    
	    // Rebuffer requested by the Renderer might not be
	    // done yet
	    if (!IsRebufferDone())
	    {
		uStatusCode = HX_STATUS_BUFFERING;
		ulPercentDone = 99;
	    }
	    else
	    {
		uStatusCode = HX_STATUS_READY;
	    }

	    return HXR_OK;
	}
    }

    if (m_pFFObject)
    {
	if (HXR_OK != m_pFFObject->QueryInterface(IID_IHXPendingStatus, (void**)&pStatus))
	{
	    goto exit;
	}

	if (HXR_OK != pStatus->GetStatus(statusCode, pStatusDesc, percentDone))
	{
	    goto exit;
	}
    }
    else if (m_pFileObject)
    {
	if (HXR_OK != m_pFileObject->QueryInterface(IID_IHXPendingStatus, (void**)&pStatus))
	{
	    goto exit;
	}

	if (HXR_OK != pStatus->GetStatus(statusCode, pStatusDesc, percentDone))
	{
	    goto exit;
	}
    }

exit:
    
    if (HX_STATUS_CONTACTING == statusCode)
    {
	uStatusCode = HX_STATUS_CONTACTING;
	ulPercentDone = 0;
    }
    else if (!m_bInitialized)
    {
	uStatusCode	= HX_STATUS_INITIALIZING;
	ulPercentDone	= 0;
    }
    else if (HX_STATUS_READY == statusCode && 100 == buffer)
    {
	uStatusCode = HX_STATUS_READY;
	ulPercentDone = 0;
	m_ulLastBufferingReturned = 100;
    }
    else
    {
	uStatusCode = HX_STATUS_BUFFERING;
	
	if (HX_STATUS_READY == statusCode)
	{
	    ulPercentDone = (UINT16)buffer;
	}
	else
	{
	    ulPercentDone = (UINT16)((buffer + percentDone) * 0.5);
	}

	// Do not go back
	if (ulPercentDone < m_ulLastBufferingReturned && m_ulLastBufferingReturned != 100)
	{
	    ulPercentDone = (UINT16) m_ulLastBufferingReturned;
	}
	else
	{
	    m_ulLastBufferingReturned = ulPercentDone;
	}
    }

    HX_RELEASE(pStatus);
  
    ulPercentDone = ulPercentDone <= 100 ? (UINT16)ulPercentDone : 100;

    if (m_bInitialBuffering && HX_STATUS_READY == uStatusCode)
    {
	InitialBufferingDone();
    }

    /* If we had a delayed start, we do not want to show that we are
     * in buffering state UNLESS it is really time to give out packets
     * and we do not have 
     */
    if (m_bInitialized && m_ulDelay > 0 && 
	uStatusCode == HX_STATUS_BUFFERING && 
	ulPercentDone < 100)
    {
	UINT32 ulCurrentTime = m_pPlayer->GetInternalCurrentPlayTime();

	if ((ulCurrentTime + MIN_BUFFERTIME_BEFORE_DELAY) < m_ulDelay)
	{
	    ulPercentDone = 100;
	}
    }

    return hResult;
}

UINT16		
HXFileSource::GetNumStreams(void)
{
    HX_ASSERT(m_bInitialized);
    
    return m_uNumStreams;
}


HX_RESULT	
HXFileSource::GetStreamInfo(ULONG32	    ulStreamNumber,
			     STREAM_INFO*&  theStreamInfo)
{
    HX_RESULT theErr = HXR_OK;
    STREAM_INFO* lpStreamInfo = 0;

    if (!mStreamInfoTable->Lookup((LONG32)ulStreamNumber, (void *&)lpStreamInfo))
    {
	theErr = HXR_INVALID_PARAMETER;
    }

    theStreamInfo = lpStreamInfo;

    return theErr;
}

HX_RESULT    
HXFileSource::GetEvent(UINT16 usStreamNumber, CHXEvent*& theEvent)
{
    HX_RESULT theErr = HXR_OK;

    HX_TRACE("HXFileSource::GetEvent");

    theEvent	= 0;
    
    if (!m_bInitialized)
    {
	return HXR_NOT_INITIALIZED;
    }

    if (mLastError != HXR_OK)
    {
	return mLastError;
    }

    if (m_bPaused && m_bDelayed)
    {
	if (TryResume())
	{
	    m_pPlayer->RegisterSourcesDone();
    	    DoResume();
	}
	else
	{
	    return HXR_NO_DATA;
	}
    }

    STREAM_INFO * lpStreamInfo;
    if (!mStreamInfoTable->Lookup((LONG32) usStreamNumber, (void *&) lpStreamInfo))
    {
	theErr = HXR_INVALID_PARAMETER;
	return theErr;
    }

#if defined(HELIX_FEATURE_RECORDCONTROL)
    if (m_bPlayFromRecordControl && m_pRecordControl)
    {
	IHXPacket* pPacket = NULL;

	HX_ASSERT(m_pRecordControl);

	theErr = m_pRecordControl->GetPacket(usStreamNumber, pPacket);
	if(theErr == HXR_OK)
	{
            UINT32 streamPreRoll = max(lpStreamInfo->BufferingState().GetMinPrerollInMs(),1000);

	    INT64 llPacketTime = 
		lpStreamInfo->BufferingState().CreateINT64Timestamp(pPacket->GetTime());

	    theEvent = new CHXEvent(pPacket, 
				    GetEventBeginTime(llPacketTime, 
						      streamPreRoll));
	    if(theEvent) 
		theEvent->SetTimeOffset(m_ulStartTime - m_ulDelay); 
	    else
		theErr = HXR_OUTOFMEMORY;

	    if(m_pBufferManager)
		m_pBufferManager->UpdateCounters(pPacket);

	    HX_RELEASE(pPacket);
	}
	else
	{
	    if(theErr == HXR_NO_DATA && (m_bSourceEnd || lpStreamInfo->m_bSrcStreamDone))
		theErr = HXR_AT_END;

	    if(theErr == HXR_NO_DATA)
	    {
		if (lpStreamInfo->m_unNeeded > 0 &&
		    lpStreamInfo->m_unNeeded != lpStreamInfo->m_unAvailable)
		{
		    // Re-initialize buffering
		    m_pBufferManager->ReBuffer();
		    FillBuffers();
		    theErr = HXR_BUFFERING;
		}
	    }
	}

	return theErr;
    }
#endif /* HELIX_FEATURE_RECORDCONTROL */

    // get the packet list for this stream
    CHXEventList  * lEventList = &lpStreamInfo->m_EventList;

    // do we need to fill buffers...
    if (lEventList->GetNumEvents() == 0)
    {
	theErr = FillBuffers();

	if (theErr == HXR_AT_END)
	{
	    SetEndOfClip();
	    theErr = HXR_OK;
	}

	// check if we have packets now...
	if (!theErr && lEventList->GetNumEvents() == 0)
	{
	    if (m_bSourceEnd || lpStreamInfo->m_bSrcStreamDone)
	    {
		return HXR_AT_END;	    
	    }
	    else
	    {
		if (lpStreamInfo->m_unNeeded > 0 &&
		    lpStreamInfo->m_unNeeded != lpStreamInfo->m_unAvailable)
		{
		    // Re-initialize buffering
		    m_pBufferManager->ReBuffer();
		    FillBuffers();
		    return HXR_BUFFERING;
		}

		return HXR_NO_DATA;
	    }
	}
    }

    if (!theErr)
    {
	// this event will be deleted by the player...
	theEvent = lEventList->RemoveHead();
    }

#ifdef LOSS_HACK
    if (m_ulLossHack > 0 && ((UINT32) (rand() % 100) < m_ulLossHack) &&
	!theErr && theEvent && !(theEvent->GetPacket())->IsLost())
    {
	GenerateFakeLostPacket(theEvent);
	/* Update the stats */
	if (lpStreamInfo->m_ulReceived > 0)
	{
	    lpStreamInfo->m_ulReceived--;

⌨️ 快捷键说明

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