توجه: این صفحه به بسته Camera2 اشاره دارد. توصیه میکنیم از CameraX استفاده کنید، مگراینکه برنامهتان به ویژگیهای خاص و سطح پایین Camera2 نیاز داشته باشد. CameraX و Camera2 هر دو از Android 5.0 (سطح میانای برنامهسازی کاربردی ۲۱) و بالاتر پشتیبانی میکنند.
Camera2 APIs از ضبط ویدیو با «دامنه پویای بالا» (HDR) پشتیبانی میکند که به شما امکان میدهد محتوای ویدیویی HDR را بااستفاده از دوربینتان پیشنمایش و ضبط کنید. درمقایسه با «دامنه پویای استاندارد» (SDR)، HDR طیف وسیعتری از رنگها را ارائه میدهد و دامنه پویای مؤلفه درخشندگی را افزایش میدهد (از ۱۰۰ cd/m2 فعلی به ۱۰۰۰ cd/m2). این امر منجر به کیفیت ویدیویی میشود که با رنگهای غنیتر، برجستگیهای روشنتر، و سایههای تیرهتر، بیشتر به واقعیت نزدیک است.
ببینید ویدیو 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 desired 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, 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
تکراری
برای پیشنمایش ضبط ارسال میکند:
کاتلین
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 استفاده کنید.
ابتدا OutputSurface را دریافت کنید،
که به میانگیری نگاشت میشود که دادههای خام ویدیو را ذخیره میکند.
برای 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 ببینید.