Exemple #1
0
 /// <summary>
 /// This function is used to intialize a heuristics module. It must be implemented by all derived classes.
 /// </summary>
 /// <param name="manifestInfo">The manifest for the stream we are reading</param>
 /// <param name="playbackInfo">The playback info for the media element</param>
 /// <param name="adInsertPoints">Optional expected points for advertising. Can be null</param>
 public abstract void Initialize(ManifestInfo manifestInfo, PlaybackInfo playbackInfo, AdInsertionPoint[] adInsertPoints);
        /// <summary>
        /// Initializes a new instance of the AdaptiveStreamingSource class
        /// </summary>
        /// <param name="mediaElement">The media element that we are sending samples to. We use it internally to keep track of playback statistics</param>
        /// <param name="url">The url of the manifest for the stream we are serving</param>
        public AdaptiveStreamingSource(MediaElement mediaElement, Uri url)
        {
            // Make sure our Url is not null
            if (null == url)
            {
                throw new ArgumentNullException("url", Errors.NullUrlOnMSSError);
            }

            // Also check the mediaElement parameter
            if (null == mediaElement)
            {
                throw new ArgumentNullException("mediaElement", Errors.NullMediaElementOnMSSError);
            }

            // Remember the Url to the manifest we are streaming
            m_manifestSourceUrl = url;

            // Create our default manifest parser
            ManifestParser = new ManifestParserImpl();

            // Create our default chunk parser factory
            ChunkParserFactory = new ChunkParserFactoryImpl();

            // Create our default url generator
            UrlGenerator = new UrlGeneratorImpl();

            // Create a new queue for processing commands. All work is done on a background thread,
            // which will shuttle events back to the UI thread in case something needs to be displayed.
            m_workQueue = new WorkQueue();

            // Create the thread that we are going to run background commands on
            m_workQueueThread = new Thread(WorkerThread);

            // Make sure we remember the Dispatcher class for the UI thread
            UIDispatcher.Load();

            // Playback info is a wrapper on around media element
            m_playbackInfo = new PlaybackInfo(mediaElement);

            // Hook our heuristics events
            m_heuristics.ChunkReplacementSuggested += HeuristicsChunkReplacementSuggested;
        }
        /// <summary>
        /// Handle a close command
        /// </summary>
        private void DoClose()
        {
            Tracer.Trace(TraceChannel.MSS, "Media closed");
            if (m_heuristics != null)
            {
                m_heuristics.Shutdown();
            }

            if (m_manifestInfo != null)
            {
                m_manifestInfo.Shutdown();
            }

            m_workQueueThread = null;
            m_isWorkQueueThreadStarted = false;
            m_workQueue = null;
            m_playbackInfo = null;
        }
        /// <summary>
        /// Implements Heuristics.Initialize(). Called to initialize this heuristics module with
        /// the given manifest file and optional adverting insertion points
        /// </summary>
        /// <param name="manifestInfo">The manifest of the stream we are using</param>
        /// <param name="playbackInfo">The playback info for the media element</param>
        /// <param name="adInsertPoints">Optional ad insertion points. Can be null</param>
        public override void Initialize(ManifestInfo manifestInfo, PlaybackInfo playbackInfo, AdInsertionPoint[] adInsertPoints)
        {
            Tracer.Trace(TraceChannel.MSS, "MediaSource instance {0}, sessionID: {1}", InstanceId.ToString("B"), sm_sessionId.ToString("B"));

            // Store our manifest info
            m_manifestInfo = manifestInfo;
            m_playbackInfo = playbackInfo;

            // We only support 1 audio and 1 video stream right now, so let's throw an exception
            // if someone tries to create us with more than that
            int numStreams = m_manifestInfo.NumberOfStreams;
            if (numStreams > 2)
            {
                throw new AdaptiveStreamingException("We only support 1 audio and 1 video stream at this time");
            }

            // Copy the add insertion points over
            m_adInsertPoints = new AdInsertionPoints();
            foreach (AdInsertionPoint ad in adInsertPoints)
            {
                m_adInsertPoints.Add(ad);
            }

            // Allocate some internal variables
            m_heuristicsMode = new HeuristicsMode[numStreams];
            m_fixedBitrateIndex = new int[numStreams];
            m_mediaStreamTypes = new MediaStreamType[numStreams];
            m_maxDownloadsPerStream = new int[numStreams];
            m_numDownloadsInProgress = new int[numStreams];
            m_nextChunkId = new int[numStreams];

            // Go through each stream in our manifest and do per-stream configuration
            int numVideoStreams = 0, numAudioStreams = 0;
            for (int i = 0; i < numStreams; i++)
            {
                StreamInfo streamInfo = m_manifestInfo.GetStreamInfoForStream(i);

                // Initialize some of the arrays we just created
                m_mediaStreamTypes[i] = streamInfo.MediaType;
                m_fixedBitrateIndex[i] = 0;
                m_maxDownloadsPerStream[i] = GlobalMaxDownloadsPerStream;
                m_numDownloadsInProgress[i] = 0;
                m_nextChunkId[i] = 0;

                // If we are a video stream, then we need to set our heuristics mode
                // to Full
                switch (streamInfo.MediaType)
                {
                    case MediaStreamType.Audio:
                        m_heuristicsMode[i] = HeuristicsMode.FixedRate;
                        ++numAudioStreams;
                        break;
                    case MediaStreamType.Video:
                        m_heuristicsMode[i] = HeuristicsMode.Full;
                        ++numVideoStreams;
                        break;
                    default:
                        throw new AdaptiveStreamingException(Errors.NonVideoOrAudioStreamsNotSupportedError);
                }

                // Configure this stream
                InitializeHeuristicsForStream(
                    streamInfo.StreamId,
                    (double)m_maxBufferSizeInMs / 1000,
                    m_manifestInfo.GetStreamInfoForStream(i).Bitrates.Count,
                    m_manifestInfo.GetStreamInfoForStream(i).GetBitrateArray());
            }

            // Make sure we found only 1 video and 1 audio stream
            if (numVideoStreams != 1)
            {
                throw new AdaptiveStreamingException(Errors.IncorrectNumberOfVideoStreamsError);
            }

            // Start scheduling our downloads
            ScheduleDownloads();
        }