توجه: این صفحه به بسته Camera2 اشاره دارد. توصیه میکنیم از CameraX استفاده کنید، مگراینکه برنامهتان به ویژگیهای خاص و سطح پایین Camera2 نیاز داشته باشد. CameraX و Camera2 هر دو از Android 5.0 (سطح میانای برنامهسازی کاربردی ۲۱) و بالاتر پشتیبانی میکنند.
Camera2 APIs از ضبط ویدیو «دامنه پویای بالا» (HDR) پشتیبانی میکند، که به شما امکان میدهد محتوای ویدیویی HDR را بااستفاده از دوربینتان پیشنمایش و ضبط کنید. درمقایسه با «دامنه پویای استاندارد» (SDR)، HDR طیف وسیعتری از رنگها را ارائه میدهد و دامنه پویای مؤلفه درخشندگی را افزایش میدهد (از ۱۰۰ شمع بر متر مربع فعلی به هزاران شمع بر متر مربع). این امر منجر به کیفیت ویدیویی میشود که بیشتر به واقعیت نزدیک است، با رنگهای غنیتر، برجستگیهای روشنتر، و سایههای تیرهتر.
ببینید ویدیو HDR چگونه غروب آفتاب را با جزئیات زندهتری ضبط میکند.
پیشنیازهای دستگاه
همه دستگاههای Android از ضبط ویدیو HDR پشتیبانی نمیکنند. قبلاز ضبط ویدیو HDR در برنامهتان، بررسی کنید که آیا دستگاهتان پیشنیازهای زیر را دارد یا نه:
- Android 13 (میانای برنامهسازی کاربردی سطح ۳۳) را هدفیابی میکند.
- حسگر دوربین با قابلیت ۱۰ بیت یا بالاتر داشته باشد. برای اطلاعات بیشتر درباره پشتیبانی HDR، به بررسی پشتیبانی HDR مراجعه کنید.
چون همه دستگاهها پیشنیازها را ندارند، میتوانید هنگام راهاندازی ضبط ویدیو HDR در برنامهتان، مسیر کد جداگانهای اضافه کنید. این کار به برنامه شما اجازه میدهد در دستگاههای ناسازگار به SDR برگردد. همچنین، اضافه کردن گزینه میانای کاربر برای SDR را درنظر بگیرید. سپس کاربر میتواند برای نیازهای ضبط ویدیو خود بین SDR و HDR جابهجا شود.
معماری ضبط HDR
نمودار زیر مؤلفههای اصلی معماری ضبط HDR را نشان میدهد.
وقتی دستگاه دوربین قابی را در HDR ضبط میکند، چارچوب Camera2 میانگیری را اختصاص میدهد که خروجی پردازششده حسگر دوربین را ذخیره میکند. همچنین درصورت نیاز نمایه HDR، فراداده HDR مربوطه را پیوست میکند. سپس چارچوب Camera2
میانگیر پرشده را برای سطح خروجی ارجاعشده در
CaptureRequest، مانند نمایشگر یا رمزگذار ویدیو،
صفبندی میکند، همانطور که در نمودار نشان داده شده است.
بررسی پشتیبانی از HDR
قبلاز ضبط ویدیو HDR در برنامهتان، بررسی کنید که آیا دستگاه از نمایه HDR انتخابی شما پشتیبانی میکند یا نه.
از روش CameraManager
getCameraCharacteristics() برای دریافت نمونه
CameraCharacteristics استفاده کنید، که میتوانید آن را برای قابلیتهای HDR دستگاهتان پُرسمان کنید.
مراحل زیر بررسی میکند که آیا دستگاه از HLG10 پشتیبانی میکند یا نه. HLG10 استاندارد HDR پایه است که سازندگان دستگاه باید در دوربینهای دارای خروجی ۱۰ بیتی پشتیبانی کنند.
ابتدا بررسی کنید که دستگاه از نمایههای ۱۰ بیتی (عمق بیت برای 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 }سپس، بررسی کنید که آیا دستگاه از 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 خام از دوربین تنظیم کنید. از
setDynamicRangeProfile() برای ارائه
OutputConfiguration جاریسازی با نمایه HDR پشتیبانیشده توسط دستگاه استفاده کنید، که سپس هنگام ایجاد به
CameraCaptureSession منتقل میشود. فهرست نمایههای HDR پشتیبانیشده را ببینید.
در نمونه کد زیر، setupSessionDynamicRangeProfile() ابتدا بررسی میکند
که دستگاه Android 13 را اجرا میکند. سپس،
CameraCaptureSession را با نمایه HDR پشتیبانیشده توسط دستگاه بهعنوان
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)
برای جزئیات بیشتر درباره پیادهسازی، به
EncoderWrapper.kt برنامه نمونه Camera2Video مراجعه کنید.
قالبهای HDR
از Android 13، دستگاههای دوربین با قابلیتهای خروجی ۱۰ بیتی باید از HLG10 برای ضبط و بازپخش HDR پشتیبانی کنند. علاوهبراین، سازندگان دستگاه میتوانند بااستفاده از معماری ضبط HDR، هر قالب HDR را که انتخاب میکنند فعال کنند.
جدول زیر قالبهای HDR دردسترس و قابلیتهای آنها را برای ضبط ویدیو HDR خلاصه میکند.
| قالب | تابع انتقال (TF) | فراداده | کدک | عمق بیت |
|---|---|---|---|---|
| HLG10 | HLG | نه | HEVC | ۱۰ بیتی |
| HDR10 | PQ | ثابت | HEVC | ۱۰ بیتی |
| HDR10+ | PQ | پویا | HEVC | ۱۰ بیتی |
| Dolby Vision 8.4 | HLG | پویا | HEVC | ۱۰ بیتی |
منابع
برای دیدن برنامه درحال کار با عملکرد ضبط ویدیو HDR، نمونه Camera2Video را در GitHub ببینید.