protected void StartPlayback() { HResult hr = m_pSession.Start(Guid.Empty, new PropVariant()); if (hr == HResult.S_OK) { mPlayPauseBtn.IsEnabled = true; mImageBtn.Source = new BitmapImage(new Uri("pack://application:,,,/WPFMediaFoundationPlayer;component/Images/pause.png", UriKind.Absolute)); mIsPlaying = true; mPresentationClock = null; m_pSession.GetClock(out mPresentationClock); mTickTimer.Start(); mIsSeek = false; } MFError.ThrowExceptionForHR(hr); //m_pSession. }
public void StartScheduler(IMFClock pClock) { if (m_bSchedulerThread != false) { throw new COMException("Scheduler already started", (int)HResult.E_UNEXPECTED); } m_pClock = pClock; // Set a high the timer resolution (ie, short timer period). timeBeginPeriod(1); // Create an event to wait for the thread to start. m_hThreadReadyEvent = new AutoResetEvent(false); try { // Use the c# threadpool to avoid creating a thread // when streaming begins ThreadPool.QueueUserWorkItem(new WaitCallback(SchedulerThreadProcPrivate)); m_hThreadReadyEvent.WaitOne(SCHEDULER_TIMEOUT, false); m_bSchedulerThread = true; } finally { // Regardless success/failure, we are done using the "thread ready" event. m_hThreadReadyEvent.Close(); m_hThreadReadyEvent = null; } }
/// <summary> /// Retrieves the current state of the clock. /// </summary> /// <param name="clock">A valid IMFClock instance.</param> /// <param name="clockState">Receives the clock state</param> /// <returns>If this function succeeds, it returns the S_OK member. Otherwise, it returns another HResult's member that describe the error.</returns> public static HResult GetState(this IMFClock clock, out MFClockState clockState) { if (clock == null) { throw new ArgumentNullException("clock"); } return(clock.GetState(0, out clockState)); }
private void GetInterface() { IMFPresentationClock pc; int hr = MFExtern.MFCreatePresentationClock(out pc); MFError.ThrowExceptionForHR(hr); m_c = pc as IMFClock; IMFMediaSession ms; hr = MFExtern.MFCreateMediaSession(null, out ms); MFError.ThrowExceptionForHR(hr); hr = ms.GetClock(out m_c); MFError.ThrowExceptionForHR(hr); }
/// <summary> /// Retrieves the last clock time that was correlated with system time. /// </summary> /// <param name="clock">A valid IMFClock instance.</param> /// <param name="clockTime">Receives the last known clock time, in units of the clock's frequency.</param> /// <param name="systemTime">Receives the system time that corresponds to the clock time.</param> /// <returns>If this function succeeds, it returns the S_OK member. Otherwise, it returns another HResult's member that describe the error.</returns> public static HResult GetCorrelatedTime(this IMFClock clock, out long clockTime, out TimeSpan systemTime) { if (clock == null) { throw new ArgumentNullException("clock"); } long tmp; HResult hr = clock.GetCorrelatedTime(0, out clockTime, out tmp); systemTime = hr.Succeeded() ? TimeSpan.FromTicks(tmp) : default(TimeSpan); return(hr); }
public Scheduler(int iMaxSamples, D3DPresentEngine pCB) { if (pCB == null) { throw new COMException("Null D3DPresentEngine", MFError.MF_E_NOT_INITIALIZED); } m_ScheduledSamples = new Queue(iMaxSamples); m_EventQueue = new Queue(iMaxSamples * 2); m_pCB = pCB; m_pClock = null; m_bSchedulerThread = false; m_hThreadReadyEvent = null; m_hFlushEvent = new AutoResetEvent(false); m_hMsgEvent = new AutoResetEvent(false); m_fRate = 1.0f; m_LastSampleTime = 0; m_PerFrameInterval = 0; m_PerFrame_1_4th = 0; }
private long m_LastSampleTime; // Most recent sample time. #endregion public Scheduler(int iMaxSamples, D3DPresentEngine pCB) { if (pCB == null) { throw new COMException("Null D3DPresentEngine", (int)HResult.MF_E_NOT_INITIALIZED); } m_ScheduledSamples = new Queue(iMaxSamples); m_EventQueue = new Queue(iMaxSamples * 2); m_pCB = pCB; m_pClock = null; m_bSchedulerThread = false; m_hThreadReadyEvent = null; m_hFlushEvent = new AutoResetEvent(false); m_hMsgEvent = new AutoResetEvent(false); m_fRate = 1.0f; m_LastSampleTime = 0; m_PerFrameInterval = 0; m_PerFrame_1_4th = 0; }
protected bool IsSampleTimePassed(IMFClock pClock, IMFSample pSample) { Debug.Assert(pClock != null); Debug.Assert(pSample != null); if (pSample == null || pClock == null) { throw new COMException("IsSampleTimePassed", E_Pointer); } int hr; bool bRet = false; long hnsTimeNow = 0; long hnsSystemTime = 0; long hnsSampleStart = 0; long hnsSampleDuration = 0; // The sample might lack a time-stamp or a duration, and the // clock might not report a time. try { hr = pClock.GetCorrelatedTime(0, out hnsTimeNow, out hnsSystemTime); MFError.ThrowExceptionForHR(hr); hr = pSample.GetSampleTime(out hnsSampleStart); MFError.ThrowExceptionForHR(hr); hr = pSample.GetSampleDuration(out hnsSampleDuration); MFError.ThrowExceptionForHR(hr); if (hnsSampleStart + hnsSampleDuration < hnsTimeNow) { bRet = true; } } catch { } return bRet; }
public int ReleaseServicePointers() { // Make sure we *never* leave this entry point with an exception try { TRACE(("ReleaseServicePointers")); // Enter the shut-down state. { lock (this) { m_RenderState = RenderState.Shutdown; } } // Flush any samples that were scheduled. Flush(); // Clear the media type and release related resources (surfaces, etc). SetMediaType(null); // Release all services that were acquired from InitServicePointers. SafeRelease(m_pClock); m_pClock = null; SafeRelease(m_pMixer); m_pMixer = null; SafeRelease(m_h2); m_h2 = null; m_pMediaEventSink = null; // SafeRelease(m_pMediaEventSink); return S_Ok; } catch (Exception e) { return Marshal.GetHRForException(e); } }
public void StartScheduler(IMFClock pClock) { if (m_bSchedulerThread != false) { throw new COMException("Scheduler already started", E_Unexpected); } m_pClock = pClock; // Set a high the timer resolution (ie, short timer period). timeBeginPeriod(1); // Create an event to wait for the thread to start. m_hThreadReadyEvent = new AutoResetEvent(false); try { // Use the c# threadpool to avoid creating a thread // when streaming begins ThreadPool.QueueUserWorkItem(new WaitCallback(SchedulerThreadProcPrivate)); m_hThreadReadyEvent.WaitOne(SCHEDULER_TIMEOUT, false); m_bSchedulerThread = true; } finally { // Regardless success/failure, we are done using the "thread ready" event. m_hThreadReadyEvent.Close(); m_hThreadReadyEvent = null; } }
public override void Dispose() { base.Dispose(); if (m_DeviceManager != null) { Marshal.ReleaseComObject(m_DeviceManager); m_DeviceManager = null; } m_pClock = null; if (m_pMixer != IntPtr.Zero) { Marshal.Release(m_pMixer); m_pMixer = IntPtr.Zero; } m_pMediaEventSink = null; m_pMediaType = null; }
public int InitServicePointersImpl(IntPtr pLookup) { try { if (pLookup == IntPtr.Zero) return E_POINTER; HRESULT hr = S_OK; lock (m_ObjectLock) { // Do not allow initializing when playing or paused. if (IsActive()) return MFHelper.MF_E_INVALIDREQUEST; if (m_pMixer != IntPtr.Zero) { Marshal.Release(m_pMixer); m_pMixer = IntPtr.Zero; } m_pClock = null; m_pMediaEventSink = null; uint dwObjectCount; MFTopologyServiceLookup _lookUp = new MFTopologyServiceLookup(pLookup); if (hr.Succeeded) { // Ask for the clock. Optional, because the EVR might not have a clock. dwObjectCount = 1; IntPtr[] o = new IntPtr[dwObjectCount]; _lookUp.LookupService( MFServiceLookUpType.GLOBAL, 0, MFServices.MR_VIDEO_RENDER_SERVICE, typeof(IMFClock).GUID, o, ref dwObjectCount ); if (o[0] != IntPtr.Zero && dwObjectCount > 0) { m_pClock = (IMFClock)Marshal.GetObjectForIUnknown(o[0]); } // Ask for the mixer. (Required.) dwObjectCount = 1; hr = (HRESULT)_lookUp.LookupService( MFServiceLookUpType.GLOBAL, 0, MFServices.MR_VIDEO_MIXER_SERVICE, typeof(IMFTransform).GUID, o, ref dwObjectCount); hr.Assert(); if (o[0] != IntPtr.Zero && dwObjectCount > 0) { m_pMixer = o[0]; } hr = ConfigureMixer((IMFTransform)Marshal.GetObjectForIUnknown(m_pMixer)); hr.Assert(); if (hr.Failed) return hr; o[0] = IntPtr.Zero; // Ask for the EVR's event-sink interface. (Required.) dwObjectCount = 1; hr = (HRESULT)_lookUp.LookupService( MFServiceLookUpType.GLOBAL, 0, MFServices.MR_VIDEO_RENDER_SERVICE, typeof(IMediaEventSink).GUID, o, ref dwObjectCount); hr.Assert(); if (hr.Failed) return hr; if (o[0] != IntPtr.Zero && dwObjectCount > 0) { m_pMediaEventSink = new MediaEventSink(o[0]); } // Successfully initialized. Set the state to "stopped." m_RenderState = RENDER_STATE.RENDER_STATE_STOPPED; } _lookUp.Dispose(); } return hr; } catch (Exception _exception) { throw _exception; } }
public HRESULT StopScheduler() { if (m_SchedulerThread == null) { return S_OK; } // Ask the scheduler thread to exit. AppendEvent(ScheduleEvent.eTerminate); m_hSchedulerQuitEvent.Set(); m_SchedulerThread.Join(); m_pClock = null; m_SchedulerThread = null; m_hSchedulerQuitEvent = null; m_hThreadReadyEvent = null; m_hFlushEvent = null; lock (m_lock) { while (m_ScheduledSamples.Count > 0) { MFSample _sample = m_ScheduledSamples.Dequeue(); _sample.Free.Set(); } } ScheduleEvent _event; while (GetEvent(out _event)) { } // Restore the timer resolution. timeEndPeriod(1); return S_OK; }
public HRESULT StartScheduler(IMFClock pClock) { if (m_SchedulerThread != null) { return E_UNEXPECTED; } m_hSchedulerQuitEvent.Reset(); m_pClock = pClock; // Set a high the timer resolution (ie, short timer period). timeBeginPeriod(1); // Create an event to wait for the thread to start. m_hThreadReadyEvent = new AutoResetEvent(false); // Create an event to wait for flush commands to complete. m_hFlushEvent = new AutoResetEvent(false); m_SchedulerThread = new Thread(new ParameterizedThreadStart(SchedulerThreadProc)); m_SchedulerThread.Start(this); // Wait for the thread to signal the "thread ready" event. int dwWait = WaitHandle.WaitAny(new WaitHandle[] { m_hThreadReadyEvent, m_hSchedulerQuitEvent }); // The thread terminated early for some reason. This is an error condition. if (0 != dwWait) { m_SchedulerThread.Join(); m_SchedulerThread = null; m_hThreadReadyEvent = null; m_hFlushEvent = null; return E_UNEXPECTED; } return S_OK; }
private void MediaEvent(uint eventType, int eventStatus) { if (eventStatus < 0) { this.mediaSession = null; // A session event reported an error if (this.EncodeError != null) { this.EncodeError(new COMException("Exception from HRESULT: 0x" + eventStatus.ToString("X", System.Globalization.NumberFormatInfo.InvariantInfo) + " (Media session event #" + eventType + ").", eventStatus)); } } else { switch (eventType) { case Consts.MESessionTopologySet: // Start playback from the start position MediaSessionStartPosition startPositionVar = new MediaSessionStartPosition((long)this.startPosition); this.mediaSession.Start(Guid.Empty, startPositionVar); break; case Consts.MESessionStarted: // Get the presentation clock IMFClock clock = null; this.mediaSession.GetClock(out clock); this.presentationClock = (IMFPresentationClock)clock; this.progressTimer.Start(); break; case Consts.MESessionEnded: // Close the media session. this.presentationClock = null; this.mediaSession.Close(); break; case Consts.MESessionStopped: // Close the media session. this.presentationClock = null; this.mediaSession.Close(); break; case Consts.MESessionClosed: // Stop the progress timer this.presentationClock = null; this.progressTimer.Stop(); // Shutdown the media source and session this.mediaSource.Shutdown(); this.mediaSession.Shutdown(); this.mediaSource = null; this.mediaSession = null; // Fire the EncodeCompleted event if (this.EncodeCompleted != null) { this.EncodeCompleted(this, null); } break; } } }
//public void InitServicePointers(IMFTopologyServiceLookup pLookup) public int InitServicePointers(IntPtr p1Lookup) { // Make sure we *never* leave this entry point with an exception try { TRACE(("InitServicePointers")); int hr; int dwObjectCount = 0; IMFTopologyServiceLookup pLookup = null; IHack h1 = (IHack)new Hack(); try { h1.Set(p1Lookup, typeof(IMFTopologyServiceLookup).GUID, true); pLookup = (IMFTopologyServiceLookup)h1; lock (this) { // Do not allow initializing when playing or paused. if (IsActive()) { throw new COMException("EVRCustomPresenter::InitServicePointers", MFError.MF_E_INVALIDREQUEST); } SafeRelease(m_pClock); m_pClock = null; SafeRelease(m_pMixer); m_pMixer = null; SafeRelease(m_h2); m_h2 = null; m_pMediaEventSink = null; // SafeRelease(m_pMediaEventSink); dwObjectCount = 1; object[] o = new object[1]; try { // Ask for the clock. Optional, because the EVR might not have a clock. hr = pLookup.LookupService( MFServiceLookupType.Global, // Not used. 0, // Reserved. MFServices.MR_VIDEO_RENDER_SERVICE, // Service to look up. typeof(IMFClock).GUID, // Interface to look up. o, ref dwObjectCount // Number of elements in the previous parameter. ); MFError.ThrowExceptionForHR(hr); m_pClock = (IMFClock)o[0]; } catch { } // Ask for the mixer. (Required.) dwObjectCount = 1; hr = pLookup.LookupService( MFServiceLookupType.Global, 0, MFServices.MR_VIDEO_MIXER_SERVICE, typeof(IMFTransform).GUID, o, ref dwObjectCount ); MFError.ThrowExceptionForHR(hr); m_pMixer = (IMFTransform)o[0]; // Make sure that we can work with this mixer. ConfigureMixer(m_pMixer); // Ask for the EVR's event-sink interface. (Required.) dwObjectCount = 1; IMFTopologyServiceLookupAlt pLookup2 = (IMFTopologyServiceLookupAlt)pLookup; IntPtr[] p2 = new IntPtr[1]; hr = pLookup2.LookupService( MFServiceLookupType.Global, 0, MFServices.MR_VIDEO_RENDER_SERVICE, typeof(IMediaEventSink).GUID, p2, ref dwObjectCount ); MFError.ThrowExceptionForHR(hr); m_h2 = (IHack)new Hack(); m_h2.Set(p2[0], typeof(IMediaEventSink).GUID, false); m_pMediaEventSink = (IMediaEventSink)m_h2; // Successfully initialized. Set the state to "stopped." m_RenderState = RenderState.Stopped; } } finally { SafeRelease(h1); } return S_Ok; } catch (Exception e) { return Marshal.GetHRForException(e); } }
protected int m_TokenCounter; // Counter. Incremented whenever we create new samples. #endregion Fields #region Constructors /// <summary> /// Constructor /// </summary> public EVRCustomPresenter() { if (System.Threading.Thread.CurrentThread.GetApartmentState() != System.Threading.ApartmentState.MTA) { throw new Exception("Unsupported theading model"); } m_iDiscarded = 0; m_pClock = null; m_pMixer = null; m_pMediaEventSink = null; m_h2 = null; m_pMediaType = null; m_bSampleNotify = false; m_bRepaint = false; m_bEndStreaming = false; m_bPrerolled = false; m_RenderState = RenderState.Shutdown; m_fRate = 1.0f; m_TokenCounter = 0; m_pD3DPresentEngine = new D3DPresentEngine(); m_FrameStep = new FrameStep(); // Frame-stepping information. m_nrcSource = new MFVideoNormalizedRect(0.0f, 0.0f, 1.0f, 1.0f); m_scheduler = new Scheduler(D3DPresentEngine.PRESENTER_BUFFER_COUNT, m_pD3DPresentEngine); // Manages scheduling of samples. m_SamplePool = new SamplePool(D3DPresentEngine.PRESENTER_BUFFER_COUNT); // Pool of allocated samples. // Force load of mf.dll now, rather than when we try to start streaming DllCanUnloadNow(); }
public int ReleaseServicePointersImpl() { try { HRESULT hr = S_OK; // Enter the shut-down state. lock (m_ObjectLock) { m_RenderState = RENDER_STATE.RENDER_STATE_SHUTDOWN; } // Flush any samples that were scheduled. Flush(); // Clear the media type and release related resources (surfaces, etc). SetMediaType(null); // Release all services that were acquired from InitServicePointers. m_pClock = null; if (m_pMixer != IntPtr.Zero) { Marshal.Release(m_pMixer); m_pMixer = IntPtr.Zero; } m_pMediaEventSink = null; return hr; } catch (Exception _exception) { throw _exception; } }