简体   繁体   English

Swift中的CMVideoFormatDescriptionCreateFromH264ParameterSets

[英]CMVideoFormatDescriptionCreateFromH264ParameterSets in Swift

The CoreMedia/Video Toolbox API uses a lot of pointers which in Swift is confusing me! CoreMedia / Video Toolbox API使用了许多指针,这些指针在Swift中令我困惑!

The SPS, PPS data has come from my h264 stream and I'm simply trying to create a VFD for it. SPS,PPS数据来自我的h264流,我只是想为它创建一个VFD。

I have tried the following and expected it to work, but I get a -12710 error (kCMFormatDescriptionError_InvalidParameter = -12710). 我已经尝试了以下内容并期望它能够正常工作,但是我得到了-12710错误(kCMFormatDescriptionError_InvalidParameter = -12710)。

Here's my playground.. What I'm I doing wrong?? 这是我的操场..我做错了什么?

// uses CoreMedia Framework
import CoreMedia

// sps and pps variables
var spsData: [UInt8] = []
var ppsData: [UInt8] = []

// CMVideoFormatDescriptionCreateFromH264ParameterSets parameters
let parameterSetCount: Int = 2
var parameterSetPointers: UnsafePointer<UnsafePointer<UInt8>> = nil
var parameterSetSizes: UnsafePointer<Int> = nil
let NALUnitHeaderLength: Int32 = 4
var formatDescriptionOut: UnsafeMutablePointer<Unmanaged<CMFormatDescription>?> = nil

// set raw sps and pps data
let rawSPS: [UInt8] = [0x00,0x00,0x00,0x01,0x67,0x64,0x00,0x32,0xAC,0xB4,0x02,0x80,0x2D,0xD2,0xA4,0x00,0x00,0x0F,0xA4,0x00,0x03,0xA9,0x85,0x81,0x00,0x00,0x63,0x2E,0x80,0x01,0x65,0x0E,0xF7,0xBE,0x17,0x84,0x42,0x35]
let rawPPS: [UInt8] = [0x00,0x00,0x00,0x01,0x68,0xEE,0x3C,0xB0]

// extract sps data
spsData = Array(rawSPS[Int(NALUnitHeaderLength)..<rawSPS.count])

// extract pps data
ppsData = Array(rawPPS[Int(NALUnitHeaderLength)..<rawPPS.count])

let dataParamArray = [UnsafePointer<UInt8>(spsData), UnsafePointer<UInt8>(ppsData)]
parameterSetPointers = UnsafePointer(dataParamArray)

let sizeParamArray = [UnsafePointer<Int>(bitPattern: spsData.count), UnsafePointer<Int>(bitPattern: ppsData.count)]
parameterSetSizes = UnsafePointer(sizeParamArray)

// create video format description
let result: OSStatus = CMVideoFormatDescriptionCreateFromH264ParameterSets(kCFAllocatorDefault, parameterSetCount, parameterSetPointers, parameterSetSizes, NALUnitHeaderLength, formatDescriptionOut)

Here is a working example based on the original code above. 这是一个基于上面原始代码的工作示例。 I had to make an additional change (noted in the code) to @ZENUAV's answer to get it working. 我不得不对@ ZENUAV的答案进行额外的更改(在代码中注明)以使其正常工作。 Tested on Xcode 6.4 with Swift 1.2. 使用Swift 1.2在Xcode 6.4上进行测试。

Note: If the h.264 NALUs happen to be stored in NSData , the bytes property value can be used in place of pointerSPS / pointerPPS . 注意:如果h.264 NALU碰巧存储在NSData ,则可以使用bytes属性值代替pointerSPS / pointerPPS

  // uses CoreMedia Framework
  import CoreMedia

  // sps and pps variables
  var spsByteArray: [UInt8] = []
  var ppsByteArray: [UInt8] = []

  // CMVideoFormatDescriptionCreateFromH264ParameterSets parameters
  let parameterSetCount: Int = 2
  var parameterSetPointers: UnsafePointer<UnsafePointer<UInt8>> = nil
  var parameterSetSizes: UnsafePointer<Int> = nil
  let NALUnitHeaderLength: Int32 = 4

  // important change (also, see usage below):
  var formatDescriptionOut = UnsafeMutablePointer<Unmanaged<CMFormatDescription>?>.alloc(1)

  let rawSPS: [UInt8] = [0x00,0x00,0x00,0x01,0x67,0x64,0x00,0x32,0xAC,0xB4,0x02,0x80,0x2D,0xD2,0xA4,0x00,0x00,0x0F,0xA4,0x00,0x03,0xA9,0x85,0x81,0x00,0x00,0x63,0x2E,0x80,0x01,0x65,0x0E,0xF7,0xBE,0x17,0x84,0x42,0x35]
  let rawPPS: [UInt8] = [0x00,0x00,0x00,0x01,0x68,0xEE,0x3C,0xB0]

  // extract sps data
  spsByteArray = Array(rawSPS[Int(NALUnitHeaderLength)..<rawSPS.count])

  // extract pps data
  ppsByteArray = Array(rawPPS[Int(NALUnitHeaderLength)..<rawPPS.count])

  let pointerSPS = UnsafePointer<UInt8>(spsByteArray)
  let pointerPPS = UnsafePointer<UInt8>(ppsByteArray)

  var dataParamArray = [pointerSPS, pointerPPS]
  parameterSetPointers = UnsafePointer<UnsafePointer<UInt8>>(dataParamArray)

  var sizeParamArray = [spsByteArray.count, ppsByteArray.count]
  parameterSetSizes = UnsafePointer<Int>(sizeParamArray)

  // create video format description
  let result: OSStatus = CMVideoFormatDescriptionCreateFromH264ParameterSets(
     kCFAllocatorDefault,
     parameterSetCount,
     parameterSetPointers,
     parameterSetSizes,
     NALUnitHeaderLength,
     formatDescriptionOut // important change
  )

Sure did. 当然可以。 Here is the code. 这是代码。

                        // get pointer to sps and pops data
                        let pointerSPS = UnsafePointer<UInt8>(spsData)
                        let pointerPPS = UnsafePointer<UInt8>(ppsData)

                        // make pointers array
                        let dataParamArray = [pointerSPS, pointerPPS]

                        // set parameter set pointers
                        _parameterSetPointers = UnsafePointer<UnsafePointer<UInt8>>(dataParamArray)

                        // make parameter sizes array
                        let sizeParamArray = [spsData.count, ppsData.count]

                        // set parameter set sizes
                        _parameterSetSizes = UnsafePointer<Int>(sizeParamArray)

                        // create video format description
                        let result: OSStatus = CMVideoFormatDescriptionCreateFromH264ParameterSets(
                            kCFAllocatorDefault,
                            _parameterSetCount,
                            _parameterSetPointers,
                            _parameterSetSizes,
                            _NALUnitHeaderLength,
                            &_formatDescriptionOut)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM