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

📄 hxflsrc.cpp

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

#if defined(HELIX_FEATURE_RECORDCONTROL)
    SendHeaderToRecordControl(FALSE, pHeader);
#endif /* HELIX_FEATURE_RECORDCONTROL */

    StreamHeaderReadyExt(pHeader);

    // fileformat initialized...clear any pending upgrade requests for this source!
    ClearUpgradeRequest();

    // we have already received enough headers...
    if (m_uNumStreams >= m_ulStreamHeadersExpected)
	return HXR_FAILED;

    theErr = ProcessStreamHeaders(pHeader, pStreamInfo);

    if (!theErr)
    {
#if defined(HELIX_FEATURE_STATS) && defined(HELIX_FEATURE_REGISTRY)
        HX_ASSERT(pStreamInfo);

	// create all the statistic registry keys
	if (m_pRegistry && m_pStats &&
	    HXR_OK == m_pRegistry->GetPropName(m_pStats->m_ulRegistryID, pszParentName))
	{
	    SafeSprintf(szRegKeyName, MAX_DISPLAY_NAME, "%s.Stream%ld", pszParentName->GetBuffer(), 
		m_ulStreamIndex);

	    /* does this ID already exists ? */
	    UINT32 ulRegistryID = m_pRegistry->GetId(szRegKeyName);
	    if (!ulRegistryID)
	    {
		ulRegistryID = m_pRegistry->AddComp(szRegKeyName);
	    }

	    pStreamInfo->m_pStats = new STREAM_STATS(m_pRegistry, ulRegistryID);

            if(pStreamInfo->m_pStats)
            {
	        // set stream bandwidth
	        pStreamInfo->m_pStats->m_pClipBandwidth->SetInt((INT32)pStreamInfo->BufferingState().AvgBandwidth());
            }
            else
            {
                // NOTE: It may be that we can still function without the 
                // m_pStats object, but can we still function if we are 
                // running out of memory at this point? Assuming no.
                theErr = HXR_OUTOFMEMORY;
            }

	}
	HX_RELEASE(pszParentName);
#endif /* HELIX_FEATURE_STATS && HELIX_FEATURE_REGISTRY */
        m_ulStreamIndex++;
        m_uNumStreams++;
    }

    if (!theErr && m_uNumStreams == m_ulStreamHeadersExpected)
    {
	m_uActiveStreams = m_uNumStreams;
	m_ulOriginalDuration = m_ulDuration;
	m_bInitialized	    = TRUE;	

	theErr = AdjustClipTime();
	m_pBufferManager->Init();
    }

    return theErr;
}

HX_RESULT
HXFileSource::StreamHeaderReadyExt(IHXValues* pHeader)
{
    return HXR_OK;
}

