MediaPlayer.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / wpf / src / Core / CSharp / System / Windows / Media / MediaPlayer.cs / 1 / MediaPlayer.cs

                            //------------------------------------------------------------------------------ 
//  Microsoft Avalon
//  Copyright (c) Microsoft Corporation, 2003
//
//  File:       MediaPlayer.cs 
//
//----------------------------------------------------------------------------- 
using System; 
using System.Threading;
using System.Security; 
using System.Security.Permissions;
using System.Diagnostics;
using System.ComponentModel;
using MS.Internal; 
using MS.Internal.PresentationCore;                        // SecurityHelper
using MS.Win32; 
using System.Windows.Media.Animation; 
using System.Windows.Media;
using System.Windows.Media.Composition; 
using System.Windows.Threading;
using System.Windows.Navigation;
using System.Runtime.InteropServices;
using System.IO; 
using System.Security.AccessControl;//for semaphore access permissions
using System.Net; 
using Microsoft.Win32; 
using SR=MS.Internal.PresentationCore.SR;
using SRID=MS.Internal.PresentationCore.SRID; 
using UnsafeNativeMethods=MS.Win32.PresentationCore.UnsafeNativeMethods;

//
// Disable the warnings that C# emmits when it finds pragmas it does not recognize, this is to 
// get rid of false positive PreSharp warning
// 
#pragma warning disable 1634, 1691 

 
namespace System.Windows.Media
{
    #region MediaPlayer
 
    /// 
    /// MediaPlayer 
    /// Provides helper methods for media related tasks 
    /// 
    public class MediaPlayer : Animatable, DUCE.IResource 
    {
        #region Constructors and Finalizers

        ///  
        /// Constructor
        ///  
        ///  
        /// Critical - access unmanaged pointers (proxy), calls critical code, indirectly access arbitrary file resources
        /// PublicOK: The URI holds relative path which is resolved just before being passed to media player 
        /// 
        public MediaPlayer()
        {
        } 

        #endregion 
 
        #region Public Methods
 
        /// 
        /// Indicates whether the media element is currently buffering.
        /// 
        public bool IsBuffering 
        {
            get 
            { 
                ReadPreamble();
 
                return _mediaPlayerState.IsBuffering;
            }
        }
 
        /// 
        /// Indicates whether given media can be paused. 
        ///  
        public bool CanPause
        { 
            get
            {
                ReadPreamble();
 
                return _mediaPlayerState.CanPause;
            } 
        } 

        ///  
        /// Returns the download progress of the media.
        /// 
        public double DownloadProgress
        { 
            get
            { 
                ReadPreamble(); 

                return _mediaPlayerState.DownloadProgress; 
            }
        }

        ///  
        /// Returns the buffering progress of the media.
        ///  
        public double BufferingProgress 
        {
            get 
            {
                ReadPreamble();

                return _mediaPlayerState.BufferingProgress; 
            }
        } 
 
        /// 
        /// Returns the natural height of the video. 
        /// 
        public Int32 NaturalVideoHeight
        {
            get 
            {
                ReadPreamble(); 
 
                return _mediaPlayerState.NaturalVideoHeight;
            } 
        }

        /// 
        /// Returns the natural width the media. 
        /// 
        public Int32 NaturalVideoWidth 
        { 
            get
            { 
                ReadPreamble();

                return _mediaPlayerState.NaturalVideoWidth;
            } 
        }
 
        ///  
        /// Returns whether the given media has audio content.
        ///  
        public bool HasAudio
        {
            get
            { 
                ReadPreamble();
 
                return _mediaPlayerState.HasAudio; 
            }
        } 

        /// 
        /// Returns whether the given media has video content
        ///  
        public bool HasVideo
        { 
            get 
            {
                ReadPreamble(); 

                return _mediaPlayerState.HasVideo;
            }
        } 

        ///  
        /// Location of the media to play. Open opens the media, this property 
        /// allows the source that is currently playing to be retrieved.
        ///  
        public Uri Source
        {
            get
            { 
                ReadPreamble();
 
                return _mediaPlayerState.Source; 
            }
        } 

        /// 
        /// The volume of the currently playing media.
        ///  
        public double Volume
        { 
            get 
            {
                ReadPreamble(); 

                return _mediaPlayerState.Volume;
            }
 
            set
            { 
                WritePreamble(); 

                _mediaPlayerState.Volume = value; 
            }
        }

        ///  
        /// Returns the balance that the current media has been set to.
        ///  
        public double Balance 
        {
            get 
            {
                ReadPreamble();

                return _mediaPlayerState.Balance; 
            }
 
            set 
            {
                WritePreamble(); 

                _mediaPlayerState.Balance = value;
            }
        } 

        ///  
        /// Whether or not scrubbing is enabled 
        /// 
        public bool ScrubbingEnabled 
        {
            get
            {
                ReadPreamble(); 

                return _mediaPlayerState.ScrubbingEnabled; 
            } 

            set 
            {
                WritePreamble();

                _mediaPlayerState.ScrubbingEnabled = value; 
            }
        } 
 
