ハイライト
Apple は AVFoundation の AVVideoComposition に HDR 編集サポートを追加しました。内蔵 compositor と内蔵 Core Image フィルタは HDR を処理できますが、カスタム compositor は 10-bit ピクセル形式、HDR source frames、Wide Color source frames を宣言する必要があります。
主要内容
動画編集 App は以前、カット、結合、変形、ブレンドに主眼を置いていました。HDR になると問題はより細かくなります。ピクセルは SDR の 0〜1 範囲を超え得ます。一般的な配信形式は 10-bit を使い、トーンカーブは HLG や PQ かもしれません。SDR 前提の既存トランジション、フィルタ、カスタム合成器はハイライトを潰したり、フィルタ結果を負の値にしたりする可能性があります。
このセッションはリスクを 1 つの中核オブジェクト AVVideoComposition に集約します。AVComposition は主にタイムライン上の素材配置を記述し、HDR はほとんど気にしません。AVVideoComposition は幾何変換、ブレンド、フィルタ処理を担い、入出力の色特性を知る必要があります。Apple の更新により、内蔵 compositor を使う場合、または AVMutableVideoComposition(asset:applyingCIFiltersWithHandler:) で内蔵 Core Image フィルタを呼ぶ場合、フレームワークが HDR フレームを処理してくれます。
開発者がコードを変える必要があるのはカスタムロジックです。カスタム Metal Core Image kernel は拡張ダイナミックレンジを受け入れ、最大輝度が 1 だと仮定してはいけません。カスタム compositor は 10-bit 以上の pixel buffer をサポートし、HDR source frames を受け取り、Wide Color を処理できることを AVFoundation に伝える必要があります。再生側では AVPlayer.eligibleForHDRPlayback で現在のハードウェアとディスプレイが HDR プレビューに適しているか判断します。
詳細
1. 内蔵 compositor の HDR パス(06:43)
一般的な編集ワークフローは AVComposition と AVVideoComposition を作り、AVPlayerItem でプレビューするか AVAssetExportSession で書き出します。セッションは HDR の鍵が AVVideoComposition にあると明言しています。ブレンドと変形を担当するためです。
let videoComposition = AVMutableVideoComposition()
videoComposition.instructions = [videoCompositionInstruction]
videoComposition.frameDuration = CMTimeMake(value: 1, timescale: 30)
videoComposition.renderSize = assetSize
キーポイント:
instructionsは各タイムライン区間でのビデオレイヤーのブレンドや変形を記述します。複数の instruction は重複せず、時間の空白も残せません。frameDurationは合成出力のフレームレートを決めます。例は 1/30 秒です。renderSizeは出力画面サイズです。- このコードは
customVideoCompositorClassを設定していないため、AVFoundation は内蔵 compositor を使います。transcript では、このパスの既存 App が HDR ビデオを入力すると、同じ instruction セットで HDR 出力が得られると説明しています。
2. Core Image フィルタで AVVideoComposition を作る(09:55)
2 番目のパスは単一ビデオレイヤーのフィルタに向いています。AVMutableVideoComposition は最初の有効なビデオトラックの現在フレームを handler に渡し、開発者は request.sourceImage を CIFilter に送り、request.finish で結果を返します。
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)
})
キーポイント:
applyingCIFiltersWithHandlerは composition instruction の手書きを省き、フレームごとのフィルタ処理に集中できます。request.sourceImageは現在の入力フレームで、transcript ではCIImageに対応します。CIZoomBlurは Core Image 内蔵フィルタです。セッションは内蔵 Core Image フィルタが HDR ソースを処理できると説明しています。request.finish(with:context:)はフィルタ出力を AVFoundation に返し、その後も video composition パイプラインが処理します。
3. カスタム Core Image kernel は拡張ダイナミックレンジを受け入れる(10:57)
handler がカスタム Metal Core Image kernel を呼ぶ場合、コードは HDR フレームのピクセル範囲を理解する必要があります。セッションはハイライト検出 kernel を示します。RGB のいずれかが 1 を超えれば、そのピクセルを極めて明るい赤に塗ります。
#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;
}
キーポイント:
CoreImage/CoreImage.hは Metal Core Image kernel に必要な型を導入します。coreimage::sample_t sは入力ピクセルです。HDR コンテンツではs.r、s.g、s.bが 1 より大きくなり得ます。float4(2.0, 0.0, 0.0, 1.0)は SDR 白点を超える赤を意図的に出力し、HDR ハイライト領域をマークします。- セッションは続けて color inverter を反例に示します。SDR 向けに
1.0 - s.rと書くと、HDR ピクセルが 1 より大きいとき結果は負になります。
4. カスタム compositor は HDR 能力を宣言する(13:58)
カスタム compositor は自由度が最も高く、複数ビデオレイヤーをブレンドし、各レイヤーに幾何変換とフィルタを適用できます。その代わり、フレームワークは 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) {
}
}
キーポイント:
sourcePixelBufferAttributesは compositor がサポートする入力 pixel buffer 形式を伝えます。requiredPixelBufferAttributesForRenderContextは出力 render context に必要な形式を伝えます。kCVPixelFormatType_420YpCbCr10BiPlanarVideoRangeは例の 10-bit 形式です。実プロジェクトでは実際にサポートする形式を列挙します。supportsHDRSourceFrames = trueは新フィールドです。未設定またはfalseの場合、フレームワークは compositor に渡す前に HDR ソースを SDR に変換します。supportsWideColorSourceFrames = trueは HDR が Wide Color と伴うことが多いことを反映します。transcript では HDR を処理できる compositor は Wide Color も処理できると仮定すると説明しています。
5. 色属性と再生適格性の確認(17:49、21:01)
composition の色属性を指定しない場合、フレームワークは HLG、PQ、SDR の優先順で出力形式を選びます。HLG、PQ、SDR への固定出力には colorPrimaries、colorTransferFunction、colorYCbCrMatrix を明示設定します。プレビュー再生ではシステムが HDR を表示できるかも確認します。
extension AVPlayer {
@available(macOS 10.15, *)
open class var eligibleForHDRPlayback: Bool { get }
}
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
}
キーポイント:
AVPlayer.eligibleForHDRPlaybackは class var で、AVPlayerインスタンスを作らずに問い合わせできます。trueはシステムが HDR ビデオを消費でき、内蔵または外付けディスプレイの少なくとも 1 台が HDR 表示できることを意味します。- HLG の例は
ITU_R_2020color primaries、ITU_R_2100_HLGtransfer function、ITU_R_2020YCbCr matrix を使います。 - HDR 再生能力がない場合、例は composition の色属性を SDR に設定し、表示できない HDR プレビューに処理を費やさないようにします。
- transcript はこの属性が再生能力のみを示すことも補足します。HDR を再生できないシステムでも HDR エクスポートパスは使える場合があります。
重要ポイント
-
HDR 編集プレビュー: macOS 動画編集のプレビューウインドウを作る。価値: 内蔵 compositor は既存の
AVVideoCompositioninstruction で HDR を扱えます。始め方: 既存のAVMutableVideoComposition構造を維持し、色属性が SDR に固定されていないか確認します。 -
HDR ハイライト診断フィルタ: SDR 白点を超える領域を赤で示す診断フィルタを作る。価値: セッションの
HDRHighlightkernel はs.r > 1.0などで HDR ハイライトを識別します。始め方: kernel を Metal Core Image ファイルに入れ、applyingCIFiltersWithHandlerでプレビューに接続します。 -
カスタム compositor の HDR 対応: 多レイヤートランジションや PiP エディタに HDR 能力を追加する。価値: カスタム compositor は多層ブレンド、幾何変換、レイヤーごとのフィルタができます。始め方: まず 10-bit pixel buffer をサポートし、
supportsHDRSourceFramesとsupportsWideColorSourceFramesを設定します。 -
HDR/SDR 自動プレビュー切替: デバイス能力に応じて HDR または SDR プレビューを表示する。価値:
eligibleForHDRPlaybackは HDR 消費能力とディスプレイ条件の両方を確認します。始め方: 再生パスでこの class var を読み、true なら HLG 色属性、false ならITU_R_709_2を設定します。 -
共有用 SDR コピー: 編集 App に「一般ディスプレイ向けエクスポート」オプションを提供する。価値: transcript は受信者に HDR 再生環境がないメール共有シナリオを示しています。始め方: そのエクスポートまたはプレビューパスで video composition の 3 つの色属性を SDR に設定します。
関連セッション
- Export HDR media in your app with AVFoundation — HDR コンテンツのエクスポートを続け、
AVAssetExportSession、AVAssetWriter、対応形式、プラットフォーム制限を扱います。 - Optimize the Core Image pipeline for your video app — 動画フィルタにおける
CIContext、Metal キュー、AVMutableVideoCompositionの性能実践を説明します。 - Build Metal-based Core Image kernels with Xcode —
.ci.metalファイル、kernel 読み込み、Core Image カスタムフィルタ統合を深掘りします。 - Decode ProRes with AVFoundation and VideoToolbox — macOS での AVFoundation デコード、VideoToolbox、Metal 表示パイプラインを補います。
コメント
GitHub Issues · utterances