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

📄 srcinfo.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	    pRendInfo->m_bInitialBeginToBeSent  = TRUE;
	    m_pPlayer->EnterToBeginList(pRendInfo);
	}

	if (m_pSource->IsLive())
	{
	    pRendInfo->m_BufferingReason    = BUFFERING_LIVE_PAUSE;
	}
	else
	{
	    pRendInfo->m_BufferingReason    = BUFFERING_SEEK;
	}
    }

    m_bSeekToLastFrame = bSeekToLastFrame;
    m_llLatestPacketTime = 0;

    return HXR_OK;
}

HX_RESULT
SourceInfo::BeginTrack(void)
{
#if defined(HELIX_FEATURE_ADVANCEDGROUPMGR)
    HX_RESULT	    rc = HXR_OK;
    UINT32	    ulDelay = 0;
    UINT32	    ulPausedTime = 0;
    RendererInfo*   pRendInfo = NULL;
    STREAM_INFO*    pStreamInfo = NULL;
    CHXAudioPlayer* pAudioPlayer = NULL;
    CHXMapLongToObj::Iterator ndxRend;

    if (!m_pSource)
    {
	rc = HXR_UNEXPECTED;
	goto cleanup;
    }

    if (m_pSource->IsPaused())
    {
	ulPausedTime = m_pPlayer->m_ulCurrentPlayTime - m_ulPausedStartTime;	
	ulDelay = m_pSource->GetDelay() + ulPausedTime;
	
	// update source's delay time which will call sourceinfo's
	// UpdateDelay()
	m_pSource->UpdateDelay(ulDelay);

	// resume
	m_pSource->ResumeAudioStreams();

	rc = Begin();
    }
    // track is stopped ahead of its duration
    else if (m_bStopped)
    {
	m_bStopped = FALSE;
	m_bSeekPending = TRUE;
	m_ulSeekTime = m_pPlayer->m_ulCurrentPlayTime;
	
	m_pSource->ReSetup();
    }
    // either track has not been played yet
    // or track is still playing
    else
    {
    	rc = HXR_FAILED;
	goto cleanup;
    }
   
cleanup:
    
    return rc;
#else
    return HXR_NOTIMPL;
#endif /* HELIX_FEATURE_ADVANCEDGROUPMGR */
}

HX_RESULT
SourceInfo::PauseTrack(void)
{
#if defined(HELIX_FEATURE_ADVANCEDGROUPMGR)
    HX_RESULT	rc = HXR_OK;

    // stop the source
    if (m_pSource)
    {
	m_pSource->PauseAudioStreams();
    }

    m_ulPausedStartTime = m_pPlayer->m_ulCurrentPlayTime;
    rc = Pause();

    return rc;
#else
    return HXR_NOTIMPL;
#endif /* HELIX_FEATURE_ADVANCEDGROUPMGR */
}

HX_RESULT
SourceInfo::SeekTrack(UINT32 ulSeekTime)
{
    // low priority since it is rarely used by the SMIL
    return HXR_NOTIMPL;
}

HX_RESULT
SourceInfo::StopTrack(void)
{
#if defined(HELIX_FEATURE_ADVANCEDGROUPMGR)
    HX_RESULT	rc = HXR_OK;

    m_bStopped = TRUE;

    // stop the source
    if (m_pSource)
    {
	m_pSource->RemoveAudioStreams();
    }

    Reset();

    m_bDone = TRUE;
    m_pPlayer->m_uNumSourcesActive--;

    return rc;
#else
    return HXR_NOTIMPL;
#endif /* HELIX_FEATURE_ADVANCEDGROUPMGR */
}

HX_RESULT
SourceInfo::SetSoundLevel(UINT16 uSoundLevel, BOOL bReflushAudioDevice)
{
    m_uSoundLevel = uSoundLevel;
    m_pSource->SetSoundLevel(uSoundLevel, bReflushAudioDevice);

    return HXR_OK;
}

void
SourceInfo::Reset()
{
    /* m_pSource should never be NULL */
    HX_ASSERT(m_pSource);

    if (!m_pSource)
    {
	return;
    }

#if defined(HELIX_FEATURE_ADVANCEDGROUPMGR)
    if(m_bIsPersistentSource)
    {
	m_bDone = FALSE;
	m_bAllPacketsReceived = FALSE;

	CHXMapLongToObj::Iterator ndxRend = m_pRendererMap->Begin();
	for (; ndxRend != m_pRendererMap->End(); ++ndxRend)
	{
	    RendererInfo* pRendInfo     = (RendererInfo*)(*ndxRend);
	    IHXRenderer* pRend         = (IHXRenderer*)pRendInfo->m_pRenderer;
	    STREAM_INFO*  pStreamInfo   = pRendInfo->m_pStreamInfo;
	    pStreamInfo->m_bSrcInfoStreamDone  = FALSE;

	    /* Reset the latest packet time */
	    pRendInfo->m_ulLatestEventTime	    = 0;

	    m_pPlayer->m_pScheduler->Remove(
             pRendInfo->m_pTimeSyncCallback->GetPendingCallback());
        
            pRendInfo->m_pTimeSyncCallback->CallbackCanceled();

	    pRendInfo->m_bIsFirstCallback	    = TRUE;
	    pRendInfo->m_ulLastSyncTime         = 0;
	    pRendInfo->m_ulNumberOfPacketsQueued= 0;
	    pRendInfo->m_ulNextDueSyncTime      = 0;
	    if (!pRendInfo->m_bInitialBeginToBeSent && pRendInfo->m_pRenderer)
	    {
		pRendInfo->m_bInitialBeginToBeSent  = TRUE;
		m_pPlayer->EnterToBeginList(pRendInfo);
	    }
	}
    }
    else
#endif /* HELIX_FEATURE_ADVANCEDGROUPMGR */
    {	
	DoCleanup();
	RenderersCleanup();
    }

    return;
}