        /// 
        /// Returns the whether the given media is muted and sets whether it is 
        /// muted.
        /// 
        public bool IsMuted
        { 
            get
            { 
                ReadPreamble(); 

                return _mediaPlayerState.IsMuted; 
            }

            set
            { 
                WritePreamble();
 
                _mediaPlayerState.IsMuted = value; 
            }
        } 

        /// 
        /// Returns the natural duration of the given media.
        ///  
        public Duration NaturalDuration
        { 
            get 
            {
                ReadPreamble(); 

                return _mediaPlayerState.NaturalDuration;
            }
        } 

        ///  
        /// Seek to specified position 
        /// 
        public TimeSpan Position 
        {
            set
            {
                WritePreamble(); 

                _mediaPlayerState.Position = value; 
            } 

            get 
            {
                ReadPreamble();

                return _mediaPlayerState.Position; 
            }
        } 
 
        /// 
        /// The current speed. This cannot be changed if a clock is controlling this player 
        /// 
        public double SpeedRatio
        {
            get 
            {
                ReadPreamble(); 
 
                return _mediaPlayerState.SpeedRatio;
            } 

            set
            {
                WritePreamble(); 

                _mediaPlayerState.SpeedRatio = value; 
            } 
        }
 
        #endregion

        #region EventHandlers
 
        /// 
        /// Raised when there is an error opening or playing media 
        ///  
        public event EventHandler MediaFailed
        { 
            add
            {
                WritePreamble();
 
                _mediaPlayerState.MediaFailed += value;
            } 
 
            remove
            { 
                WritePreamble();

                _mediaPlayerState.MediaFailed -= value;
            } 
        }
 
        ///  
        /// Raised when the media has been opened.
        ///  
        public event EventHandler MediaOpened
        {
            add
            { 
                WritePreamble();
 
                _mediaPlayerState.MediaOpened += value; 
            }
 
            remove
            {
                WritePreamble();
 
                _mediaPlayerState.MediaOpened -= value;
            } 
        } 

 
        /// 
        /// Raised when the media has finished.
        /// 
        public event EventHandler MediaEnded 
        {
            add 
            { 
                WritePreamble();
 
                _mediaPlayerState.MediaEnded += value;
            }

            remove 
            {
                WritePreamble(); 
 
                _mediaPlayerState.MediaEnded -= value;
            } 
        }


        ///  
        /// Raised when media begins buffering.
        ///  
        public event EventHandler BufferingStarted 
        {
            add 
            {
                WritePreamble();

                _mediaPlayerState.BufferingStarted += value; 
            }
 
            remove 
            {
                WritePreamble(); 

                _mediaPlayerState.BufferingStarted -= value;
            }
        } 

        ///  
        /// Raised when media finishes buffering. 
        /// 
        public event EventHandler BufferingEnded 
        {
            add
            {
                WritePreamble(); 

                _mediaPlayerState.BufferingEnded += value; 
            } 

            remove 
            {
                WritePreamble();

                _mediaPlayerState.BufferingEnded -= value; 
            }
        } 
 
        /// 
        /// Raised when a script command embedded in the media is encountered. 
        /// 
        public event EventHandler ScriptCommand
        {
            add 
            {
                WritePreamble(); 
 
                _mediaPlayerState.ScriptCommand += value;
            } 

            remove
            {
                WritePreamble(); 

                _mediaPlayerState.ScriptCommand -= value; 
            } 
        }
 
        #endregion

        #region Clock dependent properties and methods
 
        /// 
        /// The clock driving this instance of media 
        ///  
        public MediaClock Clock
        { 
            get
            {
                ReadPreamble();
 
                return _mediaPlayerState.Clock;
            } 
 
            set
            { 
                WritePreamble();

                _mediaPlayerState.SetClock(value, this);
            } 
        }
 
        ///  
        /// Open the media, at this point the underlying native resources are
        /// created. The media player cannot be controlled when it isn't opened. 
        /// 
        public
        void
        Open( 
            Uri      source
            ) 
        { 
            WritePreamble();
 
            _mediaPlayerState.Open(source);
        }

        ///  
        /// Begin playback. This operation is not allowed if a clock is
        /// controlling this player 
        ///  
        public void Play()
        { 
            WritePreamble();

            _mediaPlayerState.Play();
        } 

        ///  
        /// Halt playback at current position. This operation is not allowed if 
        /// a clock is controlling this player
        ///  
        public void Pause()
        {
            WritePreamble();
 
            _mediaPlayerState.Pause();
        } 
 
        /// 
        /// Halt playback and seek to the beginning of media. This operation is 
        /// not allowed if a clock is controlling this player
        /// 
        public void Stop()
        { 
            WritePreamble();
 
            _mediaPlayerState.Stop(); 
        }
 
        /// 
        /// Closes the underlying media. This de-allocates all of the native resources in
        /// the media. The mediaplayer can be opened again by calling the Open method.
        ///  
        public
        void 
        Close() 
        {
            WritePreamble(); 

            _mediaPlayerState.Close();
        }
 
