我写了一个很好用的 H.264 解码器。但是出于性能原因,我正在尝试对 PPS 和 SPS 参数进行硬编码(它们永远不会改变)。
作为参考,这是它们以 10 [UInt8] 为底的样子:
- SPS [103, 66, 0, 40, 244, 5, 1, 236, 128]
- PPS [104、206、9、136]
奇怪的是,当我从接收到的帧中解码 PPS 和 SPS 参数并使用它们创建格式描述和解压缩会话时,效果很好;但是当我对它们进行硬编码时,它不起作用,并且当我尝试解压缩帧时出现 VT 错误 -12909(错误数据)。据我所知,字节数组是完全相同的。
为了对它们进行硬编码,我只是像这样编写了我的 createFormatDescription:
func createFormatDescription(sps: [UInt8]?, pps: [UInt8]?) -> Bool {
self.formatDesc = nil
let sps = sps ?? [103, 66, 0, 40, 244, 5, 1, 236, 128] as [UInt8]
let pps = pps ?? [104, 206, 9, 136] as [UInt8]
let pointerSPS = UnsafePointer<UInt8>(sps)
let pointerPPS = UnsafePointer<UInt8>(pps)
let dataParamArray = [pointerSPS, pointerPPS]
let parameterSetPointers = UnsafePointer<UnsafePointer<UInt8>>(dataParamArray)
let sizeParamArray = [sps.count, pps.count]
let parameterSetSizes = UnsafePointer<Int>(sizeParamArray)
let status = CMVideoFormatDescriptionCreateFromH264ParameterSets(kCFAllocatorDefault, 2, parameterSetPointers, parameterSetSizes, 4, &formatDesc)
if status == noErr {
print("===== Format description created")
return true
} else {
return false
}
}
并在我的init()
方法中调用它。除此之外,我没有做任何改变;帧以完全相同的方式被解释。
作为参考,这是我的 VT 回调的样子:
private var callback: VTDecompressionOutputCallback = {(
decompressionOutputRefCon: UnsafeMutableRawPointer?,
sourceFrameRefCon: UnsafeMutableRawPointer?,
status: OSStatus,
infoFlags: VTDecodeInfoFlags,
imageBuffer: CVPixelBuffer?,
presentationTimeStamp: CMTime,
duration: CMTime) in
let decoder: VideoFrameDecoder = Unmanaged<VideoFrameDecoder>.fromOpaque(decompressionOutputRefCon!).takeUnretainedValue()
if imageBuffer != nil && status == noErr {
decoder.imageDecompressed(image: imageBuffer!)
} else {
decoder.delegate?.frameDecodingFailed()
print("***** FAILED TO DECOMPRESS. VT ERROR \(status)")
}
}
很基本。重申一下,我总是收到“VT ERROR -12909”