Browse Source

add automatic stream copy for hls

Luke Pulverenti 11 years ago
parent
commit
6fe7264f78

+ 105 - 2
MediaBrowser.Api/Playback/BaseStreamingService.cs

@@ -309,9 +309,9 @@ namespace MediaBrowser.Api.Playback
                 case EncodingQuality.HighSpeed:
                 case EncodingQuality.HighSpeed:
                     return 2;
                     return 2;
                 case EncodingQuality.HighQuality:
                 case EncodingQuality.HighQuality:
-                    return 2;
+                    return isWebm ? Math.Max(Environment.ProcessorCount - 1, 1) : 0;
                 case EncodingQuality.MaxQuality:
                 case EncodingQuality.MaxQuality:
-                    return isWebm ? 2 : 0;
+                    return isWebm ? Math.Max(Environment.ProcessorCount - 1, 1) : 0;
                 default:
                 default:
                     throw new Exception("Unrecognized MediaEncodingQuality value.");
                     throw new Exception("Unrecognized MediaEncodingQuality value.");
             }
             }
@@ -1499,9 +1499,112 @@ namespace MediaBrowser.Api.Playback
 
 
             ApplyDeviceProfileSettings(state);
             ApplyDeviceProfileSettings(state);
 
 
+            if (videoRequest != null && state.VideoStream != null)
+            {
+                if (CanStreamCopyVideo(videoRequest, state.VideoStream, state.VideoType))
+                {
+                    videoRequest.VideoCodec = "copy";
+                }
+            }
+
             return state;
             return state;
         }
         }
 
 
+        private bool CanStreamCopyVideo(VideoStreamRequest request, MediaStream videoStream, VideoType videoType)
+        {
+            if (videoStream.IsInterlaced)
+            {
+                return false;
+            }
+
+            // Not going to attempt this with folder rips
+            if (videoType != VideoType.VideoFile)
+            {
+                return false;
+            }
+
+            // Source and target codecs must match
+            if (!string.Equals(request.VideoCodec, videoStream.Codec, StringComparison.OrdinalIgnoreCase))
+            {
+                return false;
+            }
+
+            // If client is requesting a specific video profile, it must match the source
+            if (!string.IsNullOrEmpty(request.Profile) && !string.Equals(request.Profile, videoStream.Profile))
+            {
+                return false;
+            }
+
+            // Video width must fall within requested value
+            if (request.MaxWidth.HasValue)
+            {
+                if (!videoStream.Width.HasValue || videoStream.Width.Value > request.MaxWidth.Value)
+                {
+                    return false;
+                }
+            }
+
+            // Video height must fall within requested value
+            if (request.MaxHeight.HasValue)
+            {
+                if (!videoStream.Height.HasValue || videoStream.Height.Value > request.MaxHeight.Value)
+                {
+                    return false;
+                }
+            }
+
+            // Video framerate must fall within requested value
+            var requestedFramerate = request.MaxFramerate ?? request.Framerate;
+            if (requestedFramerate.HasValue)
+            {
+                var videoFrameRate = videoStream.AverageFrameRate ?? videoStream.RealFrameRate;
+
+                if (!videoFrameRate.HasValue || videoFrameRate.Value > requestedFramerate.Value)
+                {
+                    return false;
+                }
+            }
+
+            // Video bitrate must fall within requested value
+            if (request.VideoBitRate.HasValue)
+            {
+                if (!videoStream.BitRate.HasValue || videoStream.BitRate.Value > request.VideoBitRate.Value)
+                {
+                    return false;
+                }
+            }
+
+            // If a specific level was requested, the source must match or be less than
+            if (!string.IsNullOrEmpty(request.Level))
+            {
+                double requestLevel;
+
+                if (double.TryParse(request.Level, NumberStyles.Any, UsCulture, out requestLevel))
+                {
+                    if (!videoStream.Level.HasValue)
+                    {
+                        return false;
+                    }
+
+                    if (videoStream.Level.Value > requestLevel)
+                    {
+                        return false;
+                    }
+                }
+                return false;
+            }
+
+            return SupportsAutomaticVideoStreamCopy;
+        }
+
+        protected virtual bool SupportsAutomaticVideoStreamCopy
+        {
+            get
+            {
+                return false;
+            }
+        }
+
         private void ApplyDeviceProfileSettings(StreamState state)
         private void ApplyDeviceProfileSettings(StreamState state)
         {
         {
             var headers = new Dictionary<string, string>();
             var headers = new Dictionary<string, string>();

+ 8 - 0
MediaBrowser.Api/Playback/Hls/VideoHlsService.cs

@@ -98,6 +98,14 @@ namespace MediaBrowser.Api.Playback.Hls
             ApiEntryPoint.Instance.OnTranscodeEndRequest(playlist, TranscodingJobType.Hls);
             ApiEntryPoint.Instance.OnTranscodeEndRequest(playlist, TranscodingJobType.Hls);
         }
         }
 
 
+        protected override bool SupportsAutomaticVideoStreamCopy
+        {
+            get
+            {
+                return true;
+            }
+        }
+
         /// <summary>
         /// <summary>
         /// Gets the specified request.
         /// Gets the specified request.
         /// </summary>
         /// </summary>

+ 2 - 2
MediaBrowser.MediaEncoding/Encoder/EncodingUtils.cs

@@ -224,9 +224,9 @@ namespace MediaBrowser.MediaEncoding.Encoder
                 case EncodingQuality.HighSpeed:
                 case EncodingQuality.HighSpeed:
                     return 2;
                     return 2;
                 case EncodingQuality.HighQuality:
                 case EncodingQuality.HighQuality:
-                    return 2;
+                    return isWebm ? Math.Max(Environment.ProcessorCount - 1, 1) : 0;
                 case EncodingQuality.MaxQuality:
                 case EncodingQuality.MaxQuality:
-                    return isWebm ? 2 : 0;
+                    return isWebm ? Math.Max(Environment.ProcessorCount - 1, 1) : 0;
                 default:
                 default:
                     throw new Exception("Unrecognized MediaEncodingQuality value.");
                     throw new Exception("Unrecognized MediaEncodingQuality value.");
             }
             }