2025 Photos & CameraAudio & Video
WWDC25 · 17 min · Photos & Camera / Audio & Video
Enhance your app with machine-learning-based video effects
Discover how to add effects like frame rate conversion, super resolution, and noise filtering to improve video editing and live streaming experiences. We’ll explore the ML-based video processing algorithms optimized for Apple Silicon available in the Video Toolbox framework. Learn how to integrate these effects to enhance the capabilities of your app for real-world use cases.
Watch at developer.apple.com ↗Chapters
Code shown on screen · 4 snippets
Frame rate conversion configuration
// Frame rate conversion configuration
let processor = VTFrameProcessor()
guard let configuration = VTFrameRateConversionConfiguration(frameWidth: width,
frameHeight: height,
usePrecomputedFlow: false,
qualityPrioritization: .normal,
revision: .revision1)
else {
throw Fault.failedToCreateFRCConfiguration
}
try processor.startSession(configuration: configuration) Frame rate conversion buffer allocation
// Frame rate conversion buffer allocation
//use sourcePixelBufferAttributes and destinationPixelBufferAttributes property of VTFrameRateConversionConfiguration to create source and destination CVPixelBuffer pools
sourceFrame = VTFrameProcessorFrame(buffer: curPixelBuffer, presentationTimeStamp: sourcePTS)
nextFrame = VTFrameProcessorFrame(buffer: nextPixelBuffer, presentationTimeStamp: nextPTS)
// Interpolate 3 frames between reference frames for 4x slow-mo
var interpolationPhase: [Float] = [0.25, 0.5, 0.75]
//create destinationFrames
let destinationFrames = try framesBetween(firstPTS: sourcePTS,
lastPTS: nextPTS,
interpolationIntervals: intervals) Frame rate conversion parameters
// Frame rate conversion parameters
guard let parameters = VTFrameRateConversionParameters(sourceFrame: sourceFrame,
nextFrame: nextFrame,
opticalFlow: nil,
interpolationPhase: interpolationPhase,
submissionMode: .sequential,
destinationFrames: destinationFrames)
else {
throw Fault.failedToCreateFRCParameters
}
try await processor.process(parameters: parameters) Motion blur process parameters
// Motion blur process parameters
sourceFrame = VTFrameProcessorFrame(buffer: curPixelBuffer, presentationTimeStamp: sourcePTS)
nextFrame = VTFrameProcessorFrame(buffer: nextPixelBuffer, presentationTimeStamp: nextPTS)
previousFrame = VTFrameProcessorFrame(buffer: prevPixelBuffer, presentationTimeStamp: prevPTS)
destinationFrame = VTFrameProcessorFrame(buffer: destPixelBuffer, presentationTimeStamp: sourcePTS)
guard let parameters = VTMotionBlurParameters(sourceFrame: currentFrame,
nextFrame: nextFrame,
previousFrame: previousFrame,
nextOpticalFlow: nil,
previousOpticalFlow: nil,
motionBlurStrength: strength,
submissionMode: .sequential,
destinationFrame: destinationFrame)
else {
throw Fault.failedToCreateMotionBlurParameters
}
try await processor.process(parameters: parameters)