Catatan: Halaman ini merujuk ke paket Camera2. Kecuali jika aplikasi Anda memerlukan fitur khusus level rendah dari Camera2, sebaiknya gunakan CameraX. CameraX dan Camera2 mendukung Android 5.0 (level API 21) dan versi yang lebih baru.
Camera2 API mendukung perekaman video Rentang Dinamis Tinggi (HDR), yang memungkinkan Anda melihat pratinjau dan merekam konten video HDR menggunakan kamera. Dibandingkan dengan Standar Dynamic Range (SDR), HDR menawarkan rentang warna yang lebih luas dan meningkatkan rentang dinamis komponen luminans (dari 100 cd/m2 saat ini menjadi 1000-an cd/m2). Hal ini menghasilkan kualitas video yang lebih cocok dengan kehidupan nyata, dengan warna yang lebih kaya, sorotan yang lebih cerah, dan bayangan yang lebih gelap.
Lihat bagaimana video HDR menangkap matahari terbenam dengan detail yang lebih jelas.
Prasyarat perangkat
Tidak semua perangkat Android mendukung perekaman video HDR. Sebelum merekam video HDR di aplikasi, tentukan apakah perangkat Anda memenuhi prasyarat berikut:
- Menargetkan Android 13 (level API 33).
- Memiliki sensor kamera berkemampuan 10 bit atau lebih tinggi. Untuk mengetahui informasi selengkapnya tentang Dukungan HDR, lihat Memeriksa dukungan HDR.
Karena tidak semua perangkat memenuhi prasyarat, Anda dapat menambahkan alur kode terpisah saat menyiapkan perekaman video HDR di aplikasi. Hal ini memungkinkan aplikasi Anda beralih ke SDR di perangkat yang tidak kompatibel. Selain itu, pertimbangkan untuk menambahkan opsi UI untuk SDR. Pengguna kemudian dapat beralih antara SDR dan HDR untuk kebutuhan perekaman video mereka.
Arsitektur pengambilan HDR
Diagram berikut menunjukkan komponen utama arsitektur pengambilan HDR.
Saat perangkat kamera mengambil frame dalam HDR, framework Camera2 mengalokasikan
buffer yang menyimpan output sensor kamera yang diproses. Alat ini juga melampirkan
metadata HDR masing-masing jika diperlukan oleh profil HDR. Framework Camera2
kemudian mengantrekan buffering yang terisi untuk platform output yang direferensikan dalam
CaptureRequest, seperti layar atau encoder
video, seperti yang ditunjukkan dalam diagram.
Memeriksa dukungan HDR
Sebelum merekam video HDR di aplikasi, tentukan apakah perangkat mendukung profil HDR yang Anda pilih.
Gunakan metode CameraManager
getCameraCharacteristics() untuk mendapatkan
instance CameraCharacteristics, yang dapat Anda kueri
untuk kemampuan HDR perangkat Anda.
Langkah-langkah berikut memeriksa apakah perangkat mendukung HLG10. HLG10 adalah standar HDR dasar yang harus didukung oleh produsen perangkat pada kamera dengan output 10-bit.
Pertama, periksa apakah perangkat mendukung profil 10-bit (kedalaman bit untuk HLG10):
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 }Selanjutnya, periksa apakah perangkat mendukung HLG10 (atau profil lain yang didukung):
@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 chosen profile, in this case HLG10 return availableProfiles.contains(DynamicRangeProfiles.HLG10) } return false; }
Jika perangkat mendukung HDR, isHLGSupported() akan selalu menampilkan true. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi CameraCharacteristics.
Menyiapkan pengambilan HDR
Setelah memastikan bahwa perangkat Anda mendukung HDR, siapkan aplikasi Anda untuk mengambil streaming video HDR
mentah dari kamera. Gunakan
setDynamicRangeProfile() untuk menyediakan
OutputConfiguration streaming dengan profil HDR yang didukung perangkat, yang kemudian diteruskan ke
CameraCaptureSession setelah dibuat. Lihat
daftar profil HDR yang didukung.
Dalam contoh kode berikut, setupSessionDynamicRangeProfile() akan memeriksa terlebih dahulu
apakah perangkat menjalankan Android 13. Kemudian, kode ini menyiapkan
CameraCaptureSession dengan profil HDR yang didukung perangkat sebagai
OutputConfiguration:
/**
* Creates a [CameraCaptureSession] with a dynamic range profile.
*/
private fun setupSessionWithDynamicRangeProfile(
dynamicRange: Long,
device: CameraDevice,
targets: List<Surface>,
handler: Handler? = null,
stateCallback: CameraCaptureSession.StateCallback
): Boolean {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.TIRAMISU) {
val outputConfigs = mutableListOf<OutputConfiguration>()
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
}
}
Saat aplikasi kamera melakukan inisialisasi kamera, aplikasi akan mengirimkan
CaptureRequest berulang untuk melihat pratinjau rekaman:
session.setRepeatingRequest(previewRequest, null, cameraHandler)
Dan juga untuk memulai perekaman video:
// 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)
Mengenkode streaming kamera HDR
Untuk mengenkode streaming kamera HDR dan menulis file ke disk, gunakan
MediaCodec.
Pertama, dapatkan output Surface, yang dipetakan ke buffer yang menyimpan
data video mentah. Untuk MediaCodec, gunakan
createInputSurface().
Untuk melakukan inisialisasi MediaCodec, aplikasi harus membuat MediaFormat
dengan profil codec, ruang warna, rentang warna, dan fungsi transfer
yang ditentukan:
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)
Untuk mengetahui detail selengkapnya tentang implementasi, lihat EncoderWrapper.kt aplikasi contoh Camera2Video.
Format HDR
Mulai Android 13, perangkat kamera dengan kemampuan output 10-bit harus mendukung HLG10 untuk pengambilan dan pemutaran HDR. Selain itu, pembuat perangkat dapat mengaktifkan format HDR apa pun yang mereka pilih menggunakan arsitektur pengambilan HDR.
Tabel berikut merangkum format HDR yang tersedia dan kemampuannya untuk perekaman video HDR.
| Format | Fungsi Transfer (TF) | Metadata | Codec | Depth Bit |
|---|---|---|---|---|
| HLG10 | HLG | Tidak | HEVC | 10-bit |
| HDR10 | PQ | Statis | HEVC | 10-bit |
| HDR10+ | PQ | Dinamis | HEVC | 10-bit |
| Dolby Vision 8.4 | HLG | Dinamis | HEVC | 10-bit |
Resource
Untuk aplikasi yang berfungsi dengan fungsi perekaman video HDR, lihat contoh Camera2Video di GitHub.