Example #1
0
        ////////////////////////////////////////////////////////////////////////////////////////
        //  Name: CPlayer::Skip (Public)
        //  Description:
        //      Skips to the specified segment in the sequencer source
        //  Parameter:
        //      SegmentID: [in] The segment identifier
        ///////////////////////////////////////////////////////////////////////////////////////////
        public int Skip(int SegmentID)
        {
            Debug.WriteLine("\nCPlayer::Skip");

            int hr = 0;

            PropVariant var = new PropVariant();

            try
            {
                hr = m_pMediaSession.Stop();
                MFError.ThrowExceptionForHR(hr);

                hr = MFExtern.MFCreateSequencerSegmentOffset(SegmentID, 0, var);
                MFError.ThrowExceptionForHR(hr);

                hr = m_pMediaSession.Start(CLSID.MF_TIME_FORMAT_SEGMENT_OFFSET, var);
                MFError.ThrowExceptionForHR(hr);
            }
            catch (Exception e)
            {
                hr = Marshal.GetHRForException(e);
            }
            finally
            {
                var.Clear();
            }

            return hr;
        }
Example #2
0
        //-------------------------------------------------------------------
        // Name: SendMarkerEvent
        // Description: Saned a marker event.
        //
        // pMarker: Pointer to our custom IMarker interface, which holds
        //          the marker information.
        //-------------------------------------------------------------------
        void SendMarkerEvent(IMarker pMarker, FlushState fs)
        {
            int hrStatus = 0;  // Status code for marker event.

            if (fs == FlushState.DropSamples)
            {
                hrStatus = E_Abort;
            }

            PropVariant var = new PropVariant();

            // Get the context data.
            pMarker.GetContext(var);

            QueueEvent(MediaEventType.MEStreamSinkMarker, Guid.Empty, hrStatus, var);

            var.Clear();
        }
