2020 Developer ToolsAudio & Video
WWDC20 · 24 min · Developer Tools / Audio & Video
Edit and play back HDR video with AVFoundation
Find out how you can support HDR editing and playback in your macOS app, and how you can determine if a specific hardware configuration is eligible for HDR playback. We’ll show you how to use AVMutableVideoComposition with the built-in compositor and easily edit HDR content, explain how you can use Core Image’s built-in image filters to create your own AVMutableVideoComposition, and demonstrate how to create and use a custom compositor to enable HDR editing.
Watch at developer.apple.com ↗Code shown on screen · 8 snippets
Create AVVideoComposition with custom compositor class
// Create AVVideoComposition with custom compositor class
let videoComposition = AVMutableVideoComposition()
videoComposition.instructions = [videoCompositionInstruction]
videoComposition.frameDuration = CMTimeMake(value: 1, timescale: 30)
videoComposition.renderSize = assetSize Create AVVideoComposition using “applyingCIFiltersWithHandler”
// Create AVVideoComposition using “applyingCIFiltersWithHandler”
let videoComposition =
AVMutableVideoComposition(asset: asset,
applyingCIFiltersWithHandler: {
(request: AVAsynchronousCIImageFilteringRequest) -> Void in
let ciFilter = CIFilter(name: “CIZoomBlur”)
ciFilter!.setValue(request.sourceImage, forKey: kCIInputImageKey)
request.finish(with: ciFilter!.outputImage!, context: nil)
}) First CIKernel
// HDRHighlight.metal
using namespace metal;
extern “C” float4 HDRHighlight(coreimage::sample_t s, coreimage::destination dest) {
if (s.r > 1.0 || s.g > 1.0 || s.b > 1.0)
return float4(2.0, 0.0, 0.0, 1.0);
else
return s;
} Color Inverter CI Kernel
// ColorInverter.metal - not HDR ready
using namespace metal;
extern “C” float4 ColorInverter(coreimage::sample_t s, coreimage::destination dest) {
return float4(1.0 - s.r, 1.0 - s.g, 1.0 - s.b, 1.0);
} Custom compositor class
// Custom compositor class
class SampleCustomCompositor: NSObject, AVVideoCompositing {
…
}
// Create AVVideoComposition with custom compositor class
let videoComposition = AVMutableVideoComposition()
videoComposition.instructions = [videoCompositionInstruction]
videoComposition.frameDuration = CMTimeMake(value: 1, timescale: 30)
videoComposition.renderSize = assetSize
videoComposition.customVideoCompositorClass = SampleCustomCompositor.self Setting custom compositor to support HDR
// Setting custom compositor to support HDR
class SampleCustomCompositor: NSObject, AVVideoCompositing {
var sourcePixelBufferAttributes: [String : Any]? =
[kCVPixelBufferPixelFormatTypeKey as String:
[kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange]]
var requiredPixelBufferAttributesForRenderContext: [String : Any] =
[kCVPixelBufferPixelFormatTypeKey as String:
[kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange]]
var supportsHDRSourceFrames = true
var supportsWideColorSourceFrames = true
func startRequest(_ request: AVAsynchronousVideoCompositionRequest) {
...
}
func renderContextChanged(_ newRenderContext: AVVideoCompositionRenderContext) {
}
} AVPlayer API definition
// API definition
extension AVPlayer {
@available(macOS 10.15, *)
open class var eligibleForHDRPlayback: Bool { get }
} AVPlayer API definition 2
// API definition
extension AVPlayer {
@available(macOS 10.15, *)
open class var eligibleForHDRPlayback: Bool { get }
}
// Set video composition color properties based on HDR playback eligibility
if AVPlayer.eligibleForHDRPlayback {
videoComposition.colorPrimaries = AVVideoColorPrimaries_ITU_R_2020
videoComposition.colorTransferFunction = AVVideoTransferFunction_ITU_R_2100_HLG
videoComposition.colorYCbCrMatrix = AVVideoYCbCrMatrix_ITU_R_2020
}
else {
videoComposition.colorPrimaries = AVVideoColorPrimaries_ITU_R_709_2
videoComposition.colorTransferFunction = AVVideoTransferFunction_ITU_R_709_2
videoComposition.colorYCbCrMatrix = AVVideoYCbCrMatrix_ITU_R_709_2
} Resources
Related sessions
-
22 min -
36 min -
20 min -
34 min