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

📄 vidrend.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	delete m_pActiveVideoPacket;
	m_pActiveVideoPacket = NULL;
	m_ulActiveVideoTime = 0;
    }

    HX_RELEASE(m_pHeader);
    HX_RELEASE(m_pContext);
    HX_RELEASE(m_pCommonClassFactory);

    if (m_pVideoFormat)
    {
        m_pVideoFormat->Release();
        m_pVideoFormat = NULL;
    }

    HX_DELETE(m_pVSurf2InputBIH);
    HX_DELETE(m_pClipRect);
    HX_DELETE(m_pMutex);
    HX_DELETE(m_pBltMutex);
    HX_DELETE(m_pVSMutex);

    RemoveCallback(m_hPendingHandle);
    m_bPendingCallback = FALSE;

    HX_RELEASE(m_pOptimizedScheduler);
    HX_RELEASE(m_pScheduler);

    HX_RELEASE(m_pPreferences);
    HX_RELEASE(m_pRegistry);

    ClearBltPacketQueue();
    HX_DELETE(m_pBltPacketQueue);

    HX_RELEASE(m_pResizeCB);

#if defined(HELIX_FEATURE_STATS)
    HX_DELETE(m_pVideoStats);
#endif /* HELIX_FEATURE_STATS */
}


/************************************************************************
 *  IHXPlugin Methods
 */
/************************************************************************
 *  Method:
 *    IHXPlugin::InitPlugin
 *  Purpose:
 *    Initializes the plugin for use. This interface must always be
 *    called before any other method is called. This is primarily needed
 *    so that the plugin can have access to the context for creation of
 *    IHXBuffers and IMalloc.
 */
STDMETHODIMP CVideoRenderer::InitPlugin(IUnknown* /*IN*/ pContext)
{
    HX_RESULT retVal = HXR_OK;

    HX_ASSERT(pContext);

    m_pContext = pContext;
    m_pContext->AddRef();

    retVal = m_pContext->QueryInterface(IID_IHXCommonClassFactory,
					(void**) &m_pCommonClassFactory);

    if (SUCCEEDED(retVal))
    {
	m_pContext->QueryInterface(IID_IHXPreferences,
                                   (void**) &m_pPreferences);
    }

    m_pContext->QueryInterface(IID_IHXRegistry, (void**) &m_pRegistry);

    if (SUCCEEDED(retVal))
    {
	retVal = m_pContext->QueryInterface(IID_IHXScheduler,
					    (void **) &m_pScheduler);
    }

    if (SUCCEEDED(retVal) && !m_pMutex)
    {
#ifdef THREADS_SUPPORTED
	retVal = HXMutex::MakeMutex(m_pMutex);
#else  // THREADS_SUPPORTED
	retVal = HXMutex::MakeStubMutex(m_pMutex);
#endif  // THREADS_SUPPORTED
    }

    if (SUCCEEDED(retVal) && !m_pBltMutex)
    {
#ifdef THREADS_SUPPORTED
	retVal = HXMutex::MakeMutex(m_pBltMutex);
#else  // THREADS_SUPPORTED
	retVal = HXMutex::MakeStubMutex(m_pBltMutex);
#endif  // THREADS_SUPPORTED
    }

    if (SUCCEEDED(retVal) && !m_pVSMutex)
    {
#ifdef THREADS_SUPPORTED
	retVal = HXMutex::MakeMutex(m_pVSMutex);
#else  // THREADS_SUPPORTED
	retVal = HXMutex::MakeStubMutex(m_pVSMutex);
#endif  // THREADS_SUPPORTED
    }

#if defined(HELIX_FEATURE_STATS)
    if (SUCCEEDED(retVal))
    {
	m_pVideoStats = new CVideoStatistics(m_pContext,
					     VIDEO_STAT_INTERVAL_COUNT);

	retVal = HXR_OUTOFMEMORY;
	if (m_pVideoStats)
	{
	    retVal = HXR_OK;
	}
    }
#endif /* HELIX_FEATURE_STATS */

    if (FAILED(retVal))
    {
	HX_RELEASE(m_pCommonClassFactory);
	HX_RELEASE(m_pPreferences);
	HX_RELEASE(m_pRegistry);
	HX_RELEASE(m_pScheduler);
    }

    return retVal;
}

