Not: Bu sayfa, Camera2 paketiyle ilgilidir. Uygulamanız Camera2'nin belirli, alt düzey özelliklerini gerektirmiyorsa CameraX'i kullanmanızı öneririz. Hem CameraX hem de Camera2, Android 5.0 (API düzeyi 21) ve sonraki sürümleri destekler.
Camera2 API'leri, Yüksek Dinamik Aralıklı (HDR) video çekimini destekler. Bu sayede, kameranızı kullanarak HDR video içeriğini önizleyebilir ve kaydedebilirsiniz. HDR, Standart Dinamik Aralık'a (SDR) kıyasla daha geniş bir renk aralığı sunar ve parlaklık bileşeninin dinamik aralığını artırır (mevcut 100 cd/m2'den 1.000'lerce cd/m2'ye). Bu sayede, daha zengin renkler, daha parlak vurgular ve daha koyu gölgelerle gerçek hayata daha yakın bir video kalitesi elde edilir.
HDR videonun gün batımını nasıl daha canlı ayrıntılarla yakaladığını görün.
Cihaz ön koşulları
HDR video kaydı tüm Android cihazlarda desteklenmez. Uygulamanızda HDR video çekmeden önce cihazınızın aşağıdaki ön koşulları karşılayıp karşılamadığını belirleyin:
- Android 13'ü (API düzeyi 33) hedeflemelidir.
- 10 bit veya daha yüksek kapasiteli bir kamera sensörüne sahip olmalıdır. HDR desteği hakkında daha fazla bilgi için HDR desteğini kontrol etme başlıklı makaleyi inceleyin.
Tüm cihazlar ön koşulları karşılamadığından uygulamanızda HDR video kaydını ayarlarken ayrı bir kod yolu ekleyebilirsiniz. Bu sayede uygulamanız, uyumlu olmayan cihazlarda SDR'ye geri dönebilir. Ayrıca SDR için bir kullanıcı arayüzü seçeneği ekleyebilirsiniz. Kullanıcı daha sonra video kaydı ihtiyaçları için SDR ve HDR arasında geçiş yapabilir.
HDR yakalama mimarisi
Aşağıdaki şemada, HDR yakalama mimarisinin ana bileşenleri gösterilmektedir.
Kamera cihazı HDR'de bir kare yakaladığında Camera2 çerçevesi, işlenen kamera sensörü çıkışını depolayan bir arabellek ayırır. Ayrıca, HDR profili gerektiriyorsa ilgili HDR meta verilerini de ekler. Ardından Camera2 çerçevesi, doldurulan arabelleği CaptureRequest içinde referans verilen çıkış yüzeyi (ör. ekran veya video kodlayıcı) için sıraya alır. Bu işlem, diyagramda gösterilmiştir.
HDR desteğini kontrol etme
Uygulamanızda HDR video çekmeden önce cihazın seçtiğiniz HDR profilini destekleyip desteklemediğini belirleyin.
Cihazınızın HDR özelliklerini sorgulamak için kullanabileceğiniz bir CameraCharacteristics örneği almak üzere CameraManager
getCameraCharacteristics() yöntemini kullanın.
Aşağıdaki adımlarda, cihazın HLG10'u destekleyip desteklemediği kontrol edilir. HLG10, cihaz üreticilerinin 10 bit çıkışlı kameralarda desteklemesi gereken temel HDR standardıdır.
Öncelikle cihazın 10 bit profilleri (HLG10 için bit derinliği) destekleyip desteklemediğini kontrol edin:
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 }Ardından, cihazın HLG10'u (veya desteklenen başka bir profili) destekleyip desteklemediğini kontrol edin:
@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; }
Cihaz HDR'yi destekliyorsa isHLGSupported() her zaman true değerini döndürür. Daha fazla bilgi için CameraCharacteristics referans dokümanlarına bakın.
HDR yakalamayı ayarlama
Cihazınızın HDR'yi desteklediğinden emin olduktan sonra uygulamanızı, kameradan ham HDR video akışı yakalayacak şekilde ayarlayın. Akışın OutputConfiguration değerini cihaz tarafından desteklenen bir HDR profiliyle sağlamak için setDynamicRangeProfile() kullanın. Bu değer, oluşturulduktan sonra CameraCaptureSession değerine iletilir. Desteklenen HDR profillerinin listesini inceleyin.
Aşağıdaki kod örneğinde setupSessionDynamicRangeProfile(), öncelikle cihazın Android 13 çalıştırdığını kontrol eder. Ardından, CameraCaptureSession öğesini cihaz tarafından desteklenen HDR profiliyle OutputConfiguration olarak ayarlar:
/**
* 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
}
}
Kamera uygulamanız kamerayı başlattığında kaydı önizlemek için tekrarlanan bir CaptureRequest gönderir:
session.setRepeatingRequest(previewRequest, null, cameraHandler)
Video kaydını başlatmak için de:
// 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 kamera görüntü akışını kodlama
HDR kamera görüntü akışını kodlamak ve dosyayı diske yazmak için MediaCodec kullanın.
Öncelikle, ham video verilerini depolayan bir arabelleğe eşlenen çıkış Surface değerini alın. MediaCodec için createInputSurface() kullanın.
MediaCodec başlatmak için uygulamanın, belirtilen codec profili, renk uzayı, renk aralığı ve aktarım işleviyle bir MediaFormat oluşturması gerekir:
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)
Uygulama hakkında daha fazla bilgi için Camera2Video örnek uygulamasının EncoderWrapper.kt bölümüne bakın.
HDR biçimleri
Android 13'ten itibaren, 10 bit çıkış özelliklerine sahip kamera cihazları, HDR çekim ve oynatma için HLG10'u desteklemelidir. Ayrıca cihaz üreticileri, HDR yakalama mimarisini kullanarak istedikleri HDR formatını etkinleştirebilir.
Aşağıdaki tabloda, kullanılabilir HDR biçimleri ve HDR video kaydı için özellikleri özetlenmektedir.
| Biçim | Aktarım İşlevi (TF) | Meta veri | Codec | Bit derinliği |
|---|---|---|---|---|
| HLG10 | HLG | Hayır | HEVC | 10 bit |
| HDR10 | PQ | Statik | HEVC | 10 bit |
| HDR10+ | PQ | Dinamik | HEVC | 10 bit |
| Dolby Vision 8.4 | HLG | Dinamik | HEVC | 10 bit |
Kaynaklar
HDR video yakalama işlevine sahip çalışan bir uygulama için GitHub'daki Camera2Video örneğine bakın.