【发布时间】: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