yanxuyao пре 2 недеља
родитељ
комит
01013c45b5

+ 7 - 1
QGVAPlayer/QGVAPlayer/LNSwift/Core/LNControllers.swift

@@ -237,7 +237,11 @@ public final class LNMP4FrameHWDecoder: LNBaseDecoder {
     }
 
     deinit {
-        onInputEnd()
+        // 与 ObjC 版 onInputEnd 对齐:用 decodeQueue.sync 确保队列上正在进行的
+        // 解码任务全部完成后再执行清理,防止 VTDecompressionSession 在使用中被销毁。
+        // ObjC 版在主线程时用 dispatch_sync,非主线程用 dispatch_async;
+        // Swift 版统一用 sync,保证 deinit 返回前资源已安全释放。
+        decodeQueue.sync { self.onInputEnd() }
         fileInfo.occupiedCount -= 1
     }
 
@@ -476,6 +480,8 @@ public final class LNMP4FrameHWDecoder: LNBaseDecoder {
         guard let pixelBuffer = pixelBuffer else { return }
 
         let newFrame = LNMP4AnimatedImageFrame()
+        // Swift 的 CVPixelBuffer? 属性赋值时,ARC 会通过 __bridge_transfer 自动 Retain/Release,
+        // 与 ObjC 版手动 CVPixelBufferRetain 效果等价,无需额外调用。
         newFrame.pixelBuffer = pixelBuffer
         newFrame.frameIndex = frameIndex
         newFrame.decodeTime = Date().timeIntervalSince(startDate) * 1000.0

+ 16 - 2
QGVAPlayer/QGVAPlayer/LNSwift/View/LNVAPPlayerView.swift

@@ -469,9 +469,23 @@ private final class LNPlayerCore: NSObject {
                         return
                     }
 
+                    // 与 ObjC 版保持一致,在主线程执行渲染帧逻辑。
+                    // 使用 sync 前再次检查 isFinish,防止 stopInternal 已经在主线程
+                    // 运行时再次 sync 到主线程造成死锁(主线程等 renderQueue,
+                    // renderQueue 等主线程)。
                     var nextFrame: LNMP4AnimatedImageFrame?
-                    DispatchQueue.main.sync {
-                        nextFrame = self.displayNextFrame()
+                    if !self.isFinish {
+                        DispatchQueue.main.sync {
+                            // 进入主线程后再次检查,stopInternal 可能在等待期间执行
+                            guard !self.isFinish else { return }
+                            nextFrame = self.displayNextFrame()
+                        }
+                    }
+
+                    // isFinish 在 main.sync 内被设置时,直接退出本轮
+                    if self.isFinish {
+                        shouldBreak = true
+                        return
                     }
 
                     var duration = (nextFrame?.duration ?? 0) / 1000.0