mirror of
https://github.com/HaishinKit/HaishinKit.swift.git
synced 2026-05-07 20:12:28 +00:00
60 lines
2.5 KiB
Swift
60 lines
2.5 KiB
Swift
import Foundation
|
|
import VideoToolbox
|
|
|
|
enum VTSessionMode {
|
|
case compression
|
|
case decompression
|
|
|
|
func makeSession(_ videoCodec: VideoCodec) throws -> any VTSessionConvertible {
|
|
switch self {
|
|
case .compression:
|
|
var session: VTCompressionSession?
|
|
var status = VTCompressionSessionCreate(
|
|
allocator: kCFAllocatorDefault,
|
|
width: Int32(videoCodec.settings.videoSize.width),
|
|
height: Int32(videoCodec.settings.videoSize.height),
|
|
codecType: videoCodec.settings.format.codecType,
|
|
encoderSpecification: videoCodec.settings.makeEncoderSpecification(),
|
|
imageBufferAttributes: videoCodec.makeImageBufferAttributes(.compression) as CFDictionary?,
|
|
compressedDataAllocator: nil,
|
|
outputCallback: nil,
|
|
refcon: nil,
|
|
compressionSessionOut: &session
|
|
)
|
|
guard status == noErr, let session else {
|
|
throw VTSessionError.failedToCreate(status: status)
|
|
}
|
|
status = session.setOptions(videoCodec.settings.makeOptions())
|
|
guard status == noErr else {
|
|
throw VTSessionError.failedToPrepare(status: status)
|
|
}
|
|
status = session.prepareToEncodeFrames()
|
|
guard status == noErr else {
|
|
throw VTSessionError.failedToPrepare(status: status)
|
|
}
|
|
if let expectedFrameRate = videoCodec.settings.expectedFrameRate {
|
|
status = session.setOption(.init(key: .expectedFrameRate, value: expectedFrameRate as CFNumber))
|
|
}
|
|
videoCodec.frameInterval = videoCodec.settings.frameInterval
|
|
return session
|
|
case .decompression:
|
|
guard let formatDescription = videoCodec.inputFormat else {
|
|
throw VTSessionError.failedToCreate(status: kVTParameterErr)
|
|
}
|
|
var session: VTDecompressionSession?
|
|
let status = VTDecompressionSessionCreate(
|
|
allocator: kCFAllocatorDefault,
|
|
formatDescription: formatDescription,
|
|
decoderSpecification: nil,
|
|
imageBufferAttributes: videoCodec.makeImageBufferAttributes(.decompression) as CFDictionary?,
|
|
outputCallback: nil,
|
|
decompressionSessionOut: &session
|
|
)
|
|
guard let session, status == noErr else {
|
|
throw VTSessionError.failedToCreate(status: status)
|
|
}
|
|
return session
|
|
}
|
|
}
|
|
}
|