        #endregion
 
        #region DUCE 

        ///  
        /// AddRefOnChannel
        /// 
        /// 
        /// Critical - calls critical code 
        /// 
        [SecurityCritical] 
        DUCE.ResourceHandle DUCE.IResource.AddRefOnChannel(DUCE.Channel channel) 
        {
            EnsureState(); 

            using (CompositionEngineLock.Acquire())
            {
                return AddRefOnChannelCore(channel); 
            }
        } 
 
        /// 
        /// AddRefOnChannelCore 
        /// 
        /// Channel
        /// 
        /// Critical - accesses unmanaged objects, and critical resources 
        /// 
        [SecurityCritical] 
        internal DUCE.ResourceHandle AddRefOnChannelCore(DUCE.Channel channel) 
        {
            // 
            // Create a media resource
            //
            if (_duceResource._duceResource.CreateOrAddRefOnChannel(channel, DUCE.ResourceType.TYPE_MEDIAPLAYER))
            { 
                //
                // By definition we need an update whenever our channel changes. 
                // 
                _needsUpdate = true;
 
                UpdateResource(
                    channel,
                    true);  // Don't need a channel since we just created the resource.
            } 

            return _duceResource._duceResource.GetHandle(channel); 
        } 

        ///  
        /// ReleaseOnChannel
        /// 
        void DUCE.IResource.ReleaseOnChannel(DUCE.Channel channel)
        { 
            EnsureState();
 
            using (CompositionEngineLock.Acquire()) 
            {
                ReleaseOnChannelCore(channel); 
            }
        }

        ///  
        /// ReleaseOnChannelCore
        ///  
        /// Channel 
        internal void ReleaseOnChannelCore(DUCE.Channel channel)
        { 
            Debug.Assert(_duceResource._duceResource.IsOnChannel(channel));

            _duceResource._duceResource.ReleaseOnChannel(channel);
 
            //
            // The media state could be holding onto a bitmap source on this channel too. 
            // 
            _mediaPlayerState.ReleaseOnChannel(channel);
        } 

        /// 
        /// GetHandle
        ///  
        DUCE.ResourceHandle DUCE.IResource.GetHandle(DUCE.Channel channel)
        { 
            EnsureState(); 

            using (CompositionEngineLock.Acquire()) 
            {
                return GetHandleCore(channel);
            }
        } 

        ///  
        /// GetHandleCore 
        /// 
        /// Channel 
        internal DUCE.ResourceHandle GetHandleCore(DUCE.Channel channel)
        {
            return _duceResource._duceResource.GetHandle(channel);
        } 

        int DUCE.IResource.GetChannelCount() 
        { 
            return _duceResource._duceResource.GetChannelCount();
        } 

        DUCE.Channel DUCE.IResource.GetChannel(int index)
        {
            return _duceResource._duceResource.GetChannel(index); 
        }
 
        #endregion 

        #region Animatable 

        /// 
        /// UpdateResource is called when we need to update our resource
        /// on a particular channel. 
        /// 
        /// Channel 
        /// Whether we know we are on the 
        /// channel
        internal override 
        void
        UpdateResource(
            DUCE.Channel channel,
            bool skipOnChannelCheck 
            )
        { 
            if (skipOnChannelCheck || _duceResource._duceResource.IsOnChannel(channel)) 
            {
                // 
                // Chain this up through the base always otherwise our next
                // registration won't work.
                //
                base.UpdateResource(channel, true); 

                // 
                // Only actually send this if we are dirty. 
                //
                if (_needsUpdate) 
                {
                    //
                    // Send a new resource update
                    // 
                    UpdateResourceInternal(channel);
                } 
            } 
        }
 
        #endregion

        #region Freezable
 
        /// 
        /// CreateInstanceCore must return the new instance of the object to be 
        /// created. 
        /// 
        protected override 
        Freezable
        CreateInstanceCore()
        {
            return new MediaPlayer(); 
        }
 
        ///  
        /// Clones the object, implemented as part of Freezable contract, must
        /// be chained to the base class. 
        /// 
        protected override
        void
        CloneCore( 
            Freezable       sourceFreezable
            ) 
        { 
            CloneCommon(sourceFreezable);
 
            base.CloneCore(sourceFreezable);
        }

        ///  
        /// Clones the current value of the object, implemented as part of
        /// Freezable contract. 
        ///  
        protected override
        void 
        CloneCurrentValueCore(
            Freezable       sourceFreezable
            )
        { 
            CloneCommon(sourceFreezable);
 
            base.CloneCurrentValueCore(sourceFreezable); 
        }
 
        /// 
        /// Returns the object as frozen, media state is not really ammenable
        /// to being frozen.
        ///  
        protected override
        void 
        GetAsFrozenCore( 
            Freezable       sourceFreezable
            ) 
        {
            CloneCommon(sourceFreezable);

            base.GetAsFrozenCore(sourceFreezable); 
        }
 
