public void ResumeSync(bool forceresumePlay)
        {
            HookEvents();
            Timer.Start();

            if (forceresumePlay)
            {
                UnpauseAll();
            }
            else
            {
                HeuristicManager.StartMonitoring();
            }
        }
        private void masterMedia_MediaOpened(object sender, RoutedEventArgs e)
        {
            HeuristicManager.StartMonitoring();

            // the live video intermittently starts at the beginning of the live video
            // instead of the end, it has been difficult to reproduce and resolve, calling
            // StartSeekToLive is a workaround to solve the problem, it can be removed if
            // find the root problem of the issue
            //
            // only want to run the workaround for live streams and when the initial
            // video is loaded, not when the stream is restored by the auto retry
            //if (MainMedia.IsLive && MainMedia.RetryState == RetryState.None)
            if (MainMedia.IsLive)
            {
                MainMedia.StartSeekToLive();
            }

            MainMedia.Play();
        }
        public void RegisterMaster(SmoothStreamingMediaElement media, TimeSpan position)
        {
            UnhookEvents();

            //MainMedia is for syncing
            //HeuristicsMasterMedia is used for Heuristics
            MainMedia = media;
            //MainMedia.Position = position;

            HookEvents();

            //UpdateSlaves();

            if (media == HeuristicMasterMedia)
            {
                HeuristicManager.StartMonitoring();
            }
            else
            {
                HeuristicManager.StopMonitoring();
            }
        }
        //Assuming Master is ready
        //Assuming Slaves are in a heuristic loadable state
        public void ResetHeuristics()
        {
            if (ResettingHeuristics != null)
            {
                ResettingHeuristics(this, null);
            }

            HeuristicManager.StopMonitoring();
            HeuristicManager.Clear();

            if (HeuristicMasterMedia != null)
            {
                HeuristicManager.AddSmoothStreamingMediaElement(HeuristicMasterMedia, HeuristicSettings.PrimaryMinBitRate,
                                                                HeuristicSettings.PrimaryMinFrameRate);
                // TODO:  determin min values depending on size of master

                foreach (SlaveMediaElement slave in SubMediaElements)
                {
                    if (slave.MediaElement != HeuristicMasterMedia)
                    {
                        // reset current heuristic enabled flag
                        slave.IsPhysicalSyncEnabled = false;

                        //if (slave.IsLogicalSyncEnabled) // does it logically needed to be playing, if so, add it to HM
                        //{
                        if (slave.MediaElement != null)
                        {
                            HeuristicManager.AddSmoothStreamingMediaElement(slave.MediaElement,
                                                                            HeuristicSettings.SecondaryMinBitRate,
                                                                            HeuristicSettings.SecondaryMinFrameRate);
                        }
                    }
                }

                HeuristicManager.StartMonitoring();
            }
        }
        //private void RetrySlaves()
        //{
        //    foreach (SlaveMediaElement slave in SubMediaElements)
        //    {
        //        if (slave.MediaElement.CurrentState == SmoothStreamingMediaElementState.Closed)
        //        {
        //            slave.MediaElement.Retry();
        //        }
        //    }
        //}

        private void UnpauseAll()
        {
            HeuristicManager.StartMonitoring();

            MainMedia.Play();
        }