HDR video çekimi

Not: Bu sayfa, Kamera2 paketiyle ilgilidir. Uygulamanız Camera2'nin belirli, alt düzey özelliklerini gerektirmiyorsa KameraX'i kullanmanızı öneririz. Hem CameraX hem de Camera2, Android 5.0 (API düzeyi 21) ve sonraki sürümleri destekler.

Kamera2 API'leri, kameranızı kullanarak HDR video içeriğini önizlemenizi ve kaydetmenizi sağlayan Yüksek Dinamik Aralıklı (HDR) video yakalamayı destekler. Standart Dinamik Aralık (SDR) ile karşılaştırıldığında, HDR daha geniş bir renk aralığı sunar ve parlaklık bileşeninin dinamik aralığını artırır (mevcut 100 cd/m2'den 1.000 cd/m2'ye kadar). Böylece daha zengin renkler, daha parlak parlak alanlar ve daha koyu gölgelerle gerçek hayattakine daha yakın video kalitesi elde edersiniz.

HDR videonun gün batımını nasıl daha canlı bir ayrıntıyla yakaladığını görün.

Şekil 1. SDR (üst) ve HDR (alt) video kalitesi karşılaştırması.

Cihaz ön koşulları

HDR video yakalama bazı 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) hedefler.
  • 10 bit veya daha yüksek yetenekli 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 yakalamayı 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 eklemeyi de düşünebilirsiniz. Kullanıcı daha sonra video kayıt ihtiyacı için SDR ve HDR arasında geçiş yapabilir.

HDR çekim mimarisi

Aşağıdaki şemada, HDR yakalama mimarisinin ana bileşenleri gösterilmektedir.

HDR yakalama mimarisi şeması.
Şekil 2. HDR yakalama mimarisi şeması.

Bir kamera cihazı HDR kalitesinde bir kare yakaladığında Camera2 çerçevesi, işlenen kamera sensörü çıkışını depolayan bir tampon ayırır. HDR profilinin gerektirdiği durumlarda ilgili HDR meta verilerini de ekler. Camera2 çerçevesi daha sonra, doldurulan arabelleği şemada gösterildiği gibi CaptureRequest'da referans verilen çıkış yüzeyi (ör. ekran veya video kodlayıcı) için sıraya alır.

HDR desteğini kontrol edin

Uygulamanızda HDR video çekmeden önce, cihazın istediğiniz HDR profilini destekleyip desteklemediğini belirleyin.

Cihazınızın HDR özelliklerini sorgulayabileceğiniz bir CameraCharacteristics örneği almak için CameraManager getCameraCharacteristics() yöntemini kullanın.

Aşağıdaki adımlar, bir cihazın HLG10'u destekleyip desteklemediğini kontrol eder. HLG10, cihaz üreticilerinin 10 bit çıkışlı kameralarda desteklemesi gereken temel HDR standardıdır.

  1. Öncelikle, cihazın 10 bit profilleri (HLG10 için bit derinliği) destekleyip desteklemediğini kontrol edin:

    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
    }
    
  2. Ardından, cihazın HLG10'u (veya desteklenen başka bir profili) destekleyip desteklemediğini kontrol edin:

    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;
    }
    

Cihaz HDR'yi destekliyorsa isHLGSupported() her zaman true değerini döndürür. Daha fazla bilgi için CameraCharacteristics referans belgelerine göz atın.

HDR yakalama ayarlayın

Cihazınızın HDR'yi desteklediğinden emin olduktan sonra, uygulamanızı kameradan ham HDR video akışı yakalayacak şekilde ayarlayın. setDynamicRangeProfile() kullanarak yayının OutputConfiguration özelliğini cihaz destekli bir HDR profiliyle sağlayın. Bu profil, oluşturulduktan sonra CameraCaptureSession etiketine aktarılır. Desteklenen HDR profillerinin listesine bakın.

Aşağıdaki kod örneğinde setupSessionDynamicRangeProfile(), önce cihazın Android 13'ü çalıştırıp çalıştırmadığını kontrol eder. Ardından CameraCaptureSession cihazını desteklenen HDR profiliyle OutputConfiguration olarak ayarlar:

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
      }
  }

}

Kamera uygulamanız kamerayı başlattığında kaydı önizlemek için tekrarlanan bir CaptureRequest gönderir:

Kotlin

session.setRepeatingRequest(previewRequest, null, cameraHandler)

Ayrıca video kaydını başlatmak için:

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 kamera akışını kodlama

HDR kamera akışını kodlamak ve dosyayı diske yazmak için MediaCodec işlevini kullanın.

Öncelikle, ham video verilerini depolayan bir arabelleğe eşlenen OutputSurface'ı edinin. MediaCodec için createInputSurface() kullanın.

MediaCodec uygulamasını başlatmak için uygulamanın belirli bir codec profili, renk alanı, renk aralığı ve aktarım işleviyle bir MediaFormat oluşturması gerekir:

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)

Uygulama hakkında daha fazla bilgi için Camera2Video örnek uygulamasının EncoderWrapper.kt bölümüne bakın.

HDR biçimleri

10 bit çıkış özelliklerine sahip kamera cihazları, Android 13 sürümünden itibaren HDR yakalama ve oynatma için HLG10'u desteklemelidir. Buna ek olarak cihaz üreticileri, HDR yakalama mimarisini kullanarak istedikleri HDR biçimini etkinleştirebilir.

Aşağıdaki tabloda, kullanılabilir HDR biçimleri ve HDR video yakalama ö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 Kamera2Video örneğine bakın.