הערה: הדף הזה מתייחס לחבילה camera2. מומלץ להשתמש ב-CameraX, אלא אם לאפליקציה שלך נדרשים תכונות ספציפיות ברמה נמוכה. גם CameraX וגם Camera2 תומכים ב-Android 5.0 (רמת API 21) ואילך.
תמיכה בממשקי API של Camera2 צילום וידאו עם טווח דינמי גבוה (HDR), שמאפשר לראות תצוגה מקדימה לצלם תוכן של סרטוני HDR באמצעות המצלמה. בהשוואה לדינמיקה רגילה Range (SDR), באיכות HDR יש מגוון רחב יותר של צבעים ומגבירים את הדינמיקה. הטווח של רכיב הבהירות (החל מ- 100 cd/m2 עד 1,000s של cd/m2). התוצאה היא איכות וידאו שקרובה יותר לחיים האמיתיים, צבעים עשירים יותר, אזורים בהירים יותר וצלליות כהות יותר.
אפשר לראות איך סרטון HDR מצלמים את השקיעה בצורה מרהיבה יותר.
דרישות מוקדמות למכשירים
לא כל מכשירי Android תומכים בצילום סרטונים באיכות HDR. לפני צילום סרטון HDR באפליקציה, כדאי לבדוק אם המכשיר עומד בדרישות הדרישות המוקדמות הבאות:
- מוגדר טירגוט ל-Android 13 (רמת API 33).
- כולל חיישן מצלמה עם יכולות של 10 ביט ומעלה. למידע נוסף על HDR כאן תוכלו לקרוא איך בודקים אם יש תמיכה ב-HDR.
לא כל המכשירים עומדים בדרישות המוקדמות, ולכן ניתן להוסיף קוד נפרד נתיב בזמן ההגדרה של צילום וידאו באיכות HDR באפליקציה. כך האפליקציה תוכל לחזור ל-SDR במכשירים לא תואמים. כדאי גם להוסיף אפשרות בממשק המשתמש ל-SDR. המשתמש יכול להחליף מצב בין SDR ל-HDR בהתאם לצרכים שלהם לגבי הקלטת וידאו.
ארכיטקטורת צילום HDR
בתרשים הבא מוצגים הרכיבים העיקריים בארכיטקטורת צילום HDR.
כשמכשיר מצלמה מצלם פריים ב-HDR, ה-framework של Camera2 מקצה
מאגר נתונים זמני שמאחסן את הפלט של חיישן המצלמה המעובד.
הוא גם מצרף את המטא-נתונים המתאימים של HDR, אם הדבר נדרש על ידי פרופיל ה-HDR.
לאחר מכן, ה-framework של מצלמה2 מוסיף את מאגר הנתונים הזמני המאוכלס למשטח הפלט.
שיש הפניה אליו בCaptureRequest
, למשל תצוגה או
את מקודד הווידאו שלכם, כפי שמוצג בדיאגרמה.
איך בודקים אם יש תמיכה ב-HDR
לפני צילום סרטון HDR באפליקציה, צריך לבדוק אם המכשיר תומך פרופיל ה-HDR הרצוי.
משתמשים בשיטה CameraManager
getCameraCharacteristics()
כדי לקבל
CameraCharacteristics
שבה אפשר לשלוח שאילתה ליכולות ה-HDR של המכשיר.
תוכלו לבצע את הפעולות הבאות כדי לבדוק אם המכשיר תומך ב-HLG10. HLG10 הוא התקן הבסיסי ל-HDR שיצרני המכשירים חייבים לתמוך בו במצלמות עם פלט של 10 ביט.
קודם כול, בודקים אם המכשיר תומך בפרופילים של 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 }
בשלב הבא, בודקים אם המכשיר תומך ב-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
אחרי שמוודאים שהמכשיר תומך ב-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
החל מ-Android 13, מכשירי מצלמה עם יכולות פלט של 10 ביט חייבת לתמוך ב-HLG10 לצילום HDR הפעלה. בנוסף, יצרני המכשירים יכולים להפעיל כל פורמט HDR לפי בחירתם באמצעות ארכיטקטורת צילום HDR.
הטבלה הבאה מסכמת את הפורמטים הזמינים של HDR והיכולות שלהם לצילום סרטונים באיכות HDR.
פורמט | שיטת העברה (TF) | Metadata | קודק | עומק ביט |
---|---|---|---|---|
HLG10 | איכות חיים (HLG) | לא | מק"ט HEVC | 10-ביט |
HDR10 | PQ | סטטי | מק"ט HEVC | 10-ביט |
HDR10+ | PQ | דינמי | מק"ט HEVC | 10-ביט |
Dolby Vision 8.4 | איכות חיים (HLG) | דינמי | מק"ט HEVC | 10-ביט |
משאבים
לאפליקציה פעילה עם פונקציית צילום וידאו ב-HDR: דוגמה של Camera2Video ב-GitHub.