Dunfey · Hotel WWDC as data, est. 1983
Front desk everything
Years
Topics

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 ↗

Transcript all transcripts

Code shown on screen · 8 snippets

Create AVVideoComposition with custom compositor class swift · at 6:43 ↗
// 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” swift · at 9:55 ↗
// 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 objectivec · at 10:57 ↗
// HDRHighlight.metal

#include <metal_stdlib>
#include <CoreImage/CoreImage.h>
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 objectivec · at 11:22 ↗
// ColorInverter.metal - not HDR ready

#include <metal_stdlib>
#include <CoreImage/CoreImage.h>
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 swift · at 12:23 ↗
// 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 swift · at 13:58 ↗
// 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 swift · at 21:01 ↗
// API definition 
extension AVPlayer {
    @available(macOS 10.15, *)
    open class var eligibleForHDRPlayback: Bool { get }
}
AVPlayer API definition 2 swift · at 21:41 ↗
// 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