mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-23 22:55:00 +00:00
[WIP] Story collage
This commit is contained in:
@@ -59,15 +59,15 @@ protocol RenderTarget: AnyObject {
|
||||
|
||||
final class MediaEditorRenderer {
|
||||
enum Input {
|
||||
case texture(MTLTexture, CMTime, Bool)
|
||||
case videoBuffer(VideoPixelBuffer)
|
||||
case texture(MTLTexture, CMTime, Bool, CGRect?)
|
||||
case videoBuffer(VideoPixelBuffer, CGRect?)
|
||||
case ciImage(CIImage, CMTime)
|
||||
|
||||
var timestamp: CMTime {
|
||||
switch self {
|
||||
case let .texture(_, timestamp, _):
|
||||
case let .texture(_, timestamp, _, _):
|
||||
return timestamp
|
||||
case let .videoBuffer(videoBuffer):
|
||||
case let .videoBuffer(videoBuffer, _):
|
||||
return videoBuffer.timestamp
|
||||
case let .ciImage(_, timestamp):
|
||||
return timestamp
|
||||
@@ -85,7 +85,7 @@ final class MediaEditorRenderer {
|
||||
|
||||
private let ciInputPass = CIInputPass()
|
||||
private let mainVideoInputPass = VideoInputPass()
|
||||
private let additionalVideoInputPass = VideoInputPass()
|
||||
private var additionalVideoInputPass: [Int : VideoInputPass] = [:]
|
||||
let videoFinishPass = VideoFinishPass()
|
||||
|
||||
private let outputRenderPass = OutputRenderPass()
|
||||
@@ -103,7 +103,7 @@ final class MediaEditorRenderer {
|
||||
|
||||
private var currentMainInput: Input?
|
||||
var currentMainInputMask: MTLTexture?
|
||||
private var currentAdditionalInput: Input?
|
||||
private var currentAdditionalInputs: [Input] = []
|
||||
private(set) var resultTexture: MTLTexture?
|
||||
|
||||
var displayEnabled = true
|
||||
@@ -156,7 +156,6 @@ final class MediaEditorRenderer {
|
||||
self.commandQueue?.label = "Media Editor Command Queue"
|
||||
self.ciInputPass.setup(device: device, library: library)
|
||||
self.mainVideoInputPass.setup(device: device, library: library)
|
||||
self.additionalVideoInputPass.setup(device: device, library: library)
|
||||
self.videoFinishPass.setup(device: device, library: library)
|
||||
self.renderPasses.forEach { $0.setup(device: device, library: library) }
|
||||
}
|
||||
@@ -186,23 +185,25 @@ final class MediaEditorRenderer {
|
||||
}
|
||||
|
||||
private func combinedTextureFromCurrentInputs(device: MTLDevice, commandBuffer: MTLCommandBuffer, textureCache: CVMetalTextureCache) -> MTLTexture? {
|
||||
var mainTexture: MTLTexture?
|
||||
var additionalTexture: MTLTexture?
|
||||
var hasTransparency = false
|
||||
guard let library = self.library else {
|
||||
return nil
|
||||
}
|
||||
var passMainInput: VideoFinishPass.Input?
|
||||
var passAdditionalInputs: [VideoFinishPass.Input] = []
|
||||
|
||||
func textureFromInput(_ input: MediaEditorRenderer.Input, videoInputPass: VideoInputPass) -> (MTLTexture, Bool)? {
|
||||
func textureFromInput(_ input: MediaEditorRenderer.Input, videoInputPass: VideoInputPass) -> VideoFinishPass.Input? {
|
||||
switch input {
|
||||
case let .texture(texture, _, hasTransparency):
|
||||
return (texture, hasTransparency)
|
||||
case let .videoBuffer(videoBuffer):
|
||||
case let .texture(texture, _, hasTransparency, rect):
|
||||
return VideoFinishPass.Input(texture: texture, hasTransparency: hasTransparency, rect: rect)
|
||||
case let .videoBuffer(videoBuffer, rect):
|
||||
if let texture = videoInputPass.processPixelBuffer(videoBuffer, textureCache: textureCache, device: device, commandBuffer: commandBuffer) {
|
||||
return (texture, false)
|
||||
return VideoFinishPass.Input(texture: texture, hasTransparency: false, rect: rect)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
case let .ciImage(image, _):
|
||||
if let texture = self.ciInputPass.processCIImage(image, device: device, commandBuffer: commandBuffer) {
|
||||
return (texture, true)
|
||||
return VideoFinishPass.Input(texture: texture, hasTransparency: true, rect: nil)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
@@ -213,16 +214,26 @@ final class MediaEditorRenderer {
|
||||
return nil
|
||||
}
|
||||
|
||||
if let (texture, transparency) = textureFromInput(mainInput, videoInputPass: self.mainVideoInputPass) {
|
||||
mainTexture = texture
|
||||
hasTransparency = transparency
|
||||
if let input = textureFromInput(mainInput, videoInputPass: self.mainVideoInputPass) {
|
||||
passMainInput = input
|
||||
}
|
||||
if let additionalInput = self.currentAdditionalInput, let (texture, _) = textureFromInput(additionalInput, videoInputPass: self.additionalVideoInputPass) {
|
||||
additionalTexture = texture
|
||||
var index = 0
|
||||
for additionalInput in self.currentAdditionalInputs {
|
||||
let videoInputPass: VideoInputPass
|
||||
if let current = self.additionalVideoInputPass[index] {
|
||||
videoInputPass = current
|
||||
} else {
|
||||
videoInputPass = VideoInputPass()
|
||||
videoInputPass.setup(device: device, library: library)
|
||||
self.additionalVideoInputPass[index] = videoInputPass
|
||||
}
|
||||
if let input = textureFromInput(additionalInput, videoInputPass: videoInputPass) {
|
||||
passAdditionalInputs.append(input)
|
||||
}
|
||||
index += 1
|
||||
}
|
||||
|
||||
if let mainTexture {
|
||||
return self.videoFinishPass.process(input: mainTexture, inputMask: self.currentMainInputMask, hasTransparency: hasTransparency, secondInput: additionalTexture, timestamp: mainInput.timestamp, device: device, commandBuffer: commandBuffer)
|
||||
if let passMainInput {
|
||||
return self.videoFinishPass.process(input: passMainInput, inputMask: self.currentMainInputMask, hasTransparency: passMainInput.hasTransparency, secondInput: passAdditionalInputs, timestamp: mainInput.timestamp, device: device, commandBuffer: commandBuffer)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
@@ -300,7 +311,7 @@ final class MediaEditorRenderer {
|
||||
}
|
||||
|
||||
if let onNextAdditionalRender = self.onNextAdditionalRender {
|
||||
if self.currentAdditionalInput != nil {
|
||||
if !self.currentAdditionalInputs.isEmpty {
|
||||
self.onNextAdditionalRender = nil
|
||||
Queue.mainQueue().after(0.016) {
|
||||
onNextAdditionalRender()
|
||||
@@ -327,7 +338,7 @@ final class MediaEditorRenderer {
|
||||
|
||||
func consume(
|
||||
main: MediaEditorRenderer.Input,
|
||||
additional: MediaEditorRenderer.Input?,
|
||||
additionals: [MediaEditorRenderer.Input],
|
||||
render: Bool,
|
||||
displayEnabled: Bool = true
|
||||
) {
|
||||
@@ -338,7 +349,7 @@ final class MediaEditorRenderer {
|
||||
}
|
||||
|
||||
self.currentMainInput = main
|
||||
self.currentAdditionalInput = additional
|
||||
self.currentAdditionalInputs = additionals
|
||||
|
||||
if render {
|
||||
self.renderFrame()
|
||||
|
||||
Reference in New Issue
Block a user