View in English

  • メニューを開く メニューを閉じる
  • Apple Developer
検索
検索を終了
  • Apple Developer
  • ニュース
  • 見つける
  • デザイン
  • 開発
  • 配信
  • サポート
  • アカウント
次の内容に検索結果を絞り込む

クイックリンク

5 クイックリンク

ビデオ

メニューを開く メニューを閉じる
  • コレクション
  • トピック
  • すべてのビデオ
  • 利用方法

その他のビデオ

ストリーミングはほとんどのブラウザと
Developerアプリで視聴できます。

  • 概要
  • トランスクリプト
  • コード
  • 動画AppのためのCore Imageパイプラインの最適化

    Core Imageの処理能力を活用し、App内の動画パフォーマンスを最適化する方法について説明します。あなたのAppで動画にエフェクトを適用するためのCore Imageパイプラインを構築する方法を紹介します。CIContextを使用するときに、Appのメモリのフットプリントを減らす方法、およびCore Imageフィルタを使用した動画再生のためのAVPlayViewまたはMTKViewビュークラスの使用に関するベストプラクティスについて学びます。さらに、独自のカスタムカーネルをMetal Shading Languageで書くべき理由について説明し、Core ImageパイプラインでのMetalコマンドキューを最適に使用するためのパフォーマンスに関するヒントを紹介します。

    リソース

    • Core Image
      • HDビデオ
      • SDビデオ

    関連ビデオ

    WWDC22

    • AVFoundationやMetalによるHDR動画のEDR表示

    WWDC21

    • Core Imageカーネルの改善点
    • ProRAW画像の撮影と処理

    WWDC20

    • Discover Core Imageデバッグ技術
    • Xcodeを使用したMetalベースCore Imageカーネルの作成
  • ダウンロード

    こんにちは WWDCへようこそ

    “動画アプリケーションのための Core Imageパイプラインの最適化” デヴィッド・ヘイワードです 動画アプリのエフェクト処理で Core Imageを使用し― 最適なパフォーマンスを 引き出す方法をご紹介します 3つのトピックについて説明しましょう CIContextの最適な生成方法 カスタムCIKernelの書き方と適用方法 そしてビューへの 最適なレンダリング方法です まずはCIContextの生成です CIContextの生成は1つのビューに対し 1つのCIContextのみを生成してください 初期化に時間とメモリ容量を要するため 頻繁には生成を行いません context生成時には いくつかのオプション指定が必要です 最も重要なのは中間生成物を キャッシュに格納しないことです 動画はそれぞれのフレームが 前のフレームとは違います キャッシュの無効化により メモリ使用量を抑制します

    contextには名前を付けることを 推奨していますが Core Imageのデバッグ技術の 使用時に有効だからです Core ImageはMetalを使用していますが Core Imageと他のMetalのAPI群を 混在して使う場合もあります 例えば MetalTextureをCore Imageの入力値 または出力値に使う場合は CIContextをMetalCommandQueueで 生成することを推奨します 時系列のグラフで説明しましょう アプリがMetalTextureにデータを格納するために MetalCommandQueueを使ったとします この場合はCPU上でキューに入れ GPU上で実行します 次に 先ほどのMetalTextureを MetalQueueを使っているCore Imageに渡し 別のMetalTextureにデータを格納します ここでもCPU上でキューに入れ GPU上で実行します 最後に 再びMetalQueueを使い Core Imageから 出力textureをレンダリングします すべての処理が異なるキューで行われるため 正しい結果を得るには waitコマンドの発行が必要です 非効率なパイプライン処理による 無駄な時間を省くため 他のMetalレンダリング処理で使うキューと 同じキューでCIContextを生成します これによりアプリの待ちをなくし 最適なパフォーマンスを発揮する パイプライン処理が可能となります

    次はCIKernelをMetalで書くご説明です 動画アプリを最適に利用するには Metalでのエフェクトの実装が重要です すべてMetalで実装されているので Core Imageのビルドインフィルタを 可能な限り使用します

    ビルトインフィルタの利用に役立つ文書を アップロードしており パラメータ説明 サンプル画像 サンプルコードを記載しています

    ビルトインフィルタに適用されるコードは シンプルです CIFilterBuiltinsをインポートし filterインスタンスを生成します そして 入力プロパティを設定し 出力画像を取得します カスタムCIKernelをMetalで書くことを 推奨する理由は他にもあります CIKernelの通常機能である 自動タイリングや自動連結などに加え Metalで書くことでコンパイル処理時間を 減らすことができるのです ギャザー読み取りやグループ書き込み 半精度浮動小数点などの機能も利用可能です 開発者の作業を快適化するため タイピング時の構文ハイライトや ビルド時の構文チェックが行われます MetalでCIKernelを書く例を お見せしましょう プレゼンテーションの中でお見せした kernelでデモを行い HDR動画をAVFoundationで 編集し再生します カスタムCIKernelを書くのは簡単です 最初にソースの冒頭でCoreImage.hの ヘッダーをインクルードすることで Core Imageが提供する追加クラスと同様に Metal標準すべてのクラスにアクセスができます 次に kernelのための関数 extern “C”を宣言します この例はCIColorKernelなので 関数は float4を戻り値として返す必要があります そして引数を取ることができます これは最初の引数がCore Imageのsample_tで 入力画像から得たピクセルを表すものです これはリニア色空間の乗算済み アルファ RGBA float4で SDRにもHDRにも適合します

    最後の引数はCore Imageのdestinationです これは返却するピクセル座標を提供します このkernelの実装では destinationのXY座標の値を使用して どの斜め線にいるかを決定します そして 単純な数学を用い ゼブラストライプにいるかどうかを計算します

    ゼブラストライプと 現在処理中のピクセルサンプルが SDRの標準的な白より明るいならば 明るい赤のピクセルを返します さもないとピクセルサンプルは 変更されません 詳細は“Build Metal-Based Core Image Kernels with Xcode”をご覧ください

    最後は動画アプリの開発における 最適なビュークラスの選択についてお話しします アプリに動画エフェクト処理がある場合 UIImageViewやNSImageViewクラスは 使用を避けましょう 静的コンテンツ表示のために 設計されているからです 最も簡単に使えるAVPlayerViewは ビューにフィルタ処理した動画を 自動的に映します パフォーマンス向上のためには MetalKitViewも選択可能です これら2つをCore Imageと使う方法を 紹介します

    AVPlayerViewの使用は非常に単純です キーとなるオブジェクト AVMutableVideoCompositionは 動画のアセットとハンドラブロックと共に 初期化されます このブロックは毎回呼び出され AVAsynchronousCIImageFilteringRequestに 渡されます そして CIFilterを生成し 入力値を設定すると 出力画像が取得されます 次に リクエストオブジェクトに その画像を渡します

    Xcodeでは デバッグ中に CIImageの変数をマウスオーバーすると オブジェクトのアドレスを示す ポップオーバーが現れます 目のマークをクリックすると 新たなウィンドウが立ち上がり 画像を構成するレシピが表示されます 入力値の動画フレームが 10ビットHDR表示ということが分かります Core Imageは自動的に HLGからCore Image作業領域へと カラー管理されています 加工した動画を映す もう1つの選択肢はMetalKitViewです

    MetalKitViewを使う場合の Core Imageの最適な利用方法を説明します 最初にframeとdeviceと一緒に initをオーバーライドします initメソッドはビューに対して CIContextを生成する最適なタイミングです Core ImageがMetal演算を使えるよう framebufferOnlyはfalseに設定してください macOSでは ビューがHDR対応の場合 colorPixelFormatを rgba16floatに設定してください wantsExtendedDynamicRangeContentも trueを設定します 次にdraw in viewメソッドを実装します CIRenderDestinationは 特殊な方法で生成されます 正しいwidth height pixelformatによって destinationを生成しますが Metal textureを渡す代わりに textureを返すブロックを渡します CIContextは 前のフレーム処理が終わる前に Metal処理のキュー追加が可能となります 次に CIContextにdestinationへの 画像レンダリングタスクを指示します

    最後に 現在描画可能なビューを示すための コマンドバッファを生成します

    本日はCore Imageを使用して 動画アプリのパフォーマンスを 最適化する方法をご紹介しました 本日 紹介したトピックは CIContextsの生成 CIKernelsの適用 そして ビューへのレンダリングです これらの方法で 皆様のアプリ動画は より素晴らしいものになるでしょう ご視聴ありがとうございました WWDC 2020をお楽しみください

    • 0:52 - Creating CIContext

      let context =  CIContext(options: [
          .cacheIntermediates : false,
          .name : ”MyAppView”
      ])
    • 1:26 - Creating CIContext 2

      let context =  CIContext(MTLCommandQueue : queue, options: […])
    • 2:59 - Use builtins Whenever possible

      import CoreImage.CIFilterBuiltins
      
      func motionBlur(inputImage: CIImage) -> CIImage? {
          let motionBlurFilter = CIFilter.motionBlur()
          motionBlurFilter.inputImage = inputImage
          motionBlurFilter.angle = 0
          motionBlurFilter.radius = 20
          return motionBlurFilter.outputImage
      }
    • 3:56 - Put your kernels in .ci.metal sources

      // MyKernels.ci.metal
      #include <CoreImage/CoreImage.h> // includes CIKernelMetalLib.h
      using namespace metal;
      
      extern "C" float4 HDRZebra (coreimage::sample_t s, float time, coreimage::destination dest) 
      {
      	float diagLine = dest.coord().x + dest.coord().y;
      	float zebra = fract(diagLine/20.0 + time*2.0);
      	if ((zebra > 0.5) && (s.r > 1 || s.g > 1 || s.b > 1))
      		return float4(2.0, 0.0, 0.0, 1.0);
      	return s;
      }
    • 5:50 - Using AVPlayer View

      let videoComposition = AVMutableVideoComposition(
          asset: asset, 
    applyingCIFiltersWithHandler:
          { (request: AVAsynchronousCIImageFilteringRequest) -> Void in
              let filter = HDRZebraFilter()
        filter.inputImage = request.sourceImage
              let output = filter.outputImage
      
              if (output != nil) {
                  request.finish(with: output, context: myCtx)
              }
              else { request.finish(with: err) }
          }
      )
    • 7:01 - Using MTKView

      class MyView : MTKView {
          var context: CIContext
          var commandQueue : MTLCommandQueue
          
          override init(frame frameRect: CGRect, device: MTLDevice?) {
              let dev = device ?? MTLCreateSystemDefaultDevice()!
              context = CIContext(mtlDevice: dev, options: [.cacheIntermediates : false] )
              commandQueue = dev.makeCommandQueue()!
              
              super.init(frame: frameRect, device: dev)
      
              framebufferOnly = false  // allow Core Image to use Metal Compute
              colorPixelFormat = MTLPixelFormat.rgba16Float
              if let caml = layer as? CAMetalLayer {
                  caml.wantsExtendedDynamicRangeContent = true
              }
          }
    • 7:29 - Using MTKView 2

      func draw(in view: MTKView) {
      
              let size = self.convertToBacking(self.bounds.size)
              let rd = CIRenderDestination(width: Int(size.width),
                                           height: Int(size.height),
                                           pixelFormat: colorPixelFormat,
                                           commandBuffer: nil)
                        { () -> MTLTexture in return view.currentDrawable!.texture }
      
              context.startTask(toRender:image, from:rect, to:rd, at:point)
      
              // Present the current drawable
              let cmdBuf = commandQueue.makeCommandBuffer()!
              cmdBuf.present(view.currentDrawable!)
              cmdBuf.commit()
         }
  • 特定のトピックをお探しの場合は、上にトピックを入力すると、関連するトピックにすばやく移動できます。

    クエリの送信中にエラーが発生しました。インターネット接続を確認して、もう一度お試しください。

Developer Footer

  • ビデオ
  • WWDC20
  • 動画AppのためのCore Imageパイプラインの最適化
  • メニューを開く メニューを閉じる
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    Open Menu Close Menu
    • Swift
    • SwiftUI
    • Swift Playground
    • TestFlight
    • Xcode
    • Xcode Cloud
    • SF Symbols
    メニューを開く メニューを閉じる
    • アクセシビリティ
    • アクセサリ
    • App Extension
    • App Store
    • オーディオとビデオ(英語)
    • 拡張現実
    • デザイン
    • 配信
    • 教育
    • フォント(英語)
    • ゲーム
    • ヘルスケアとフィットネス
    • アプリ内課金
    • ローカリゼーション
    • マップと位置情報
    • 機械学習
    • オープンソース(英語)
    • セキュリティ
    • SafariとWeb(英語)
    メニューを開く メニューを閉じる
    • 英語ドキュメント(完全版)
    • 日本語ドキュメント(一部トピック)
    • チュートリアル
    • ダウンロード(英語)
    • フォーラム(英語)
    • ビデオ
    Open Menu Close Menu
    • サポートドキュメント
    • お問い合わせ
    • バグ報告
    • システム状況(英語)
    メニューを開く メニューを閉じる
    • Apple Developer
    • App Store Connect
    • Certificates, IDs, & Profiles(英語)
    • フィードバックアシスタント
    メニューを開く メニューを閉じる
    • Apple Developer Program
    • Apple Developer Enterprise Program
    • App Store Small Business Program
    • MFi Program(英語)
    • News Partner Program(英語)
    • Video Partner Program(英語)
    • セキュリティ報奨金プログラム(英語)
    • Security Research Device Program(英語)
    Open Menu Close Menu
    • Appleに相談
    • Apple Developer Center
    • App Store Awards(英語)
    • Apple Design Awards
    • Apple Developer Academy(英語)
    • WWDC
    Apple Developerアプリを入手する
    Copyright © 2025 Apple Inc. All rights reserved.
    利用規約 プライバシーポリシー 契約とガイドライン