diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs
index a52449078..86f06213c 100644
--- a/MediaBrowser.Api/Playback/BaseStreamingService.cs
+++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs
@@ -290,13 +290,6 @@ namespace MediaBrowser.Api.Playback
{
get
{
- var lib = ApiEntryPoint.Instance.GetEncodingOptions().H264Encoder;
-
- if (!string.IsNullOrWhiteSpace(lib))
- {
- return lib;
- }
-
return "libx264";
}
}
@@ -809,6 +802,46 @@ namespace MediaBrowser.Api.Playback
return "copy";
}
+ ///
+ /// Gets the name of the output video codec
+ ///
+ /// The state.
+ /// System.String.
+ protected string GetVideoDecoder(StreamState state)
+ {
+ if (string.Equals(ApiEntryPoint.Instance.GetEncodingOptions().HardwareVideoDecoder, "qsv", StringComparison.OrdinalIgnoreCase))
+ {
+ if (state.VideoStream != null && !string.IsNullOrWhiteSpace(state.VideoStream.Codec))
+ {
+ switch (state.MediaSource.VideoStream.Codec.ToLower())
+ {
+ case "avc":
+ case "h264":
+ if (MediaEncoder.SupportsDecoder("h264_qsv"))
+ {
+ return "-c:v h264_qsv ";
+ }
+ break;
+ case "mpeg2video":
+ if (MediaEncoder.SupportsDecoder("mpeg2_qsv"))
+ {
+ return "-c:v mpeg2_qsv ";
+ }
+ break;
+ case "vc1":
+ if (MediaEncoder.SupportsDecoder("vc1_qsv"))
+ {
+ return "-c:v vc1_qsv ";
+ }
+ break;
+ }
+ }
+ }
+
+ // leave blank so ffmpeg will decide
+ return string.Empty;
+ }
+
///
/// Gets the input argument.
///
@@ -816,7 +849,7 @@ namespace MediaBrowser.Api.Playback
/// System.String.
protected string GetInputArgument(StreamState state)
{
- var arg = "-i " + GetInputPathArgument(state);
+ var arg = string.Format("{1}-i {0}", GetInputPathArgument(state), GetVideoDecoder(state));
if (state.SubtitleStream != null)
{
@@ -826,7 +859,7 @@ namespace MediaBrowser.Api.Playback
}
}
- return arg;
+ return arg.Trim();
}
private string GetInputPathArgument(StreamState state)
diff --git a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs
index 23285b612..427af6f6d 100644
--- a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs
+++ b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs
@@ -24,6 +24,13 @@ namespace MediaBrowser.Controller.MediaEncoding
/// The version.
string Version { get; }
+ ///
+ /// Supportses the decoder.
+ ///
+ /// The decoder.
+ /// true if XXXX, false otherwise.
+ bool SupportsDecoder(string decoder);
+
///
/// Extracts the audio image.
///
diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
index 01be4924a..d317acc59 100644
--- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
@@ -97,6 +97,22 @@ namespace MediaBrowser.MediaEncoding.Encoder
FFMpegPath = ffMpegPath;
}
+ public void SetAvailableEncoders(List list)
+ {
+
+ }
+
+ private List _decoders = new List();
+ public void SetAvailableDecoders(List list)
+ {
+ _decoders = list.ToList();
+ }
+
+ public bool SupportsDecoder(string decoder)
+ {
+ return _decoders.Contains(decoder, StringComparer.OrdinalIgnoreCase);
+ }
+
///
/// Gets the encoder path.
///
diff --git a/MediaBrowser.Model/Configuration/EncodingOptions.cs b/MediaBrowser.Model/Configuration/EncodingOptions.cs
index 6d3894f02..77b894eb8 100644
--- a/MediaBrowser.Model/Configuration/EncodingOptions.cs
+++ b/MediaBrowser.Model/Configuration/EncodingOptions.cs
@@ -6,14 +6,13 @@ namespace MediaBrowser.Model.Configuration
public int EncodingThreadCount { get; set; }
public string TranscodingTempPath { get; set; }
public double DownMixAudioBoost { get; set; }
- public string H264Encoder { get; set; }
public bool EnableDebugLogging { get; set; }
public bool EnableThrottling { get; set; }
public int ThrottleThresholdInSeconds { get; set; }
+ public string HardwareVideoDecoder { get; set; }
public EncodingOptions()
{
- H264Encoder = "libx264";
DownMixAudioBoost = 2;
EnableThrottling = true;
ThrottleThresholdInSeconds = 120;
diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs
index b55e727d6..c38c81866 100644
--- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs
+++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs
@@ -595,9 +595,7 @@ namespace MediaBrowser.Server.Startup.Common
var info = await new FFMpegDownloader(Logger, ApplicationPaths, HttpClient, ZipClient, FileSystemManager, NativeApp.Environment)
.GetFFMpegInfo(NativeApp.Environment, _startupOptions, progress).ConfigureAwait(false);
- new FFmpegValidator(Logger, ApplicationPaths, FileSystemManager).Validate(info);
-
- MediaEncoder = new MediaEncoder(LogManager.GetLogger("MediaEncoder"),
+ var mediaEncoder = new MediaEncoder(LogManager.GetLogger("MediaEncoder"),
JsonSerializer,
info.EncoderPath,
info.ProbePath,
@@ -611,7 +609,17 @@ namespace MediaBrowser.Server.Startup.Common
SessionManager,
() => SubtitleEncoder,
() => MediaSourceManager);
+
+ MediaEncoder = mediaEncoder;
RegisterSingleInstance(MediaEncoder);
+
+ Task.Run(() =>
+ {
+ var result = new FFmpegValidator(Logger, ApplicationPaths, FileSystemManager).Validate(info);
+
+ mediaEncoder.SetAvailableDecoders(result.Item1);
+ mediaEncoder.SetAvailableEncoders(result.Item2);
+ });
}
///
diff --git a/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegDownloadInfo.cs b/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegDownloadInfo.cs
index 2910479ef..c4fe7e43b 100644
--- a/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegDownloadInfo.cs
+++ b/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegDownloadInfo.cs
@@ -33,7 +33,7 @@ namespace MediaBrowser.Server.Startup.Common.FFMpeg
case OperatingSystem.Linux:
info.ArchiveType = "7z";
- info.Version = "20150717";
+ info.Version = "20150917";
break;
case OperatingSystem.Osx:
@@ -42,7 +42,7 @@ namespace MediaBrowser.Server.Startup.Common.FFMpeg
switch (environment.SystemArchitecture)
{
case Architecture.X86_X64:
- info.Version = "20150827";
+ info.Version = "20150917";
break;
case Architecture.X86:
info.Version = "20150110";
@@ -54,7 +54,7 @@ namespace MediaBrowser.Server.Startup.Common.FFMpeg
info.FFMpegFilename = "ffmpeg.exe";
info.FFProbeFilename = "ffprobe.exe";
- info.Version = "20150717";
+ info.Version = "20150916";
info.ArchiveType = "7z";
switch (environment.SystemArchitecture)
@@ -83,14 +83,14 @@ namespace MediaBrowser.Server.Startup.Common.FFMpeg
case Architecture.X86_X64:
return new[]
{
- "http://ffmpeg.zeranoe.com/builds/win64/static/ffmpeg-20150717-git-8250943-win64-static.7z",
- "https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/windows/ffmpeg-20150901-git-b54e03c-win64-static.7z"
+ "http://ffmpeg.zeranoe.com/builds/win64/static/ffmpeg-20150916-git-cbbd906-win64-static.7z",
+ "https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/windows/ffmpeg-20150916-git-cbbd906-win64-static.7z"
};
case Architecture.X86:
return new[]
{
- "http://ffmpeg.zeranoe.com/builds/win32/static/ffmpeg-20150717-git-8250943-win32-static.7z",
- "https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/windows/ffmpeg-20150901-git-b54e03c-win32-static.7z"
+ "http://ffmpeg.zeranoe.com/builds/win32/static/ffmpeg-20150916-git-cbbd906-win32-static.7z",
+ "https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/windows/ffmpeg-20150916-git-cbbd906-win32-static.7z"
};
}
break;
@@ -102,7 +102,7 @@ namespace MediaBrowser.Server.Startup.Common.FFMpeg
case Architecture.X86_X64:
return new[]
{
- "https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/osx/ffmpeg-x64-2.7.2.7z"
+ "https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/osx/ffmpeg-x64-2.8.0.7z"
};
case Architecture.X86:
return new[]
@@ -119,12 +119,12 @@ namespace MediaBrowser.Server.Startup.Common.FFMpeg
case Architecture.X86_X64:
return new[]
{
- "https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/linux/ffmpeg-2.7.1-64bit-static.7z"
+ "https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/linux/ffmpeg-2.8.0-64bit-static.7z"
};
case Architecture.X86:
return new[]
{
- "https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/linux/ffmpeg-2.7.1-32bit-static.7z"
+ "https://github.com/MediaBrowser/Emby.Resources/raw/master/ffmpeg/linux/ffmpeg-2.8.0-32bit-static.7z"
};
}
break;
diff --git a/MediaBrowser.Server.Startup.Common/FFMpeg/FFmpegValidator.cs b/MediaBrowser.Server.Startup.Common/FFMpeg/FFmpegValidator.cs
index 54cd1357a..d3388f47e 100644
--- a/MediaBrowser.Server.Startup.Common/FFMpeg/FFmpegValidator.cs
+++ b/MediaBrowser.Server.Startup.Common/FFMpeg/FFmpegValidator.cs
@@ -7,6 +7,7 @@ using System.Globalization;
using System.IO;
using System.Text;
using MediaBrowser.Common.IO;
+using System.Collections.Generic;
namespace MediaBrowser.Server.Startup.Common.FFMpeg
{
@@ -23,71 +24,65 @@ namespace MediaBrowser.Server.Startup.Common.FFMpeg
_fileSystem = fileSystem;
}
- public void Validate(FFMpegInfo info)
+ public Tuple,List> Validate(FFMpegInfo info)
{
_logger.Info("FFMpeg: {0}", info.EncoderPath);
_logger.Info("FFProbe: {0}", info.ProbePath);
- string cacheKey;
+ var decoders = GetDecoders(info.EncoderPath);
+ var encoders = GetEncoders(info.EncoderPath);
+ return new Tuple, List>(decoders, encoders);
+ }
+
+ private List GetDecoders(string ffmpegPath)
+ {
+ string output = string.Empty;
try
{
- cacheKey = new FileInfo(info.EncoderPath).Length.ToString(CultureInfo.InvariantCulture).GetMD5().ToString("N");
- }
- catch (IOException)
- {
- // This could happen if ffmpeg is coming from a Path variable and we don't have the full path
- cacheKey = Guid.NewGuid().ToString("N");
+ output = GetFFMpegOutput(ffmpegPath, "-decoders");
}
catch
{
- cacheKey = Guid.NewGuid().ToString("N");
}
- var cachePath = Path.Combine(_appPaths.CachePath, "1" + cacheKey);
+ var found = new List();
+ var required = new[]
+ {
+ "h264_qsv",
+ "mpeg2_qsv",
+ "vc1_qsv"
+ };
- ValidateCodecs(info.EncoderPath, cachePath);
+ foreach (var codec in required)
+ {
+ var srch = " " + codec + " ";
+
+ if (output.IndexOf(srch, StringComparison.OrdinalIgnoreCase) == -1)
+ {
+ _logger.Warn("ffmpeg is missing decoder " + codec);
+ }
+ else
+ {
+ found.Add(codec);
+ }
+ }
+
+ return found;
}
- private void ValidateCodecs(string ffmpegPath, string cachePath)
+ private List GetEncoders(string ffmpegPath)
{
string output = null;
try
{
- output = _fileSystem.ReadAllText(cachePath, Encoding.UTF8);
+ output = GetFFMpegOutput(ffmpegPath, "-encoders");
}
catch
{
-
}
- if (string.IsNullOrWhiteSpace(output))
- {
- try
- {
- output = GetFFMpegOutput(ffmpegPath, "-encoders");
- }
- catch
- {
- return;
- }
-
- try
- {
- _fileSystem.CreateDirectory(Path.GetDirectoryName(cachePath));
- _fileSystem.WriteAllText(cachePath, output, Encoding.UTF8);
- }
- catch
- {
-
- }
- }
-
- ValidateCodecsFromOutput(output);
- }
-
- private void ValidateCodecsFromOutput(string output)
- {
+ var found = new List();
var required = new[]
{
"libx264",
@@ -103,16 +98,21 @@ namespace MediaBrowser.Server.Startup.Common.FFMpeg
"srt"
};
- foreach (var encoder in required)
+ foreach (var codec in required)
{
- var srch = " " + encoder + " ";
+ var srch = " " + codec + " ";
if (output.IndexOf(srch, StringComparison.OrdinalIgnoreCase) == -1)
{
- _logger.Error("ffmpeg is missing encoder " + encoder);
- //throw new ArgumentException("ffmpeg is missing encoder " + encoder);
+ _logger.Warn("ffmpeg is missing encoder " + codec);
+ }
+ else
+ {
+ found.Add(codec);
}
}
+
+ return found;
}
private string GetFFMpegOutput(string path, string arguments)