Fix stuck frames while scrubbing video

This commit is contained in:
Peter 2019-07-25 18:02:02 +01:00
parent 209319ec23
commit db4aa60e6e
3 changed files with 25 additions and 24 deletions

View File

@ -63,26 +63,28 @@ private final class MediaPlayerFramePreviewImpl {
let takeDisposable = MetaDisposable() let takeDisposable = MetaDisposable()
let disposable = (self.context.get() let disposable = (self.context.get()
|> take(1)).start(next: { [weak self] context in |> take(1)).start(next: { [weak self] context in
queue.async { queue.justDispatch {
guard context.queue === queue else { guard context.queue === queue else {
return return
} }
context.with { context in context.with { context in
let disposable = context.source.takeFrame(at: timestamp).start(next: { result in let disposable = context.source.takeFrame(at: timestamp).start(next: { result in
guard let strongSelf = self else { queue.async {
return guard let strongSelf = self else {
} return
switch result {
case .waitingForData:
strongSelf.framePipe.putNext(.waitingForData)
case let .image(image):
if let image = image {
strongSelf.framePipe.putNext(.image(image))
} }
strongSelf.currentFrameTimestamp = nil switch result {
if let nextFrameTimestamp = strongSelf.nextFrameTimestamp { case .waitingForData:
strongSelf.nextFrameTimestamp = nil strongSelf.framePipe.putNext(.waitingForData)
strongSelf.generateFrame(at: nextFrameTimestamp) case let .image(image):
if let image = image {
strongSelf.framePipe.putNext(.image(image))
}
strongSelf.currentFrameTimestamp = nil
if let nextFrameTimestamp = strongSelf.nextFrameTimestamp {
strongSelf.nextFrameTimestamp = nil
strongSelf.generateFrame(at: nextFrameTimestamp)
}
} }
} }
}) })
@ -91,8 +93,10 @@ private final class MediaPlayerFramePreviewImpl {
} }
}) })
self.currentFrameDisposable.set(ActionDisposable { self.currentFrameDisposable.set(ActionDisposable {
takeDisposable.dispose() queue.async {
disposable.dispose() takeDisposable.dispose()
disposable.dispose()
}
}) })
} }

View File

@ -249,11 +249,11 @@ private final class UniversalSoftwareVideoSourceImpl {
self.currentNumberOfReads = 0 self.currentNumberOfReads = 0
self.currentReadBytes = 0 self.currentReadBytes = 0
for i in 0 ..< 10 { for _ in 0 ..< 10 {
let (decodableFrame, loop) = self.readDecodableFrame() let (decodableFrame, loop) = self.readDecodableFrame()
if let decodableFrame = decodableFrame { if let decodableFrame = decodableFrame {
if let renderedFrame = videoStream.decoder.render(frame: decodableFrame) { if let renderedFrame = videoStream.decoder.render(frame: decodableFrame) {
print("Frame rendered in \(self.currentNumberOfReads) reads, \(self.currentReadBytes) bytes, total frames read: \(i + 1)") //print("Frame rendered in \(self.currentNumberOfReads) reads, \(self.currentReadBytes) bytes, total frames read: \(i + 1)")
return (renderedFrame, CGFloat(videoStream.rotationAngle), CGFloat(videoStream.aspect), loop) return (renderedFrame, CGFloat(videoStream.rotationAngle), CGFloat(videoStream.aspect), loop)
} }
} }
@ -332,11 +332,11 @@ private final class UniversalSoftwareVideoSourceThread: NSObject {
source.cancelRead = params.cancel source.cancelRead = params.cancel
source.requiredDataIsNotLocallyAvailable = params.requiredDataIsNotLocallyAvailable source.requiredDataIsNotLocallyAvailable = params.requiredDataIsNotLocallyAvailable
source.state.set(.generatingFrame) source.state.set(.generatingFrame)
let startTime = CFAbsoluteTimeGetCurrent()
let image = source.readImage(at: params.timestamp).0 let image = source.readImage(at: params.timestamp).0
params.completion(image) source.cancelRead = .single(false)
source.requiredDataIsNotLocallyAvailable = nil
source.state.set(.ready) source.state.set(.ready)
print("take frame: \(CFAbsoluteTimeGetCurrent() - startTime) s") params.completion(image)
} }
} }

View File

@ -605,9 +605,6 @@ private final class MultipartFetchManager {
while 1024 * 1024 % downloadRange.count != 0 { while 1024 * 1024 % downloadRange.count != 0 {
downloadRange = downloadRange.lowerBound ..< (downloadRange.upperBound - 1) downloadRange = downloadRange.lowerBound ..< (downloadRange.upperBound - 1)
} }
if case .maximum = priority {
print("fetch maximum \(downloadRange.lowerBound), \(downloadRange.count)")
}
var intervalIndexSet = IndexSet(integersIn: intervalsToFetch[currentIntervalIndex].0) var intervalIndexSet = IndexSet(integersIn: intervalsToFetch[currentIntervalIndex].0)
intervalIndexSet.remove(integersIn: downloadRange) intervalIndexSet.remove(integersIn: downloadRange)