Media Enhancement API は、ハードウェア アクセラレーションを活用して高品質のメディア改善を実現する、低レイテンシでプライバシーの保護に配慮したオンデバイス AI ソリューションです。APK の肥大化は発生しません。詳しくは、メディア拡張機能についてをご覧ください。
次のアーキテクチャ図は、Media Enhancement API の非同期サーフェス モードの実行ライフサイクルを示しています。このモードでは、ハードウェア バッファを直接リンクして、CPU と GPU のメモリバッファ間で非圧縮フレームをコピーする際のパフォーマンスのボトルネックを解消します。
拡張パイプラインは、次の手順で実装されます。
フェーズ 1. 拡張セッションを設定する
1. 入力サーフェスを提供する: アプリは、処理するフレームにアクセスするための入力サーフェス ハンドルを拡張フレームワークに提供します。
2. 出力サーフェスを設定する: アプリがレンダリング ターゲット(SurfaceView や TextureView など)をプロビジョニングして、フレームワークに直接バインドします。
フェーズ 2: 入力フレームを生成する
3. ベース メディアを準備する: アプリがベースの非圧縮メディアを取得します。たとえば、ローカル ディスクからファイルを読み取ります。
4. フレームデータを挿入: アプリがバインドされた入力サーフェス パイプラインに未加工の画像ペイロードを直接書き込みます。
フェーズ 3. 処理と補正
5. AI 処理を実行: フレームワークはデバイスの GPU または NPU でフレームを処理し、トーンマッピング、ぼかし除去、アップスケーリングなどの ML 拡張機能を適用します。
6. 拡張フレームを配信: エンジンは、拡張されたフル解像度のフレームをバインドされた出力サーフェスに直接出力します。
フェーズ 4. 結果を表示または保存する
7. 出力の最終処理: 処理されたハードウェア ストリーム バッファがアプリに渡され、UI でレンダリングされるか、ストレージに保存されます。
EnhancementSession は、永続的な GPU または NPU メモリ パイプラインを維持するヘビーウェイト コンテキスト オブジェクトです。専用のビデオ RAM(VRAM)とネイティブ システム ハンドルを割り当てます。重大なメモリリークや OutOfMemoryError クラッシュの可能性を防ぐため、次のライフサイクル原則を遵守してください。
- 遅延インスタンス化: ユーザーが拡張アクションを開始するまでセッションを作成しません。
- 戦略的な再利用: 同じ構成(ディメンションと切り替えオプション)でストリームまたはフレームを処理するときに、単一のセッション インスタンスを維持して再利用します。
- プロンプトのティアダウン: 視覚タスクが終了するとすぐに
session.release()を呼び出して、共有ハードウェア リソースを解放します。
拡張エンジンを初期化する
このメソッドは 2 段階のチェックを調整します。デバイスのハードウェアがアクセラレーションをサポートしているかどうかを確認し、必要な機械学習モジュールが存在することを確認します。
これを前提条件の手順として実行すると、アプリがメディアの処理を試みる前に機能を検証することで、ランタイムの初期化の失敗を防ぐことができます。
class MediaSetupViewModel(application: Application) : AndroidViewModel(application) {
private val enhancementClient = Enhancement.getClient(application)
fun initializeEnhancementEngine() {
viewModelScope.launch {
try {
// 1. Verify hardware capability
val isSupported = enhancementClient.isDeviceSupportedAsync()
if (!isSupported) {
notifyUiDeviceIncompatible()
return@launch
}
// 2. Verify and download the Google Play services ML modules
val isInstalled = enhancementClient.isModuleInstalledAsync()
if (!isInstalled) {
notifyUiDownloadingModels()
enhancementClient.installModule().await()
}
notifyUiEngineReady()
} catch (e: Exception) {
// Handle potential errors during session creation or image
// processing.
handleInitializationError(e)
}
}
}
}
実装: サーフェス モード(サーフェス イン、サーフェス アウト)
Surface 実行モード(EnhancementMode.SURFACE)では、CPU と GPU のメモリバッファ間でフレームを移動する際のパフォーマンス オーバーヘッドを回避できます。代わりに、拡張ライブラリは未加工のハードウェア バッファを直接マッピングし、入力 Surface からフレームを読み取ってネイティブに処理し、出力 Surface に直接パイプします。
単一フレームのサーフェス スナップショット
このメソッドは、ハードウェア デコードされた単一の画像フレームに効果を効率的に適用するために使用されます。
// Provisions input Surface (for example, ImageReader) and output Surface (for
// example, SurfaceView)
val inputSurface: Surface = imageReader.surface
val outputSurface: Surface = surfaceView.holder.surface
// 1. Configure parameters for SURFACE mode
val surfaceOptions = EnhancementOptions(
imageReader.width,
imageReader.height,
EnhancementMode.SURFACE,
enableTonemap = true,
enableDeblurDenoise = true,
enableFaceDetection = false
).also {
// 2. Bind hardware surfaces
it.setInputSurface(inputSurface)
it.setOutputSurface(outputSurface)
}
// 3. Create the session to process the hardware frame
val singleFrameSession = enhancementClient.createSessionAsync(surfaceOptions, executor)
// The API processes the single frame. Upon completion, release the session.
singleFrameSession.release()