        // 
        // We don't need to implement FreezeCore and SetFreezableContextCore
        // because we don't really freeze our data. 
        //
        private
        void
        CloneCommon( 
            Freezable       sourceFreezable
            ) 
        { 
            MediaPlayer player = (MediaPlayer)sourceFreezable;
 
            //
            // For the first clone both source and destination
            // might not be initialized yet.
            // 
            player.EnsureState();
 
            _mediaPlayerState = player._mediaPlayerState; 
            _duceResource = player._duceResource;
        } 

        #endregion

        #region Private Methods 

        ///  
        /// Freezable forces us to have a new instance without parameters. However 
        /// Creating MediaPlayerState is expensive so we use EnsureState to make sure
        /// that media state is created if we are not cloned after instantiation. 
        /// 
        private
        void
        EnsureState() 
        {
            if (null == _mediaPlayerState) 
            { 
                _mediaPlayerState = new MediaPlayerState(this);
            } 
        }


        ///  
        /// Called before any read, ensures that the media player is called from only
        /// one thread. We also create our state if necessary at this point. 
        ///  
        protected new
        void 
        ReadPreamble()
        {
            base.ReadPreamble();
 
            EnsureState();
        } 
 
        /// 
        /// Called before a write to check whether the given object is frozen. 
        /// We also ensure that we have the media state initialized if this passes.
        /// 
        protected new
        void 
        WritePreamble()
        { 
            base.WritePreamble(); 

            EnsureState(); 
        }

        /// 
        /// Our event handler for receiving frame updates. When we get a new frame, 
        /// we cause an async resource update.
        ///  
        private 
        void
        OnNewFrame( 
            object      sender,
            EventArgs   args
            )
        { 
            _needsUpdate = true;
 
            // 
            // This means "call us back on the channel when the render pass happens"
            // 
            RegisterForAsyncUpdateResource();

            //
            // Tell the freezable that we have changed. 
            //
            FireChanged(); 
        } 

        ///  
        /// Update our resources on the channel, how we do this depends on what the
        /// channel is.
        /// 
        private 
        void
        UpdateResourceInternal( 
            DUCE.Channel        channel 
            )
        { 
            bool    notifyUceDirectly = false;
            bool    isRemote          = true;

            // 
            // Check what sort of channel type we have, we do quite different
            // things depending on what the channel type is. 
            // 
            switch(channel.MarshalType)
            { 
            case ChannelMarshalType.ChannelMarshalTypeSameThread:

                isRemote = false;
                break; 

            case ChannelMarshalType.ChannelMarshalTypeCrossThread: 
 
                isRemote = false;
                notifyUceDirectly = true; 
                break;


            case ChannelMarshalType.ChannelMarshalTypeCrossProcess: 
            case ChannelMarshalType.ChannelMarshalTypeCrossMachine:
 
                // 
                // Cross machine we shouldn't notify the Uce directly and it
                // will be remote. 
                //
                break;

            default: 

                throw new System.NotSupportedException(SR.Get(SRID.Media_UnknownChannelType)); 
            } 

            // 
            // If we aren't going to notify the Uce directly, then we need to register for a
            // frame update.
            //
            if (!notifyUceDirectly) 
            {
                if (null == _newFrameHandler) 
                { 
                    _newFrameHandler = new EventHandler(OnNewFrame);
 
                    _mediaPlayerState.NewFrame += _newFrameHandler;
                }
            }
            else 
            {
                if (null != _newFrameHandler) 
                { 
                    _mediaPlayerState.NewFrame -= _newFrameHandler;
 
                    _newFrameHandler = null;
                }
            }
 
            _mediaPlayerState.SendCommandMedia(
                    channel, 
                    _duceResource._duceResource.GetHandle(channel), 
                    notifyUceDirectly,
                    isRemote); 

            //
            // We don't need to update anymore until we get a new frame or
            // a new channel. 
            //
            _needsUpdate = false; 
        } 

        #endregion 

        #region Properties called by the clock

        // Set the current speed. 
        //
        internal 
        void 
        SetSpeedRatio(
            double value 
            )
        {
            _mediaPlayerState.SetSpeedRatio(value);
        } 

        ///  
        /// Sets the source of the media (and opens it), without checking whether 
        /// we are under clock control. This is called by the clock.
        ///  
        internal
        void
        SetSource(
            Uri      source 
            )
        { 
            _mediaPlayerState.SetSource(source); 
        }
 
        internal
        void
        SetPosition(
            TimeSpan value 
            )
        { 
            _mediaPlayerState.SetPosition(value); 
        }
 
        #endregion

        #region Data Members
 
        private MediaPlayerState      _mediaPlayerState = null;
 
        ///  
        /// DUCE resource handle - we need to use ShareableDUCEMultiChannelResource, because clones
        /// of a MediaPlayer all share the same underlying DUCE.MultiChannelResource. 
        /// 
        internal DUCE.ShareableDUCEMultiChannelResource _duceResource = new DUCE.ShareableDUCEMultiChannelResource();

        private EventHandler    _newFrameHandler = null; 

        private bool            _needsUpdate = false; 
 
        #endregion
    } 

    #endregion
};
 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------ 
//  Microsoft Avalon
//  Copyright (c) Microsoft Corporation, 2003
//
//  File:       MediaPlayer.cs 
//
//----------------------------------------------------------------------------- 
using System; 
using System.Threading;
using System.Security; 
using System.Security.Permissions;
using System.Diagnostics;
using System.ComponentModel;
using MS.Internal; 
using MS.Internal.PresentationCore;                        // SecurityHelper
using MS.Win32; 
using System.Windows.Media.Animation; 
using System.Windows.Media;
using System.Windows.Media.Composition; 
using System.Windows.Threading;
using System.Windows.Navigation;
using System.Runtime.InteropServices;
using System.IO; 
using System.Security.AccessControl;//for semaphore access permissions
using System.Net; 
using Microsoft.Win32; 
using SR=MS.Internal.PresentationCore.SR;
using SRID=MS.Internal.PresentationCore.SRID; 
using UnsafeNativeMethods=MS.Win32.PresentationCore.UnsafeNativeMethods;

//
// Disable the warnings that C# emmits when it finds pragmas it does not recognize, this is to 
// get rid of false positive PreSharp warning
// 
#pragma warning disable 1634, 1691 

 
namespace System.Windows.Media
{
    #region MediaPlayer
 
    /// 
    /// MediaPlayer 
    /// Provides helper methods for media related tasks 
    /// 
    public class MediaPlayer : Animatable, DUCE.IResource 
    {
        #region Constructors and Finalizers

        ///  
        /// Constructor
        ///  
        ///  
        /// Critical - access unmanaged pointers (proxy), calls critical code, indirectly access arbitrary file resources
        /// PublicOK: The URI holds relative path which is resolved just before being passed to media player 
        /// 
        public MediaPlayer()
        {
        } 

        #endregion 
 
        #region Public Methods
 
        /// 
        /// Indicates whether the media element is currently buffering.
        /// 
        public bool IsBuffering 
        {
            get 
            { 
                ReadPreamble();
 
                return _mediaPlayerState.IsBuffering;
            }
        }
 
        /// 
        /// Indicates whether given media can be paused. 
        ///  
        public bool CanPause
        { 
            get
            {
                ReadPreamble();
 
                return _mediaPlayerState.CanPause;
            } 
        } 

        ///  
        /// Returns the download progress of the media.
        /// 
        public double DownloadProgress
        { 
            get
            { 
                ReadPreamble(); 

                return _mediaPlayerState.DownloadProgress; 
            }
        }

        ///  
        /// Returns the buffering progress of the media.
        ///  
        public double BufferingProgress 
        {
            get 
            {
                ReadPreamble();

                return _mediaPlayerState.BufferingProgress; 
            }
        } 
 
        /// 
        /// Returns the natural height of the video. 
        /// 
        public Int32 NaturalVideoHeight
        {
            get 
            {
                ReadPreamble(); 
 
                return _mediaPlayerState.NaturalVideoHeight;
            } 
        }

        /// 
        /// Returns the natural width the media. 
        /// 
        public Int32 NaturalVideoWidth 
        { 
            get
            { 
                ReadPreamble();

                return _mediaPlayerState.NaturalVideoWidth;
            } 
        }
 
        ///  
        /// Returns whether the given media has audio content.
        ///  
        public bool HasAudio
        {
            get
            { 
                ReadPreamble();
 
                return _mediaPlayerState.HasAudio; 
            }
        } 

        /// 
        /// Returns whether the given media has video content
        ///  
        public bool HasVideo
        { 
            get 
            {
                ReadPreamble(); 

                return _mediaPlayerState.HasVideo;
            }
        } 

        ///  
        /// Location of the media to play. Open opens the media, this property 
        /// allows the source that is currently playing to be retrieved.
        ///  
        public Uri Source
        {
            get
            { 
                ReadPreamble();
 
                return _mediaPlayerState.Source; 
            }
        } 

        /// 
        /// The volume of the currently playing media.
        ///  
        public double Volume
        { 
            get 
            {
                ReadPreamble(); 

                return _mediaPlayerState.Volume;
            }
 
            set
            { 
                WritePreamble(); 

                _mediaPlayerState.Volume = value; 
            }
        }

        ///  
        /// Returns the balance that the current media has been set to.
        ///  
        public double Balance 
        {
            get 
            {
                ReadPreamble();

                return _mediaPlayerState.Balance; 
            }
 
            set 
            {
                WritePreamble(); 

                _mediaPlayerState.Balance = value;
            }
        } 

        ///  
        /// Whether or not scrubbing is enabled 
        /// 
        public bool ScrubbingEnabled 
        {
            get
            {
                ReadPreamble(); 

                return _mediaPlayerState.ScrubbingEnabled; 
            } 

            set 
            {
                WritePreamble();

                _mediaPlayerState.ScrubbingEnabled = value; 
            }
        } 
 
