From 6f268d7998fc926312280e1c83d076bd20a27af7 Mon Sep 17 00:00:00 2001 From: Peter <> Date: Wed, 17 Jul 2019 17:45:23 +0100 Subject: [PATCH] More granular video scrubbing --- .../Sources/UniversalSoftwareVideoSource.swift | 13 ++++++++----- submodules/Postbox/Postbox/MediaBox.swift | 1 + .../TelegramCore/TelegramCore/MultipartFetch.swift | 14 +++++++++----- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/submodules/MediaPlayer/Sources/UniversalSoftwareVideoSource.swift b/submodules/MediaPlayer/Sources/UniversalSoftwareVideoSource.swift index 9eefce0a6b..e2eb160c36 100644 --- a/submodules/MediaPlayer/Sources/UniversalSoftwareVideoSource.swift +++ b/submodules/MediaPlayer/Sources/UniversalSoftwareVideoSource.swift @@ -19,11 +19,18 @@ private func readPacketCallback(userData: UnsafeMutableRawPointer?, buffer: Unsa data = context.mediaBox.resourceData(context.fileReference.media.resource, size: context.size, in: requestRange, mode: .partial) let requiredDataIsNotLocallyAvailable = context.requiredDataIsNotLocallyAvailable var fetchedData: Data? + let fetchDisposable = MetaDisposable() + let isInitialized = context.videoStream != nil + let mediaBox = context.mediaBox + let reference = context.fileReference.resourceReference(context.fileReference.media.resource) let disposable = data.start(next: { data in if data.count == readCount { fetchedData = data semaphore.signal() } else { + if isInitialized { + fetchDisposable.set(fetchedMediaResource(mediaBox: mediaBox, reference: reference, ranges: [(requestRange, .maximum)]).start()) + } requiredDataIsNotLocallyAvailable?() } }) @@ -32,15 +39,11 @@ private func readPacketCallback(userData: UnsafeMutableRawPointer?, buffer: Unsa semaphore.signal() } }) - var fetchDisposable: Disposable? - if context.videoStream != nil { - fetchDisposable = fetchedMediaResource(mediaBox: context.mediaBox, reference: context.fileReference.resourceReference(context.fileReference.media.resource), ranges: [(requestRange, .elevated)]).start() - } semaphore.wait() disposable.dispose() cancelDisposable.dispose() - fetchDisposable?.dispose() + fetchDisposable.dispose() if let fetchedData = fetchedData { fetchedData.withUnsafeBytes { (bytes: UnsafePointer) -> Void in diff --git a/submodules/Postbox/Postbox/MediaBox.swift b/submodules/Postbox/Postbox/MediaBox.swift index 9cd04f3ef1..81a554f8f5 100644 --- a/submodules/Postbox/Postbox/MediaBox.swift +++ b/submodules/Postbox/Postbox/MediaBox.swift @@ -70,6 +70,7 @@ public protocol MediaResourceDataFetchCopyLocalItem { public enum MediaBoxFetchPriority: Int32 { case `default` = 0 case elevated = 1 + case maximum = 2 } public enum MediaResourceDataFetchResult { diff --git a/submodules/TelegramCore/TelegramCore/MultipartFetch.swift b/submodules/TelegramCore/TelegramCore/MultipartFetch.swift index b09ae7d48b..544306a9b1 100644 --- a/submodules/TelegramCore/TelegramCore/MultipartFetch.swift +++ b/submodules/TelegramCore/TelegramCore/MultipartFetch.swift @@ -400,7 +400,7 @@ private enum MultipartFetchSource { private final class MultipartFetchManager { let parallelParts: Int let defaultPartSize = 128 * 1024 - let partAlignment = 128 * 1024 + let partAlignment = 4 * 1024 var resource: TelegramMediaResource var resourceReference: MediaResourceReference? @@ -571,15 +571,19 @@ private final class MultipartFetchManager { } while !intervalsToFetch.isEmpty && self.fetchingParts.count < self.parallelParts && !self.reuploadingToCdn && !self.revalidatingMediaReference { - var elevatedIndices: [Int] = [] + + var indicesByPriority: [MediaBoxFetchPriority: [Int]] = [:] for i in 0 ..< intervalsToFetch.count { - if case .elevated = intervalsToFetch[i].1 { - elevatedIndices.append(i) + if indicesByPriority[intervalsToFetch[i].1] == nil { + indicesByPriority[intervalsToFetch[i].1] = [] } + indicesByPriority[intervalsToFetch[i].1]!.append(i) } let currentIntervalIndex: Int - if !elevatedIndices.isEmpty { + if let maxIndices = indicesByPriority[.maximum], !maxIndices.isEmpty { + currentIntervalIndex = maxIndices[self.nextFetchingPartId % maxIndices.count] + } else if let elevatedIndices = indicesByPriority[.elevated], !elevatedIndices.isEmpty { currentIntervalIndex = elevatedIndices[self.nextFetchingPartId % elevatedIndices.count] } else { currentIntervalIndex = self.nextFetchingPartId % intervalsToFetch.count