Luke Pulverenti пре 9 година
родитељ
комит
9bfb2f0813

+ 54 - 21
MediaBrowser.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs

@@ -117,8 +117,23 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts
 
                 foreach (var host in hostsWithChannel)
                 {
+                    var resourcePool = GetLock(host.Url);
+                    Logger.Debug("GetChannelStreamMediaSources - Waiting on tuner resource pool");
+
+                    await resourcePool.WaitAsync(cancellationToken).ConfigureAwait(false);
+                    Logger.Debug("GetChannelStreamMediaSources - Unlocked resource pool");
+
                     try
                     {
+                        // Check to make sure the tuner is available
+                        // If there's only one tuner, don't bother with the check and just let the tuner be the one to throw an error
+                        if (hostsWithChannel.Count > 1 &&
+                            !await IsAvailable(host, channelId, cancellationToken).ConfigureAwait(false))
+                        {
+                            Logger.Error("Tuner is not currently available");
+                            continue;
+                        }
+
                         var mediaSources = await GetChannelStreamMediaSources(host, channelId, cancellationToken).ConfigureAwait(false);
 
                         // Prefix the id with the host Id so that we can easily find it
@@ -133,6 +148,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts
                     {
                         Logger.Error("Error opening tuner", ex);
                     }
+                    finally
+                    {
+                        resourcePool.Release();
+                    }
                 }
             }
 
@@ -170,17 +189,35 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts
 
                 foreach (var host in hostsWithChannel)
                 {
+                    var resourcePool = GetLock(host.Url);
+                    Logger.Debug("GetChannelStream - Waiting on tuner resource pool");
+                    await resourcePool.WaitAsync(cancellationToken).ConfigureAwait(false);
+                    Logger.Debug("GetChannelStream - Unlocked resource pool");
                     try
                     {
+                        // Check to make sure the tuner is available
+                        // If there's only one tuner, don't bother with the check and just let the tuner be the one to throw an error
+                        // If a streamId is specified then availibility has already been checked in GetChannelStreamMediaSources
+                        if (string.IsNullOrWhiteSpace(streamId) && hostsWithChannel.Count > 1)
+                        {
+                            if (!await IsAvailable(host, channelId, cancellationToken).ConfigureAwait(false))
+                            {
+                                Logger.Error("Tuner is not currently available");
+                                resourcePool.Release();
+                                continue;
+                            }
+                        }
+
                         var stream = await GetChannelStream(host, channelId, streamId, cancellationToken).ConfigureAwait(false);
-                        var resourcePool = GetLock(host.Url);
 
-                        await AddMediaInfo(stream, false, resourcePool, cancellationToken).ConfigureAwait(false);
+                        //await AddMediaInfo(stream, false, resourcePool, cancellationToken).ConfigureAwait(false);
                         return new Tuple<MediaSourceInfo, SemaphoreSlim>(stream, resourcePool);
                     }
                     catch (Exception ex)
                     {
                         Logger.Error("Error opening tuner", ex);
+
+                        resourcePool.Release();
                     }
                 }
             }
@@ -188,6 +225,21 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts
             throw new LiveTvConflictException();
         }
 
+        protected async Task<bool> IsAvailable(TunerHostInfo tuner, string channelId, CancellationToken cancellationToken)
+        {
+            try
+            {
+                return await IsAvailableInternal(tuner, channelId, cancellationToken).ConfigureAwait(false);
+            }
+            catch (Exception ex)
+            {
+                Logger.ErrorException("Error checking tuner availability", ex);
+                return false;
+            }
+        }
+
+        protected abstract Task<bool> IsAvailableInternal(TunerHostInfo tuner, string channelId, CancellationToken cancellationToken);
+
         /// <summary>
         /// The _semaphoreLocks
         /// </summary>
@@ -202,25 +254,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts
             return _semaphoreLocks.GetOrAdd(url, key => new SemaphoreSlim(1, 1));
         }
 