Example #3
0
        //////////////////////////////////////////////////////////////////////////
        //  Name: CPlayer::Invoke
        //  Description:
        //      Implementation of CAsyncCallback::Invoke.
        //      Callback for asynchronous BeginGetEvent method.
        //  Parameter:
        //      pAsyncResult: Pointer to the result.
        //
        /////////////////////////////////////////////////////////////////////////
        int IMFAsyncCallback.Invoke(IMFAsyncResult pAsyncResult)
        {
            MediaEventType eventType = MediaEventType.MEUnknown;
            IMFMediaEvent pEvent;
            PropVariant eventData = null;
            Exception excpt = null;
            int hr = S_Ok;

            try
            {
                int eventStatus = 0;             // Event status
                eventData = new PropVariant();                  // Event data

                // Get the event from the event queue.
                hr = m_pMediaSession.EndGetEvent(pAsyncResult, out pEvent);
                MFError.ThrowExceptionForHR(hr);

                // Get the event type.
                hr = pEvent.GetType(out eventType);
                MFError.ThrowExceptionForHR(hr);

                // Get the event data
                hr = pEvent.GetValue(eventData);
                MFError.ThrowExceptionForHR(hr);

                // Get the event status. If the operation that triggered the event
                // did not succeed, the status is a failure code.
                hr = pEvent.GetStatus(out eventStatus);
                MFError.ThrowExceptionForHR(hr);

                // Switch on the event type. Update the internal state of the CPlayer
                // as needed.

                switch (eventType)
                {
                    // Session events
                    case MediaEventType.MESessionStarted:
                        {
                            Debug.WriteLine(string.Format("{0}: MESessionStarted, Status: 0x{1:x}", eventType.ToString(), eventStatus));

                            m_State = PlayerState.Playing;
                            PostMessage(m_hWnd, Form1.WM_NOTIFY_APP, new IntPtr((int)eventType), new IntPtr((int)m_State));

                            break;
                        }
                    case MediaEventType.MESessionPaused:
                        {
                            Debug.WriteLine(string.Format("{0}: MESessionPaused, Status: 0x{1:x}", eventType.ToString(), eventStatus));

                            m_State = PlayerState.Paused;
                            PostMessage(m_hWnd, Form1.WM_NOTIFY_APP, new IntPtr((int)eventType), new IntPtr((int)m_State));

                            break;
                        }
                    case MediaEventType.MESessionStopped:
                        {
                            Debug.WriteLine(string.Format("{0}: MESessionStopped, Status: 0x{1:x}", eventType.ToString(), eventStatus));

                            m_State = PlayerState.Stopped;
                            PostMessage(m_hWnd, Form1.WM_NOTIFY_APP, new IntPtr((int)eventType), new IntPtr((int)m_State));

                            break;
                        }

                    case MediaEventType.MESessionTopologyStatus:
                        {
                            Debug.WriteLine(string.Format("{0}: MESessionTopologyStatus, Status: 0x{1:x}", eventType.ToString(), eventStatus));

                            int value = 0;

                            hr = pEvent.GetUINT32(MFAttributesClsid.MF_EVENT_TOPOLOGY_STATUS, out value);
                            MFError.ThrowExceptionForHR(hr);
                            int SegmentID = 0;
                            long ID;

                            //Get information about the new segment
                            IMFTopology pTopology;

                            pTopology = (IMFTopology)eventData.GetIUnknown();

                            try
                            {
                                hr = pTopology.GetTopologyID(out ID);
                                MFError.ThrowExceptionForHR(hr);
                                m_Segments.GetSegmentIDByTopoID(ID, out SegmentID);

                                topostat.iTopologyStatusType = (MFTopoStatus)value;
                                topostat.iSegmentId = SegmentID;

                                switch (topostat.iTopologyStatusType)
                                {
                                    case MFTopoStatus.StartedSource:
                                        m_ActiveSegment = SegmentID;
                                        break;

                                    case MFTopoStatus.Ended:
                                        m_ActiveSegment = -1;
                                        break;
                                }

                                GCHandle gc = GCHandle.Alloc(topostat);

                                PostMessage(m_hWnd, Form1.WM_NOTIFY_APP, new IntPtr((int)MediaEventType.MESessionTopologyStatus), GCHandle.ToIntPtr(gc));
                            }
                            finally
                            {
                                SafeRelease(pTopology);
                            }

                            break;
                        }
                    case MediaEventType.MENewPresentation:
                        {
                            Debug.WriteLine(string.Format("{0}: MENewPresentation, Status: 0x{1:x}", eventType.ToString(), eventStatus));

                            IMFPresentationDescriptor pPresentationDescriptor;

                            int SegmentId = 0;

                            pPresentationDescriptor = (IMFPresentationDescriptor)eventData.GetIUnknown();

                            try
                            {
                                //Queue the next segment on the media session
                                QueueNextSegment(pPresentationDescriptor, out SegmentId);
                            }
                            finally
                            {
                                SafeRelease(pPresentationDescriptor);
                            }

                            PostMessage(m_hWnd, Form1.WM_NOTIFY_APP, new IntPtr((int)eventType), new IntPtr(SegmentId));

                            break;
                        }

                    case MediaEventType.MEEndOfPresentation:
                        {
                            Debug.WriteLine(string.Format("{0}: MEEndOfPresentation, Status: 0x{1:x}", eventType.ToString(), eventStatus));

                            int value = 0;

                            try
                            {
                                hr = pEvent.GetUINT32(MFAttributesClsid.MF_EVENT_SOURCE_TOPOLOGY_CANCELED, out value);
                                MFError.ThrowExceptionForHR(hr);
                            }
                            catch { }

                            PostMessage(m_hWnd, Form1.WM_NOTIFY_APP, new IntPtr((int)eventType), new IntPtr(value));

                            break;
                        }

                    case MediaEventType.MEEndOfPresentationSegment:
                        {
                            Debug.WriteLine(string.Format("{0}: MEEndOfPresentationSegment, Status: 0x{1:x}", eventType.ToString(), eventStatus));

                            int value = 0;

                            try
                            {
                                hr = pEvent.GetUINT32(MFAttributesClsid.MF_EVENT_SOURCE_TOPOLOGY_CANCELED, out value);
                                MFError.ThrowExceptionForHR(hr);
                            }
                            catch { }

                            PostMessage(m_hWnd, Form1.WM_NOTIFY_APP, new IntPtr((int)eventType), new IntPtr(value));

                            break;
                        }

                    case MediaEventType.MESessionNotifyPresentationTime:
                        {
                            Debug.WriteLine(string.Format("{0}: MESessionNotifyPresentationTime, Status: 0x{1:x}", eventType.ToString(), eventStatus));

                            HandleNotifyPresentationTime(pEvent);
                            break;
                        }
                    case MediaEventType.MESessionClosed:
                        {
                            Debug.WriteLine(string.Format("{0}: MESessionClosed, Status: 0x{1:x}", eventType.ToString(), eventStatus));

                            m_hCloseEvent.Set();

                            break;
                        }

                    default:
                        Debug.WriteLine(string.Format("{0}: Event", eventType.ToString()));
                        break;
                }

            }
            catch (Exception e)
            {
                excpt = e;
            }
            finally
            {
                if (eventData != null)
                {
                    eventData.Clear();
                }
            }

            // Request another event.
            if (eventType != MediaEventType.MESessionClosed)
            {
                hr = m_pMediaSession.BeginGetEvent(this, null);
                MFError.ThrowExceptionForHR(hr);
            }

            if (excpt == null)
            {
                hr = S_Ok;
            }
            else
            {
                hr = Marshal.GetHRForException(excpt);
            }

            return hr;
        }
