122 lines
3.5 KiB
Swift
122 lines
3.5 KiB
Swift
import Accelerate
|
|
import AVFoundation
|
|
import CoreMedia
|
|
|
|
extension CMSampleBuffer {
|
|
var isNotSync: Bool {
|
|
get {
|
|
getAttachmentValue(for: kCMSampleAttachmentKey_NotSync) ?? false
|
|
}
|
|
set {
|
|
setAttachmentValue(for: kCMSampleAttachmentKey_NotSync, value: newValue)
|
|
}
|
|
}
|
|
|
|
@available(iOS, obsoleted: 13.0)
|
|
@available(tvOS, obsoleted: 13.0)
|
|
@available(macOS, obsoleted: 10.15)
|
|
var isValid: Bool {
|
|
CMSampleBufferIsValid(self)
|
|
}
|
|
|
|
@available(iOS, obsoleted: 13.0)
|
|
@available(tvOS, obsoleted: 13.0)
|
|
@available(macOS, obsoleted: 10.15)
|
|
var dataBuffer: CMBlockBuffer? {
|
|
get {
|
|
CMSampleBufferGetDataBuffer(self)
|
|
}
|
|
set {
|
|
_ = newValue.map {
|
|
CMSampleBufferSetDataBuffer(self, newValue: $0)
|
|
}
|
|
}
|
|
}
|
|
|
|
@available(iOS, obsoleted: 13.0)
|
|
@available(tvOS, obsoleted: 13.0)
|
|
@available(macOS, obsoleted: 10.15)
|
|
var imageBuffer: CVImageBuffer? {
|
|
CMSampleBufferGetImageBuffer(self)
|
|
}
|
|
|
|
@available(iOS, obsoleted: 13.0)
|
|
@available(tvOS, obsoleted: 13.0)
|
|
@available(macOS, obsoleted: 10.15)
|
|
var numSamples: CMItemCount {
|
|
CMSampleBufferGetNumSamples(self)
|
|
}
|
|
|
|
@available(iOS, obsoleted: 13.0)
|
|
@available(tvOS, obsoleted: 13.0)
|
|
@available(macOS, obsoleted: 10.15)
|
|
var duration: CMTime {
|
|
CMSampleBufferGetDuration(self)
|
|
}
|
|
|
|
@available(iOS, obsoleted: 13.0)
|
|
@available(tvOS, obsoleted: 13.0)
|
|
@available(macOS, obsoleted: 10.15)
|
|
var formatDescription: CMFormatDescription? {
|
|
CMSampleBufferGetFormatDescription(self)
|
|
}
|
|
|
|
@available(iOS, obsoleted: 13.0)
|
|
@available(tvOS, obsoleted: 13.0)
|
|
@available(macOS, obsoleted: 10.15)
|
|
var decodeTimeStamp: CMTime {
|
|
CMSampleBufferGetDecodeTimeStamp(self)
|
|
}
|
|
|
|
@available(iOS, obsoleted: 13.0)
|
|
@available(tvOS, obsoleted: 13.0)
|
|
@available(macOS, obsoleted: 10.15)
|
|
var presentationTimeStamp: CMTime {
|
|
CMSampleBufferGetPresentationTimeStamp(self)
|
|
}
|
|
|
|
func muted(_ muted: Bool) -> CMSampleBuffer? {
|
|
guard muted else {
|
|
return self
|
|
}
|
|
guard let dataBuffer = dataBuffer else {
|
|
return nil
|
|
}
|
|
let status = CMBlockBufferFillDataBytes(
|
|
with: 0,
|
|
blockBuffer: dataBuffer,
|
|
offsetIntoDestination: 0,
|
|
dataLength: dataBuffer.dataLength
|
|
)
|
|
guard status == noErr else {
|
|
return nil
|
|
}
|
|
return self
|
|
}
|
|
|
|
// swiftlint:disable discouraged_optional_boolean
|
|
@inline(__always)
|
|
private func getAttachmentValue(for key: CFString) -> Bool? {
|
|
guard
|
|
let attachments = CMSampleBufferGetSampleAttachmentsArray(self, createIfNecessary: false) as? [[CFString: Any]],
|
|
let value = attachments.first?[key] as? Bool else {
|
|
return nil
|
|
}
|
|
return value
|
|
}
|
|
|
|
@inline(__always)
|
|
private func setAttachmentValue(for key: CFString, value: Bool) {
|
|
guard
|
|
let attachments: CFArray = CMSampleBufferGetSampleAttachmentsArray(self, createIfNecessary: true), 0 < CFArrayGetCount(attachments) else {
|
|
return
|
|
}
|
|
let attachment = unsafeBitCast(CFArrayGetValueAtIndex(attachments, 0), to: CFMutableDictionary.self)
|
|
CFDictionarySetValue(
|
|
attachment,
|
|
Unmanaged.passUnretained(key).toOpaque(),
|
|
Unmanaged.passUnretained(value ? kCFBooleanTrue : kCFBooleanFalse).toOpaque()
|
|
)
|
|
}
|
|
}
|