|  | @@ -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)
 |