HDR ভিডিও ক্যাপচার

মনে রাখবেন: এই পৃষ্ঠা Camera2 প্যাকেজকে রেফার করে। আপনার অ্যাপের Camera2 থেকে নির্দিষ্ট, লো-লেভেল ফিচারের প্রয়োজন না হলে, আমরা CameraX ব্যবহার করার সাজেশন দিই। CameraX এবং Camera2, দুটিই Android 5.0 (API লেভেল ২১) এবং তার পরবর্তী যেকোনও ভার্সনে কাজ করে।

Camera2 API হাই ডায়নামিক রেঞ্জ (HDR) ভিডিও ক্যাপচার করার সুবিধা দেয়, যার মাধ্যমে আপনি ক্যামেরার সাহায্যে HDR ভিডিও কন্টেন্ট প্রিভিউ ও রেকর্ড করতে পারবেন। স্ট্যান্ডার্ড ডায়নামিক রেঞ্জের (SDR) তুলনায়, HDR আরও বেশি রঙের রেঞ্জ অফার করে এবং লুমিন্যান্স কম্পোনেন্টের ডায়নামিক রেঞ্জ বাড়ায় (বর্তমান ১০০ cd/m2 থেকে ১০০০ cd/m2 পর্যন্ত)। এর ফলে ভিডিও কোয়ালিটি আরও বেশি প্রাণবন্ত হয়, রঙ আরও গাঢ়, হাইলাইট আরও উজ্জ্বল এবং শ্যাডো আরও ডার্ক হয়।

HDR ভিডিও কীভাবে সূর্যাস্তকে আরও প্রাণবন্তভাবে ক্যাপচার করে তা দেখুন।

SDR ভিডিও কোয়ালিটিতে ক্যাপচার করা সূর্যাস্ত HDR ভিডিও কোয়ালিটিতে ক্যাপচার করা সূর্যাস্ত
ছবি ১. SDR (উপরে) বনাম HDR (নিচে) ভিডিও কোয়ালিটির তুলনা।

ডিভাইস সংক্রান্ত পূর্বশর্ত

সব Android ডিভাইসে HDR ভিডিও ক্যাপচার করার সুবিধা নেই। আপনার অ্যাপে HDR ভিডিও ক্যাপচার করার আগে, আপনার ডিভাইস নিম্নলিখিত পূর্বশর্তগুলি পূরণ করে কিনা তা নির্ধারণ করুন:

  • Android 13 (API লেভেল 33) টার্গেট করে।
  • ১০-বিট বা তার বেশি ক্ষমতা সম্পন্ন ক্যামেরা সেন্সর আছে। HDR সাপোর্ট সম্পর্কে আরও জানতে, HDR সাপোর্ট চেক করুন।

সব ডিভাইস পূর্বশর্ত পূরণ করে না বলে, আপনার অ্যাপে HDR ভিডিও ক্যাপচার সেট-আপ করার সময় আপনি আলাদা কোড পাথ যোগ করতে পারবেন। এর ফলে, আপনার অ্যাপ, কাজ করে না এমন ডিভাইসে SDR-এ ফিরে যেতে পারবে। এছাড়াও, SDR-এর জন্য UI বিকল্প যোগ করার কথা বিবেচনা করুন। ব্যবহারকারী তার ভিডিও রেকর্ডিংয়ের প্রয়োজন অনুযায়ী SDR ও HDR-এর মধ্যে টগল করতে পারবেন।

HDR ক্যাপচার আর্কিটেকচার

নিচে দেওয়া ডায়াগ্রামে HDR ক্যাপচার আর্কিটেকচারের প্রধান কম্পোনেন্ট দেখা যাচ্ছে।

HDR ক্যাপচার আর্কিটেকচার ডায়াগ্রাম।
ছবি ২. HDR ক্যাপচার আর্কিটেকচার ডায়াগ্রাম।

কোনও ক্যামেরা ডিভাইস HDR-এ ফ্রেম ক্যাপচার করলে, Camera2 ফ্রেমওয়ার্ক একটি বাফার বরাদ্দ করে যা প্রসেস করা ক্যামেরা সেন্সর আউটপুট স্টোর করে। এছাড়াও, HDR প্রোফাইলের প্রয়োজন হলে, এটি সংশ্লিষ্ট HDR মেটাডেটা অ্যাটাচ করে। Camera2 ফ্রেমওয়ার্ক তারপর CaptureRequest-এ রেফারেন্স করা আউটপুট সারফেসের জন্য পপুলেট করা বাফারকে সারিবদ্ধ করে, যেমন ডিসপ্লে বা ভিডিও এনকোডার, যেমন ডায়াগ্রামে দেখানো হয়েছে।

HDR কাজ করে কিনা তা চেক করুন

আপনার অ্যাপে HDR ভিডিও ক্যাপচার করার আগে, ডিভাইসটি আপনার বেছে নেওয়া HDR প্রোফাইল সাপোর্ট করে কিনা তা নির্ধারণ করুন।

