Hardware decodingとは、SoC内の専用GPUチップ、DSP、またはビデオ処理ブロックを使用したメディアデータのハードウェアによる圧縮解除です。ソフトウェアデコードとは異なり、ハードウェアデコードはビデオの圧縮解除専用に設計された物理回路で実行されます。Apple VideoToolboxのドキュメント(2026年)によると、Aシリーズチップでのハードウェアデコードは、60 FPSの4K H.264でエネルギー効率0.3Wを達成しています。
重要なポイント
Hardware decodingとは、汎用CPUではなく、システムオンチップ(SoC)に統合された専用集積回路でメディアデータを圧縮解除するプロセスです。このようなブロックはビデオデコーダーまたはVPU(Video Processing Unit)と呼ばれ、特定の圧縮アルゴリズムに最適化されたASICアクセラレータです。
最新のモバイルSoCには、人気のある各コーデック用に個別のハードウェアブロックが含まれています。例えば、Apple A17 Proチップには、H.264、H.265、VP9、AV1、ProRes用のデコーダーが含まれています。各ブロックは完全な処理パイプラインであり、入力で圧縮ビットストリームを受け入れ、CPUの関与なしに出力でYUVまたはBGRA形式のデコード済みフレームを提供できます。
ハードウェアデコードは2012–2013年にモバイル業界で標準になり、Qualcomm Snapdragon 800とApple A7が初めて専用のH.264デコードブロックを搭載しました。それ以来、この技術は単一フォーマットのサポートから、複数のストリームを同時にデコードできるユニバーサルマルチフォーマットブロックへと進化しました — 例えば、別々のビデオストリームを使用したPiP用などです。
ハードウェアデコードのプロセスはソフトウェアデコードとは根本的に異なります。CPUの逐次命令実行ではなく、ハードウェアブロックは圧縮解除の各段階(エントロピーデコード、逆量子化、逆DCT、動き補償)に物理回路を実装します。
典型的なハードウェアデコーダーは複数のパイプラインステージで構成されます。最初のステージはエントロピーデコーダーで、CABACまたはCAVLC用の有限状態機械(FSM)として実装されます。各ビットが条件分岐で処理されるソフトウェア実装とは異なり、ハードウェアCABACは並列コンテキスト予測回路を使用し、1サイクルあたり1ビットではなく2–3ビットを処理できます。
2番目のステージは逆DCTブロックです。ソフトウェアDCTではCPUで乗算累積ループが必要です。ハードウェア実装では、8x8ブロックの64すべての係数を1サイクルで計算する行列乗算器を使用します。ハードウェア逆DCTは400–600 MHzで動作し、毎秒最大400万マクロブロックを処理します。これはリアルタイムの8Kビデオデコードに十分です。
3番目のステージは動き補償(MC)モジュールです。逆DCTと並行して、ハードウェアブロックはビットストリームから動きベクトルを受け取り、デコード済みフレームバッファーから参照領域を抽出します。DPBバッファー(Decoded Picture Buffer)は最大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を受け入れ、CPUを介したコピーなしでGPUへの直接デコードが可能です。
ハードウェアデコードにはソフトウェアに比べて3つの主な利点があります:エネルギー効率、パフォーマンス、安定性。それぞれがバッテリーリソースと熱的制約が限られたモバイルデバイスにとって極めて重要です。
ハードウェアデコードの主な利点は、根本的に低い消費電力です。標準的なH.264/H.265ハードウェアデコーダーは、1080pビデオをリアルタイムでデコードする際に0.2–0.5Wを消費します。比較すると、CPUでの同じストリームのソフトウェアデコードは、プロセッサーアーキテクチャに応じて1.5–4Wを消費します。5–10倍の差はバッテリー寿命に直接影響します:ハードウェアデコードによるビデオ再生では10–15時間の映画鑑賞が可能ですが、CPUでのソフトウェアデコードでは2–4時間です。
エネルギー効率は狭い専門化によって達成されます。幅広い命令を実行し複雑な制御論理を持つCPUとは異なり、ハードウェアデコーダーは特定のアルゴリズムに必要な回路のみを含みます。これらのブロックのクロック周波数は200–600 MHzで、CPUの2–3 GHzと比較して、電圧の二乗に比例して動的消費電力を削減します。
ハードウェアデコードは高解像度でも保証されたフレームレートを提供します。パイプラインアーキテクチャのおかげで、ハードウェアブロックは複数の圧縮解除段階を同時に処理できます:一方のモジュールが次のマクロブロックのエントロピーデコードを実行している間に、もう一方は現在のマクロブロックに逆DCTを適用します。このような並列処理は各段階が逐次処理となるCPUでは実現不可能です。
ハードウェアデコーダーの放熱は大幅に低く、4Kビデオデコード中の標準的なブロックは0.3–0.8Wの熱を放散しますが、CPUでは2–6Wです。つまり、長時間の視聴でもデバイスが過熱せず、スロットリングが発生せず、ユーザーはドロップなしの安定した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メソッドはタイムアウト付きで利用可能な入力バッファーを待機します。バッファーが利用できない場合は現在のフレームがスキップされ、不均一なビットレート時のキューオーバーフローを防ぎます。
ハードウェアデコードはほとんどの本番シナリオに最適な選択ですが、万能な解決策ではありません。適用範囲の限界を理解することで、ハードウェアコーデックサポートの欠如がユーザーエクスペリエンスを損なう状況を回避できます。
ハードウェアデコードは次の3つの場合に必須です:長時間のビデオ再生(30分以上)、4Kコンテンツのデコード、およびバッテリー寿命を最大限に重視するあらゆるアプリケーション。ストリーミングサービス(Netflix、YouTube、Twitch)は排他的にハードウェアデコードを使用します。ソフトウェアでは高ビットレートと大解像度での安定した再生を保証できないためです。これらのサービスにとってDRMサポート(FairPlay、Widevine)は重要であり、これはデコーダーからディスプレイ出力までの保護されたパイプラインを提供するハードウェアブロックを介してのみ利用可能です。
統合ビデオ(カットシーン、広告、ゲーム内シネマティック)を使用するゲームでも、ハードウェアデコードが推奨されます。UnityやUnreal Engineなどの最新ゲームエンジンには、VideoToolboxとMediaCodecの組み込みサポートがあります。ゲームでのハードウェアデコードは、物理シミュレーション、敵AI、入力処理のためにCPUを解放し、全体的なパフォーマンスを向上させます。
ハードウェアデコードの主な制限は、ハードウェアフォーマットサポートへの依存です。SoCにAV1用のデコーダーがない場合(例:Snapdragon 8 Gen 1搭載デバイス)、アプリケーションはFFmpegとdav1dを介したソフトウェアフォールバックを提供する必要があります。同じ状況は古いデバイスのH.265と、Apple A13+チップでのみデコードをサポートするProResにも当てはまります。再生開始前に必要なフォーマットのハードウェアデコーダーの可用性を確認し、動的にデコード戦略を選択することをお勧めします。
2つ目の制限は、同時デコードセッションの数です。ほとんどのSoCは1–2の並列ハードウェアデコーダーをサポートしています。3番目のセッションを開こうとするとAPIがエラーを返し、アプリケーションはソフトウェアデコードに切り替える必要があります。セッション数はSoCメーカーによって異なります:AppleチップはA17 Proで最大4つのH.264デコードセッションを許可しますが、Snapdragon 8 Gen 2はH.265で最大2、VP9で合計最大2をサポートします。
よくある質問
iOSでは、VTDecompressionSessionCopySupportedPropertyDictionaryを使用してkVTDecompressionPropertyKey_UsingHardwareAcceleratedVideoDecoderを確認します。Androidでは、デコーダーを作成した後にMediaCodec.getCodecInfo().isHardwareAccelerated()を呼び出します。フラグがfalseの場合、ソフトウェアデコーダー(通常はOMX.google.*)が使用されています。
はい、ストリーミングサービスでのDRMコンテンツにはハードウェアデコードが必須です。iOSのFairPlayとAndroidのWidevine L1は、デコーダーからディスプレイ出力までの保護されたパイプラインを必要とし、デコード済みフレームはアプリケーションからアクセスできません。このようなパイプラインは、セキュアセッションをサポートするハードウェアデコードでのみ可能です。
VDADecoder(Video Decode Acceleration)はiOS 6–8のレガシーフレームワークで、VideoToolboxに置き換えられました。VideoToolboxはH.265、HDR、マルチスレッドをサポートする、より現代的で柔軟なAPIを提供します。VDADecoderは新規プロジェクトには推奨されません — VideoToolboxのVTDecompressionSessionを使用してください。
ほとんどの場合、できません。iOSでは、消費電力の制約によりハードウェアデコーダーはアクティブなフォアグラウンドアプリケーションを必要とします。Androidでは、サービス内のMediaCodecを介したバックグラウンドデコードが可能ですが、パフォーマンスが低下する可能性があります。例外はPiPモードで、システムがフローティングウィンドウでのハードウェアデコードを許可します。
絶対的なリーダーはH.264で、最新のモバイルデバイスの100%でハードウェアデコードされます。H.265は約80%のデバイス(iOS 8+、適切なSoCを搭載したAndroid 5+)でサポートされています。AV1が最も限定的です:ハードウェアサポートはSnapdragon 8 Gen 2、Exynos 2200、Apple A17 Proを搭載した2023年以降のデバイスのみです。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。