        /// 
        /// Returns the whether the given media is muted and sets whether it is 
        /// muted.
        /// 
        public bool IsMuted
        { 
            get
            { 
                ReadPreamble(); 

                return _mediaPlayerState.IsMuted; 
            }

            set
            { 
                WritePreamble();
 
                _mediaPlayerState.IsMuted = value; 
            }
        } 

        /// 
        /// Returns the natural duration of the given media.
        ///  
        public Duration NaturalDuration
        { 
            get 
            {
                ReadPreamble(); 

                return _mediaPlayerState.NaturalDuration;
            }
        } 

        ///  
        /// Seek to specified position 
        /// 
        public TimeSpan Position 
        {
            set
            {
                WritePreamble(); 

                _mediaPlayerState.Position = value; 
            } 

            get 
            {
                ReadPreamble();

                return _mediaPlayerState.Position; 
            }
        } 
 
        /// 
        /// The current speed. This cannot be changed if a clock is controlling this player 
        /// 
        public double SpeedRatio
        {
            get 
            {
                ReadPreamble(); 
 
                return _mediaPlayerState.SpeedRatio;
            } 

            set
            {
                WritePreamble(); 

                _mediaPlayerState.SpeedRatio = value; 
            } 
        }
 
        #endregion

        #region EventHandlers
 
        /// 
        /// Raised when there is an error opening or playing media 
        ///  
        public event EventHandler MediaFailed
        { 
            add
            {
                WritePreamble();
 
                _mediaPlayerState.MediaFailed += value;
            } 
 
            remove
            { 
                WritePreamble();

                _mediaPlayerState.MediaFailed -= value;
            } 
        }
 
        ///  
        /// Raised when the media has been opened.
        ///  
        public event EventHandler MediaOpened
        {
            add
            { 
                WritePreamble();
 
                _mediaPlayerState.MediaOpened += value; 
            }
 
            remove
            {
                WritePreamble();
 
                _mediaPlayerState.MediaOpened -= value;
            } 
        } 

 
        /// 
        /// Raised when the media has finished.
        /// 
        public event EventHandler MediaEnded 
        {
            add 
            { 
                WritePreamble();
 
                _mediaPlayerState.MediaEnded += value;
            }

            remove 
            {
                WritePreamble(); 
 
                _mediaPlayerState.MediaEnded -= value;
            } 
        }


        ///  
        /// Raised when media begins buffering.
        ///  
        public event EventHandler BufferingStarted 
        {
            add 
            {
                WritePreamble();

                _mediaPlayerState.BufferingStarted += value; 
            }
 
            remove 
            {
                WritePreamble(); 

                _mediaPlayerState.BufferingStarted -= value;
            }
        } 

        ///  
        /// Raised when media finishes buffering. 
        /// 
        public event EventHandler BufferingEnded 
        {
            add
            {
                WritePreamble(); 

                _mediaPlayerState.BufferingEnded += value; 
            } 

            remove 
            {
                WritePreamble();

                _mediaPlayerState.BufferingEnded -= value; 
            }
        } 
 
        /// 
        /// Raised when a script command embedded in the media is encountered. 
        /// 
        public event EventHandler ScriptCommand
        {
            add 
            {
                WritePreamble(); 
 
                _mediaPlayerState.ScriptCommand += value;
            } 

            remove
            {
                WritePreamble(); 

                _mediaPlayerState.ScriptCommand -= value; 
            } 
        }
 
        #endregion

        #region Clock dependent properties and methods
 
        /// 
        /// The clock driving this instance of media 
        ///  
        public MediaClock Clock
        { 
            get
            {
                ReadPreamble();
 
                return _mediaPlayerState.Clock;
            } 
 
            set
            { 
                WritePreamble();

                _mediaPlayerState.SetClock(value, this);
            } 
        }
 
        ///  
        /// Open the media, at this point the underlying native resources are
        /// created. The media player cannot be controlled when it isn't opened. 
        /// 
        public
        void
        Open( 
            Uri      source
            ) 
        { 
            WritePreamble();
 
            _mediaPlayerState.Open(source);
        }

        ///  
        /// Begin playback. This operation is not allowed if a clock is
        /// controlling this player 
        ///  
        public void Play()
        { 
            WritePreamble();

            _mediaPlayerState.Play();
        } 

        ///  
        /// Halt playback at current position. This operation is not allowed if 
        /// a clock is controlling this player
        ///  
        public void Pause()
        {
            WritePreamble();
 
            _mediaPlayerState.Pause();
        } 
 
        /// 
        /// Halt playback and seek to the beginning of media. This operation is 
        /// not allowed if a clock is controlling this player
        /// 
        public void Stop()
        { 
            WritePreamble();
 
            _mediaPlayerState.Stop(); 
        }
 
        /// 
        /// Closes the underlying media. This de-allocates all of the native resources in
        /// the media. The mediaplayer can be opened again by calling the Open method.
        ///  
        public
        void 
        Close() 
        {
            WritePreamble(); 

            _mediaPlayerState.Close();
        }
 
        #endregion
 
        #region DUCE 

        ///  
        /// AddRefOnChannel
        /// 
        /// 
        /// Critical - calls critical code 
        /// 
        [SecurityCritical] 
        DUCE.ResourceHandle DUCE.IResource.AddRefOnChannel(DUCE.Channel channel) 
        {
            EnsureState(); 

            using (CompositionEngineLock.Acquire())
            {
                return AddRefOnChannelCore(channel); 
            }
        } 
 
        /// 
        /// AddRefOnChannelCore 
        /// 
        /// Channel
        /// 
        /// Critical - accesses unmanaged objects, and critical resources 
        /// 
        [SecurityCritical] 
        internal DUCE.ResourceHandle AddRefOnChannelCore(DUCE.Channel channel) 
        {
            // 
            // Create a media resource
            //
            if (_duceResource._duceResource.CreateOrAddRefOnChannel(channel, DUCE.ResourceType.TYPE_MEDIAPLAYER))
            { 
                //
                // By definition we need an update whenever our channel changes. 
                // 
                _needsUpdate = true;
 
                UpdateResource(
                    channel,
                    true);  // Don't need a channel since we just created the resource.
            } 

            return _duceResource._duceResource.GetHandle(channel); 
        } 

        ///  
        /// ReleaseOnChannel
        /// 
        void DUCE.IResource.ReleaseOnChannel(DUCE.Channel channel)
        { 
            EnsureState();
 
            using (CompositionEngineLock.Acquire()) 
            {
                ReleaseOnChannelCore(channel); 
            }
        }

        ///  
        /// ReleaseOnChannelCore
        ///  
        /// Channel 
        internal void ReleaseOnChannelCore(DUCE.Channel channel)
        { 
            Debug.Assert(_duceResource._duceResource.IsOnChannel(channel));

            _duceResource._duceResource.ReleaseOnChannel(channel);
 
            //
            // The media state could be holding onto a bitmap source on this channel too. 
            // 
            _mediaPlayerState.ReleaseOnChannel(channel);
        } 

        /// 
        /// GetHandle
        ///  
        DUCE.ResourceHandle DUCE.IResource.GetHandle(DUCE.Channel channel)
        { 
            EnsureState(); 

            using (CompositionEngineLock.Acquire()) 
            {
                return GetHandleCore(channel);
            }
        } 

        ///  
        /// GetHandleCore 
        /// 
        /// Channel 
        internal DUCE.ResourceHandle GetHandleCore(DUCE.Channel channel)
        {
            return _duceResource._duceResource.GetHandle(channel);
        } 

        int DUCE.IResource.GetChannelCount() 
        { 
            return _duceResource._duceResource.GetChannelCount();
        } 

        DUCE.Channel DUCE.IResource.GetChannel(int index)
        {
            return _duceResource._duceResource.GetChannel(index); 
        }
 
        #endregion 

        #region Animatable 

        /// 
        /// UpdateResource is called when we need to update our resource
        /// on a particular channel. 
        /// 
        /// Channel 
        /// Whether we know we are on the 
        /// channel
        internal override 
        void
        UpdateResource(
            DUCE.Channel channel,
            bool skipOnChannelCheck 
            )
        { 
            if (skipOnChannelCheck || _duceResource._duceResource.IsOnChannel(channel)) 
            {
                // 
                // Chain this up through the base always otherwise our next
                // registration won't work.
                //
                base.UpdateResource(channel, true); 

                // 
                // Only actually send this if we are dirty. 
                //
                if (_needsUpdate) 
                {
                    //
                    // Send a new resource update
                    // 
                    UpdateResourceInternal(channel);
                } 
            } 
        }
 
        #endregion

        #region Freezable
 
        /// 
        /// CreateInstanceCore must return the new instance of the object to be 
        /// created. 
        /// 
        protected override 
        Freezable
        CreateInstanceCore()
        {
            return new MediaPlayer(); 
        }
 
        ///  
        /// Clones the object, implemented as part of Freezable contract, must
        /// be chained to the base class. 
        /// 
        protected override
        void
        CloneCore( 
            Freezable       sourceFreezable
            ) 
        { 
            CloneCommon(sourceFreezable);
 
            base.CloneCore(sourceFreezable);
        }

        ///  
        /// Clones the current value of the object, implemented as part of
        /// Freezable contract. 
        ///  
        protected override
        void 
        CloneCurrentValueCore(
            Freezable       sourceFreezable
            )
        { 
            CloneCommon(sourceFreezable);
 
            base.CloneCurrentValueCore(sourceFreezable); 
        }
 
        /// 
        /// Returns the object as frozen, media state is not really ammenable
        /// to being frozen.
        ///  
        protected override
        void 
        GetAsFrozenCore( 
            Freezable       sourceFreezable
            ) 
        {
            CloneCommon(sourceFreezable);

            base.GetAsFrozenCore(sourceFreezable); 
        }
 
