HDR video yakalama

Not: Bu sayfada Camera2 paketi ele alınmaktadır. Uygulamanız Camera2'den belirli, düşük seviyeli özellikler 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, kameranızı kullanarak HDR video içeriklerini önizlemenize ve kaydetmenize olanak tanıyan Yüksek Dinamik Aralıklı (HDR) video çekimini destekler. 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 binlerce 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 video ile gün batımının nasıl daha canlı ayrıntılarla yakalandığını görün.

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

Cihaz ön koşulları

HDR video çekimi 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) hedefliyor.
  • 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ı makaleye bakın.

Tüm cihazlar ön koşulları karşılamadığından uygulamanızda HDR video yakalamayı ayarlarken ayrı bir kod yolu ekleyebilirsiniz. Bu sayede uygulamanız, uyumsuz 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 kaydı ihtiyaçlarına göre SDR ve HDR arasında geçiş yapabilir.

HDR yakalama 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'de bir kare yakaladığında Camera2 çerçevesi, işlenmiş 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, şemada gösterildiği gibi CaptureRequest içinde referans verilen çıkış yüzeyi (ör. ekran veya video kodlayıcı) için doldurulmuş arabelleği sıraya alır.

HDR desteğini kontrol etme

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

Cihazınızın HDR özelliklerini sorgulayabileceğiniz bir CameraManager getCameraCharacteristics() yöntemiyle CameraCharacteristics örneği alın.

Aşağıdaki adımlarda bir cihazın HLG10'u destekleyip desteklemediği kontrol edilir. 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 döndürülür. Daha fazla bilgi için CameraCharacteristics referans belgelerine 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 cihaz tarafından desteklenen bir HDR profiliyle sağlamak için setDynamicRangeProfile() kullanın. Bu profil, oluşturulduktan sonra CameraCaptureSession'a aktarılır. Desteklenen HDR profillerinin listesini inceleyin.

Aşağıdaki kod örneğinde setupSessionDynamicRangeProfile() önce cihazda Android 13'ün çalışıp çalışmadığı kontrol edilir. Ardından, cihaz tarafından desteklenen HDR profiliyle CameraCaptureSessionOutputConfiguration 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)

Video kaydını başlatmak için de:

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 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 arabellekle eşlenen OutputSurface değerini alın. MediaCodec için createInputSurface() kullanın.

MediaCodec'yı başlatmak için bir uygulamanın belirtilen codec profili, renk alanı, renk aralığı ve aktarım işleviyle 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

Android 13'ten itibaren, 10 bit çıkış özelliklerine sahip kamera cihazları, HDR yakalama ve oynatma için HLG10'u desteklemelidir. Ayrıca, cihaz üreticileri HDR yakalama mimarisini kullanarak istedikleri HDR biçimini etkinleştirebilir.

Aşağıdaki tabloda, HDR video çekimi için kullanılabilen HDR biçimleri ve özellikleri özetlenmektedir.

Biçim Aktarım iş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.