STDMETHODIMP	
HXFileSource::PacketReady(HX_RESULT status, IHXPacket* pPacket)
{
    HX_RESULT theErr = HXR_OK;

    // We should have been initialized by now
    HX_ASSERT(m_bInitialized);
    if (!m_bInitialized)
    {
	return HXR_NOT_INITIALIZED;
    }
    
    // Report a non-HXR_OK error code only if no packet. If a packet
    // accompanies the error code we assume end of stream and handle
    // later on (see below).
    if (!pPacket)
    {
        if (HXR_OK != status)
        {
	    mLastError = status;
	    ReportError(mLastError);
            return HXR_OK;
        }
        else
        {
	    // HXR_OK with a NULL packet makes no sense
	    return HXR_INVALID_PARAMETER;
        }
    }
    
    IHXBuffer*	    pBuffer	    = 0;
    UINT32	    ulPacketTime    = 0;	    // packet time encoded
    UINT32	    ulPacketFilledDuration = 0;	    // packets' time have been filled 
    UINT32 	    ulEventBeginTime = 0;	    // start pos of the packet(event) 
    INT64	    llActualPacketTime = 0;	    // packet time with timestamp rollover
    INT64	    llActualEventBeginTime = 0;	    // start pos of the packet(event) with timestamp rollover
    ULONG32	    ulFlags	    = 0;
    UINT16	    uStreamNumber   = 0;
    UINT8	    unASMFlags	    = 0;
    UINT16	    unASMRuleNumber = 0;
    UINT32	    streamPreRoll   = 0;
    UINT32	    ulMinimumTotalPreroll = 0;

    if (HXR_OK != pPacket->Get(pBuffer, ulPacketTime, uStreamNumber, unASMFlags, unASMRuleNumber))
    {
	theErr = HXR_FAILED;
	return theErr;
    }

#if defined(_DEBUG) && defined(DEBUG_LOG_INFO)
    HXStaticStatLog::StatPrintf("Packet: StreamNumber: %u TimeStamp: %lu\n", uStreamNumber, ulPacketTime);
#endif

    HX_RELEASE(pBuffer);

    CHXEvent*	    theEvent	    = NULL;
    STREAM_INFO*    lpStreamInfo    = NULL;
    CHXEventList*  lEventList	    = NULL;

    if (!mStreamInfoTable->Lookup((LONG32) uStreamNumber, (void *&) lpStreamInfo))
    {
	return HXR_INVALID_PARAMETER;
    }

    if (status != HXR_OK)
    {
	if (!lpStreamInfo->m_bSrcStreamDone)
	{
	    // if the status is not OK, it is probably the end of the stream..
	    // we should mark this stream as DONE...
	    lpStreamInfo->m_bPacketRequested	    = FALSE;
	    lpStreamInfo->m_bSrcStreamFillingDone   = TRUE;
	    lpStreamInfo->m_bSrcStreamDone	    = TRUE;

	    if (m_uNumStreamsToBeFilled > 0)
	    {
		m_uNumStreamsToBeFilled--;
	    }
	    
	    if (m_uActiveStreams > 0)
	    {
		m_uActiveStreams--;
	    }
	    
	    if (m_uActiveStreams == 0)
	    {
		SetEndOfClip();
	    }
	}

	return HXR_OK;
    }

    lpStreamInfo->m_ulReceived++;

    if (!theErr)
    {
	// reset
	lpStreamInfo->m_bPacketRequested    = FALSE;
	lEventList = &lpStreamInfo->m_EventList;
    }

    /*
     * Save off the initial timestamp for live streams so we can buffer
     * relative to the first timstamp
     */
    if (m_bInitialPacket)
    {
	m_bInitialPacket = FALSE;
	m_ulFirstPacketTime = ulPacketTime;
    }

    // This is the time according to the stream...
    llActualPacketTime = 
	lpStreamInfo->BufferingState().CreateINT64Timestamp(ulPacketTime);

    llActualEventBeginTime = llActualPacketTime + m_ulDelay;

    /* subtract start time from player time */
    if (m_ulStartTime > 0)
    {
	if (m_ulStartTime < llActualPacketTime) 
	{
	    llActualPacketTime -= m_ulStartTime; 
	}
	else
	{
	    llActualPacketTime = 0;
	}

	if (m_ulStartTime < llActualEventBeginTime) 
	{
	    llActualEventBeginTime -= m_ulStartTime; 
	}
	else
	{
	    llActualEventBeginTime = 0;
	}
    }
    
    HX_ASSERT(llActualEventBeginTime < MAX_UINT32);
    HX_ASSERT(llActualPacketTime < MAX_UINT32);
    ulEventBeginTime = INT64_TO_UINT32(llActualEventBeginTime);
    ulPacketFilledDuration = INT64_TO_UINT32(llActualPacketTime);

#if defined(HELIX_FEATURE_RECORDCONTROL)
    if (m_pRecordControl)
    {
	m_pRecordControl->OnPacket(pPacket, m_ulStartTime - m_ulDelay);
    }
#endif /* HELIX_FEATURE_RECORDCONTROL */

    if (!m_bPlayFromRecordControl)
    {
	/* 
	 * force a minimum preroll of 1 second to ensure that we deliver
	 * packet in time to the renderers. e.g. with delayed RealText
	 * with a preroll of 0 and delay of 10 seconds, it is 
	 * possible to send packets at time 0 AFTER 10 seconds if we 
	 * do not ensure this minimum preroll
	 * helps in fixing random "realtext not displaying" bug
	 */
#ifdef HELIX_FEATURE_MIN_PREROLL
        streamPreRoll = max(lpStreamInfo->BufferingState().GetMinPrerollInMs(),150);
#else  //HELIX_FEATURE_MIN_PREROLL
        streamPreRoll = max(lpStreamInfo->BufferingState().GetMinPrerollInMs(),1000);
#endif //HELIX_FEATURE_MIN_PREROLL

	ulEventBeginTime = (ulEventBeginTime > streamPreRoll) ? (ulEventBeginTime - streamPreRoll) : 0;
	theEvent = new CHXEvent(pPacket, ulEventBeginTime);
	if(!theEvent) 
	{
	    theErr = HXR_OUTOFMEMORY;
	}

	// enqueue the event into event queue
	if(!theErr) 
	{
    	    /* offset used by Player::ProcessCurrentEvents to send to renderer::OnPacket */
    	    theEvent->SetTimeOffset(m_ulStartTime - m_ulDelay); 
	    theErr = lEventList->InsertEvent(theEvent);
	}

	if (!theErr)
	{
	    m_pBufferManager->UpdateCounters(pPacket);
	}
    }

    m_llLastFillEndTime = llActualPacketTime;

    if (m_bInFillMode)
    {
	UINT32 ulDuration = 0;
	UINT32 ulRemainToBufferInMs = 0;
	UINT32 ulRemainToBuffer = 0;

	m_pBufferManager->GetRemainToBuffer(ulRemainToBufferInMs,
					    ulRemainToBuffer);
	/* Logic:
	    In FillBuffers(), we ask for a packet for a particular stream. If
	    the fileformat does not return the packet immediately (i.e. we 
	    go again to ask for the packet from the same stream but find out that
	    we had already asked for it earlier and have not yet received it,
	    the streamFilling is marked as done for that fillbuffer() iteration.
	    In the meantime, we keep on asking for the packets from other streams
	    In meanwhile, if the fileformat returns a packet for the stream marked 
	    as done earlier, we re-activate that stream if the time of the packet
	    is less than the time we fill all streams up to.
	 */
	if (lpStreamInfo->m_bSrcStreamFillingDone &&
	    (ulRemainToBufferInMs > 0 || ulRemainToBuffer > 0) &&
	    ulPacketFilledDuration <= lpStreamInfo->m_ulDuration &&
	    !lpStreamInfo->m_bSrcStreamDone)
	{
	    lpStreamInfo->m_bSrcStreamFillingDone = FALSE;
    	    m_uNumStreamsToBeFilled++;
	}
	
	if (!lpStreamInfo->m_bSrcStreamDone && 
	    !lpStreamInfo->m_bSrcStreamFillingDone &&
	    m_uNumStreamsToBeFilled > 0)
	{
            /* When playing from Record Control buffering can happen after seek to 
               a cached position. In this case we dont need to accelerate packet 
               retriaval and can stop filling the stream.
             */
	    if (ulPacketFilledDuration > lpStreamInfo->m_ulDuration ||
		(ulRemainToBufferInMs == 0 && ulRemainToBuffer == 0) ||
                (m_bPlayFromRecordControl && ulPacketFilledDuration >= m_pPlayer->GetInternalCurrentPlayTime() + ulRemainToBufferInMs))
	    {
		// this value also updated in PacketReady()
		lpStreamInfo->m_bSrcStreamFillingDone  = TRUE;
		if (m_uNumStreamsToBeFilled > 0)
		{
		    m_uNumStreamsToBeFilled--;
		}
	    }
	}
    }

    if (!theErr)
    {
	m_bReceivedData	    = TRUE;
    }
    else if (theEvent)
    {
        HX_DELETE(theEvent);
    }

    return theErr;
}


STDMETHODIMP	
HXFileSource::StreamDone(UINT16   uStreamNumber)
{
    STREAM_INFO	   *lpStreamInfo    = NULL;

    if (!mStreamInfoTable->Lookup((LONG32) uStreamNumber, (void *&) lpStreamInfo))
    {
	return HXR_INVALID_PARAMETER;
    }

    if (!lpStreamInfo->m_bSrcStreamDone)
    {
	lpStreamInfo->m_bSrcStreamDone		= TRUE;
	lpStreamInfo->m_bSrcStreamFillingDone	= TRUE;
	lpStreamInfo->m_bPacketRequested	= FALSE;

	if (m_uNumStreamsToBeFilled > 0)
	{
	    m_uNumStreamsToBeFilled--;
	}

	if (m_uActiveStreams > 0)
	{
	    m_uActiveStreams--;
	}
    
	if (m_uActiveStreams == 0)
	{
	    SetEndOfClip();
	}
    }

    return HXR_OK;
}

STDMETHODIMP	
HXFileSource::SeekDone(HX_RESULT status)
{
    HX_RESULT lResult = HXR_OK;
    
    if (m_nSeeking > 0)
    {
	m_nSeeking--;
    }

    _ProcessIdle(FALSE);

    return lResult;
}

STDMETHODIMP HXFileSource::RedirectDone(IHXBuffer* pURL)
{
    HX_RESULT	hr = HXR_NOTIMPL;

    // handle redirect to diff. protocol from HTTP file system
    if (m_pszURL && pURL)
    {
	if (strncasecmp(m_pszURL, "http://", 7) == 0 &&
	    strncasecmp((const char*)pURL->GetBuffer(), "http://", 7) != 0)
	{
            if (m_bPartOfNextGroup)
            {
                m_bRedirectPending = TRUE;
                HX_DELETE(m_pRedirectURL);

                m_pRedirectURL = new CHXURL((const char*)pURL->GetBuffer());
            }
            else
            {
 	        hr = m_pSourceInfo->HandleRedirectRequest((char*)pURL->GetBuffer());
            }
	}
    }
    
    return hr;
}

