التقاط فيديو بنطاق عالي الديناميكية (HDR)

ملاحظة: تشير هذه الصفحة إلى حزمة camera2. ننصحك باستخدام cameraX ما لم يكن تطبيقك يتطلب ميزات محدّدة ومنخفضة المستوى من Camera2. يتوافق كل من CameraX و Camera2 مع الإصدار Android 5.0 (المستوى 21 من واجهة برمجة التطبيقات) والإصدارات الأحدث.

تتيح واجهات برمجة تطبيقات Camera2 إمكانية التقاط الفيديو بنطاق عالي الديناميكية (HDR)، ما يمكّنك من معاينة محتوى فيديو بنطاق عالي الديناميكية وتسجيله باستخدام الكاميرا. مقارنةً بالنطاق الديناميكي العادي (SDR)، يوفّر النطاق العالي الديناميكية مجموعة أكبر من الألوان ويزيد من النطاق الديناميكي لمكوِّن السطوع (من 100 قرص مضغوط/متر مربّع حاليًا إلى 1,000 ثانية من القرص المضغوط/المتر المربّع). يؤدي ذلك إلى جودة الفيديو التي تتطابق بشكل وثيق مع الحياة الواقعية، من خلال ألوان أكثر ثراءً وتظليلًا أكثر سطوعًا وظلالاً داكنة.

يمكنك الاطّلاع على مزيد من التفاصيل النابضة بالحياة حول كيفية التقاط فيديو بنطاق عالي الديناميكية (HDR).

الشكل 1. مقارنة جودة الفيديو بنطاق عالي الديناميكية (في الجزء العلوي) مقارنةً بجودة الفيديو بنطاق عالي الديناميكية (في أسفل الشاشة)

المتطلبات الأساسية للأجهزة

لا تتيح بعض أجهزة Android إمكانية التقاط الفيديو بنطاق عالي الديناميكية. قبل التقاط فيديو بنطاق عالي الديناميكية في تطبيقك، عليك تحديد ما إذا كان جهازك يستوفي المتطلّبات الأساسية التالية:

بما أنّ بعض الأجهزة لا تلبّي المتطلّبات الأساسية، يمكنك إضافة مسار رمز منفصل عند إعداد التقاط فيديو بنطاق عالي الديناميكية في تطبيقك. يتيح ذلك لتطبيقك استخدام النطاق العادي الديناميكية (SDR) على الأجهزة غير المتوافقة. يمكنك أيضًا إضافة خيار واجهة المستخدم لنطاق SDR. يمكن للمستخدم بعد ذلك التبديل بين النطاق العادي الديناميكية والنطاق العالي الديناميكية لاحتياجات تسجيل الفيديو.

بنية التقاط الصور بنطاق عالي الديناميكية (HDR)

يعرض المخطّط التالي المكوّنات الرئيسية لبنية التقاط الصور بنطاق عالي الديناميكية (HDR).

مخطّط لبنية التقاط المحتوى بنطاق عالي الديناميكية (HDR)
الشكل 2. مخطّط لبنية التقاط المحتوى بنطاق عالي الديناميكية (HDR)

عندما يلتقط جهاز الكاميرا إطارًا بنطاق عالي الديناميكية، يخصّص إطار عمل Camera2 مخزنًا مؤقتًا يخزّن البيانات التي تمّت معالجتها لأداة استشعار الكاميرا. وتُرفِق أيضًا بيانات النطاق الوصفية ذات الصلة بالبيانات الوصفية ذات الصلة إذا كان ذلك مطلوبًا في ملف تعريف النطاق العالي الديناميكية (HDR). يضع إطار عمل Camera2 في قائمة انتظار المخزن المؤقت المعبأ لواجهة الإخراج المشار إليها في CaptureRequest، مثل جهاز عرض أو برنامج ترميز فيديو، كما هو موضّح في الرسم البياني.

التحقّق من توفّر تقنية النطاق العالي الديناميكية

قبل التقاط فيديو بنطاق عالي الديناميكية في تطبيقك، عليك تحديد ما إذا كان الجهاز متوافقًا مع الملف الشخصي الذي تريده بنطاق عالي الديناميكية (HDR).

استخدِم طريقة CameraManager getCameraCharacteristics() للحصول على مثيل CameraCharacteristics الذي يمكنك الاستعلام فيه عن إمكانات النطاق العالي الديناميكية (HDR) في جهازك.

