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.
        }
예제 #2
0
        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;
            }
        }
예제 #3
0
        /// <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));
        }
예제 #4
0
        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);
        }
예제 #5
0
        /// <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);
        }
예제 #6
0
        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;
        }
예제 #7
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;
        }
예제 #8
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;
        }
예제 #9
0
        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);
            }
        }
예제 #10
0
        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;
            }
        }
예제 #11
0
 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;
 }
예제 #12
0
        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;
            }
        }
예제 #13
0
            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;
            }
예제 #14
0
            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;
                }
            }
        }
예제 #16
0
        //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);
            }
        }
예제 #17
0
        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();
        }
예제 #18
0
        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;
            }
        }