Hardware decoding — 使用SoC内部的专用GPU芯片、DSP或视频处理块对媒体数据进行硬件解码。与软件解码不同,硬件解码在专门为视频解压缩设计的物理电路上执行。根据Apple VideoToolbox documentation (2026)的数据,A系列芯片上的硬件解码在60 FPS下对4K H.264可达到能效0.3 W。
要点
Hardware decoding — 是一种媒体数据解压缩过程,不在通用CPU上执行,而在集成到片上系统(SoC)中的专用集成电路上执行。这些块称为视频解码器或VPU(视频处理单元),是针对特定压缩算法优化的ASIC加速器。
现代移动SoC包含针对每种流行编解码器的独立硬件块。例如,Apple A17 Pro芯片包含H.264、H.265、VP9、AV1和ProRes的解码器。每个块是一个完整的处理流水线,能够在输入接收压缩比特流,并在输出提供YUV或BGRA格式的已解码帧,无需CPU参与。
硬件解码在2012–2013年成为移动行业的标准,当时Qualcomm Snapdragon 800和Apple A7首次包含专用的H.264解码块。从那时起,技术从支持单一格式发展到能够同时解码多个流的通用多格式块——例如,用于带有单独视频流的PiP操作。
硬件解码过程与软件截然不同。硬件块不是顺序执行CPU指令,而是为解压缩的每个阶段实现物理电路:熵解码、逆量化、逆DCT和运动补偿。
典型的硬件解码器由多个流水线级组成。第一级——熵解码器,作为用于CABAC或CAVLC的有限状态机(FSM)实现。与软件实现中每个位通过条件跳转处理不同,硬件CABAC使用并行上下文预测电路,允许每个时钟周期处理2–3位而不是一位。
第二级——逆DCT块。软件DCT需要在CPU上进行乘累加循环。硬件实现使用矩阵乘法器,在一个时钟周期内计算8×8块的所有64个系数。硬件逆DCT以400–600 MHz频率工作,每秒处理多达400万个宏块,足以实时解码8K视频。
第三级——运动补偿(MC)模块。与逆DCT并行,硬件块从比特流接收运动矢量,并从解码帧缓冲器中提取参考区域。DPB缓冲器(解码图像缓冲器)存储最多16个参考帧,通过具有低延迟的专用缓存访问这些帧。现代解码器使用具有自适应平滑和亚像素插值的预测,这对H.265和AV1至关重要。
硬件解码器的管理通过DMA控制器进行。应用程序向解码器传递指向共享内存中压缩数据的指针,解码器通过直接内存访问独立读取比特流。帧解码完成后,中断通知驱动程序,准备好的帧在输出缓冲池中变为可用。这种机制完全消除了数据处理阶段CPU的负载——处理器仅启动解码并接收准备好的结果。
两个移动平台都提供用于硬件解码的原生API,但在缓冲区管理和解码器生命周期方面有不同的方法。iOS上的VideoToolbox与Metal紧密集成以输出到屏幕,而Android上的MediaCodec使用Surface进行直接渲染。
| 参数 | VideoToolbox(iOS) | MediaCodec(Android) |
|---|---|---|
| 输出格式 | CVPixelBuffer(Metal/OpenGL) | Surface或ByteBuffer |
| 内存管理 | 通过池自动管理 | 通过dequeue手动管理 |
| 线程安全 | 是,异步回调 | 是,同步API |
| HDR支持 | 是(PQ、HLG) | 是(HDR10、HDR10+) |
| 多路解码 | 最多4个会话(A17) | 取决于SoC |
VideoToolbox — iOS和macOS上用于硬件解码的框架。它使用异步解码模型:调用VTDecompressionSessionDecodeFrame立即返回,准备好的帧通过单独队列中的回调到达。VideoToolbox自动管理像素缓冲池(CVPixelBufferPool),并可重新使用释放的缓冲区用于新帧。对于HDR视频,VideoToolbox支持ITU-R BT.2020色彩空间和PQ/HLG EOTF。
MediaCodec使用具有输入和输出缓冲区队列的同步模型。应用程序循环调用dequeueInputBuffer发送压缩数据,并调用dequeueOutputBuffer获取解码结果。这种方法为开发人员提供了对解码速率的完全控制,这对音频和视频同步很重要。对于屏幕输出,MediaCodec接受Surface,允许在GPU上直接解码而无需通过CPU复制。
硬件解码相比软件解码有三个关键优势:能效、性能和稳定性。每个优势对于电池资源有限和热约束的移动设备都至关重要。
硬件解码的主要优势——功耗显著降低。典型的硬件H.264/H.265解码器在实时解码1080p视频时消耗0.2–0.5 W。相比之下,相同流在CPU上的软件解码根据处理器架构消耗1.5–4 W。5–10倍的差异直接影响电池续航时间:观看视频时,硬件解码允许观看10–15小时电影,而CPU上的软件解码只能观看2–4小时。
能效通过狭窄的专业化实现。与执行广泛指令集并具有复杂控制逻辑的CPU不同,硬件解码器仅包含特定算法所需的电路。时钟频率这些块为200–600 MHz,而CPU为2–3 GHz,这将动态功耗按电压的平方成比例降低。
硬件解码即使在高等分辨率下也能保证帧率。得益于流水线架构,硬件块可以同时处理多个解压缩阶段:当一个模块为下一个宏块执行熵解码时,另一个已经对当前宏块应用逆DCT。这种并行性在CPU上是无法实现的,其中每个阶段都是顺序操作。
硬件解码器的散热显著更低:典型块在4K视频软件解码时散发0.3–0.8 W热量,而CPU散发2–6 W。这意味着设备即使在长时间观看时也不会过热,不会发生节流,用户可以获得稳定的60 FPS而不会下降。外壳温度在硬件解码时通常比软件低5–10度,这对于没有主动散热的平板电脑尤为重要。
让我们看看通过VideoToolbox在iOS上具有回调处理的硬件解码和通过MediaCodec在Android上的完整流水线的实际实现。
import VideoToolbox
import CoreMedia
class HardwareDecoder {
var session: VTDecompressionSession?
func setup() {
let formatDesc = createFormatDescription()
var callback = VTDecompressionOutputCallbackRecord(
decompressionOutputCallback: decodingCallback,
decompressionOutputRefCon: nil
)
VTDecompressionSessionCreate(
allocator: nil,
videoFormatDescription: formatDesc,
videoDecoderSpecification: nil,
destinationImageBufferAttributes: nil,
outputCallback: &callback,
decompressionSessionOut: &session
)
}
func decode(sampleBuffer: CMSampleBuffer) {
VTDecompressionSessionDecodeFrame(
session!, sampleBuffer: sampleBuffer,
flags: ._EnableAsynchronousDecompression,
frameRefcon: nil, infoFlagsOut: nil
)
}
}
代码创建一个具有异步回调的VideoToolbox解码会话。VTDecompressionSessionCreate根据传递的CMVideoFormatDescription自动确定可用的硬件解码器。标志kVTDecodeFrame_EnableAsynchronousDecompression激活异步模式——应用程序在解码期间不会被阻塞,而是通过回调接收帧。对于H.264,需要通过CMVideoFormatDescriptionCreateFromH264ParameterSets从SPS/PPS NAL单元预先创建格式描述。
class HardwareDecoder(private val surface: Surface) {
private var mediaCodec: MediaCodec? = null
fun initDecoder(mimeType: String, width: Int, height: Int) {
mediaCodec = MediaCodec.createDecoderByType(mimeType)
val format = MediaFormat.createVideoFormat(mimeType, width, height)
mediaCodec?.configure(format, surface, null, 0)
mediaCodec?.start()
}
fun feedFrame(data: ByteArray, pts: Long) {
val inputIndex = mediaCodec!!.dequeueInputBuffer(TIMEOUT_US)
if (inputIndex >= 0) {
val buffer = mediaCodec!!.getInputBuffer(inputIndex)
buffer?.put(data)
mediaCodec!!.queueInputBuffer(inputIndex, 0, data.size, pts, 0)
}
}
}
Kotlin代码创建绑定到Surface的MediaCodec,确保直接输出到屏幕而无需通过CPU复制数据。参数mimeType使用MediaFormat常量:H.264使用video/avc,H.265使用video/hevc,AV1使用video/av01。方法dequeueInputBuffer等待带超时的空闲输入缓冲区;如果缓冲区不可用——跳过当前帧,防止在比特率不均匀时队列溢出。
硬件解码是大多数生产场景的最佳选择,但不是通用解决方案。理解适用范围有助于避免编解码器的硬件支持缺失破坏用户体验的情况。
硬件解码在三种情况下是强制性的:长时间视频播放(超过30分钟)、4K内容解码以及任何以最大电池续航为目标的应用程序。流媒体服务(Netflix、YouTube、Twitch)专门使用硬件解码,因为软件解码无法在高比特率和大分辨率下保证稳定播放。对于这些服务,DRM支持(FairPlay、Widevine)至关重要,只有通过提供从解码器到显示的受保护流水线的硬件块才能实现。
对于集成视频的游戏(过场动画、广告、游戏内视频)也推荐使用硬件解码。现代游戏引擎,如Unity和Unreal Engine,内置了对VideoToolbox和MediaCodec的支持。硬件解码在游戏中释放CPU用于物理模拟、敌人AI和输入处理,从而提高整体性能。
硬件解码的主要限制——对格式硬件支持的依赖。如果SoC不包含AV1的解码器(例如Snapdragon 8 Gen 1设备),应用程序必须通过FFmpeg和dav1d提供软件回退。H.265在旧设备上和ProRes(仅Apple A13+芯片支持解码)也存在类似情况。建议在开始播放前检查所需格式的硬件解码器的可用性,并动态选择解码策略。
第二个限制——同时解码会话的数量。大多数SoC支持1–2个并行硬件解码器。尝试打开第三个会话时,API将返回错误,应用程序必须切换到软件解码。会话数量取决于SoC制造商:Apple芯片在A17 Pro上允许最多4个H.264解码会话,Snapdragon 8 Gen 2允许最多2个H.265会话和总共最多2个VP9会话。
常见问题
在iOS上使用VTDecompressionSessionCopySupportedPropertyDictionary,并检查kVTDecompressionPropertyKey_UsingHardwareAcceleratedVideoDecoder。在Android上,创建解码器后调用MediaCodec.getCodecInfo().isHardwareAccelerated()。如果标志为false——使用的是软件解码器,通常是OMX.google.*。
是的,硬件解码对于流媒体服务中的DRM内容是强制性的。iOS上的FairPlay和Android上的Widevine L1需要从解码器到显示的受保护流水线,其中解码后的帧不能被应用程序读取。这种流水线只有在支持安全会话的硬件解码时才可能实现。
VDADecoder(视频解码加速)——来自iOS 6–8的过时框架,已被VideoToolbox取代。VideoToolbox提供更现代、更灵活的API,支持H.265、HDR和多线程。VDADecoder不建议用于新项目——使用VideoToolbox中的VTDecompressionSession。
大多数情况下不能。在iOS上,由于功耗限制,硬件解码器需要前台活动的应用程序。在Android上,可以通过MediaCodec在服务中进行后台解码,但性能可能会降低。例外——PiP模式,系统允许在浮动窗口中进行硬件解码。
绝对领先者是H.264,它在100%的现代移动设备上被硬件解码。H.265在约80%的设备上受支持(iOS 8+,具有相应SoC的Android 5+)。AV1是最受限制的:只有在2023+设备上的硬件支持,使用Snapdragon 8 Gen 2、Exynos 2200和Apple A17 Pro。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。