注: このページでは、Camera2 パッケージについて説明します。アプリで Camera2 の特定の低レベルの機能を必要とする場合を除き、CameraX を使用することをおすすめします。CameraX と Camera2 は、どちらも Android 5.0(API レベル 21)以降に対応しています。
Camera2 API のサポート ハイ ダイナミック レンジ(HDR)動画キャプチャ。 カメラで HDR 動画コンテンツを撮影する。標準のダイナミック広告との比較 レンジ(SDR)、HDR ではより広い色彩を使用でき、ダイナミックさが増します (現在の 100 cd/m2 から数千 cd/m2 まで) その結果、日常生活に近い動画品質が得られます。 より色鮮やか、ハイライトはより明るく、シャドウはより暗くなります。
HDR 動画によって、夕焼けを細部まで鮮明に捉えることができます。
<ph type="x-smartling-placeholder">![](https://developer.android.com/static/images/training/camera/camera2/sdr_comparison.png?authuser=0000&hl=ja)
![](https://developer.android.com/static/images/training/camera/camera2/hdr_comparison.png?authuser=0000&hl=ja)
デバイスの前提条件
すべての Android デバイスが HDR 動画キャプチャをサポートしているわけではありません。 アプリで HDR 動画をキャプチャする前に、デバイスが次の要件を満たしているかどうかを確認します。 次の前提条件を満たす必要があります
- Android 13(API レベル 33)をターゲットとする。
- 10 ビット以上対応のカメラセンサーを搭載している。HDR について詳しくは、 サポートについては、HDR サポートを確認するをご覧ください。
すべてのデバイスが前提条件を満たすとは限らないため、別のコードを追加して アプリで HDR 動画キャプチャを設定する際のパスを指定します。 これにより、互換性のないデバイスでアプリを SDR にフォールバックできます。 また、SDR の UI オプションの追加も検討してください。ユーザーはここで 動画撮影のニーズに応じて SDR と HDR の間で切り替えます。
HDR キャプチャ アーキテクチャ
次の図は、HDR キャプチャ アーキテクチャの主なコンポーネントを示しています。
![HDR キャプチャ アーキテクチャの図。](https://developer.android.com/static/images/training/camera/camera2/hdr_capture_architecture_diagram.png?authuser=0000&hl=ja)
カメラデバイスが HDR でフレームをキャプチャすると、Camera2 フレームワークは
処理されたカメラセンサー出力を保存するバッファです。
また、HDR プロファイルで必要な場合は、それぞれの HDR メタデータも添付します。
Camera2 フレームワークは、入力されたバッファを出力サーフェスのキューに入れます。
CaptureRequest
で参照される
構成する必要があります。
HDR サポートを確認する
アプリで HDR 動画をキャプチャする前に、デバイスがサポートしているかどうかを確認する HDR プロファイルを設定します。
CameraManager
getCameraCharacteristics()
メソッドを使用して、
CameraCharacteristics
たとえば、デバイスの HDR 機能をクエリできます。
次の手順では、デバイスが HLG10 に対応しているかどうかを確認します。 HLG10 は、デバイス メーカーがサポートする必要のある HDR ベースライン標準です。 10 ビット出力のカメラでキャプチャできます。
まず、デバイスが 10 ビット プロファイル(HLG10 のビット深度)をサポートしているかどうかを確認します。
Kotlin
private fun isTenBitProfileSupported(cameraId: String): Boolean { val cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraId) val availableCapabilities = cameraCharacteristics.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES) for (capability in availableCapabilities!!) { if (capability == CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_DYNAMIC_RANGE_TEN_BIT) { return true } } return false }
次に、デバイスが HLG10(またはサポートされている別のプロファイル)に対応しているかどうかを確認します。
Kotlin
@RequiresApi(api = 33) private fun isHLGSupported(cameraId: String): Boolean { if (isTenBitProfileSupported(cameraId)) { Val cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraId) val availableProfiles = cameraCharacteristics .get(CameraCharacteristics.REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES)!! .getSupportedProfiles() // Checks for the desired profile, in this case HLG10 return availableProfiles.contains(DynamicRangeProfiles.HLG10) } return false; }
デバイスが HDR をサポートしている場合、isHLGSupported()
は常に true
を返します。
詳しくは、
CameraCharacteristics
ご覧ください。
HDR キャプチャを設定する
デバイスが HDR に対応していることを確認したら、
未処理の HDR 動画ストリームが出力されます。
setDynamicRangeProfile()
を使用して、ストリームの OutputConfiguration
を指定します。
デバイスでサポートされている HDR プロファイルを設定したうえで、
CameraCaptureSession
に
作成できます。
サポートされている HDR プロファイルのリストをご覧ください。
次のコードサンプルでは、setupSessionDynamicRangeProfile()
は最初に
デバイスに Android 13 が搭載されていることを確認できます。
次に、デバイスでサポートされているデバイスで CameraCaptureSession
をセットアップします。
OutputConfiguration
としての HDR プロファイル:
Kotlin
/** * Creates a [CameraCaptureSession] with a dynamic range profile. */ private fun setupSessionWithDynamicRangeProfile( dynamicRange: Long, device: CameraDevice, targets: List, handler: Handler? = null, stateCallback: CameraCaptureSession.StateCallback ): Boolean { if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.TIRAMISU) { val outputConfigs = mutableListOf () for (target in targets) { val outputConfig = OutputConfiguration(target) //sets the dynamic range profile, for example DynamicRangeProfiles.HLG10 outputConfig.setDynamicRangeProfile(dynamicRange) outputConfigs.add(outputConfig) } device.createCaptureSessionByOutputConfigurations( outputConfigs, stateCallback, handler) return true } else { device.createCaptureSession(targets, stateCallback, handler) return false } }
}
カメラアプリは、カメラを初期化する際に、
繰り返し
CaptureRequest
録画をプレビューします。
Kotlin
session.setRepeatingRequest(previewRequest, null, cameraHandler)
動画の録画を開始することもできます。
Kotlin
// Start recording repeating requests, which stops the ongoing preview // repeating requests without having to explicitly call // `session.stopRepeating` session.setRepeatingRequest(recordRequest, object : CameraCaptureSession.CaptureCallback() { override fun onCaptureCompleted(session: CameraCaptureSession, request: CaptureRequest, result: TotalCaptureResult) { if (currentlyRecording) { encoder.frameAvailable() } } }, cameraHandler)
HDR カメラ ストリームをエンコードする
HDR カメラ ストリームをエンコードしてファイルをディスクに書き込むには、
MediaCodec
を使用します。
まず、OutputSurface
を取得します。
未処理の動画データを格納するバッファにマッピングされます。
MediaCodec
の場合、
createInputSurface()
を使用します。
MediaCodec
を初期化するには、アプリで
MediaFormat
は、
コーデック プロファイル、色空間、色範囲、伝達関数:
Kotlin
val mimeType = when { dynamicRange == DynamicRangeProfiles.STANDARD -> MediaFormat.MIMETYPE_VIDEO_AVC dynamicRange < DynamicRangeProfiles.PUBLIC_MAX -> MediaFormat.MIMETYPE_VIDEO_HEVC else -> throw IllegalArgumentException("Unknown dynamic range format") } val codecProfile = when { dynamicRange == DynamicRangeProfiles.HLG10 -> MediaCodecInfo.CodecProfileLevel.HEVCProfileMain10 dynamicRange == DynamicRangeProfiles.HDR10 -> MediaCodecInfo.CodecProfileLevel.HEVCProfileMain10HDR10 dynamicRange == DynamicRangeProfiles.HDR10_PLUS -> MediaCodecInfo.CodecProfileLevel.HEVCProfileMain10HDR10Plus else -> -1 } // Failing to correctly set color transfer causes quality issues // for example, washout and color clipping val transferFunction = when (codecProfile) { MediaCodecInfo.CodecProfileLevel.HEVCProfileMain10 -> MediaFormat.COLOR_TRANSFER_HLG MediaCodecInfo.CodecProfileLevel.HEVCProfileMain10HDR10 -> MediaFormat.COLOR_TRANSFER_ST2084 MediaCodecInfo.CodecProfileLevel.HEVCProfileMain10HDR10Plus -> MediaFormat.COLOR_TRANSFER_ST2084 else -> MediaFormat.COLOR_TRANSFER_SDR_VIDEO } val format = MediaFormat.createVideoFormat(mimeType, width, height) // Set some properties. Failing to specify some of these can cause the MediaCodec // configure() call to throw an exception. format.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface) format.setInteger(MediaFormat.KEY_BIT_RATE, bitRate) format.setInteger(MediaFormat.KEY_FRAME_RATE, frameRate) format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, IFRAME_INTERVAL) if (codecProfile != -1) { format.setInteger(MediaFormat.KEY_PROFILE, codecProfile) format.setInteger(MediaFormat.KEY_COLOR_STANDARD, MediaFormat.COLOR_STANDARD_BT2020) format.setInteger(MediaFormat.KEY_COLOR_RANGE, MediaFormat.COLOR_RANGE_LIMITED) format.setInteger(MediaFormat.KEY_COLOR_TRANSFER, transferFunction) format.setFeatureEnabled(MediaCodecInfo.CodecCapabilities.FEATURE_HdrEditing, true) } mediaCodec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE)
実装について詳しくは、Camera2Video サンプルアプリの
EncoderWrapper.kt
。
HDR 形式
Android 13 以降、10 ビット出力機能を持つカメラデバイス HDR キャプチャで HLG10 をサポートし、 playback を使用します。 さらに、デバイス メーカーは任意の HDR 形式を有効にすることができます。 HDR キャプチャ アーキテクチャを使用する。
次の表は、利用可能な HDR 形式とその機能をまとめたものです。 HDR 動画キャプチャに使用できます
形式 | 伝達関数(TF) | メタデータ | コーデック | ビット深度 |
---|---|---|---|---|
HLG10 | HLG | × | HEVC | 10 ビット |
HDR10 | PQ | 静的 | HEVC | 10 ビット |
HDR10+ | PQ | 動的 | HEVC | 10 ビット |
ドルビー ビジョン 8.4 | HLG | 動的 | HEVC | 10 ビット |
リソース
HDR 動画キャプチャ機能を備えた動作中のアプリについては、 Camera2Video のサンプル ご覧ください。