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

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

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

يمكنك الاطّلاع على الطريقة التي يلتقط بها فيديو HDR طريقة التقاط غروب الشمس بتفاصيل أكثر حيوية.

الشكل 1. مقارنة بين جودة الفيديو بنطاق SDR (في الأعلى) وHDR (الأدنى)

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

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

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

بنية التقاط الصور بتقنية HDR

يوضح المخطّط التالي المكونات الرئيسية لبنية الالتقاط بتقنية HDR.

الرسم التخطيطي لبنية التقاط HDR.
الشكل 2. الرسم التخطيطي لبنية التقاط HDR.

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

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

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

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

تتحقّق الخطوات التالية مما إذا كان الجهاز متوافقًا مع HLG10. تقنية HLG10 هي معيار HDR الأساسي الذي يجب أن يتيحه صنّاع الأجهزة على الكاميرات بمخرجات 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;
    }
    

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

إعداد التقاط HDR

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

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

لترميز بث الكاميرا بتقنية 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

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

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

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

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

المراجع

إذا كان أحد التطبيقات تعمل ومزوّد بوظيفة التقاط الفيديوهات بنطاق عالي الديناميكية (HDR)، يمكنك الاطّلاع على نموذج للكاميرا 2Video على GitHub.