-        private async Task AddMediaInfo(MediaSourceInfo mediaSource, bool isAudio, SemaphoreSlim resourcePool, CancellationToken cancellationToken)
-        {
-            await resourcePool.WaitAsync(cancellationToken).ConfigureAwait(false);
-
-            try
-            {
-                await AddMediaInfoInternal(mediaSource, isAudio, cancellationToken).ConfigureAwait(false);
-
-                // Leave the resource locked. it will be released upstream
-            }
-            catch (Exception)
-            {
-                // Release the resource if there's some kind of failure.
-                resourcePool.Release();
-
-                throw;
-            }
-        }
-
         private async Task AddMediaInfoInternal(MediaSourceInfo mediaSource, bool isAudio, CancellationToken cancellationToken)
         {
             var originalRuntime = mediaSource.RunTimeTicks;

+ 19 - 4
MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs

@@ -15,6 +15,7 @@ using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
 using MediaBrowser.Controller.MediaEncoding;
+using MediaBrowser.Model.Configuration;
 using MediaBrowser.Model.Dlna;
 
 namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
@@ -23,7 +24,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
     {
         private readonly IHttpClient _httpClient;
 
-        public HdHomerunHost(IConfigurationManager config, ILogger logger, IJsonSerializer jsonSerializer, IMediaEncoder mediaEncoder, IHttpClient httpClient) : base(config, logger, jsonSerializer, mediaEncoder)
+        public HdHomerunHost(IConfigurationManager config, ILogger logger, IJsonSerializer jsonSerializer, IMediaEncoder mediaEncoder, IHttpClient httpClient)
+            : base(config, logger, jsonSerializer, mediaEncoder)
         {
             _httpClient = httpClient;
         }
@@ -232,7 +234,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
             int? width = null;
             int? height = null;
             bool isInterlaced = true;
-            var videoCodec = "mpeg2video";
+            var videoCodec = !string.IsNullOrWhiteSpace(GetEncodingOptions().HardwareVideoDecoder) ? null : "mpeg2video";
+
             int? videoBitrate = null;
 
             if (string.Equals(profile, "mobile", StringComparison.OrdinalIgnoreCase))
@@ -326,8 +329,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
                                 BitRate = 128000
                             }
                         },
-                RequiresOpening = true,
-                RequiresClosing = true,
+                RequiresOpening = false,
+                RequiresClosing = false,
                 BufferMs = 1000,
                 Container = "ts",
                 Id = profile,
@@ -339,6 +342,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
             return mediaSource;
         }
 
+        protected EncodingOptions GetEncodingOptions()
+        {
+            return Config.GetConfiguration<EncodingOptions>("encoding");
+        }
+
         protected override async Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(TunerHostInfo info, string channelId, CancellationToken cancellationToken)
         {
             var list = new List<MediaSourceInfo>();
@@ -404,5 +412,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
                 await GetChannels(info, false, CancellationToken.None).ConfigureAwait(false);
             }
         }
+
+        protected override async Task<bool> IsAvailableInternal(TunerHostInfo tuner, string channelId, CancellationToken cancellationToken)
+        {
+            var info = await GetTunerInfos(tuner, cancellationToken).ConfigureAwait(false);
+
+            return info.Any(i => i.Status == LiveTvTunerStatus.Available);
+        }
     }
 }

+ 7 - 1
MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs

@@ -25,7 +25,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts
         private readonly IFileSystem _fileSystem;
         private readonly IHttpClient _httpClient;
 
-        public M3UTunerHost(IConfigurationManager config, ILogger logger, IJsonSerializer jsonSerializer, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IHttpClient httpClient) : base(config, logger, jsonSerializer, mediaEncoder)
+        public M3UTunerHost(IConfigurationManager config, ILogger logger, IJsonSerializer jsonSerializer, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IHttpClient httpClient)
+            : base(config, logger, jsonSerializer, mediaEncoder)
         {
             _fileSystem = fileSystem;
             _httpClient = httpClient;
@@ -209,5 +210,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts
             }
             return new List<MediaSourceInfo> { };
         }
+
+        protected override Task<bool> IsAvailableInternal(TunerHostInfo tuner, string channelId, CancellationToken cancellationToken)
+        {
+            return Task.FromResult(true);
+        }
     }
 }