CameraCharacteristics ইনস্ট্যান্স পেতে CameraManager getCameraCharacteristics() পদ্ধতি ব্যবহার করুন, যা আপনি আপনার ডিভাইসের HDR ক্ষমতা সম্পর্কে কোয়েরি করতে পারবেন।

কোনও ডিভাইসে HLG10 কাজ করে কিনা তা নিম্নলিখিত ধাপগুলি চেক করে। HLG10 হল বেসলাইন HDR স্ট্যান্ডার্ড যা ডিভাইস প্রস্তুতকারকদের অবশ্যই 10-বিট আউটপুট সহ ক্যামেরায় সাপোর্ট করতে হবে।

  1. প্রথমে, ডিভাইসটি 10-বিট প্রোফাইল (HLG10-এর জন্য বিট-ডেপথ) সাপোর্ট করে কিনা তা চেক করুন:

    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 (বা অন্য কোনও কাজ করে এমন প্রোফাইল) কাজ করে কিনা তা চেক করুন:

    @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 chosen profile, in this case HLG10
        return availableProfiles.contains(DynamicRangeProfiles.HLG10)
      }
      return false;
    }
    

ডিভাইসে HDR কাজ করলে, isHLGSupported() সবসময় true রিটার্ন করে। আরও তথ্যের জন্য, CameraCharacteristics রেফারেন্স ডকুমেন্টেশন দেখুন।

HDR ক্যাপচার সেট-আপ করা

আপনার ডিভাইসে HDR কাজ করে কিনা তা নিশ্চিত করার পরে, ক্যামেরা থেকে র HDR ভিডিও স্ট্রিম ক্যাপচার করার জন্য আপনার অ্যাপ সেট-আপ করুন। ডিভাইস-সমর্থিত HDR প্রোফাইল সহ স্ট্রিমের OutputConfiguration প্রদান করতে setDynamicRangeProfile() ব্যবহার করুন, যা পরে CameraCaptureSession-এ পাস করা হয়। উপযুক্ত HDR প্রোফাইলের তালিকা দেখুন।

নিচে দেওয়া কোডের স্যাম্পেলে, setupSessionDynamicRangeProfile() প্রথমে চেক করে যে ডিভাইসটি Android 13-এ চলছে কিনা। তারপর, এটি ডিভাইস-সমর্থিত HDR প্রোফাইল সহ CameraCaptureSession-কে OutputConfiguration হিসেবে সেট-আপ করে:

  /**
   * Creates a [CameraCaptureSession] with a dynamic range profile.
   */
  private fun setupSessionWithDynamicRangeProfile(
      dynamicRange: Long,
      device: CameraDevice,
      targets: List<Surface>,
      handler: Handler? = null,
      stateCallback: CameraCaptureSession.StateCallback
  ): Boolean {
      if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.TIRAMISU) {
          val outputConfigs = mutableListOf<OutputConfiguration>()
          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 পাঠায়:

session.setRepeatingRequest(previewRequest, null, cameraHandler)

এছাড়াও, ভিডিও রেকর্ডিং শুরু করতে:

// 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 ব্যবহার করুন।

প্রথমে, আউটপুট Surface পান, যা র ভিডিও ডেটা স্টোর করে এমন বাফারে ম্যাপ করে। MediaCodec-এর জন্য, createInputSurface() ব্যবহার করুন।

MediaCodec শুরু করতে, কোনও অ্যাপকে অবশ্যই নির্দিষ্ট কোডেক প্রোফাইল, কালার স্পেস, কালার রেঞ্জ এবং ট্রান্সফার ফাংশন সহ MediaFormat তৈরি করতে হবে:

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 ফর্ম্যাট

Android 13 থেকে শুরু করে, ১০-বিট আউটপুট ক্ষমতা সহ ক্যামেরা ডিভাইসগুলিকে অবশ্যই HDR ক্যাপচার এবং প্লেব্যাক-এর জন্য HLG10-কে সাপোর্ট করতে হবে। এছাড়াও, ডিভাইস প্রস্তুতকারক HDR ক্যাপচার আর্কিটেকচার ব্যবহার করে তাদের পছন্দের যেকোনও HDR ফর্ম্যাট চালু করতে পারবেন।

নিম্নলিখিত সারণীতে উপলভ্য HDR ফর্ম্যাট এবং HDR ভিডিও ক্যাপচার করার জন্য সেগুলির ক্ষমতা সম্পর্কে সংক্ষিপ্ত বিবরণ দেওয়া হয়েছে।

ফর্ম্যাট ট্রান্সফার ফাংশন (TF) মেটাডেটা কোডেক বিট ডেপথ
HLG10 HLG না HEVC ১০-বিট
HDR10 PQ স্থির HEVC ১০-বিট
HDR10+ PQ ডায়নামিক HEVC ১০-বিট
Dolby Vision 8.4 HLG ডায়নামিক HEVC ১০-বিট

রিসোর্স

HDR ভিডিও ক্যাপচার করার কার্যকারিতা সহ একটি কার্যকরী অ্যাপের জন্য, GitHub-এ Camera2Video স্যাম্পেল দেখুন।