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

📄 vidrend.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    {
	m_pDecoderPump->Suspend(FALSE);
	m_pDecoderPump->Signal();
    }

    if (m_bUseVideoSurface2 && m_pMISUSSite)
    {
	FlushVideoSurface2(m_pMISUSSite);
    }

    DisplayMutex_Unlock();

    // PostSeek signals the proper packets are to start arriving
    m_pMutex->Lock();
    m_PlayState = PlayStarting;
    m_pMutex->Unlock();

    return HXR_OK;
}

/////////////////////////////////////////////////////////////////////////
//  Method:
//	IHXRenderer::OnPause
//  Purpose:
//	Called by client engine to inform the renderer that a pause has
//	just occured. The render is informed the last time for the
//	stream's time line before the pause.
//
STDMETHODIMP CVideoRenderer::OnPause(ULONG32 ulTime)
{
    m_pMutex->Lock();

    m_PlayState = Paused;

    m_pMutex->Unlock();

    return HXR_OK;
}

/////////////////////////////////////////////////////////////////////////
//  Method:
//	IHXRenderer::OnBegin
//  Purpose:
//	Called by client engine to inform the renderer that a begin or
//	resume has just occured. The render is informed the first time
//	for the stream's time line after the resume.
//
STDMETHODIMP CVideoRenderer::OnBegin(ULONG32 ulTime)
{
    HX_RESULT retVal = HXR_OK;

    m_pMutex->Lock();

    m_bBufferingOccured = FALSE;
    // If we are seeking, PostSeek will notify us when the play
    // will be starting
    if (m_PlayState != Seeking)
    {
	m_PlayState = PlayStarting;
    }

    // No need to clear the Blt Packet queue here since
    // The Refresh event will always clear it and clearing
    // it here would create a race condition on Blt Packet
    // Queue (ring buffer) read.
    // ClearBltPacketQueue();
    m_ulSyncSmoothingDepth = 0;
    m_ulBadSeqSampleCount = 0;
    m_ulGoodSeqSampleCount = 0;
    m_bIsScheduledCB = 0;
    m_bVS2BufferUnavailableOnLastBlt = FALSE;

    retVal = StartSchedulers();

    m_pMutex->Unlock();

#ifdef HELIX_FEATURE_VIDREND_BOOSTDECODE_ON_STARTUP
    if (m_pDecoderPump)
    {
       //m_pDecoderPump->Suspend(TRUE);
       //m_pDecoderPump->WaitForSuspend();  // Wait for decoder thread to start and suspends itself
       //m_pDecoderPump->Suspend(FALSE);
       m_pDecoderPump->Signal();   // Kick-out decoder pump from suspension
    }
#endif  // HELIX_FEATURE_VIDREND_BOOSTDECODE_ON_STARTUP

    return retVal;
}

/////////////////////////////////////////////////////////////////////////
//  Method:
//	IHXRenderer::OnBuffering
//  Purpose:
//	Called by client engine to inform the renderer that buffering
//	of data is occuring. The render is informed of the reason for
//	the buffering (start-up of stream, seek has occured, network
//	congestion, etc.), as well as percentage complete of the
//	buffering process.
//
STDMETHODIMP CVideoRenderer::OnBuffering(ULONG32 ulFlags, UINT16 unPercentComplete)
{
    HX_RESULT retVal = HXR_OK;

    m_pMutex->Lock();

    if (m_PlayState == Buffering)
    {
	if (IsBufferingComplete())
	{
	    EndBuffering();
	}
    }
    else if (m_PlayState == Playing)
    {
	m_PlayState = PlayStarting;
    }

    m_pMutex->Unlock();

    return retVal;
}

/////////////////////////////////////////////////////////////////////////
//  Method:
//	IHXRenderer::GetDisplayType
//  Purpose:
//	Called by client engine to ask the renderer for it's preferred
//	display type. When layout information is not present, the
//	renderer will be asked for it's prefered display type. Depending
//	on the display type a buffer of additional information may be
//	needed. This buffer could contain information about preferred
//	window size.
//
STDMETHODIMP CVideoRenderer::GetDisplayType(REF(HX_DISPLAY_TYPE) ulFlags,
					   REF(IHXBuffer*) pBuffer)
{
    ulFlags = HX_DISPLAY_WINDOW |
	      HX_DISPLAY_SUPPORTS_RESIZE |
	      HX_DISPLAY_SUPPORTS_FULLSCREEN |
	      HX_DISPLAY_SUPPORTS_VIDCONTROLS;

    return HXR_OK;
}

/************************************************************************
*	Method:
*	    IHXRenderer::OnEndofPackets
*	Purpose:
*	    Called by client engine to inform the renderer that all the
*	    packets have been delivered. However, if the user seeks before
*	    EndStream() is called, renderer may start getting packets again
*	    and the client engine will eventually call this function again.
*/
STDMETHODIMP CVideoRenderer::OnEndofPackets(void)
{
    if (m_pVideoFormat)
    {
	m_pVideoFormat->OnRawPacketsEnded();
    }

    return HXR_OK;
}


