Browse Source

added setting for intel qsv hardware decoding

Luke Pulverenti 9 years ago
parent
commit
5340bfe8da

+ 42 - 9
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";
         }
 
+        /// <summary>
+        /// Gets the name of the output video codec
+        /// </summary>
+        /// <param name="state">The state.</param>
+        /// <returns>System.String.</returns>
+        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;
+        }
+
         /// <summary>
         /// Gets the input argument.
         /// </summary>
@@ -816,7 +849,7 @@ namespace MediaBrowser.Api.Playback
         /// <returns>System.String.</returns>
         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)

+ 7 - 0
MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs

@@ -24,6 +24,13 @@ namespace MediaBrowser.Controller.MediaEncoding
         /// <value>The version.</value>
         string Version { get; }
 
+        /// <summary>
+        /// Supportses the decoder.
+        /// </summary>
+        /// <param name="decoder">The decoder.</param>
+        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
+        bool SupportsDecoder(string decoder);
+
         /// <summary>
         /// Extracts the audio image.
         /// </summary>

+ 16 - 0
MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs

@@ -97,6 +97,22 @@ namespace MediaBrowser.MediaEncoding.Encoder
             FFMpegPath = ffMpegPath;
         }
 
+        public void SetAvailableEncoders(List<string> list)
+        {
+
+        }
+
+        private List<string> _decoders = new List<string>();
+        public void SetAvailableDecoders(List<string> list)
+        {
+            _decoders = list.ToList();
+        }
+
+        public bool SupportsDecoder(string decoder)
+        {
+            return _decoders.Contains(decoder, StringComparer.OrdinalIgnoreCase);
+        }
+
         /// <summary>
         /// Gets the encoder path.
         /// </summary>

+ 1 - 2
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;

+ 11 - 3
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);
+            });
         }
 
         /// <summary>

+ 10 - 10
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;

+ 43 - 43
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<string>,List<string>> 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);
 
-            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");
-            }
-            catch
-            {
-                cacheKey = Guid.NewGuid().ToString("N");
-            }
-
-            var cachePath = Path.Combine(_appPaths.CachePath, "1" + cacheKey);
-
-            ValidateCodecs(info.EncoderPath, cachePath);
+            return new Tuple<List<string>, List<string>>(decoders, encoders);
         }
 
-        private void ValidateCodecs(string ffmpegPath, string cachePath)
+        private List<string> GetDecoders(string ffmpegPath)
         {
-            string output = null;
+            string output = string.Empty;
             try
             {
-				output = _fileSystem.ReadAllText(cachePath, Encoding.UTF8);
+                output = GetFFMpegOutput(ffmpegPath, "-decoders");
             }
             catch
             {
-
             }
 
-            if (string.IsNullOrWhiteSpace(output))
+            var found = new List<string>();
+            var required = new[]
             {
-                try
-                {
-                    output = GetFFMpegOutput(ffmpegPath, "-encoders");
-                }
-                catch
-                {
-                    return;
-                }
+                "h264_qsv",
+                "mpeg2_qsv",
+                "vc1_qsv"
+            };
 
-                try
+            foreach (var codec in required)
+            {
+                var srch = " " + codec + "  ";
+
+                if (output.IndexOf(srch, StringComparison.OrdinalIgnoreCase) == -1)
                 {
-					_fileSystem.CreateDirectory(Path.GetDirectoryName(cachePath));
-					_fileSystem.WriteAllText(cachePath, output, Encoding.UTF8);
+                    _logger.Warn("ffmpeg is missing decoder " + codec);
                 }
-                catch
+                else
                 {
-
+                    found.Add(codec);
                 }
             }
 
-            ValidateCodecsFromOutput(output);
+            return found;
         }
 
-        private void ValidateCodecsFromOutput(string output)
+        private List<string> GetEncoders(string ffmpegPath)
         {
+            string output = null;
+            try
+            {
+                output = GetFFMpegOutput(ffmpegPath, "-encoders");
+            }
+            catch
+            {
+            }
+
+            var found = new List<string>();
             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)