/************************************************************************
 *  Method:
 *    IHXPlugin::GetPluginInfo
 *  Purpose:
 *    Returns the basic information about this plugin. Including:
 *
 *    bLoadMultiple	whether or not this plugin DLL can be loaded
 *			multiple times. All File Formats must set
 *			this value to TRUE.
 *    pDescription	which is used in about UIs (can be NULL)
 *    pCopyright	which is used in about UIs (can be NULL)
 *    pMoreInfoURL	which is used in about UIs (can be NULL)
 */
STDMETHODIMP CVideoRenderer::GetPluginInfo
(
   REF(BOOL)        /*OUT*/ bLoadMultiple,
   REF(const char*) /*OUT*/ pDescription,
   REF(const char*) /*OUT*/ pCopyright,
   REF(const char*) /*OUT*/ pMoreInfoURL,
   REF(ULONG32)     /*OUT*/ ulVersionNumber
)
{
    bLoadMultiple = TRUE;   // Must be true for file formats.

    pDescription    = zm_pDescription;
    pCopyright	    = zm_pCopyright;
    pMoreInfoURL    = zm_pMoreInfoURL;
    ulVersionNumber = TARVER_ULONG32_VERSION;

    return HXR_OK;
}

/************************************************************************
 *  Method:
 *    IHXPlugin::GetRendererInfo
 *  Purpose:
 *    If this object is a file format object this method returns
 *    information vital to the instantiation of file format plugins.
 *    If this object is not a file format object, it should return
 *    HXR_UNEXPECTED.
 */
STDMETHODIMP CVideoRenderer::GetRendererInfo
(
 REF(const char**) /*OUT*/ pStreamMimeTypes,
 REF(UINT32)      /*OUT*/ unInitialGranularity
)
{
    pStreamMimeTypes = (const char**) zm_pStreamMimeTypes;
    unInitialGranularity = SYNC_INTERVAL;
    return HXR_OK;
}




/************************************************************************
 *  IHXRenderer Methods
 */
/////////////////////////////////////////////////////////////////////////
//  Method:
//		IHXRenderer::StartStream
//  Purpose:
//		Called by client engine to inform the renderer of the stream it
//		will be rendering. The stream interface can provide access to
//		its source or player. This method also provides access to the
//		primary client controller interface.
//
STDMETHODIMP CVideoRenderer::StartStream(IHXStream* pStream,
					   IHXPlayer* pPlayer)
{
    m_pStream  = pStream;

    if (m_pStream)
    {
	m_pStream->AddRef();
    }

#if defined (HELIX_FEATURE_MISU)
    m_pCommonClassFactory->CreateInstance(
	CLSID_IHXMultiInstanceSiteUserSupplier,
	(void**) &m_pMISUS);

    if (m_pMISUS)
    {
	m_pMISUS->SetSingleSiteUser((IUnknown*)(IHXSiteUser*) this);
    }
#endif //HELIX_FEATURE_MISU

    if (m_pStream)
    {
	IHXStreamSource* pSource = 0;
	if (m_pStream->GetSource(pSource) == HXR_OK)
	{
	    /* It is OK if the source does not support backchannel. Reasons:
	     *
	     * 1. This stream may not be coming from h261 fileformat.
	     *	  It may instead be merged into a container fileformat which
	     *	  may be does not support BackChannel.
	     *
	     * 2. The protocol used to serve this stream may not support
	     *	  BackChannel.
	     */
	    pSource->QueryInterface(IID_IHXBackChannel, (void**) &m_pBackChannel);

	    pSource->Release();
	}
    }

    return HXR_OK;
}

