1

So previously I opened Initialization of 'UnsafePointer<Int>' results in a dangling pointer but the mods said it's a duplicate one.

However I don't think this is a duplicate one, as the links being referred in that post cannot easily direct to a solution. Thus I have to open a new one after 3 days. I tried what is answered from @bscothern in the previous post, but more errors come.

The code being used currently is like below from @bscothern, and it still throws

Generic parameter 'R' could not be inferred

var formatDesc: CMVideoFormatDescription?
func createH264FormatDescription(SPS: Array<UInt8>, PPS: Array<UInt8>) -> OSStatus {
    if formatDesc != nil { formatDesc = nil }

    let status = SPS.withUnsafeBufferPointer { SPS in
        PPS.withUnsafeBufferPointer { PPS in
            let paramSet = [SPS.baseAddress!, PPS.baseAddress!]
            let paramSizes = [SPS.count, PPS.count]
            return paramSet.withUnsafeBufferPointer { paramSet in
                paramSizes.withUnsafeBufferPointer { paramSizes in
                    CMVideoFormatDescriptionCreateFromH264ParameterSets(allocator: kCFAllocatorDefault, parameterSetCount: 2, parameterSetPointers: paramSet.baseAddress!, parameterSetSizes: paramSizes.baseAddress!, nalUnitHeaderLength: 4, formatDescriptionOut: &formatDesc)
                }
            }
        }
    }
    return status
}

Original question from previous post:

So I have some code to create H264ParameterSets like:

var formatDesc: CMVideoFormatDescription?

func createH264FormatDescription(SPS: Array<UInt8>, PPS: Array<UInt8>) -> OSStatus {
    if formatDesc != nil { formatDesc = nil }

    let paramSet = [UnsafePointer<UInt8>(SPS), UnsafePointer<UInt8>(PPS)]
    let paramPointers = UnsafePointer<UnsafePointer<UInt8>>(paramSet)
    let paramSizes = UnsafePointer<Int>([SPS.count, PPS.count])

    let status = CMVideoFormatDescriptionCreateFromH264ParameterSets(allocator: kCFAllocatorDefault, parameterSetCount: 2, parameterSetPointers: paramPointers, parameterSetSizes: paramSizes, nalUnitHeaderLength: 4, formatDescriptionOut: &formatDesc)

    return status
}

Starting on Xcode 11.4 I got warnings for those UnsafePointer(), which seems not happen before:

Initialization of UnsafePointer<UInt8> results in a dangling pointer

Initialization of UnsafePointer<UnsafePointer<UInt8>> results in a dangling pointer

Initialization of UnsafePointer<Int> results in a dangling pointer

I'm not sure why we see this? and how can I remove the warning? Thank in advance.

Wingzero
  • 9,644
  • 10
  • 39
  • 80
  • Among other issues, `paramSet` (misnomer: it's an array, not a set)` is allocated as a local variable in your function, and is deallocated by the end of your function, because no other strong references are made. By taking a pointer to that buffer in the meanwhile, you have a pointer that's valid only in that function body. I'm not familiar with `CMFormatDescription`. Does it keep these pointers and store them internally? or does it only borrow them temporarily while it copies the data out? – Alexander Apr 20 '20 at 02:03
  • @Alexander-ReinstateMonica The core media API ask me to provide such params, ahd those SPS, PPS is get from the video raw data bytes. – Wingzero Apr 20 '20 at 04:04

1 Answers1

3

When you find some error message like: Generic parameter 'R' could not be inferred, there may be two possible reasons.

  • There is some type-related error somewhere, so Swift cannot infer the actual type R in that context
  • The expression is a little more complex than Swift can infer the type

In case 1, you need to find where is the actual error causing the issue.

In case 2, you can add some explicit type annotations to help Swift infer the types.

Please try something like this:

    var formatDesc: CMVideoFormatDescription?
    func createH264FormatDescription(SPS sps: Array<UInt8>, PPS pps: Array<UInt8>) -> OSStatus {
        if formatDesc != nil { formatDesc = nil }

        let status = sps.withUnsafeBufferPointer { spsBP->OSStatus in //<- Specify return type explicitly.
            pps.withUnsafeBufferPointer { ppsBP in
                let paramSet = [spsBP.baseAddress!, ppsBP.baseAddress!]
                let paramSizes = [spsBP.count, ppsBP.count]
                return paramSet.withUnsafeBufferPointer { paramSetBP in
                    paramSizes.withUnsafeBufferPointer { paramSizesBP in
                        CMVideoFormatDescriptionCreateFromH264ParameterSets(allocator: kCFAllocatorDefault, parameterSetCount: 2, parameterSetPointers: paramSetBP.baseAddress!, parameterSetSizes: paramSizesBP.baseAddress!, nalUnitHeaderLength: 4, formatDescriptionOut: &formatDesc)
                    }
                }
            }
        }
        return status
    }
OOPer
  • 47,149
  • 6
  • 107
  • 142
  • hi @OOPer, how do you know spsBP has OSStatus? Could you explain more? I'm a little confused these nested blocks. Could you help clean up my mind? e.g. nested blocks to have a return value eventually, how? – Wingzero Apr 20 '20 at 04:09
  • oops, I misunderstood. spsBP->OSStatus is a function type, not C `->` operation. I figured out hot it returns by tearing up each block. `withUnsafeBufferPointer` has return as body's return value. – Wingzero Apr 20 '20 at 06:12