Media Enhancement API 提供了一种低延迟、可保护隐私的设备端 AI 解决方案,该解决方案利用硬件加速功能,在不增加 APK 大小的情况下,提供高质量的媒体改进。如需了解详情,请参阅了解媒体增强功能。
以下架构图展示了 Media Enhancement API 的异步 Surface 模式执行生命周期。此模式直接链接硬件缓冲区,从而消除在 CPU 和 GPU 内存缓冲区之间来回复制未压缩帧的性能瓶颈。
增强流水线通过以下步骤实现:
第 1 阶段:设置增强会话
1. 提供输入 surface:您的应用会向增强框架提供输入 surface 句柄,以便访问要处理的帧。
2. 设置输出 Surface:您的应用会直接向框架预配和绑定渲染目标(例如 SurfaceView 或 TextureView)。
第 2 阶段:生成输入帧
3. 准备基础媒体:您的应用会检索基础未压缩媒体。例如,通过从本地磁盘读取文件。
4. 注入帧数据:应用将原始图片载荷直接写入绑定的输入 Surface 流水线。
第 3 阶段:处理和增强
5. 执行 AI 处理:框架在设备的 GPU 或 NPU 上处理帧,应用色调映射、模糊修复或高清重塑等通过机器学习技术增强的功能。
6. 提供增强帧:引擎将增强的全分辨率帧直接输出到绑定的输出 Surface。
第 4 阶段:显示或保存结果
7. 最终确定输出:您的应用会收到经过处理的硬件流缓冲区,以便在界面中呈现或保存回存储空间。
EnhancementSession 是一个重量级上下文对象,用于维护永久性 GPU 或 NPU 内存流水线。它会分配专用视频 RAM (VRAM) 和原生系统句柄。为防止严重的内存泄漏和潜在的 OutOfMemoryError 崩溃,请遵循以下生命周期原则:
- 延迟实例化:在用户发起增强操作之前,请勿创建会话。
- 策略性重用:在处理具有相同配置(尺寸和开关选项)的数据流或帧时,维护并重用单个会话实例。
- 提示拆解:在视觉任务终止时立即调用
session.release(),以释放共享硬件资源。
初始化增强引擎
此方法会编排一个两步检查。它会验证设备的硬件是否支持加速,然后确保存在所需的机器学习模块。
在应用尝试处理媒体之前,先运行此步骤作为前提条件,验证功能,从而防止运行时初始化失败。
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 模式(Surface 输入,Surface 输出)
Surface 执行模式 (EnhancementMode.SURFACE) 可避免在 CPU 和 GPU 内存缓冲区之间移动帧所产生的性能开销。而是直接映射原始硬件缓冲区,从输入 Surface 读取帧,在原生层进行处理,然后直接传送到输出 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()