/////////////////////////////////////////////////////////////////////////
//  Method:
//		IHXRenderer::EndStream
//  Purpose:
//		Called by client engine to inform the renderer that the stream
//		is was rendering is closed.
//
STDMETHODIMP CVideoRenderer::EndStream()
{
    // Stop Blts by changing state
    m_pMutex->Lock();
    m_PlayState = Stopped;
    m_pMutex->Unlock();

    // Stop Decoder
    if (m_pDecoderPump)
    {
	m_pDecoderPump->Stop();
	m_pDecoderPump->Signal();
	m_pDecoderPump->WaitForStop();
	m_pDecoderPump->Release();
	m_pDecoderPump = NULL;
    }

    // Wait for Blt if in progress and then flush packet queues
    DisplayMutex_Lock();
    if (m_pVideoFormat)
    {
	m_pVideoFormat->Reset();
    }
    DisplayMutex_Unlock();

    // IHXStream, IHXSourceStream or IHXBackChannel
    // cannot be used after EndStream has been called.
    HX_RELEASE(m_pStream);
    HX_RELEASE(m_pBackChannel);

    // Stop Bltr pump
    if (m_pBltrPump)
    {
	m_pBltrPump->Stop();
	m_pBltrPump->Signal();
    }

    // Flush Optimized Video Surface if used
    if (m_bUseVideoSurface2 && m_pMISUSSite)
    {
	FlushVideoSurface2(m_pMISUSSite);
    }

    if (m_pBltrPump)
    {
	m_pBltrPump->WaitForStop();
	m_pBltrPump->Release();
	m_pBltrPump = NULL;
    }

    DisplayMutex_Lock();
    if (m_pVideoFormat)
    {
        m_pVideoFormat->Release();
        m_pVideoFormat = NULL;
    }
    DisplayMutex_Unlock();

#ifdef ENABLE_SYNC_TRACE
    DumpSyncEntries();
#endif	// ENABLE_SYNC_TRACE

#ifdef ENABLE_SCHED_TRACE
    DumpSchedEntries();
#endif	// ENABLE_SCHED_TRACE

#ifdef ENABLE_FETCH_TRACE
    DumpFetchEntries();
#endif	// ENABLE_FETCH_TRACE

#ifdef ENABLE_INPUT_TRACE
    DumpInputEntries();
#endif	// ENABLE_INPUT_TRACE

    return HXR_OK;
}

/////////////////////////////////////////////////////////////////////////
//  Method:
//		IHXRenderer::OnHeader
//  Purpose:
//		Called by client engine when a header for this renderer is
//		available. The header will arrive before any packets.
//
STDMETHODIMP CVideoRenderer::OnHeader(IHXValues* pHeader)
{
    HX_RESULT retVal = HXR_OK;

    HX_DELETE(m_pClipRect);

    // Keep this for later use...
    HX_RELEASE(m_pHeader);
    m_pHeader = pHeader;
    m_pHeader->AddRef();

    m_ulStreamBaseTime = 0;
    m_ulBaseTime = 0;
    m_ulTimeNormalizationOffset = 0;

    // check the stream versions
    m_pHeader->AddRef();
    retVal = CheckStreamVersions(m_pHeader);
    m_pHeader->Release();

#ifdef HELIX_FEATURE_QUICKTIME
    IHXBuffer* pSDPData = NULL;

    if (SUCCEEDED(retVal) &&
	SUCCEEDED(pHeader->GetPropertyCString("SDPData", pSDPData)))
    {
	char *pData = (char*) pSDPData->GetBuffer();
	IHXValues *pValues = NULL;

	if (pData &&
	    SUCCEEDED(SDPParseChunk(pData,
				    strlen(pData),
				    pValues,
				    m_pCommonClassFactory,
				    SDPCTX_Renderer)))
	{
	    ULONG32 ulLeft;
	    ULONG32 ulRight;
	    ULONG32 ulTop;
	    ULONG32 ulBottom;

	    if (SUCCEEDED(pValues->GetPropertyULONG32(
		    "ClipFrameLeft", ulLeft)) &&
		SUCCEEDED(pValues->GetPropertyULONG32(
		    "ClipFrameRight", ulRight)) &&
		SUCCEEDED(pValues->GetPropertyULONG32(
		    "ClipFrameTop", ulTop)) &&
		SUCCEEDED(pValues->GetPropertyULONG32(
		    "ClipFrameBottom", ulBottom)))
	    {
		retVal = HXR_OUTOFMEMORY;

		m_pClipRect = (HXxRect*) new HXxRect;
		if (m_pClipRect)
		{
		    m_pClipRect->left = (INT32) ulLeft;
		    m_pClipRect->right = (INT32) ulRight;
		    m_pClipRect->top = (INT32) ulTop;
		    m_pClipRect->bottom = (INT32) ulBottom;
		    retVal = HXR_OK;
		}
	    }
	}

	HX_RELEASE(pValues);
    }

    HX_RELEASE(pSDPData);
#endif	// HELIX_FEATURE_QUICKTIME

    if (SUCCEEDED(retVal))
    {
	m_pVideoFormat = CreateFormatObject(m_pHeader);

	retVal = HXR_OUTOFMEMORY;
	if (m_pVideoFormat)
	{
	    m_pVideoFormat->AddRef();
	    retVal = HXR_OK;
	}
    }

    if (SUCCEEDED(retVal))
    {
	retVal = m_pVideoFormat->Init(pHeader);
    }

    if (SUCCEEDED(retVal))
    {
	m_ulEarlyFrameTol = GetEarlyFrameTolerance();
	m_ulLateFrameTol = GetLateFrameTolerance();
	m_ulMaxOptimizedVideoLead = GetMaxOptimizedVideoLead();

	m_ulMaxSleepTime = GetMaxSleepTime();
	m_ulNoFramesPollingInterval = GetNoFramesPollingInterval();
	m_ulBltPacketQueueSize = GetBltPacketQueueSize();
	m_ulSyncGoalSmoothingDepth = GetSyncGoalSmoothingDepth();
	m_ulSpeedupGoalSmoothingDepth = GetSpeedupGoalSmoothingDepth();
	m_ulMaxBadSeqSamples = GetMaxBadSeqSamples();
    }

    // Setup preroll
    if (SUCCEEDED(retVal))
    {
	BOOL bSetNewPreroll = FALSE;
        m_ulPreroll = 0;
	ULONG32 ulMinPreroll = m_pVideoFormat->GetMinimumPreroll(pHeader);
	ULONG32 ulMaxPreroll = m_pVideoFormat->GetMaximumPreroll(pHeader);

        // Check that the stream header has a preroll value. If not...
	pHeader->GetPropertyULONG32("Preroll", m_ulPreroll);
	if (m_ulPreroll == 0)
	{
            // ... let's use default value.
	    m_ulPreroll = m_pVideoFormat->GetDefaultPreroll(pHeader);
	    bSetNewPreroll = TRUE;
	}
        else if( m_ulPreroll > ulMaxPreroll )
        {
            m_ulPreroll = ulMaxPreroll;
	    bSetNewPreroll = TRUE;
        }
	else if (m_ulPreroll < ulMinPreroll)
	{
	    m_ulPreroll = ulMinPreroll;
	    bSetNewPreroll = TRUE;
	}

	if (bSetNewPreroll)
	{
	    pHeader->SetPropertyULONG32("Preroll", m_ulPreroll);
	}
    }

    // Determine Average Bitrate
    if (SUCCEEDED(retVal))
    {
	if (FAILED(pHeader->GetPropertyULONG32("AvgBitRate", m_ulAvgBitRate)))
	{
	    m_ulAvgBitRate = 0;
	}
    }

    // Create Blt Queue
    if (SUCCEEDED(retVal))
    {
	m_pBltPacketQueue = new CRingBuffer(m_ulBltPacketQueueSize);

	retVal = HXR_OUTOFMEMORY;
	if (m_pBltPacketQueue)
	{
	    retVal = HXR_OK;
	}
    }

    return retVal;
}


/////////////////////////////////////////////////////////////////////////////
//  Method:
//	CVideoRenderer::CheckStreamVersions
//  copied from CRealAudioRenderer
HX_RESULT CVideoRenderer::CheckStreamVersions(IHXValues* pHeader)
{
    // check stream and content versions so an upgrade can
    // be called if necessary...
    HX_RESULT pnr = HXR_OK;

    BOOL bVersionOK = TRUE;

    UINT32 ulStreamVersion = 0;
    UINT32 ulContentVersion = 0;

⌨️ 快捷键说明

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