aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke <luke.pulverenti@gmail.com>2015-10-30 12:43:17 -0400
committerLuke <luke.pulverenti@gmail.com>2015-10-30 12:43:17 -0400
commit80c5ef35a10f24c0a10c76ea3dba147c33f9bd44 (patch)
tree28fdb3d12654df86d7bc606cdd83edddcc199417
parent23d65f487195283d134a341489234e64a62e931c (diff)
parent9bfb2f081328f8877bdb0ce3a05e76e6488ce5ae (diff)
Merge pull request #1240 from MediaBrowser/master
update tuner pooling
-rw-r--r--MediaBrowser.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs75
-rw-r--r--MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs23
-rw-r--r--MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs8
3 files changed, 80 insertions, 26 deletions
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs
index d811152c2..41ba1967a 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs
+++ b/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;
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs
index eebb381af..a237bb226 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs
+++ b/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);
+ }
}
}
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs
index afd41e3d8..ddbbb030d 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs
+++ b/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);
+ }
}
}