Example #4
0
    ///////////////////////////////////////////////////////////////////////
    //  Name: Invoke
    //  Description:  Callback for asynchronous BeginGetEvent method.
    //
    //  pAsyncResult: Pointer to the result.
    /////////////////////////////////////////////////////////////////////////
    int IMFAsyncCallback.Invoke(IMFAsyncResult pAsyncResult)
    {
        // Make sure we *never* leave this entry point with an exception
        try
        {
            int hr;
            IMFMediaEvent pEvent;
            MediaEventType meType = MediaEventType.MEUnknown;  // Event type
            PropVariant varEventData = new PropVariant();	        // Event data

            // Get the event from the event queue.
            hr = m_pMEG.EndGetEvent(pAsyncResult, out pEvent);
            MFError.ThrowExceptionForHR(hr);

            // Get the event type.
            hr = pEvent.GetType(out meType);
            MFError.ThrowExceptionForHR(hr);

            // Get the event status. If the operation that triggered the event did
            // not succeed, the status is a failure code.
            hr = pEvent.GetStatus(out m_hrStatus);
            MFError.ThrowExceptionForHR(hr);

            if (m_hrStatus == 862022) // NS_S_DRM_MONITOR_CANCELLED
            {
                m_hrStatus = MFError.MF_E_OPERATION_CANCELLED;
                m_state = Enabler.Complete;
            }

            // Get the event data.
            hr = pEvent.GetValue(varEventData);
            MFError.ThrowExceptionForHR(hr);

            // For the MEEnablerCompleted action, notify the application.
            // Otherwise, request another event.
            Debug.WriteLine(string.Format("Content enabler event: {0}", meType.ToString()));

            if (meType == MediaEventType.MEEnablerCompleted)
            {
                PostMessage(m_hwnd, WM_APP_CONTENT_ENABLER, IntPtr.Zero, IntPtr.Zero);
            }
            else
            {
                if (meType == MediaEventType.MEEnablerProgress)
                {
                    if (varEventData.GetVariantType() == PropVariant.VariantType.String)
                    {
                        Debug.WriteLine(string.Format("Progress: {0}", varEventData.GetString()));
                    }
                }
                hr = m_pMEG.BeginGetEvent(this, null);
                MFError.ThrowExceptionForHR(hr);
            }

            // Clean up.
            varEventData.Clear();
            SafeRelease(pEvent);

            return S_Ok;
        }
        catch (Exception e)
        {
            return Marshal.GetHRForException(e);
        }
    }
        public void Copy(PropVariant pval)
        {
            if (pval == null)
            {
                throw new Exception("Null PropVariant sent to Copy");
            }

            pval.Clear();

            PropVariantCopy(pval, this);
        }
        public IntPtr MarshalManagedToNative(object managedObj)
        {
            IntPtr p;

            // Cast the object back to a PropVariant
            m_prop = managedObj as PropVariant;

            if (m_prop != null)
            {
                // Release any memory currently allocated
                m_prop.Clear();

                // Create an appropriately sized buffer, blank it, and send it to
                // the marshaler to make the COM call with.
                int iSize = GetNativeDataSize();
                p = Marshal.AllocCoTaskMem(iSize);

                if (IntPtr.Size == 4)
                {
                    Marshal.WriteInt64(p, 0);
                    Marshal.WriteInt64(p, 8, 0);
                }
                else
                {
                    Marshal.WriteInt64(p, 0);
                    Marshal.WriteInt64(p, 8, 0);
                    Marshal.WriteInt64(p, 16, 0);
                }
            }
            else
            {
                p = IntPtr.Zero;
            }

            return p;
        }
