Browse Source

[*] 暂时提交

yanxuyao 2 tuần trước cách đây
mục cha
commit
6c46c9ab2d

+ 32 - 27
QGVAPlayer/QGVAPlayer/LNSwift/Core/LNControllers.swift

@@ -425,33 +425,38 @@ public final class LNMP4FrameHWDecoder: LNBaseDecoder {
         )
         guard status == noErr, let sampleBuffer, let decodeSession else { return }
 
-        var flagOut: VTDecodeInfoFlags = []
-        let decodeStatus = VTDecompressionSessionDecodeFrame(
-            decodeSession,
-            sampleBuffer: sampleBuffer,
-            flags: [],
-            infoFlagsOut: &flagOut
-        ) { [weak self] status, _, imageBuffer, _, _ in
-            guard let self else { return }
-            self.handleDecodePixelBuffer(
-                imageBuffer,
-                frameIndex: frameIndex,
-                currentPts: currentPts,
-                startDate: startDate,
-                status: status,
-                needDrop: drop,
-                buffers: buffers,
-                fps: parser.fps
-            )
-        }
-
-        if decodeStatus == kVTInvalidSessionErr {
-            invalidRetryCount += 1
-            if invalidRetryCount >= 3 { return }
-            resetDecoder()
-            findKeyFrameAndDecodeToCurrent(frameIndex)
-        } else {
-            invalidRetryCount = 0
+        // 与 ObjC 版 CFRelease(sampleBuffer) 对齐:将 sampleBuffer 放在 autoreleasepool
+        // 内,确保解码提交后立即释放,避免高帧率场景下多帧 sampleBuffer 同时滞留内存。
+        autoreleasepool {
+            var flagOut: VTDecodeInfoFlags = []
+            let decodeStatus = VTDecompressionSessionDecodeFrame(
+                decodeSession,
+                sampleBuffer: sampleBuffer,
+                flags: [],
+                infoFlagsOut: &flagOut
+            ) { [weak self] status, _, imageBuffer, _, _ in
+                guard let self else { return }
+                self.handleDecodePixelBuffer(
+                    imageBuffer,
+                    frameIndex: frameIndex,
+                    currentPts: currentPts,
+                    startDate: startDate,
+                    status: status,
+                    needDrop: drop,
+                    buffers: buffers,
+                    fps: parser.fps
+                )
+            }
+
+            if decodeStatus == kVTInvalidSessionErr {
+                invalidRetryCount += 1
+                if invalidRetryCount < 3 {
+                    resetDecoder()
+                    findKeyFrameAndDecodeToCurrent(frameIndex)
+                }
+            } else {
+                invalidRetryCount = 0
+            }
         }
     }
 

+ 17 - 4
QGVAPlayer/QGVAPlayer/LNSwift/View/LNVAPPlayerView.swift

@@ -1,6 +1,8 @@
 import UIKit
 import CoreVideo
 import Metal
+import OpenGLES
+import GLKit
 
 private let lnDefaultFPS = kLNMP4DefaultFPS
 private let lnMinFPS = kLNMP4MinFPS
@@ -554,10 +556,21 @@ private final class LNPlayerCore: NSObject {
         isFinish = true
         onPause = true
 
-        openGLView?.pause = true
-        openGLView?.dispose()
-        openGLView?.removeFromSuperview()
-        openGLView = nil
+        if let glView = openGLView {
+            glView.pause = true
+            // 与 ObjC 版对齐:切换到 GL context 后 dispose,再 glFinish() 确保 GPU
+            // 命令全部执行完毕,最后清空 context,防止释放资源时出现野指针或画面异常。
+            if let glContext = glView.glContext as? EAGLContext {
+                if EAGLContext.current() != glContext {
+                    EAGLContext.setCurrent(glContext)
+                }
+            }
+            glView.dispose()
+            glFinish()
+            EAGLContext.setCurrent(nil)
+            glView.removeFromSuperview()
+            openGLView = nil
+        }
 
         metalView?.dispose()
         metalView?.removeFromSuperview()