void
SourceInfo::DoCleanup(EndCode endCode)
{
    if (m_pProcessCallback && m_pPlayer->m_pScheduler)
    {
	m_pPlayer->m_pScheduler->Remove(m_pProcessCallback->GetPendingCallback());
        m_pProcessCallback->CallbackCanceled();
    }

    if (m_bIsPersistentSource)
    {
	return;
    }

    m_bLocked = TRUE;
    m_pMutex->Lock();

    CHXMapLongToObj::Iterator ndxRend = m_pRendererMap->Begin();
    for (; ndxRend != m_pRendererMap->End(); ++ndxRend)
    {
	RendererInfo* pRendInfo = (RendererInfo*)(*ndxRend);

	/* Tell each renderer that we are done with the stream */
	if(pRendInfo)
	{
            if (pRendInfo->m_pStream &&
                pRendInfo->m_pStreamInfo && pRendInfo->m_pStreamInfo->m_pHeader)
            {
                IHXBuffer* pMimeTypeBuffer = NULL;
	        pRendInfo->m_pStreamInfo->m_pHeader->GetPropertyCString("MimeType", pMimeTypeBuffer);

	        if (pMimeTypeBuffer && pMimeTypeBuffer->GetBuffer() &&
                    ::strcasecmp((const char*) pMimeTypeBuffer->GetBuffer(), "application/vnd.rn-objectsstream") == 0 ||
                    ::strcasecmp((const char*) pMimeTypeBuffer->GetBuffer(), "application/x-rn-objects") == 0 ||
		    ::strcasecmp((const char*) pMimeTypeBuffer->GetBuffer(), "application/vnd.rn-objects") == 0)
	        {
	            m_pPlayer->m_pEngine->m_lROBActive--;
                    HX_ASSERT(m_pPlayer->m_pEngine->m_lROBActive >=0 );
	        }

                HX_RELEASE(pMimeTypeBuffer);
            }

	    if(pRendInfo->m_pRenderer)
		pRendInfo->m_pRenderer->EndStream();

	    if (pRendInfo->m_bInitialBeginToBeSent)
	    {
		m_pPlayer->RemoveFromPendingList(pRendInfo);
	    }

	    if (pRendInfo->m_pTimeSyncCallback)
	    {
//{FILE* f1 = ::fopen("c:\\temp\\ts.txt", "a+"); ::fprintf(f1, "%p RELEASING TimeSyncCallback: Pending: %d Handle: %lu\n", pRendInfo->m_pTimeSyncCallback, (int)pRendInfo->m_bIsCallbackPending, (UINT32) pRendInfo->m_PendingHandle);::fclose(f1);}

	        m_pPlayer->m_pScheduler->Remove(
                 pRendInfo->m_pTimeSyncCallback->GetPendingCallback());
        
                pRendInfo->m_pTimeSyncCallback->CallbackCanceled();
                HX_RELEASE(pRendInfo->m_pTimeSyncCallback);
	    }

	    HX_RELEASE(pRendInfo->m_pStream);
	}
    }

    // cleanup (i.e. registry)
    m_pSource->DoCleanup(endCode);

    UnRegister();

    m_lastError = HXR_OK;
    m_bAreStreamsSetup = FALSE;
    m_bDone = FALSE;
    m_bInitialized = FALSE;
    m_bSeekPending = FALSE;
    m_bSeekToLastFrame = FALSE;

    m_pMutex->Unlock();
    m_bLocked = FALSE;
}

void
SourceInfo::Stop(EndCode endCode)
{
    /* We have already been here once */
    if (m_pSource == NULL)
    {
	return;
    }

    DoCleanup(endCode);

    if (m_bIsPersistentSource)
    {
	return;
    }

    m_bLocked = TRUE;
    m_pMutex->Lock();

    m_pSource->Stop();

#if defined(HELIX_FEATURE_BASICGROUPMGR)
    if (m_bTrackStoppedToBeSent)
    {
	m_pPlayer->m_pGroupManager->TrackStopped(m_uGroupID, m_uTrackID);  
	m_bTrackStoppedToBeSent = FALSE;
	if (m_pPeerSourceInfo)
	{
	    m_pPeerSourceInfo->m_bTrackStoppedToBeSent = FALSE;
	}
    }
#endif /* HELIX_FEATURE_BASICGROUPMGR */

    m_pMutex->Unlock();
    m_bLocked = FALSE;
}

