| 
					
				 | 
			
			
				@@ -0,0 +1,206 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  File.swift 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  BFFramework 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//  Created by ak on 2021/7/13. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import Foundation 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import UIKit 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import OpenGLES 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import AVFoundation 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+open class PQGPUImageDebug: BasicOperation { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // ui label 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var subtitleLab: PQSubTitleLabel = PQSubTitleLabel() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 全屏模式 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var isBigSubtile: Bool = false 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 所有字幕 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var mSubtitles: [PQEditSubTitleModel]? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var subtitleSize: CGSize? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 画布大小 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var inputCGSize: CGSize = .zero 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 字幕gpu texture 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var subTitleTexture: GLuint = 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var subtitleImage: UIImage? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var lastSubtitle: PQEditSubTitleModel? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    deinit { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        FilterLog(message: "字幕析构 ") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        clearData() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    init(inputSize: CGSize) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        super.init(fragmentShader: AlphaPassthroughFragmentShader, numberOfInputs: 1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        BFLog(message: "isBigSubtile 强制设置 \(isBigSubtile)") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        subTitleTexture = 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    func getWidthWithTitle(text: String, font: UIFont) -> CGFloat { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let label = UILabel(frame: CGRect(x: 0, y: 0, width: inputCGSize.width * 0.8, height: 0)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        label.text = text 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        label.font = font 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        label.sizeToFit() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let width = label.frame.size.width 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return width 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    func setupLabel(text: String) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var boundingRect: CGRect = .zero 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 小字幕字号大小 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var font: Int = 60 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if inputCGSize.width / inputCGSize.height > 1.5 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            font = 68 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//        if !isBigSubtile { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        boundingRect = text.boundingRect(with: CGSize(width: inputCGSize.width * 0.8, height: 0), options: .usesLineFragmentOrigin, attributes: [NSAttributedString.Key.font: UIFont.systemFont(ofSize: CGFloat(114))], context: nil) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let strokeWidth: CGFloat = 6 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        subtitleLab = PQSubTitleLabel(frame: CGRect(x: 0, y: 0, width: inputCGSize.width * 0.8, height: boundingRect.height > inputCGSize.height - 120 ? inputCGSize.height - 120 : boundingRect.height)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        subtitleLab.strokeColor = UIColor.black 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        subtitleLab.strokeWidth = strokeWidth 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        subtitleLab.font = UIFont.boldSystemFont(ofSize: CGFloat(isBigSubtile ? 114 : font)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        subtitleLab.numberOfLines = 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        FilterLog(message: "字幕初始化时大小 \(subtitleLab.frame)") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        subtitleLab.textAlignment = .center 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        subtitleLab.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 0.5) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        subtitleLab.alpha = 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        subtitleLab.textColor = UIColor.white 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        subtitleLab.text = text 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 把 UIVIEW 转到 texture 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    func getSubtitleImage(view: UIView) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        autoreleasepool { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let size: CGSize = view.bounds.size 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            UIGraphicsBeginImageContextWithOptions(size, false, 1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            view.layer.render(in: UIGraphicsGetCurrentContext()!) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            subtitleImage = UIGraphicsGetImageFromCurrentImageContext() ?? UIImage() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            UIGraphicsEndImageContext() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 清空数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    func clearData() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        BFLog(message: "清空字幕数据!") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        subtitleImage = nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        glDeleteTextures(1, &subTitleTexture) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        subTitleTexture = 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        lastSubtitle = nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    func update(text :String) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        setupLabel(text: text) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        getSubtitleImage(view: subtitleLab) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    func createTexture(text: String) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DispatchQueue.main.async { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            FilterLog(message: "value istimescale is \(text)") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            self.update(text: text) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            self.subtitleSize = self.subtitleLab.frame.size 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if self.subtitleImage?.cgImage != nil, self.subTitleTexture == 0 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                sharedImageProcessingContext.runOperationSynchronously { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    autoreleasepool { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        self.subTitleTexture = PQGPUImageTools.setupTexture(image: self.subtitleImage!.cgImage!) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    func createTexture(currtime: CMTime) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DispatchQueue.main.async { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            FilterLog(message: "value istimescale is \(currtime)") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//            self.update(withTimestamp: currtime) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            self.subtitleSize = self.subtitleLab.frame.size 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if self.subtitleImage?.cgImage != nil, self.subTitleTexture == 0 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                sharedImageProcessingContext.runOperationSynchronously { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    autoreleasepool { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        self.subTitleTexture = PQGPUImageTools.setupTexture(image: self.subtitleImage!.cgImage!) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    override public func newFramebufferAvailable(_ framebuffer: Framebuffer, fromSourceIndex: UInt) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        super.newFramebufferAvailable(framebuffer, fromSourceIndex: fromSourceIndex) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let inputSize = framebuffer.sizeForTargetOrientation(.portrait) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        inputCGSize = CGSize(width: CGFloat(inputSize.width), height: CGFloat(inputSize.height)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let value: Double = Double(framebuffer.timingStyle.timestamp?.value ?? 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let timescale: Double = Double(framebuffer.timingStyle.timestamp?.timescale ?? 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let currtime: CMTime = CMTime(value: CMTimeValue(value), timescale: CMTimeScale(timescale)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//        createTexture(currtime: currtime) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    override open func renderFrame() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let inputFramebuffer: Framebuffer = inputFramebuffers[0]! 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let inputSize = inputFramebuffer.sizeForTargetOrientation(.portrait) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let currTime = CMTimeGetSeconds(CMTime(value: inputFramebuffer.timingStyle.timestamp!.value, timescale: inputFramebuffer.timingStyle.timestamp!.timescale)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        FilterLog(message: "subtitle 当前时间: \(currTime)") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 原有画布 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        renderFramebuffer = sharedImageProcessingContext.framebufferCache.requestFramebufferWithProperties(orientation: .portrait, size: inputSize, stencil: false) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let textureProperties = InputTextureProperties(textureCoordinates: inputFramebuffer.orientation.rotationNeededForOrientation(.portrait).textureCoordinates(), texture: inputFramebuffer.texture) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        renderFramebuffer.activateFramebufferForRendering() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        clearFramebufferWithColor(backgroundColor) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        renderQuadWithShader(shader, uniformSettings: uniformSettings, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                             vertexBufferObject: sharedImageProcessingContext.standardImageVBO, inputTextures: [textureProperties]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        releaseIncomingFramebuffers() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if subTitleTexture != 0 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            FilterLog(message: "UIElementFramebuffer 有值可以正常显示") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let texturePropertiesimagetwo = InputTextureProperties(textureCoordinates: inputFramebuffer.orientation.rotationNeededForOrientation(.portrait).textureCoordinates(), texture: subTitleTexture) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            FilterLog(message: "subtitleSize subtitleSize is\(String(describing: subtitleSize)) \(inputCGSize)") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let size: CGSize = inputCGSize 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let bounds2: CGRect = CGRect(x: (inputCGSize.width - subtitleSize!.width) / 2, y: inputCGSize.height - subtitleSize!.height - 60, width: subtitleSize!.width, height: subtitleSize!.height) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            FilterLog(message: "inputCGSize is \(size)  bounds2\(bounds2)") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            renderQuadWithShader(shader, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                 uniformSettings: uniformSettings, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                 vertexBufferObject: PQGPUImageTools.NXGenerateVBO(for: PQGPUImageTools.computeVertices(viewSize: inputCGSize, _bounds: CGRect(x: (inputCGSize.width - subtitleSize!.width) / 2, y: isBigSubtile ? (inputCGSize.height - subtitleSize!.height - 60) / 2 : inputCGSize.height - subtitleSize!.height - 60, width: subtitleSize!.width, height: subtitleSize!.height))), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                 inputTextures: [texturePropertiesimagetwo]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            releaseIncomingFramebuffers() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    override public func transmitPreviousImage(to _: ImageConsumer, atIndex _: UInt) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        print("this is running") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 |