تحدِّد الخطوات التالية ما إذا كان الجهاز متوافقًا مع تقنية HLG10. HLG10 هو معيار النطاق العالي الديناميكية الأساسي الذي يجب على صنّاع الأجهزة اعتماده في الكاميرات ذات إخراج 10 بت.

  1. أولاً، عليك التأكّد مما إذا كان الجهاز متوافقًا مع الملفات الشخصية بتردد 10 بت (عمق البت لتقنية 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. بعد ذلك، تحقَّق مما إذا كان الجهاز متوافقًا مع HLG10 (أو ملف شخصي آخر متوافق):

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

إذا كان الجهاز متوافقًا مع تقنية HDR، يجب أن تعرض السمة isHLGSupported() دائمًا true. لمزيد من المعلومات، اطّلِع على المستندات المرجعية CameraCharacteristics.

إعداد التقاط نطاق عالي الديناميكية

بعد التأكّد من أنّ جهازك متوافق مع تقنية HDR، يجب إعداد التطبيق لالتقاط بث فيديو مباشر بنطاق عالي الديناميكية من الكاميرا. استخدِم setDynamicRangeProfile() لتزويد OutputConfiguration البث بملف شخصي بنطاق عالي الديناميكية متوافق مع الأجهزة، ويتم تمريره بعد ذلك إلى CameraCaptureSession عند الإنشاء. راجع قائمة الملفات الشخصية المتوافقة ذات النطاق العالي الديناميكية (HDR) المتوافقة.

في الرمز النموذجي التالي، يتحقّق setupSessionDynamicRangeProfile() أولاً من أنّ الجهاز يعمل بنظام التشغيل Android 13. بعد ذلك، يتم ضبط CameraCaptureSession مع ملف شخصي بنطاق عالي الديناميكية متوافق مع الجهاز على أنّه 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
      }
  }

}

عندما يبدأ تطبيق الكاميرا تشغيل الكاميرا، يرسل رمز CaptureRequest متكرر لمعاينة التسجيل:

Kotlin

session.setRepeatingRequest(previewRequest, null, cameraHandler)

ولبدء تسجيل الفيديو أيضًا، يُرجى اتّباع الخطوات التالية:

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 ونقل الملف على القرص، استخدِم MediaCodec.

أولاً، احصل على OutputSurface الذي يرتبط بمخزن مؤقت يخزّن بيانات الفيديو الأوّلية. بالنسبة إلى MediaCodec، استخدِم createInputSurface().

لإعداد MediaCodec، يجب أن ينشئ التطبيق MediaFormat بملف شخصي محدد في برنامج الترميز، ومساحة لونية، ونطاق لون، ودالة نقل:

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)

لمزيد من التفاصيل حول عملية التنفيذ، يُرجى الاطّلاع على نموذج تطبيق Camera2Video EncoderWrapper.kt.

تنسيقات النطاق العالي الديناميكية

بدءًا من نظام التشغيل Android 13، يجب أن تكون الكاميرات المزوّدة بإمكانيات الإخراج 10 بت متوافقة مع تقنية HLG10 لالتقاط صور بدقة عالية وتشغيل بنطاق عالي الديناميكية. بالإضافة إلى ذلك، يمكن للشركات المصنّعة للأجهزة تفعيل أي تنسيق نطاق عالي الديناميكية من اختيارهم، باستخدام بنية الالتقاط بنطاق عالي الديناميكية.

يلخّص الجدول التالي تنسيقات النطاق العالي الديناميكية المتاحة وإمكاناتها في التقاط فيديو بنطاق عالي الديناميكية.

التنسيق وظيفة النقل (TF) البيانات الوصفية برنامج الترميز عمق البت
تقنية HLG10 تقنية HLG لا تنسيق HEVC 10 وحدات بت
نطاق عالي الديناميكية (HDR10) جودة الهواء (PQ) ثابت تنسيق HEVC 10 وحدات بت
+HDR10 جودة الهواء (PQ) ديناميكي تنسيق HEVC 10 وحدات بت
تقنية Dolby Vision 8.4 تقنية HLG ديناميكي تنسيق HEVC 10 وحدات بت

المَراجع

للحصول على تطبيق يعمل مع وظيفة التقاط فيديو بنطاق عالي الديناميكية، يمكنك الاطّلاع على نموذج Camera2Video على GitHub.