Index: TVLibrary/TvControl/Controller.cs =================================================================== --- TVLibrary/TvControl/Controller.cs (revision 26258) +++ TVLibrary/TvControl/Controller.cs (working copy) @@ -837,7 +837,13 @@ /// The user. void StopCard(User user); + /// + /// Pauses the card. + /// + /// The user. + void PauseCard(User user); + /// /// Query what card would be used for timeshifting on any given channel /// Index: TVLibrary/TvLibrary.Interfaces/Interfaces/ITVCard.cs =================================================================== --- TVLibrary/TvLibrary.Interfaces/Interfaces/ITVCard.cs (revision 26258) +++ TVLibrary/TvLibrary.Interfaces/Interfaces/ITVCard.cs (working copy) @@ -53,6 +53,12 @@ bool SupportsSubChannels { get; } /// + /// Gets wether or not card supports pausing the graph. + /// + bool SupportsPauseGraph { get; } + + + /// /// Gets or sets the timeout parameters. /// /// The parameters. @@ -86,6 +92,12 @@ void StopGraph(); /// + /// Pauses the current graph + /// + /// + void PauseGraph(); + + /// /// returns the min. channel number for analog cards /// int MinChannel { get; } Index: TVLibrary/TVLibrary/Implementations/Analog/Graphs/Analog/TvCardAnalog.cs =================================================================== --- TVLibrary/TVLibrary/Implementations/Analog/Graphs/Analog/TvCardAnalog.cs (revision 26258) +++ TVLibrary/TVLibrary/Implementations/Analog/Graphs/Analog/TvCardAnalog.cs (working copy) @@ -116,7 +116,53 @@ return true; } + /// + /// Pause the current graph + /// + /// + public override void PauseGraph() + { + if (!CheckThreadId()) + return; + FreeAllSubChannels(); + FilterState state; + if (_graphBuilder == null) + return; + IMediaControl mediaCtl = (_graphBuilder as IMediaControl); + if (mediaCtl == null) + { + throw new TvException("Can not convert graphBuilder to IMediaControl"); + } + mediaCtl.GetState(10, out state); + + Log.Log.WriteFile("analog: PauseGraph state:{0}", state); + _isScanning = false; + if (_tsFileSink != null) + { + IMPRecord record = _tsFileSink as IMPRecord; + if (record != null) + { + record.StopTimeShifting(_subChannelId); + record.StopRecord(_subChannelId); + } + } + if (state != FilterState.Running) + { + _graphState = GraphState.Created; + return; + } + int hr = mediaCtl.Pause(); + if (hr < 0 || hr > 1) + { + Log.Log.WriteFile("analog: PauseGraph returns:0x{0:X}", hr); + throw new TvException("Unable to pause graph"); + } + Log.Log.WriteFile("analog: Graph paused"); + } + + + /// /// Stops the current graph /// /// @@ -633,7 +679,7 @@ /// /// Methods which starts the graph /// - private void RunGraph(int subChannel) + public override void RunGraph(int subChannel) { bool graphRunning = GraphRunning(); Index: TVLibrary/TVLibrary/Implementations/Analog/Graphs/HDPVR/TVCardHDPVR.cs =================================================================== --- TVLibrary/TVLibrary/Implementations/Analog/Graphs/HDPVR/TVCardHDPVR.cs (revision 26258) +++ TVLibrary/TVLibrary/Implementations/Analog/Graphs/HDPVR/TVCardHDPVR.cs (working copy) @@ -127,6 +127,38 @@ /// Stops the current graph /// /// + public override void PauseGraph() + { + FreeAllSubChannels(); + FilterState state; + if (_graphBuilder == null) + return; + IMediaControl mediaCtl = (_graphBuilder as IMediaControl); + if (mediaCtl == null) + { + throw new TvException("Can not convert graphBuilder to IMediaControl"); + } + mediaCtl.GetState(10, out state); + Log.Log.WriteFile("HDPVR: PauseGraph state:{0}", state); + _isScanning = false; + if (state != FilterState.Running) + { + _graphState = GraphState.Created; + return; + } + int hr = mediaCtl.Pause(); + if (hr < 0 || hr > 1) + { + Log.Log.WriteFile("HDPVR: PauseGraph returns:0x{0:X}", hr); + throw new TvException("Unable to pause graph"); + } + Log.Log.WriteFile("HDPVR: Graph paused"); + } + + /// + /// Stops the current graph + /// + /// public override void StopGraph() { FreeAllSubChannels(); @@ -767,7 +799,7 @@ /// /// Method which starts the graph /// - private void RunGraph(int subChannel) + public override void RunGraph(int subChannel) { bool graphRunning = GraphRunning(); Index: TVLibrary/TVLibrary/Implementations/DVB/ConditionalAccess/ConditionalAccess.cs =================================================================== --- TVLibrary/TVLibrary/Implementations/DVB/ConditionalAccess/ConditionalAccess.cs (revision 26258) +++ TVLibrary/TVLibrary/Implementations/DVB/ConditionalAccess/ConditionalAccess.cs (working copy) @@ -387,6 +387,7 @@ if (_twinhan.IsCamPresent()) return false; } + return true; } } Index: TVLibrary/TVLibrary/Implementations/DVB/Graphs/DVBIP/TvCardDVBIP.cs =================================================================== --- TVLibrary/TVLibrary/Implementations/DVB/Graphs/DVBIP/TvCardDVBIP.cs (revision 26258) +++ TVLibrary/TVLibrary/Implementations/DVB/Graphs/DVBIP/TvCardDVBIP.cs (working copy) @@ -246,6 +246,14 @@ } /// + /// Gets wether or not card supports pausing the graph. + /// + public override bool SupportsPauseGraph + { + get { return false; } + } + + /// /// Stops graph /// public override void StopGraph() Index: TVLibrary/TVLibrary/Implementations/DVB/Graphs/TvCardDvbBase.cs =================================================================== --- TVLibrary/TVLibrary/Implementations/DVB/Graphs/TvCardDvbBase.cs (revision 26258) +++ TVLibrary/TVLibrary/Implementations/DVB/Graphs/TvCardDvbBase.cs (working copy) @@ -633,7 +633,7 @@ /// /// Methods which starts the graph /// - protected void RunGraph(int subChannel) + public override void RunGraph(int subChannel) { bool graphRunning = GraphRunning(); @@ -680,6 +680,41 @@ } /// + /// Methods which pauses the graph + /// + public override void PauseGraph() + { + Log.Log.WriteFile("dvb:PauseGraph called"); + if (!CheckThreadId()) + return; + _epgGrabbing = false; + _isScanning = false; + FreeAllSubChannels(); + if (_mdplugs != null) + { + _mdplugs.FreeAllChannels(); + } + if (_graphBuilder == null) + return; + + FilterState state; + ((IMediaControl)_graphBuilder).GetState(10, out state); + if (state != FilterState.Running) + { + Log.Log.WriteFile("dvb:StopGraph filterstate already paused, returning."); + return; + } + Log.Log.WriteFile("dvb:PauseGraph"); + int hr = ((IMediaControl)_graphBuilder).Pause(); + if (hr < 0 || hr > 1) + { + Log.Log.Error("dvb:PauseGraph returns:0x{0:X}", hr); + throw new TvException("Unable to pause graph"); + } + _graphState = GraphState.Created; + } + + /// /// Methods which stops the graph /// public override void StopGraph() @@ -722,7 +757,13 @@ } else { + int hr = ((IMediaControl)_graphBuilder).Stop(); Log.Log.WriteFile("dvb:StopGraph - conditionalAccess.AllowedToStopGraph = false"); + if (hr < 0 || hr > 1) + { + Log.Log.Error("dvb:StopGraph returns:0x{0:X}", hr); + throw new TvException("Unable to stop graph"); + } _graphState = GraphState.Created; } } Index: TVLibrary/TVLibrary/Implementations/Hybrid/HybridCard.cs =================================================================== --- TVLibrary/TVLibrary/Implementations/Hybrid/HybridCard.cs (revision 26258) +++ TVLibrary/TVLibrary/Implementations/Hybrid/HybridCard.cs (working copy) @@ -78,6 +78,14 @@ #region properties /// + /// Gets wether or not card supports pausing the graph. + /// + public bool SupportsPauseGraph + { + get { return true; } + } + + /// /// returns true if card is currently present /// public bool CardPresent @@ -176,7 +184,15 @@ _group.StopGraph(); } + /// + /// Pauses the current graph + /// + public void PauseGraph() + { + _group.PauseGraph(); + } + /// /// returns true if card is currently grabbing the epg /// Index: TVLibrary/TVLibrary/Implementations/Hybrid/HybridCardGroup.cs =================================================================== --- TVLibrary/TVLibrary/Implementations/Hybrid/HybridCardGroup.cs (revision 26258) +++ TVLibrary/TVLibrary/Implementations/Hybrid/HybridCardGroup.cs (working copy) @@ -97,6 +97,14 @@ } /// + /// Pauses the current graph + /// + public void PauseGraph() + { + _cards[_currentCardIndex].PauseGraph(); + } + + /// /// returns true if card is currently grabbing the epg /// /// Index: TVLibrary/TVLibrary/Implementations/RadioWebStream/RadioWebStreamCard.cs =================================================================== --- TVLibrary/TVLibrary/Implementations/RadioWebStream/RadioWebStreamCard.cs (revision 26258) +++ TVLibrary/TVLibrary/Implementations/RadioWebStream/RadioWebStreamCard.cs (working copy) @@ -322,6 +322,23 @@ } /// + /// Gets wether or not card supports pausing the graph. + /// + public bool SupportsPauseGraph + { + get { return false; } + } + + /// + /// Pause the current graph + /// + /// + public void PauseGraph() + { + if (!CheckThreadId()) return; + } + + /// /// Returns if the tuner belongs to a hybrid card /// public bool IsHybrid Index: TVLibrary/TVLibrary/Implementations/TvCardBase.cs =================================================================== --- TVLibrary/TVLibrary/Implementations/TvCardBase.cs (revision 26258) +++ TVLibrary/TVLibrary/Implementations/TvCardBase.cs (working copy) @@ -224,6 +224,14 @@ #region properties /// + /// Gets wether or not card supports pausing the graph. + /// + public virtual bool SupportsPauseGraph + { + get { return true; } + } + + /// /// Gets or sets the unique id of this card /// public virtual int CardId @@ -590,6 +598,17 @@ public abstract void StopGraph(); /// + /// Pauses the current graph + /// + /// + public abstract void PauseGraph(); + + /// + /// Starts the graph + /// + public abstract void RunGraph(int subChannel); + + /// /// A derrived class should activate / deactivate the epg grabber /// /// Mode @@ -681,8 +700,15 @@ _subChannelId = 0; if (!continueGraph) { - Log.Log.Info("tvcard:FreeSubChannel : no subchannels present, stopping graph"); - StopGraph(); + Log.Log.Info("tvcard:FreeSubChannel : no subchannels present, pausing graph"); + if (SupportsPauseGraph) + { + PauseGraph(); + } + else + { + StopGraph(); + } } else { Index: TVLibrary/TvService/CardManagement/CardHandler/ITvCardHandler.cs =================================================================== --- TVLibrary/TvService/CardManagement/CardHandler/ITvCardHandler.cs (revision 26258) +++ TVLibrary/TvService/CardManagement/CardHandler/ITvCardHandler.cs (working copy) @@ -66,6 +66,7 @@ bool IsScrambled(ref User user); void StopCard(User user); + void PauseCard(User user); void SetParameters(); void Dispose(); } Index: TVLibrary/TvService/CardManagement/CardHandler/TimeShifter.cs =================================================================== --- TVLibrary/TvService/CardManagement/CardHandler/TimeShifter.cs (revision 26258) +++ TVLibrary/TvService/CardManagement/CardHandler/TimeShifter.cs (working copy) @@ -517,7 +517,7 @@ if (_cardHandler.IsIdle) { - _cardHandler.StopCard(user); + _cardHandler.PauseCard(user); } else { Index: TVLibrary/TvService/CardManagement/CardHandler/TvCardHandler.cs =================================================================== --- TVLibrary/TvService/CardManagement/CardHandler/TvCardHandler.cs (revision 26258) +++ TVLibrary/TvService/CardManagement/CardHandler/TvCardHandler.cs (working copy) @@ -789,7 +789,61 @@ } } + /// + /// Pauses the card. + /// + public void PauseCard(User user) + { + try + { + if (_dbsCard.Enabled == false) + return; + if (IsLocal == false) + { + try + { + RemoteControl.HostName = _dbsCard.ReferencedServer().HostName; + RemoteControl.Instance.PauseCard(user); + return; + } + catch (Exception) + { + Log.Error("card: unable to connect to slave controller at:{0}", _dbsCard.ReferencedServer().HostName); + return; + } + } + Log.Info("Pausecard"); + + //remove all subchannels, except for this user... + ITvSubChannel[] channels = _card.SubChannels; + for (int i = 0; i < channels.Length; ++i) + { + _card.FreeSubChannel(channels[i].SubChannelId); + } + + TvCardContext context = _card.Context as TvCardContext; + if (context != null) + { + context.Clear(); + } + + if (_card.SupportsPauseGraph) + { + _card.PauseGraph(); + } + else + { + _card.StopGraph(); + } + } + catch (Exception ex) + { + Log.Write(ex); + } + } + + /// /// Stops the card. /// public void StopCard(User user) Index: TVLibrary/TvService/CardManagement/CardHandler/UserManagement.cs =================================================================== --- TVLibrary/TvService/CardManagement/CardHandler/UserManagement.cs (revision 26258) +++ TVLibrary/TvService/CardManagement/CardHandler/UserManagement.cs (working copy) @@ -151,8 +151,15 @@ } } if (_cardHandler.IsIdle) - { - _cardHandler.Card.StopGraph(); + { + if (_cardHandler.Card.SupportsPauseGraph) + { + _cardHandler.Card.PauseGraph(); + } + else + { + _cardHandler.Card.StopGraph(); + } } } Index: TVLibrary/TvService/Epg/EpgCard.cs =================================================================== --- TVLibrary/TvService/Epg/EpgCard.cs (revision 26258) +++ TVLibrary/TvService/Epg/EpgCard.cs (working copy) @@ -197,7 +197,7 @@ _state = EpgState.Idle; _tvController.StopGrabbingEpg(_user); - _tvController.StopCard(_user); + _tvController.PauseCard(_user); _user.CardId = -1; _currentTransponder.InUse = false; return 0; @@ -678,7 +678,7 @@ if (_state != EpgState.Idle && _user.CardId >= 0) { _tvController.StopGrabbingEpg(_user); - _tvController.StopCard(_user); + _tvController.PauseCard(_user); } _currentTransponder.InUse = false; _state = EpgState.Idle; Index: TVLibrary/TvService/TVController.cs =================================================================== --- TVLibrary/TvService/TVController.cs (revision 26258) +++ TVLibrary/TvService/TVController.cs (working copy) @@ -29,6 +29,7 @@ using System.Reflection; using TvLibrary; using TvLibrary.Implementations; +using TvLibrary.Implementations.DVB; using TvLibrary.Interfaces; using TvLibrary.Implementations.Analog; using TvLibrary.Implementations.Hybrid; @@ -604,11 +605,12 @@ if (card.PreloadCard) { Log.Info("Controller: preloading card :{0}", card.Name); - card.BuildGraph(); + card.BuildGraph(); if (unknownCard is TvCardAnalog) { ((TvCardAnalog)unknownCard).ReloadCardConfiguration(); } + card.RunGraph(0); } else { @@ -1815,6 +1817,13 @@ _cards[user.CardId].StopCard(user); } + public void PauseCard(User user) + { + if (ValidateTvControllerParams(user)) + return; + _cards[user.CardId].PauseCard(user); + } + public bool StopTimeShifting(ref User user, TvStoppedReason reason) { if (ValidateTvControllerParams(user))