Perekaman video HDR

Catatan: Halaman ini merujuk ke paket Camera2. Kecuali aplikasi Anda memerlukan fitur tingkat rendah tertentu dari Camera2, sebaiknya gunakan CameraX. CameraX dan Camera2 mendukung Android 5.0 (level API 21) dan versi yang lebih baru.

Dukungan Camera2 API Perekaman video Rentang Dinamis Tinggi (HDR), yang memungkinkan Anda melihat pratinjau dan merekam konten video HDR menggunakan kamera Anda. Dibandingkan dengan Standar Dinamis Rentang (SDR), HDR menawarkan rentang warna yang lebih luas dan meningkatkan kisaran komponen luminans (dari 100 cd/m2 saat ini sampai 1000 s cd/m2). Hal ini menghasilkan kualitas video yang lebih mendekati kehidupan nyata, dengan warna yang lebih kaya, sorotan yang lebih terang, dan bayangan yang lebih gelap.

Lihat cara video HDR merekam matahari terbenam dengan detail yang lebih cerah.

Gambar 1. Perbandingan kualitas video SDR (atas) vs. HDR (bawah).

Prasyarat perangkat

Tidak semua perangkat Android mendukung perekaman video HDR. Sebelum merekam video HDR di aplikasi, tentukan apakah perangkat memenuhi prasyarat berikut:

  • Menargetkan Android 13 (API level 33).
  • Memiliki sensor kamera berkemampuan 10-bit atau lebih tinggi. Untuk mengetahui informasi lebih lanjut tentang HDR Untuk dukungan HDR, lihat Memeriksa dukungan HDR.

Karena tidak semua perangkat memenuhi prasyarat, Anda dapat menambahkan kode terpisah saat menyiapkan perekaman video HDR di aplikasi. Hal ini memungkinkan aplikasi Anda kembali ke SDR pada perangkat yang tidak kompatibel. Selain itu, pertimbangkan untuk menambahkan opsi UI untuk SDR. Kemudian, pengguna dapat beralih antara SDR dan HDR untuk kebutuhan perekaman video.

Arsitektur pengambilan gambar HDR

Diagram berikut menunjukkan komponen utama arsitektur pengambilan gambar HDR.

Diagram arsitektur pengambilan HDR.
Gambar 2. Diagram arsitektur pengambilan HDR.

Saat perangkat kamera menangkap bingkai dalam HDR, framework Camera2 mengalokasikan {i>buffer<i} yang menyimpan {i>output <i} sensor kamera yang diproses. Kamera ini juga melampirkan metadata HDR masing-masing jika diperlukan oleh profil HDR. Framework Camera2 kemudian mengantrekan buffer yang terisi untuk platform output yang direferensikan dalam CaptureRequest, seperti tampilan atau encoder video, seperti yang terlihat dalam diagram.

Memeriksa dukungan HDR

Sebelum merekam video HDR di aplikasi Anda, tentukan apakah perangkat tersebut mendukung profil HDR yang Anda inginkan.

Gunakan metode CameraManager getCameraCharacteristics() untuk mendapatkan CameraCharacteristics yang dapat Anda kueri untuk mengetahui 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.

  1. Pertama, periksa apakah perangkat mendukung profil 10-bit (kedalaman bit untuk 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
    }
    
  2. Selanjutnya, periksa apakah perangkat mendukung HLG10 (atau profil lain yang didukung):

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

Jika perangkat mendukung HDR, isHLGSupported() selalu menampilkan true. Untuk informasi selengkapnya, lihat CameraCharacteristics dokumentasi referensi.

Menyiapkan pengambilan HDR

Setelah memastikan perangkat Anda mendukung HDR, siapkan aplikasi untuk mengambil foto streaming video HDR mentah dari kamera. Gunakan setDynamicRangeProfile() untuk memberikan 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() pertama kali memeriksa bahwa perangkat menjalankan Android 13. Kemudian, kode ini akan menyiapkan CameraCaptureSession dengan perangkat yang didukung Profil HDR sebagai OutputConfiguration:

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

}

Saat aplikasi kamera melakukan inisialisasi kamera, aplikasi akan mengirimkan sebuah berulang CaptureRequest untuk melihat pratinjau rekaman:

Kotlin

session.setRepeatingRequest(previewRequest, null, cameraHandler)

Dan juga untuk memulai perekaman video:

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)

Mengenkode streaming kamera HDR

Untuk mengenkode streaming kamera HDR dan menulis file ke disk, gunakan MediaCodec.

Pertama, dapatkan OutputSurface, yang memetakan ke {i>buffer<i} 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:

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)

Untuk detail selengkapnya tentang implementasi, lihat aplikasi contoh Camera2Video EncoderWrapper.kt

Format HDR

Mulai Android 13, perangkat kamera dengan kemampuan output 10-bit harus mendukung HLG10 untuk pengambilan gambar HDR dan pemutaran. Selain itu, produsen perangkat dapat mengaktifkan format HDR apa pun pilihan mereka menggunakan arsitektur pengambilan HDR.

Tabel berikut merangkum format HDR yang tersedia beserta 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

Referensi

Untuk aplikasi yang berfungsi dengan fungsi perekaman video HDR, lihat Contoh Camera2Video di GitHub.