【问题标题】:EXC_BAD_ACCESS when trying to pass and read UnsafeMutableRawPointer through VTDecompressionSessionDecodeFrame尝试通过 VTDecompressionSessionDecodeFrame 传递和读取 UnsafeMutableRawPointer 时的 EXC_BAD_ACCESS
【发布时间】:2021-11-02 04:41:03
【问题描述】:

我认为这更像是一个指针问题而不是 VideoToolbox 会话。我正在尝试做类似于How to calculate FPS of Hardware Decode on iOS 8 exactly? 的事情,并通过 VTDecompressionSessionDecodeFrame 的 sourceFrameRefCon 传递一些元数据,以便我可以在另一端访问它。就我而言,我只想传递一个字符串。

我的解压代码的其他一切都可以正常工作。

我在这里传递一个字符串。

...

let string = "Test"
var cString = (string as NSString)

VTDecompressionSessionDecodeFrame(
     decompressionSession,
     sampleBuffer: sampleBuffer,
     flags: [
          ._EnableAsynchronousDecompression,
          ._EnableTemporalProcessing],
     frameRefcon: &cString,
     infoFlagsOut: &flagsOut)

在我的回调中,我尝试打印它:

callback = { (decompressionOutputRefCon: UnsafeMutableRawPointer?, sourceFrameRefCon: UnsafeMutableRawPointer?, status: OSStatus, infoFlags: VTDecodeInfoFlags, imageBuffer: CVBuffer?, presentationTimeStamp: CMTime, duration: CMTime) in
            
     if let sourceFrameRefCon = sourceFrameRefCon {
          let nsString = sourceFrameRefCon.load(as: NSString.self)
          let string = String(nsString)
          print(string)
     }
    ...

这实际上有点作用。我会看到Test 在控制台中打印了十几次,但随后我会在.load 上看到EXC_BAD_ACCESS

我猜有一种更聪明的方法可以通过这些 UnsafeMutableRawPointer。

【问题讨论】:

  • 您需要在传入之前保留该值。查看Unmanaged的文档我现在很忙,但我明天可以写一个答案。
  • 在使用 Unmanaged 和 passUnRetainedValue 时,我似乎仍然遇到错误的访问崩溃。有什么想法吗?
  • 您需要passRetained。想一想:当你创建一个Unmanaged 值时,系统需要知道你是否打算让这个新的Unmanaged 值像一个强引用(因为你希望Unmanaged 值的存在就足够了使您的目标实例保持活动状态,即使其他引用过期)或无主引用(您希望另一个强引用保持您的实例活动,并且您不想自己拥有所有权)。如果你passUnretained,你的cString 实例将在它被声明的函数中被 ARC 释放后立即过期。
  • 您希望保留cString,以便您可以将其传递给VTDecompressionSessionDecodeFrame,后者将保留它并将其传递给您的回调,在分配的函数结束后很久cString。之后,您有责任在适当的时候释放实例。如果回调只被调用一次,那么您可以使用takeRetainedValue() 来获取局部变量中字符串的值。一旦该局部变量到期,您的 cString 将被释放。
  • 在我正在使用的输入中:let nsString = NSString(string: "Test") 和 var ptr = Unmanaged.passRetained(nsString).toOpaque() 以 &ptr 传递到 VTDecompressionSessionDecodeFrame。在另一边if let sourceFrameRefCon = sourceFrameRefCon { let obj = Unmanaged<NSString>.fromOpaque(sourceFrameRefCon).takeRetainedValue() print(obj) },但我仍然无法访问fromOpaque。

标签: ios swift unsafe-pointers unsafemutablepointer video-toolbox


【解决方案1】:

最终通过使用以下方法完成了这项工作:

输入到VTDecompressionSessionDecodeFrame 的frameRefCon:

let nsString = NSString(string: "Anything")
let frameRefCon = Unmanaged.passRetained(nsString).toOpaque()

确保通过frameRefCon 而不 &frameRefCon

关于参数为sourceFrameRefCon: UnsafeMutableRawPointer?的输出回调:

if let sourceFrameRefCon = sourceFrameRefCon {
   let nsString = Unmanaged<NSString>.fromOpaque(sourceFrameRefCon).takeRetainedValue()
   print(nsString)
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-09
    • 1970-01-01
    • 2015-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多