// routine to read from the file to keep all streams filled to their preroll value
HX_RESULT    
HXFileSource::FillBuffers(void)
{
    /* 
     * Do not call GetPacket if we have not yet received SeekDone from
     * the file format plugin.
     *	    || 
     * We are in a paused state and no rebuffering and no fast start 
     * is required.
     *	    ||
     * We are in force end mode such as seeking to the end of the source duration
     */
    if (m_nSeeking > 0 ||
	(m_bPaused && !m_bFastStartInProgress && !m_bRebufferingRequired && !m_pRecordControl) ||
	m_bForcedSourceEnd)
    {
	return HXR_OK;
    }

    HX_RESULT	theErr			= HXR_OK;
    UINT32	ulRemainToBufferInMs	= 0; 
    UINT32	ulRemainToBuffer	= 0;
    UINT32	lPlayPos		= m_pPlayer->GetInternalCurrentPlayTime();
    UINT32	ulCurrentTime		= HX_GET_TICKCOUNT();

    m_uNumStreamsToBeFilled		= 0;
    m_ulMaxPreRoll			= 0;
  
    CHXMapLongToObj::Iterator	ndxStream	= mStreamInfoTable->Begin();
    STREAM_INFO*		lpStreamInfo    = NULL;

    m_pBufferManager->GetMaximumPreroll(m_ulMaxPreRoll);
    m_pBufferManager->GetRemainToBuffer(ulRemainToBufferInMs,
					ulRemainToBuffer);

    for(; ndxStream != mStreamInfoTable->End(); ++ndxStream)
    {
	lpStreamInfo	= (STREAM_INFO*) (*ndxStream);
	
	if(!lpStreamInfo->m_bSrcStreamDone)
	{
	    m_uNumStreamsToBeFilled++;
	    lpStreamInfo->m_bSrcStreamFillingDone = FALSE;
	}
    }

    /*
     * The fill end time must be offset by the intial timestamp if this
     * is a live stream which is saved in the initial PacketReady
     */

    // we will always attempt to have m_MaxPreRoll time of data in the audio and video event queues
    m_llFillEndTime = CAST_TO_INT64 (lPlayPos + 
			      m_ulMaxPreRoll + m_pPlayer->m_ulMinimumAudioPreroll + 
			      m_pPlayer->GetGranularity());

    if (!m_pRecordControl &&
	!m_bRebufferingRequired &&
	ulRemainToBufferInMs == 0 &&
	ulRemainToBuffer == 0 && 
	m_llFillEndTime <= m_llLastFillEndTime)
    {
	return HXR_OK;
    }

#if defined(HELIX_FEATURE_RECORDCONTROL)
    if (m_pRecordControl && !m_pRecordControl->CanAcceptPackets())
    {
	return HXR_OK;
    }
#endif /* HELIX_FEATURE_RECORDCONTROL */

    m_bInFillMode   = TRUE;

    while(!theErr && m_uNumStreamsToBeFilled > 0)
    {
	ndxStream = mStreamInfoTable->Begin();

	for (; !theErr && ndxStream != mStreamInfoTable->End(); ++ndxStream)
	{
	    lpStreamInfo    = (STREAM_INFO*) (*ndxStream);

	    if (!lpStreamInfo->m_bSrcStreamDone && 
		!lpStreamInfo->m_bSrcStreamFillingDone && 
		!lpStreamInfo->m_bPacketRequested)
	    {
		// this will be reset in PacketReady()
		lpStreamInfo->m_bPacketRequested    = TRUE;
	
                HX_RESULT retVal = m_pFFObject->GetPacket((UINT16) lpStreamInfo->m_uStreamNumber);
		if (HXR_OK != retVal )
		{
                    StreamDone(lpStreamInfo->m_uStreamNumber);
                    // Don't lose OOM errors.
                    if( retVal == HXR_OUTOFMEMORY )
                    {
                        theErr = retVal;
                    }
#ifdef HELIX_FEATURE_STOP_STREAM_BY_TEMP_FILE_ERROR
                    if( retVal == HXR_TEMP_FILE )
                    {
			theErr = retVal;
			m_pBufferManager->Stop();
			SetE

⌨️ 快捷键说明

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