Video editor fixes

This commit is contained in:
Ilya Laktyushin
2020-05-29 13:51:58 +03:00
parent 5dadaeb29e
commit d0b4ba6f7e
3 changed files with 47 additions and 31 deletions

View File

@@ -21,6 +21,8 @@ class LegacyPaintStickerView: UIView, TGPhotoPaintStickerRenderView {
private var didSetUpAnimationNode = false private var didSetUpAnimationNode = false
private let stickerFetchedDisposable = MetaDisposable() private let stickerFetchedDisposable = MetaDisposable()
private let cachedDisposable = MetaDisposable()
init(context: AccountContext, file: TelegramMediaFile) { init(context: AccountContext, file: TelegramMediaFile) {
self.context = context self.context = context
self.file = file self.file = file
@@ -40,6 +42,7 @@ class LegacyPaintStickerView: UIView, TGPhotoPaintStickerRenderView {
deinit { deinit {
self.stickerFetchedDisposable.dispose() self.stickerFetchedDisposable.dispose()
self.cachedDisposable.dispose()
} }
func image() -> UIImage! { func image() -> UIImage! {
@@ -103,7 +106,11 @@ class LegacyPaintStickerView: UIView, TGPhotoPaintStickerRenderView {
self.didSetUpAnimationNode = true self.didSetUpAnimationNode = true
let dimensions = self.file.dimensions ?? PixelDimensions(width: 512, height: 512) let dimensions = self.file.dimensions ?? PixelDimensions(width: 512, height: 512)
let fittedDimensions = dimensions.cgSize.aspectFitted(CGSize(width: 384.0, height: 384.0)) let fittedDimensions = dimensions.cgSize.aspectFitted(CGSize(width: 384.0, height: 384.0))
self.animationNode?.setup(source: AnimatedStickerResourceSource(account: self.context.account, resource: self.file.resource), width: Int(fittedDimensions.width), height: Int(fittedDimensions.height), mode: .direct) let source = AnimatedStickerResourceSource(account: self.context.account, resource: self.file.resource)
self.animationNode?.setup(source: source, width: Int(fittedDimensions.width), height: Int(fittedDimensions.height), mode: .direct)
self.cachedDisposable.set((source.cachedDataPath(width: 384, height: 384)
|> deliverOn(Queue.concurrentDefaultQueue())).start())
} }
} }
} }

View File

@@ -20,6 +20,30 @@ protocol LegacyPaintEntity {
func image(for time: CMTime, fps: Int, completion: @escaping (CIImage?) -> Void) func image(for time: CMTime, fps: Int, completion: @escaping (CIImage?) -> Void)
} }
private func render(width: Int, height: Int, bytesPerRow: Int, data: Data, type: AnimationRendererFrameType) -> CIImage? {
let calculatedBytesPerRow = (4 * Int(width) + 15) & (~15)
assert(bytesPerRow == calculatedBytesPerRow)
let image = generateImagePixel(CGSize(width: CGFloat(width), height: CGFloat(height)), scale: 1.0, pixelGenerator: { _, pixelData, bytesPerRow in
switch type {
case .yuva:
data.withUnsafeBytes { (bytes: UnsafePointer<UInt8>) -> Void in
decodeYUVAToRGBA(bytes, pixelData, Int32(width), Int32(height), Int32(bytesPerRow))
}
case .argb:
data.withUnsafeBytes { (bytes: UnsafePointer<UInt8>) -> Void in
memcpy(pixelData, bytes, data.count)
}
}
})
if let image = image {
return CIImage(image: image)
} else {
return nil
}
}
private class LegacyPaintStickerEntity: LegacyPaintEntity { private class LegacyPaintStickerEntity: LegacyPaintEntity {
var position: CGPoint { var position: CGPoint {
return self.entity.position return self.entity.position
@@ -71,7 +95,7 @@ private class LegacyPaintStickerEntity: LegacyPaintEntity {
self.source = AnimatedStickerResourceSource(account: account, resource: file.resource) self.source = AnimatedStickerResourceSource(account: account, resource: file.resource)
if let source = self.source { if let source = self.source {
let dimensions = self.file.dimensions ?? PixelDimensions(width: 512, height: 512) let dimensions = self.file.dimensions ?? PixelDimensions(width: 512, height: 512)
let fittedDimensions = dimensions.cgSize.aspectFitted(CGSize(width: 512.0, height: 512.0)) let fittedDimensions = dimensions.cgSize.aspectFitted(CGSize(width: 384, height: 384))
self.disposables.add((source.cachedDataPath(width: Int(fittedDimensions.width), height: Int(fittedDimensions.height)) self.disposables.add((source.cachedDataPath(width: Int(fittedDimensions.width), height: Int(fittedDimensions.height))
|> deliverOn(self.queue)).start(next: { [weak self] path, complete in |> deliverOn(self.queue)).start(next: { [weak self] path, complete in
if let strongSelf = self, complete { if let strongSelf = self, complete {
@@ -119,30 +143,6 @@ private class LegacyPaintStickerEntity: LegacyPaintEntity {
return self.durationPromise.get() return self.durationPromise.get()
} }
private func render(width: Int, height: Int, bytesPerRow: Int, data: Data, type: AnimationRendererFrameType) -> CIImage? {
let calculatedBytesPerRow = (4 * Int(width) + 15) & (~15)
assert(bytesPerRow == calculatedBytesPerRow)
let image = generateImagePixel(CGSize(width: CGFloat(width), height: CGFloat(height)), scale: 1.0, pixelGenerator: { _, pixelData, bytesPerRow in
switch type {
case .yuva:
data.withUnsafeBytes { (bytes: UnsafePointer<UInt8>) -> Void in
decodeYUVAToRGBA(bytes, pixelData, Int32(width), Int32(height), Int32(bytesPerRow))
}
case .argb:
data.withUnsafeBytes { (bytes: UnsafePointer<UInt8>) -> Void in
memcpy(pixelData, bytes, data.count)
}
}
})
if let image = image {
return CIImage(image: image)
} else {
return nil
}
}
var currentFrameIndex: Int? var currentFrameIndex: Int?
var cachedCIImage: CIImage? var cachedCIImage: CIImage?
@@ -194,7 +194,7 @@ private class LegacyPaintStickerEntity: LegacyPaintEntity {
return frame return frame
} }
if let maybeFrame = maybeFrame, let frame = maybeFrame { if let maybeFrame = maybeFrame, let frame = maybeFrame {
let image = strongSelf.render(width: frame.width, height: frame.height, bytesPerRow: frame.bytesPerRow, data: frame.data, type: frame.type) let image = render(width: frame.width, height: frame.height, bytesPerRow: frame.bytesPerRow, data: frame.data, type: frame.type)
completion(image) completion(image)
strongSelf.cachedCIImage = image strongSelf.cachedCIImage = image
} else { } else {

View File

@@ -61,6 +61,7 @@ private final class DrawingStickersScreenNode: ViewControllerTracingNode {
private let stickerListView: ListView private let stickerListView: ListView
private let maskListView: ListView private let maskListView: ListView
private var hiddenListView: ListView?
private var searchContainerNode: PaneSearchContainerNode? private var searchContainerNode: PaneSearchContainerNode?
private let searchContainerNodeLoadedDisposable = MetaDisposable() private let searchContainerNodeLoadedDisposable = MetaDisposable()
@@ -293,8 +294,8 @@ private final class DrawingStickersScreenNode: ViewControllerTracingNode {
} }
} }
} }
}, openPeerSpecificSettings: { [weak self] in }, openPeerSpecificSettings: {
}, dismissPeerSpecificSettings: { [weak self] in }, dismissPeerSpecificSettings: {
}, clearRecentlyUsedStickers: { [weak self] in }, clearRecentlyUsedStickers: { [weak self] in
if let strongSelf = self { if let strongSelf = self {
let actionSheet = ActionSheetController(theme: ActionSheetControllerTheme(presentationTheme: strongSelf.presentationData.theme, fontSize: strongSelf.presentationData.listsFontSize)) let actionSheet = ActionSheetController(theme: ActionSheetControllerTheme(presentationTheme: strongSelf.presentationData.theme, fontSize: strongSelf.presentationData.listsFontSize))
@@ -410,8 +411,8 @@ private final class DrawingStickersScreenNode: ViewControllerTracingNode {
} }
} }
} }
}, openPeerSpecificSettings: { [weak self] in }, openPeerSpecificSettings: {
}, dismissPeerSpecificSettings: { [weak self] in }, dismissPeerSpecificSettings: {
}, clearRecentlyUsedStickers: { [weak self] in }, clearRecentlyUsedStickers: { [weak self] in
if let strongSelf = self { if let strongSelf = self {
let actionSheet = ActionSheetController(theme: ActionSheetControllerTheme(presentationTheme: strongSelf.presentationData.theme, fontSize: strongSelf.presentationData.listsFontSize)) let actionSheet = ActionSheetController(theme: ActionSheetControllerTheme(presentationTheme: strongSelf.presentationData.theme, fontSize: strongSelf.presentationData.listsFontSize))
@@ -1274,6 +1275,11 @@ private final class DrawingStickersScreenNode: ViewControllerTracingNode {
if let hiddenPane = self.hiddenPane { if let hiddenPane = self.hiddenPane {
self.insertSubnode(hiddenPane, belowSubnode: self.collectionListContainer) self.insertSubnode(hiddenPane, belowSubnode: self.collectionListContainer)
self.hiddenPane = nil
}
if let hiddenListView = self.hiddenListView {
self.collectionListContainer.addSubnode(hiddenListView)
self.hiddenListView = nil
} }
self.layer.animatePosition(from: CGPoint(x: self.layer.position.x, y: self.layer.position.y + self.layer.bounds.size.height), to: self.layer.position, duration: 0.5, timingFunction: kCAMediaTimingFunctionSpring, completion: { [weak self] _ in self.layer.animatePosition(from: CGPoint(x: self.layer.position.x, y: self.layer.position.y + self.layer.bounds.size.height), to: self.layer.position, duration: 0.5, timingFunction: kCAMediaTimingFunctionSpring, completion: { [weak self] _ in
@@ -1291,10 +1297,13 @@ private final class DrawingStickersScreenNode: ViewControllerTracingNode {
if let strongSelf = self { if let strongSelf = self {
if strongSelf.stickerPane.supernode != nil { if strongSelf.stickerPane.supernode != nil {
strongSelf.hiddenPane = strongSelf.stickerPane strongSelf.hiddenPane = strongSelf.stickerPane
strongSelf.hiddenListView = strongSelf.stickerListView
} else if strongSelf.maskPane.supernode != nil { } else if strongSelf.maskPane.supernode != nil {
strongSelf.hiddenPane = strongSelf.maskPane strongSelf.hiddenPane = strongSelf.maskPane
strongSelf.hiddenListView = strongSelf.maskListView
} }
strongSelf.hiddenPane?.removeFromSupernode() strongSelf.hiddenPane?.removeFromSupernode()
strongSelf.hiddenListView?.removeFromSupernode()
strongSelf.isHidden = true strongSelf.isHidden = true
} }
}) })