/************************************************************************
 *  IHXStatistics Methods
 */
/************************************************************************
 *  InitializeStatistics
 */
#define MAX_STAT_ENTRY_PAIRS	32
STDMETHODIMP CVideoRenderer::InitializeStatistics(UINT32 ulRegistryID)
{
    BOOL bCodecNameKnown = FALSE;
    char* pValue = NULL;
    HX_RESULT retVal = HXR_UNEXPECTED;

    m_ulRegistryID = ulRegistryID;

#if defined(HELIX_FEATURE_STATS)
    if (m_pVideoStats)
    {
	retVal = HXR_OK;
    }

    if (SUCCEEDED(retVal))
    {
	pValue = (char*) GetCodecName();
	if (pValue != NULL)
	{
	    ReportStat(VS_CODEC_NAME, pValue);
	    bCodecNameKnown = TRUE;
	}
    }

    if (SUCCEEDED(retVal))
    {
	pValue = (char*) GetRendererName();
	if (pValue != NULL)
	{
	    ReportStat(VS_REND_NAME, pValue);
	    // If Codec name is unknown, use a more generic renderer name
	    if (!bCodecNameKnown)
	    {
		ReportStat(VS_CODEC_NAME, pValue);
	    }
	}
    }

    if (SUCCEEDED(retVal))
    {
	pValue = (char*) GetCodecFourCC();
	if (pValue != NULL)
	{
	    ReportStat(VS_CODEC_4CC, pValue);
	}
    }

    if (SUCCEEDED(retVal))
    {
	ReportStat(VS_CURRENT_FRAMERATE, "0.0");
	ReportStat(VS_FRAMES_DISPLAYED, "100.0");
	ReportStat(VS_FRAMES_DROPPED, (INT32) 0);
	ReportStat(VS_FRAMES_LOST, (INT32) 0);
	ReportStat(VS_SURESTREAM, "FALSE");
	ReportStat(VS_IMAGE_WIDTH, (INT32) 0);
	ReportStat(VS_IMAGE_HEIGHT, (INT32) 0);
    }

    if (SUCCEEDED(retVal))
    {
	InitExtraStats();
    }

    if (SUCCEEDED(retVal))
    {
	retVal = m_pVideoStats->DisplayStats(m_ulRegistryID);
    }

    return retVal;
#else
    return HXR_NOTIMPL;
#endif /* HELIX_FEATURE_STATS */
}

/************************************************************************
 *  UpdateStatistics
 */
STDMETHODIMP CVideoRenderer::UpdateStatistics()
{
#if defined(HELIX_FEATURE_STATS)
    HX_RESULT retVal = HXR_UNEXPECTED;

    if (m_pVideoStats)
    {
	retVal = HXR_OK;
    }

    if (SUCCEEDED(retVal))
    {
	retVal = m_pVideoStats->DisplayStats(m_ulRegistryID);
    }

    return retVal;
#else
    return HXR_NOTIMPL;
#endif /* HELIX_FEATURE_STATS */
}


/************************************************************************
 *  IHXUntimedDecoder Methods
 */
#ifdef HELIX_FEATURE_VIDREND_UNTIMED_DECODE
STDMETHODIMP_(BOOL) CVideoRenderer::IsUntimedRendering()
{
    return m_bUntimedRendering;
}
STDMETHODIMP_(HX_RESULT) CVideoRenderer::SetUntimedRendering(BOOL bUntimedRendering)
{

    if( m_PlayState != Stopped && m_PlayState != PlayStarting )

    {

	return HXR_UNEXPECTED;

    }


    m_bUntimedRendering = bUntimedRendering;


    return HXR_OK;
}
#endif /* HELIX_FEATURE_VIDREND_UNTIMED_DECODE */

/************************************************************************
 *  IHXUpdateProperties Methods
 */
/************************************************************************
 *  UpdatePacketTimeOffset
 *	Call this method to update the timestamp offset of cached packets
 */
STDMETHODIMP CVideoRenderer::UpdatePacketTimeOffset(INT32 lTimeOffset)
{
    m_lTimeLineOffset -= lTimeOffset;

    return HXR_OK;
}


/************************************************************************
 *	Method:
 *	    IHXUpdateProperties::UpdatePlayTimes
 *	Purpose:
 *	    Call this method to update the playtime attributes
 */
STDMETHODIMP
CVideoRenderer::UpdatePlayTimes(IHXValues* pProps)
{
    return HXR_OK;
}


/************************************************************************
 *  IHXRenderTimeLine Methods
 */
/************************************************************************
 *  GetTimeLineValue
 */
STDMETHODIMP CVideoRenderer::GetTimeLineValue(REF(UINT32) ulTime)
{
    ulTime = ((ULONG32) -ComputeTimeAhead(0, 0));

    if (m_PlayState != Playing)
    {
        return HXR_TIMELINE_SUSPENDED;
    }

    return HXR_OK;
}


/************************************************************************
 *  IHXSiteUser Methods
 */
