Skip to content

Instantly share code, notes, and snippets.

@standinga
Created December 15, 2020 11:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save standinga/438b4429b8f7931b3cd1cf59111be42a to your computer and use it in GitHub Desktop.
Save standinga/438b4429b8f7931b3cd1cf59111be42a to your computer and use it in GitHub Desktop.
updated H264Coder
import AVFoundation
import VideoToolbox
class H264Coder {
var session: VTCompressionSession?
var onFrame: ((CMSampleBuffer) -> Void)?
let outputCallback: VTCompressionOutputCallback = { refcon, sourceFrameRefCon, status, infoFlags, sampleBuffer in
guard let refcon = refcon,
status == noErr,
let sampleBuffer = sampleBuffer else {
print("H264Coder outputCallback sampleBuffer NIUL or status: \(status)")
return
}
let encoder: H264Coder = Unmanaged<H264Coder>.fromOpaque(refcon).takeUnretainedValue()
encoder.didEncodeFrame(frame: sampleBuffer)
}
init(width: Int32, height: Int32) {
let status = VTCompressionSessionCreate(allocator: kCFAllocatorDefault, width: width, height: height, codecType: kCMVideoCodecType_H264, encoderSpecification: nil, imageBufferAttributes: nil, compressedDataAllocator: nil, outputCallback: outputCallback, refcon: Unmanaged.passUnretained(self).toOpaque(), compressionSessionOut: &session)
guard let session = session else { return }
VTSessionSetProperty(session, key: kVTCompressionPropertyKey_RealTime, value: kCFBooleanTrue)
VTSessionSetProperty(session, key: kVTCompressionPropertyKey_AllowFrameReordering, value: kCFBooleanFalse)
VTSessionSetProperty(session, key: kVTCompressionPropertyKey_MaxKeyFrameInterval, value: NSNumber(1))
VTSessionSetProperty(session, key: kVTCompressionPropertyKey_ProfileLevel, value: kVTProfileLevel_H264_Main_AutoLevel)
VTSessionSetProperty(session, key: kVTCompressionPropertyKey_ExpectedFrameRate, value: NSNumber(30))
VTCompressionSessionPrepareToEncodeFrames(session)
print("H264Coder init \(status == noErr) \(status)")
}
func encode(_ sampleBuffer: CMSampleBuffer) {
guard let compressionSession = session,
let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else { return }
let timestamp = CMSampleBufferGetPresentationTimeStamp(sampleBuffer)
let _ = VTCompressionSessionEncodeFrame(compressionSession, imageBuffer: imageBuffer, presentationTimeStamp: timestamp, duration: .invalid, frameProperties: nil, sourceFrameRefcon: nil, infoFlagsOut: nil)
}
func didEncodeFrame(frame: CMSampleBuffer) {
print ("Received encoded frame in delegate...")
onFrame?(frame)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment