2015-08-14 111 views
3

CoreMedia/Video Toolbox API使用了很多指针,这些指针在Swift中令我困惑!CMVideoFormatDescriptionCreateFromH264ParameterSets in Swift

SPS,PPS数据来自我的h264流,我只是试图为它创建一个VFD。

我已经尝试了以下,并期望它能够工作,但我得到一个-12710错误(kCMFormatDescriptionError_InvalidParameter = -12710)。

这是我的操场..我在做什么错?

// 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) 
+0

你有没有想过这个? @ZENUAV –

+0

嘿@ZENUAV,我试图将H.264流形式的DJI转换为MP4文件。我注意到你也遇到类似的问题(在DJI论坛上看到)。你能转换它吗?你能分享一个有效的代码吗? –

回答

0

当然可以。这是代码。

     // 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) 
2

这是一个基于上面原始代码的工作示例。我必须做一个额外的改变(在代码中注明)到@ ZENUAV的答案才能正常工作。用Swift 1.2测试Xcode 6.4。

注意:如果H.264的NALU碰巧被存储在NSDatabytes属性值可以代替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 
)