📄 vidrend.cpp
字号:
} 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 CRealAudioRendererHX_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; if(HXR_OK == pHeader->GetPropertyULONG32("StreamVersion", ulStreamVersion)) { UINT32 ulMajorVersion = HX_GET_MAJOR_VERSION(ulStreamVersion); UINT32 ulMinorVersion = HX_GET_MINOR_VERSION(ulStreamVersion); ULONG32 ulThisMajorVersion = 0; ULONG32 ulThisMinorVersion = 0; GetStreamVersion(ulThisMajorVersion, ulThisMinorVersion); if((ulMajorVersion > ulThisMajorVersion) || ((ulMinorVersion > ulThisMinorVersion) && (ulMajorVersion == ulThisMajorVersion))) { bVersionOK = FALSE; } } if(bVersionOK && (HXR_OK == pHeader->GetPropertyULONG32("ContentVersion",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -