瀏覽代碼

improve video startup performance

Luke Pulverenti 8 年之前
父節點
當前提交
30538f0731

+ 24 - 13
Emby.Server.Implementations/LiveTv/TunerHosts/MulticastStream.cs

@@ -1,4 +1,5 @@
 using System;
+using System.Collections.Concurrent;
 using System.Collections.Generic;
 using System.IO;
 using System.Linq;
@@ -11,10 +12,11 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
 {
     public class MulticastStream
     {
-        private readonly List<QueueStream> _outputStreams = new List<QueueStream>();
+        private readonly ConcurrentDictionary<Guid,QueueStream> _outputStreams = new ConcurrentDictionary<Guid, QueueStream>();
         private const int BufferSize = 81920;
         private CancellationToken _cancellationToken;
         private readonly ILogger _logger;
+        private readonly ConcurrentQueue<byte[]> _sharedBuffer = new ConcurrentQueue<byte[]>();
 
         public MulticastStream(ILogger logger)
         {
@@ -35,17 +37,19 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
                 {
                     byte[] copy = new byte[bytesRead];
                     Buffer.BlockCopy(buffer, 0, copy, 0, bytesRead);
-                   
-                    List<QueueStream> streams = null;
 
-                    lock (_outputStreams)
+                    _sharedBuffer.Enqueue(copy);
+
+                    while (_sharedBuffer.Count > 3000)
                     {
-                        streams = _outputStreams.ToList();
+                        byte[] bytes;
+                        _sharedBuffer.TryDequeue(out bytes);
                     }
 
-                    foreach (var stream in streams)
+                    var allStreams = _outputStreams.ToList();
+                    foreach (var stream in allStreams)
                     {
-                        stream.Queue(copy);
+                        stream.Value.Queue(copy);
                     }
 
                     if (onStarted != null)
@@ -70,11 +74,20 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
                 OnFinished = OnFinished
             };
 
-            lock (_outputStreams)
+            var initial = _sharedBuffer.ToList();
+            var list = new List<byte>();
+
+            foreach (var bytes in initial)
             {
-                _outputStreams.Add(result);
+                list.AddRange(bytes);
             }
 
+            _logger.Info("QueueStream started with {0} initial bytes", list.Count);
+
+            result.Queue(list.ToArray());
+
+            _outputStreams.TryAdd(result.Id, result);
+
             result.Start(_cancellationToken);
 
             return result.TaskCompletion.Task;
@@ -82,10 +95,8 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
 
         public void RemoveOutputStream(QueueStream stream)
         {
-            lock (_outputStreams)
-            {
-                _outputStreams.Remove(stream);
-            }
+            QueueStream removed;
+            _outputStreams.TryRemove(stream.Id, out removed);
         }
 
         private void OnFinished(QueueStream queueStream)

+ 3 - 13
Emby.Server.Implementations/LiveTv/TunerHosts/QueueStream.cs

@@ -19,7 +19,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
 
         public Action<QueueStream> OnFinished { get; set; }
         private readonly ILogger _logger;
-        private bool _isActive;
+        public Guid Id = Guid.NewGuid();
 
         public QueueStream(Stream outputStream, ILogger logger)
         {
@@ -30,10 +30,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
 
         public void Queue(byte[] bytes)
         {
-            if (_isActive)
-            {
-                _queue.Enqueue(bytes);
-            }
+            _queue.Enqueue(bytes);
         }
 
         public void Start(CancellationToken cancellationToken)
@@ -59,10 +56,8 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
 
             try
             {
-                while (!cancellationToken.IsCancellationRequested)
+                while (true)
                 {
-                    _isActive = true;
-
                     var bytes = Dequeue();
                     if (bytes != null)
                     {
@@ -73,9 +68,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
                         await Task.Delay(50, cancellationToken).ConfigureAwait(false);
                     }
                 }
-
-                TaskCompletion.TrySetResult(true);
-                _logger.Debug("QueueStream complete");
             }
             catch (OperationCanceledException)
             {
@@ -89,8 +81,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
             }
             finally
             {
-                _isActive = false;
-
                 if (OnFinished != null)
                 {
                     OnFinished(this);

+ 18 - 11
MediaBrowser.Api/Playback/BaseStreamingService.cs

@@ -2720,6 +2720,15 @@ namespace MediaBrowser.Api.Playback
                     //inputModifier += " -noaccurate_seek";
                 }
 
+                if (!string.IsNullOrWhiteSpace(state.InputContainer))
+                {
+                    var inputFormat = GetInputFormat(state.InputContainer);
+                    if (!string.IsNullOrWhiteSpace(inputFormat))
+                    {
+                        inputModifier += " -f " + inputFormat;
+                    }
+                }
+
                 if (state.RunTimeTicks.HasValue)
                 {
                     foreach (var stream in state.MediaSource.MediaStreams)
@@ -2738,21 +2747,19 @@ namespace MediaBrowser.Api.Playback
                         }
                     }
                 }
+            }
 
-                //var videoStream = state.VideoStream;
-                //if (videoStream != null && !string.IsNullOrWhiteSpace(videoStream.Codec))
-                //{
-                //    inputModifier += "  -codec:0 " + videoStream.Codec;
+            return inputModifier;
+        }
 
-                //    var audioStream = state.AudioStream;
-                //    if (audioStream != null && !string.IsNullOrWhiteSpace(audioStream.Codec))
-                //    {
-                //        inputModifier += "  -codec:1 " + audioStream.Codec;
-                //    }
-                //}
+        private string GetInputFormat(string container)
+        {
+            if (string.Equals(container, "mkv", StringComparison.OrdinalIgnoreCase))
+            {
+                return "matroska";
             }
 
-            return inputModifier;
+            return container;
         }
 
         private string GetDecoderFromCodec(string codec)

+ 1 - 1
MediaBrowser.Api/Playback/Hls/BaseHlsService.cs

@@ -103,7 +103,7 @@ namespace MediaBrowser.Api.Playback.Hls
                             throw;
                         }
 
-                        var waitForSegments = state.SegmentLength >= 10 ? 2 : 3;
+                        var waitForSegments = state.SegmentLength >= 10 ? 2 : 2;
                         await WaitForMinimumSegmentCount(playlist, waitForSegments, cancellationTokenSource.Token).ConfigureAwait(false);
                     }
                 }