/************************************************************************
 *  AttachSite
 */
STDMETHODIMP CVideoRenderer::AttachSite(IHXSite* /*IN*/ pSite)
{
    if (m_pMISUSSite)
    {
	return HXR_UNEXPECTED;
    }

    m_bSiteAttached = TRUE;

    m_pMISUSSite = pSite;
    m_pMISUSSite->AddRef();

    // for sync
    IHXInterruptSafe* pIHXInterruptSafe = NULL;

    if (HXR_OK == m_pMISUSSite->QueryInterface(IID_IHXInterruptSafe,
					       (void**)&pIHXInterruptSafe))
    {
	// Get the pref to use the optimized scheduler or not
	BOOL bUseOptimized = TRUE;
	IHXBuffer* pPrefBuffer;

	if( m_pPreferences &&
            m_pPreferences->ReadPref("UseOptimizedScheduler",
		pPrefBuffer) == HXR_OK)
	{
	    bUseOptimized = *(pPrefBuffer->GetBuffer()) == '1';
	    HX_RELEASE(pPrefBuffer);
	}

	if (pIHXInterruptSafe->IsInterruptSafe() && bUseOptimized)
	{
	    HX_RELEASE(m_pOptimizedScheduler);
	    if (HXR_OK !=
		    m_pContext->QueryInterface(IID_IHXOptimizedScheduler,
		    (void **) &m_pOptimizedScheduler))
	    {
		// just for good luck
		m_pOptimizedScheduler = NULL;
	    }
	}
    }
    HX_RELEASE(pIHXInterruptSafe);

#ifdef HELIX_FEATURE_VIDREND_OPTIMIZEDVIDEO
    // Get Run Configuration
    // Use of VideoSurface2
    if (m_pPreferences)
    {
	ReadPrefBOOL(m_pPreferences, "VideoBoost\\NoFlip", m_bTryVideoSurface2);
    }

    // Use of OS Granule Boosting
    if (m_pPreferences)
    {
	ReadPrefBOOL(m_pPreferences, "VideoBoost\\NoOSGranuleBoost", m_bOSGranuleBoost);
	m_bOSGranuleBoostVS2 = m_bOSGranuleBoost;
    }

    // Hardware buffer count to request from VideoSurface2
    if (m_bTryVideoSurface2 && m_pPreferences)
    {
	ReadPrefINT32(m_pPreferences, "VideoBoost\\InitialHSCount", m_ulConfigHWBufCount);
    }

#endif	// HELIX_FEATURE_VIDREND_OPTIMIZEDVIDEO

    /*
     * This is the best time to set the size of the site, we
     * know for example the the header has already been received
     * at this point.
     *
     * In most display renderers, you will store size information
     * in your stream header. In this example, we assume a specific
     * size, but we will initialize that size here as if it had
     * come from our header.
     *
     */
    SetupBitmapDefaults(m_pHeader, m_BitmapInfoHeader);
    FormatAndSetViewFrame(m_pClipRect,
			  m_BitmapInfoHeader,
			  m_rViewRect);

    m_bBitmapSet = ((m_BitmapInfoHeader.biWidth > 0) &&
		    (m_BitmapInfoHeader.biHeight > 0));

    return HXR_OK;
}


STDMETHODIMP
CVideoRenderer::DetachSite()
{
    m_bSiteAttached = FALSE;

    HX_RELEASE(m_pMISUSSite);

    // We're done with these...
    if (m_pMISUS)
    {
	m_pMISUS->ReleaseSingleSiteUser();
    }

    HX_RELEASE(m_pMISUS);

    return HXR_OK;
}

STDMETHODIMP_(BOOL)
CVideoRenderer::NeedsWindowedSites()
{
    return FALSE;
};

STDMETHODIMP
CVideoRenderer::HandleEvent(HXxEvent* /*IN*/ pEvent)
{
    HX_RESULT retVal = HXR_OK;

    pEvent->handled = FALSE;
    pEvent->result  = 0;

    switch (pEvent->event)
    {
    case HX_SURFACE_UPDATE:
	m_pVSMutex->Lock();
	retVal = UpdateDisplay(pEvent, TRUE);
	m_pVSMutex->Unlock();
	break;

#if defined(HELIX_FEATURE_VIDREND_OPTIMIZEDVIDEO)
    case HX_SURFACE_MODE_CHANGE:
	switch ((int) pEvent->param2)
	{
	case HX_VIDEOSURFACE1_RECOMMENDED:
	    pEvent->result = SwitchToVideoSurface1();

	    if (SUCCEEDED(pEvent->result))
	    {
		pEvent->handled = TRUE;
	    }
	    break;

	case HX_VIDEOSURFACE1_NOT_RECOMMENDED:
	    pEvent->result = SwitchToVideoSurface2();

	    if (SUCCEEDED(pEvent->result))
	    {
		pEvent->handled = TRUE;
	    }
	    break;

	default:
	    HX_ASSERT(FALSE);
	    break;
	}
	break;

⌨️ 快捷键说明

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