void
SourceInfo::Remove()
{
    // stop the source
    if (m_pSource)
    {
	m_pSource->RemoveAudioStreams();
    }

    m_bDone = TRUE;

    Stop();
    CloseRenderers();
}

/*
 * -- LIVE SYNC SUPPORT --
 *
 * SharedWallClock class is used for live sync support.
 * There is one of these objects per shared wall clock.
 *
 * This object will also be associated with an HXPlayer
 * since we won't ever share wall clocks between two players.
 * This is an intentional design choice, since it doesn't
 * reall make sense to do any sync-ing across multiple players.
 * 
 * This object will keep a list of source's that are sharing
 * it. This is mainly needed so that the wall clock can
 * reset the start time for all the sources in the event that
 * it gets a new start time that is earlier than it had
 * previously thought. Basically, the start time of the wall
 * clock is what does the syncing.      
 */
SharedWallClock::SharedWallClock
(
    const char* pName, 
    UINT32 ulStartTime,
    HXPlayer* pPlayer
)
    : m_ulStartTime(ulStartTime)
    , m_strName(pName)
    , m_pPlayer(pPlayer)
{
    HX_ASSERT(m_pPlayer);
    (*m_pPlayer->m_pSharedWallClocks)[pName] = this;
};

/*
 * -- LIVE SYNC SUPPORT --
 *
 * Obviously this is the method that handles resyncing the
 * start times for all the sources that share the wall clock.
 *
 * This method also returns the start time. The intended useage
 * is for the caller to pass the start time that it expects, and
 * then respect the start time that is returned. In the event that
 * the input start time is less than the previously known start
 * time, then all sources are reset.
 */
UINT32
SharedWallClock::ResetStartTime(UINT32 ulStartTime)
{
    if (ulStartTime < m_ulStartTime)
    {
	m_ulStartTime = ulStartTime;
	CHXSimpleList::Iterator indx = m_UserList.Begin();

	for (; indx != m_UserList.End(); ++indx)
	{
	    SourceInfo* pSourceInfo = (SourceInfo*)(*indx);
	    pSourceInfo->ResetStartTime(ulStartTime);
	}
    }
    return m_ulStartTime;
};

/*
 * -- LIVE SYNC SUPPORT --
 *
 * Nothing tricky here, we just track the incoming user on our
 * list of known users.
 */
void
SharedWallClock::AddUser(SourceInfo* pSourceInfo)
{
    m_UserList.AddTail(pSourceInfo);
};

/*
 * -- LIVE SYNC SUPPORT --
 *
 * This method removes users from the shared clock's user list
 * and also cleans up the shared clock when the last user is
 * removed. So, any caller of this method should take note to
 * NOT use the shared clock after calling this method.
 */
void
SharedWallClock::RemoveUser(SourceInfo* pSourceInfo)
{
    LISTPOSITION pos = m_UserList.Find(pSourceInfo);
    HX_ASSERT(pos);

    m_UserList.RemoveAt(pos);
    
    if (m_UserList.IsEmpty())
    {
	m_pPlayer->m_pSharedWallClocks->RemoveKey(m_strName);
	delete this;
    }
};

/*
 * -- LIVE SYNC SUPPORT --
 *
 * If the start time is changed for a source then all the
 * renderer's need to have their start time's reset. This
 * method just loops through the renderer info to do the work.
 */
void
SourceInfo::ResetStartTime(UINT32 ulStartTime)
{
    if (ulStartTime < m_ulStreamStartTime)
    {
	m_ulStreamStartTime = ulStartTime;
	CHXMapLongToObj::Iterator indx = m_pRendererMap->Begin();

	for (; indx != m_pRendererMap->End(); ++indx)
	{
	    RendererInfo* pRendererInfo = (RendererInfo*)(*indx);
	    pRendererInfo->m_ulStreamStartTime = ulStartTime;
	}
    }
};

/*
 * -- LIVE SYNC SUPPORT --
 *
 * This is the real work horse for live sync support. This
 * method actually determines if the URL for the source is
 * targeted at a shared wall clock by looking for the wallclock
 * option in the URL.
 *
 * If the wallclock name is found then we try to find the wall
 * clock object for this name and player. If we don't find it
 * then we create a new clock. If we do find it then we want
 * to determine if the start time should be reset to the lower
 * value. We also return the start time to be stored in the
 * renderers.
 */
UINT32
SourceInfo::CalculateLiveStartTime(IHXPacket* pFirstPacket)
{
    UINT32 ulStreamStartTime = pFirstPacket->GetTime();;

    /*
     * Find out if this live feed has a "wallclock" property.
     */
    CHXURL*	pURL = m_pSource->GetCHXURL();
    IHXValues*  pValues = pURL->GetOptions();
    IHXBuffer* pWallClockName = NULL;

    pValues->GetPropertyBuffer("wallclock", pWallClockName);

    if (pWallClockName)
    {

⌨️ 快捷键说明

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