| 
					
				 | 
			
			
				@@ -199,82 +199,83 @@ namespace MediaBrowser.MediaEncoding.Encoder 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             await _ffProbeResourcePool.WaitAsync(cancellationToken).ConfigureAwait(false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var processWrapper = new ProcessWrapper(process, this); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            try 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                StartProcess(processWrapper); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            catch (Exception ex) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            using (var processWrapper = new ProcessWrapper(process, this)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                _ffProbeResourcePool.Release(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                try 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    StartProcess(processWrapper); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                catch (Exception ex) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    _ffProbeResourcePool.Release(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                _logger.ErrorException("Error starting ffprobe", ex); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    _logger.ErrorException("Error starting ffprobe", ex); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                throw; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    throw; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            try 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                process.BeginErrorReadLine(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                try 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    process.BeginErrorReadLine(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                var result = _jsonSerializer.DeserializeFromStream<InternalMediaInfoResult>(process.StandardOutput.BaseStream); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    var result = _jsonSerializer.DeserializeFromStream<InternalMediaInfoResult>(process.StandardOutput.BaseStream); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                if (result != null) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    if (result.streams != null) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if (result != null) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        // Normalize aspect ratio if invalid 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        foreach (var stream in result.streams) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        if (result.streams != null) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            if (string.Equals(stream.display_aspect_ratio, "0:1", StringComparison.OrdinalIgnoreCase)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                stream.display_aspect_ratio = string.Empty; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            if (string.Equals(stream.sample_aspect_ratio, "0:1", StringComparison.OrdinalIgnoreCase)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            // Normalize aspect ratio if invalid 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            foreach (var stream in result.streams) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                stream.sample_aspect_ratio = string.Empty; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                if (string.Equals(stream.display_aspect_ratio, "0:1", StringComparison.OrdinalIgnoreCase)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                    stream.display_aspect_ratio = string.Empty; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                if (string.Equals(stream.sample_aspect_ratio, "0:1", StringComparison.OrdinalIgnoreCase)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                    stream.sample_aspect_ratio = string.Empty; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    var mediaInfo = new ProbeResultNormalizer(_logger, FileSystem).GetMediaInfo(result, videoType, isAudio, primaryPath, protocol); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        var mediaInfo = new ProbeResultNormalizer(_logger, FileSystem).GetMediaInfo(result, videoType, isAudio, primaryPath, protocol); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    if (extractKeyFrameInterval && mediaInfo.RunTimeTicks.HasValue) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        foreach (var stream in mediaInfo.MediaStreams) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        if (extractKeyFrameInterval && mediaInfo.RunTimeTicks.HasValue) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            if (stream.Type == MediaStreamType.Video && string.Equals(stream.Codec, "h264", StringComparison.OrdinalIgnoreCase)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            foreach (var stream in mediaInfo.MediaStreams) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                try 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                    //stream.KeyFrames = await GetKeyFrames(inputPath, stream.Index, cancellationToken) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                    //            .ConfigureAwait(false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                catch (OperationCanceledException) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                catch (Exception ex) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                if (stream.Type == MediaStreamType.Video && string.Equals(stream.Codec, "h264", StringComparison.OrdinalIgnoreCase)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                    _logger.ErrorException("Error getting key frame interval", ex); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                    try 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                        //stream.KeyFrames = await GetKeyFrames(inputPath, stream.Index, cancellationToken) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                        //            .ConfigureAwait(false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                    catch (OperationCanceledException) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                    catch (Exception ex) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                        _logger.ErrorException("Error getting key frame interval", ex); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    return mediaInfo; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        return mediaInfo; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            catch 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                StopProcess(processWrapper, 100, true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                catch 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    StopProcess(processWrapper, 100, true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                throw; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            finally 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                _ffProbeResourcePool.Release(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    throw; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                finally 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    _ffProbeResourcePool.Release(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             throw new ApplicationException(string.Format("FFProbe failed for {0}", inputPath)); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -307,31 +308,32 @@ namespace MediaBrowser.MediaEncoding.Encoder 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             _logger.Debug("{0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var processWrapper = new ProcessWrapper(process, this); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            StartProcess(processWrapper); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            using (var processWrapper = new ProcessWrapper(process, this)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                StartProcess(processWrapper); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var lines = new List<int>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                var lines = new List<int>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            try 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                process.BeginErrorReadLine(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                try 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    process.BeginErrorReadLine(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                await StartReadingOutput(process.StandardOutput.BaseStream, lines, 120000, cancellationToken).ConfigureAwait(false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            catch (OperationCanceledException) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                if (cancellationToken.IsCancellationRequested) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    await StartReadingOutput(process.StandardOutput.BaseStream, lines, 120000, cancellationToken).ConfigureAwait(false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                catch (OperationCanceledException) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    throw; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if (cancellationToken.IsCancellationRequested) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        throw; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                finally 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    StopProcess(processWrapper, 100, true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            finally 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                StopProcess(processWrapper, 100, true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            return lines; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return lines; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         private async Task StartReadingOutput(Stream source, List<int> lines, int timeoutMs, CancellationToken cancellationToken) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -490,51 +492,53 @@ namespace MediaBrowser.MediaEncoding.Encoder 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             await resourcePool.WaitAsync(cancellationToken).ConfigureAwait(false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var processWrapper = new ProcessWrapper(process, this); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            bool ranToCompletion; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            using (var processWrapper = new ProcessWrapper(process, this)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                bool ranToCompletion; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var memoryStream = new MemoryStream(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                var memoryStream = new MemoryStream(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            try 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                StartProcess(processWrapper); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                try 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    StartProcess(processWrapper); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #pragma warning disable 4014 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                // Important - don't await the log task or we won't be able to kill ffmpeg when the user stops playback 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                process.StandardOutput.BaseStream.CopyToAsync(memoryStream); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    // Important - don't await the log task or we won't be able to kill ffmpeg when the user stops playback 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    process.StandardOutput.BaseStream.CopyToAsync(memoryStream); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #pragma warning restore 4014 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                // MUST read both stdout and stderr asynchronously or a deadlock may occurr 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                process.BeginErrorReadLine(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    // MUST read both stdout and stderr asynchronously or a deadlock may occurr 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    process.BeginErrorReadLine(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                ranToCompletion = process.WaitForExit(10000); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    ranToCompletion = process.WaitForExit(10000); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                if (!ranToCompletion) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if (!ranToCompletion) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        StopProcess(processWrapper, 1000, false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                finally 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    StopProcess(processWrapper, 1000, false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    resourcePool.Release(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            finally 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                resourcePool.Release(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                var exitCode = ranToCompletion ? processWrapper.ExitCode ?? 0 : -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var exitCode = ranToCompletion ? processWrapper.ExitCode ?? 0 : -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (exitCode == -1 || memoryStream.Length == 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    memoryStream.Dispose(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (exitCode == -1 || memoryStream.Length == 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                memoryStream.Dispose(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    var msg = string.Format("ffmpeg image extraction failed for {0}", inputPath); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                var msg = string.Format("ffmpeg image extraction failed for {0}", inputPath); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    _logger.Error(msg); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                _logger.Error(msg); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    throw new ApplicationException(msg); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                throw new ApplicationException(msg); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                memoryStream.Position = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return memoryStream; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            memoryStream.Position = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            return memoryStream; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         public string GetTimeParameter(long ticks) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -603,55 +607,56 @@ namespace MediaBrowser.MediaEncoding.Encoder 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             bool ranToCompletion = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var processWrapper = new ProcessWrapper(process, this); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            try 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            using (var processWrapper = new ProcessWrapper(process, this)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                StartProcess(processWrapper); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                try 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    StartProcess(processWrapper); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                // Need to give ffmpeg enough time to make all the thumbnails, which could be a while, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                // but we still need to detect if the process hangs. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                // Making the assumption that as long as new jpegs are showing up, everything is good. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    // Need to give ffmpeg enough time to make all the thumbnails, which could be a while, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    // but we still need to detect if the process hangs. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    // Making the assumption that as long as new jpegs are showing up, everything is good. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                bool isResponsive = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                int lastCount = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    bool isResponsive = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    int lastCount = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                while (isResponsive) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    if (process.WaitForExit(30000)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    while (isResponsive) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        ranToCompletion = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        if (process.WaitForExit(30000)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            ranToCompletion = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        cancellationToken.ThrowIfCancellationRequested(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    cancellationToken.ThrowIfCancellationRequested(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        var jpegCount = Directory.GetFiles(targetDirectory) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            .Count(i => string.Equals(Path.GetExtension(i), ".jpg", StringComparison.OrdinalIgnoreCase)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    var jpegCount = Directory.GetFiles(targetDirectory) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        .Count(i => string.Equals(Path.GetExtension(i), ".jpg", StringComparison.OrdinalIgnoreCase)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        isResponsive = (jpegCount > lastCount); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        lastCount = jpegCount; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    isResponsive = (jpegCount > lastCount); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    lastCount = jpegCount; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if (!ranToCompletion) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        StopProcess(processWrapper, 1000, false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                if (!ranToCompletion) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                finally 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    StopProcess(processWrapper, 1000, false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    resourcePool.Release(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            finally 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                resourcePool.Release(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var exitCode = ranToCompletion ? processWrapper.ExitCode ?? 0 : -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                var exitCode = ranToCompletion ? processWrapper.ExitCode ?? 0 : -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (exitCode == -1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                var msg = string.Format("ffmpeg image extraction failed for {0}", inputArgument); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (exitCode == -1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    var msg = string.Format("ffmpeg image extraction failed for {0}", inputArgument); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                _logger.Error(msg); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    _logger.Error(msg); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                throw new ApplicationException(msg); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    throw new ApplicationException(msg); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -781,7 +786,7 @@ namespace MediaBrowser.MediaEncoding.Encoder 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        private class ProcessWrapper 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        private class ProcessWrapper : IDisposable 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             public readonly Process Process; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             public bool HasExited; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -810,6 +815,25 @@ namespace MediaBrowser.MediaEncoding.Encoder 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 process.Dispose(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            private bool _disposed; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            private readonly object _syncLock = new object(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            public void Dispose() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                lock (_syncLock) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if (!_disposed) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        if (Process != null) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            Process.Exited -= Process_Exited; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            Process.Dispose(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    _disposed = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 |