        // 
        // We don't need to implement FreezeCore and SetFreezableContextCore
        // because we don't really freeze our data. 
        //
        private
        void
        CloneCommon( 
            Freezable       sourceFreezable
            ) 
        { 
            MediaPlayer player = (MediaPlayer)sourceFreezable;
 
            //
            // For the first clone both source and destination
            // might not be initialized yet.
            // 
            player.EnsureState();
 
            _mediaPlayerState = player._mediaPlayerState; 
            _duceResource = player._duceResource;
        } 

        #endregion

        #region Private Methods 

        ///  
        /// Freezable forces us to have a new instance without parameters. However 
        /// Creating MediaPlayerState is expensive so we use EnsureState to make sure
        /// that media state is created if we are not cloned after instantiation. 
        /// 
        private
        void
        EnsureState() 
        {
            if (null == _mediaPlayerState) 
            { 
                _mediaPlayerState = new MediaPlayerState(this);
            } 
        }


        ///  
        /// Called before any read, ensures that the media player is called from only
        /// one thread. We also create our state if necessary at this point. 
        ///  
        protected new
        void 
        ReadPreamble()
        {
            base.ReadPreamble();
 
            EnsureState();
        } 
 
        /// 
        /// Called before a write to check whether the given object is frozen. 
        /// We also ensure that we have the media state initialized if this passes.
        /// 
        protected new
        void 
        WritePreamble()
        { 
            base.WritePreamble(); 

            EnsureState(); 
        }

        /// 
        /// Our event handler for receiving frame updates. When we get a new frame, 
        /// we cause an async resource update.
        ///  
        private 
        void
        OnNewFrame( 
            object      sender,
            EventArgs   args
            )
        { 
            _needsUpdate = true;
 
            // 
            // This means "call us back on the channel when the render pass happens"
            // 
            RegisterForAsyncUpdateResource();

            //
            // Tell the freezable that we have changed. 
            //
            FireChanged(); 
        } 

        ///  
        /// Update our resources on the channel, how we do this depends on what the
        /// channel is.
        /// 
        private 
        void
        UpdateResourceInternal( 
            DUCE.Channel        channel 
            )
        { 
            bool    notifyUceDirectly = false;
            bool    isRemote          = true;

            // 
            // Check what sort of channel type we have, we do quite different
            // things depending on what the channel type is. 
            // 
            switch(channel.MarshalType)
            { 
            case ChannelMarshalType.ChannelMarshalTypeSameThread:

                isRemote = false;
                break; 

            case ChannelMarshalType.ChannelMarshalTypeCrossThread: 
 
                isRemote = false;
                notifyUceDirectly = true; 
                break;


            case ChannelMarshalType.ChannelMarshalTypeCrossProcess: 
            case ChannelMarshalType.ChannelMarshalTypeCrossMachine:
 
                // 
                // Cross machine we shouldn't notify the Uce directly and it
                // will be remote. 
                //
                break;

            default: 

                throw new System.NotSupportedException(SR.Get(SRID.Media_UnknownChannelType)); 
            } 

            // 
            // If we aren't going to notify the Uce directly, then we need to register for a
            // frame update.
            //
            if (!notifyUceDirectly) 
            {
                if (null == _newFrameHandler) 
                { 
                    _newFrameHandler = new EventHandler(OnNewFrame);
 
                    _mediaPlayerState.NewFrame += _newFrameHandler;
                }
            }
            else 
            {
                if (null != _newFrameHandler) 
                { 
                    _mediaPlayerState.NewFrame -= _newFrameHandler;
 
                    _newFrameHandler = null;
                }
            }
 
            _mediaPlayerState.SendCommandMedia(
                    channel, 
                    _duceResource._duceResource.GetHandle(channel), 
                    notifyUceDirectly,
                    isRemote); 

            //
            // We don't need to update anymore until we get a new frame or
            // a new channel. 
            //
            _needsUpdate = false; 
        } 

        #endregion 

        #region Properties called by the clock

        // Set the current speed. 
        //
        internal 
        void 
        SetSpeedRatio(
            double value 
            )
        {
            _mediaPlayerState.SetSpeedRatio(value);
        } 

        ///  
        /// Sets the source of the media (and opens it), without checking whether 
        /// we are under clock control. This is called by the clock.
        ///  
        internal
        void
        SetSource(
            Uri      source 
            )
        { 
            _mediaPlayerState.SetSource(source); 
        }
 
        internal
        void
        SetPosition(
            TimeSpan value 
            )
        { 
            _mediaPlayerState.SetPosition(value); 
        }
 
        #endregion

        #region Data Members
 
        private MediaPlayerState      _mediaPlayerState = null;
 
        ///  
        /// DUCE resource handle - we need to use ShareableDUCEMultiChannelResource, because clones
        /// of a MediaPlayer all share the same underlying DUCE.MultiChannelResource. 
        /// 
        internal DUCE.ShareableDUCEMultiChannelResource _duceResource = new DUCE.ShareableDUCEMultiChannelResource();

        private EventHandler    _newFrameHandler = null; 

        private bool            _needsUpdate = false; 
 
        #endregion
    } 

    #endregion
};
 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK