第11章:キャプチャの種類
11.1 パイプラインへの3つの投入方法
第10章では、リクエストが Camera2 パイプラインをどのように流れるかを見ました。しかし、それらのリクエストをどのように送信するかが非常に重要です。Camera2 には 3 つの送信メカニズムがあり、それぞれ挙動が根本的に異なります:
- 単発 (One-shot) (
capture()) — 単一のリクエストを 1 回だけ実行します。 - バースト (Burst) (
captureBurst()) — リクエストのリストを順番に、連続して実行します。 - 繰り返し (Repeating) (
setRepeatingRequest()) — 同じリクエストを(中断されるまで)永遠に継続的に実行します。
これら 3 つの送信モードに加えて、フレームワークは 6 つのキャプチャテンプレートを提供しています。これらは、一般的なユースケース(プレビュー、静止画キャプチャ、ビデオ録画、マニュアル制御など)に合わせた推奨の初期設定を CaptureRequest.Builder に入力してくれます。
この章を読み終える頃には、それぞれのキャプチャタイプとテンプレートをいつ使うべきかを正確に理解できるでしょう。
Android Camera Parameters アプリ(GitHub、Play ストア)では、Capture Demo タブでこれら 3 つのキャプチャタイプすべてを確認できます。
11.2 単発:capture()
最も単純な送信モードは、CameraCaptureSession.capture() による単発キャプチャです。これは名前の通り、単一の CaptureRequest をパイプラインに投入し、1 回だけ実行して終了します。
いつ使うか
| ユースケース | なぜ単発か? |
|---|---|
| 単一の静止画撮影 | シャッタークリックごとに 1 回だけ実行するため。 |
| 単一の AF/AE トリガー | タップフォーカスイベントのために CONTROL_AF_TRIGGER_START を 1 回だけ発火させる。 |
| ビデオ中のスナップショット | ビデオ録画中に、高解像度のフレームを 1 つだけ取得する。 |
プレビューとの相互作用
Camera2 における重要なデザインパターンは、プレビューを繰り返しリクエストとして実行し、静止画撮影を単発リクエストとして「注入」することです。単発リクエストは保留キュー内で繰り返しリクエストよりも先に割り込むため、即座に実行されます。単発リクエストが完了すると、フレームワークは自動的に繰り返しリクエスト(プレビュー)を再開します。
この自動再開動作は Camera2 フレームワークに組み込まれています。単発キャプチャの後に手動で「プレビューを再起動」する必要はありません。
11.3 バースト:captureBurst()
capture() が 1 つのリクエストを送信するのに対し、captureBurst() は List<CaptureRequest> を送信し、リスト内の N 個のフレームすべてが連続して順番に、他のリクエスト(繰り返しリクエストを含む)が割り込むことなく実行されることを保証します。
この原子的な連続性の保証は、以下のようなケースで不可欠です:
- 露出ブラケティング — ±1EV、±2EV で 3〜5 枚撮影し、HDR 合成する。
- フォーカスブラケティング — フォーカス距離をスイープさせながら撮影し、深度合成(フォーカススタック)する。
- アクション / 連写 — 速く動く被写体を 10〜30 枚撮影する。
- スローモーションビデオ — 最適化されたバーストリストを作成して高速撮影する。
11.4 繰り返し:setRepeatingRequest()
Camera2 の主役は、CameraCaptureSession.setRepeatingRequest() を介して送信される繰り返しリクエストです。1 回実行して終わるのではなく、フレームワークはすべてのフレームの後に同じリクエストを自動的に再度エンキューし続け、ハードウェアのネイティブフレームレートで連続したストリームを生成します。
なぜプレビューには繰り返しリクエストが必要なのか
タイマーを使って 1 秒間に 30 回 capture() を呼び出してプレビューを実装しようとすると、CPU を浪費し、タイミングのズレやフレームの隙間が発生してしまいます。繰り返しリクエストはフレームワーク/HAL 内部で処理されるため、アプリスレッドを介さずにスムーズで隙間のないプレビューを実現できます。
11.5 キャプチャテンプレート
すべての CaptureRequest.Builder はテンプレートから始まります。cameraDevice.createCaptureRequest(TEMPLATE_XXX) を呼び出すと、そのユースケースに最適化されたデフォルト設定が入力されます。
| テンプレート | ユースケース |
|---|---|
TEMPLATE_PREVIEW | ライブビューファインダー。低レイテンシ優先。 |
TEMPLATE_STILL_CAPTURE | 静止画写真。最高画質優先。 |
TEMPLATE_RECORD | ビデオ録画。安定したフレームレート、動画向けのAF。 |
TEMPLATE_VIDEO_SNAPSHOT | ビデオ録画中の高解像度写真。 |
TEMPLATE_ZERO_SHUTTER_LAG | ゼロシャッターラグ。最近のフレームをバッファから取得。 |
TEMPLATE_MANUAL | プロ/マニュアル制御。自動制御(3A)がデフォルトで OFF。 |
常にテンプレートから開始し、必要な特定のフィールドだけをオーバーライドしてください。
11.6 3つのキャプチャタイプの比較
| 次元 | 単発 capture() | バースト captureBurst() | 繰り返し setRepeatingRequest() |
|---|---|---|---|
| 実行 | 1 回だけ実行 | リスト内のリクエストを連続実行 | 永遠に継続実行 |
| 優先順位 | 最高。キューの先頭に割り込む | 高。リスト全体が先頭に割り込む | 最低。割り込まれた後に再開 |
| 典型的な用途 | 静止画、AF トリガー | ブラケティング、高速連写 | プレビュー、ビデオ録画 |
11.7 まとめ
- 単発
capture(): 1 つのリクエストを 1 回。静止画やトリガー用。 - バースト
captureBurst(): リクエストのリストを隙間なく実行。ブラケティング用。 - 繰り返し
setRepeatingRequest(): 継続的なストリーム。プレビューやビデオ用。 - テンプレート:
PREVIEW、STILL_CAPTUREなど。推奨の初期設定を提供。
次のステップ
第12章:CameraCharacteristics ディープダイブでは、カメラを開く前に、そのカメラが「何ができるか」を記述する静的メタデータについて詳しく見ていきます。