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()