Example #7
0
        //-------------------------------------------------------------------
        // Name: Start
        // Description: Switches to running state.
        //-------------------------------------------------------------------
        public int Start(
           IMFPresentationDescriptor pPresentationDescriptor,
           Guid pguidTimeFormat,
           ConstPropVariant pvarStartPosition
           )
        {
            // Make sure we *never* leave this entry point with an exception
            try
            {
                int hr;
                m_Log.WriteLine("-Start");

                lock (this)
                {
                    PropVariant var;
                    long llStartOffset = 0;
                    bool bIsSeek = false;
                    bool bIsRestartFromCurrentPosition = false;

                    // Fail if the source is shut down.
                    CheckShutdown();

                    // Check parameters.
                    // Start position and presentation descriptor cannot be null.
                    if (pPresentationDescriptor == null) // pvarStartPosition == null ||
                    {
                        throw new COMException("null presentation descriptor", E_InvalidArgument);
                    }

                    // Check the time format. Must be "reference time" units.
                    if ((pguidTimeFormat != null) && (pguidTimeFormat != Guid.Empty))
                    {
                        // Unrecognized time format GUID.
                        throw new COMException("unrecognized time format guid", MFError.MF_E_UNSUPPORTED_TIME_FORMAT);
                    }

                    // Check the start position.
                    if ((pvarStartPosition == null) || (pvarStartPosition.GetMFAttributeType() == MFAttributeType.None))
                    {
                        // Start position is "current position".
                        // For stopped, that means 0. Otherwise, use the current position.
                        if (m_state == State.Stopped)
                        {
                            llStartOffset = 0;
                        }
                        else
                        {
                            llStartOffset = GetCurrentPosition();
                            bIsRestartFromCurrentPosition = true;
                        }
                    }
                    else if (pvarStartPosition.GetMFAttributeType() == MFAttributeType.Uint64)
                    {
                        // Start position is given in pvarStartPosition in 100-ns units.
                        llStartOffset = (long)pvarStartPosition;

                        if (m_state != State.Stopped)
                        {
                            // Source is running or paused, so this is a seek.
                            bIsSeek = true;
                        }
                    }
                    else
                    {
                        // We don't support this time format.
                        throw new COMException("We don't support this time format", MFError.MF_E_UNSUPPORTED_TIME_FORMAT);
                    }

                    // Validate the caller's presentation descriptor.
                    ValidatePresentationDescriptor(pPresentationDescriptor);

                    // Sends the MENewStream or MEUpdatedStream event.
                    QueueNewStreamEvent(pPresentationDescriptor);

                    // Notify the stream of the new start time.
                    m_pStream.SetPosition(llStartOffset);

                    // Send Started or Seeked events. We will send them
                    // 1. from the media source
                    // 2. from each stream

                    var = new PropVariant(llStartOffset);

                    // (1) Send the source event.
                    if (bIsSeek)
                    {
                        QueueEvent(MediaEventType.MESourceSeeked, Guid.Empty, S_Ok, var);
                    }
                    else
                    {
                        // For starting, if we are RESTARTING from the current position and our
                        // previous state was running/paused, then we need to add the
                        // MF_EVENT_SOURCE_ACTUAL_START attribute to the event. This requires
                        // creating the event object first.

                        IMFMediaEvent pEvent = null;

                        // Create the event.
                        hr = MFExtern.MFCreateMediaEvent(
                            MediaEventType.MESourceStarted,
                            Guid.Empty,
                            S_Ok,
                            var,
                            out pEvent
                            );
                        MFError.ThrowExceptionForHR(hr);

                        // For restarts, set the actual start time as an attribute.
                        if (bIsRestartFromCurrentPosition)
                        {
                            hr = pEvent.SetUINT64(MFAttributesClsid.MF_EVENT_SOURCE_ACTUAL_START, llStartOffset);
                            MFError.ThrowExceptionForHR(hr);
                        }

                        // Now  queue the event.
                        hr = m_pEventQueue.QueueEvent(pEvent);
                        MFError.ThrowExceptionForHR(hr);

                        //SAFE_RELEASE(pEvent);
                    }

                    // 2. Send the stream event.
                    if (m_pStream != null)
                    {
                        if (bIsSeek)
                        {
                            m_pStream.QueueEvent(MediaEventType.MEStreamSeeked, Guid.Empty, S_Ok, var);
                        }
                        else
                        {
                            m_pStream.QueueEvent(MediaEventType.MEStreamStarted, Guid.Empty, S_Ok, var);
                        }
                    }

                    // Update our state.
                    m_state = State.Started;

                    // NOTE: If this method were implemented as an asynchronous operation
                    // and the operation Failed asynchronously, the media source would need
                    // to send an MESourceStarted event with the failure code. For this
                    // sample, all operations are synchronous (which is allowed), so any
                    // failures are also synchronous.

                    var.Clear();
                }
                return S_Ok;
            }
            catch (Exception e)
            {
                return Marshal.GetHRForException(e);
            }
        }