หมายเหตุ: หน้านี้อ้างอิงถึงแพ็กเกจ Camera2 เราขอแนะนำให้ใช้ CameraX เว้นแต่ว่าแอปของคุณจะต้องใช้ฟีเจอร์เฉพาะระดับต่ำจาก Camera2 ทั้ง CameraX และ Camera2 รองรับ Android 5.0 (API ระดับ 21) ขึ้นไป
Camera2 API รองรับ การบันทึกวิดีโอแบบ High Dynamic Range (HDR) ซึ่งช่วยให้คุณแสดงตัวอย่างและ บันทึกเนื้อหาวิดีโอ HDR โดยใช้กล้องได้ เมื่อเทียบกับ Standard Dynamic Range (SDR) แล้ว HDR มีช่วงสีที่กว้างกว่าและเพิ่มช่วงไดนามิกของคอมโพเนนต์ความสว่าง (จาก 100 cd/m2 ปัจจุบันเป็น 1000 cd/m2) ซึ่งส่งผลให้วิดีโอมีคุณภาพใกล้เคียงกับชีวิตจริงมากขึ้น โดยมีสีสันที่สมบูรณ์ยิ่งขึ้น ไฮไลต์ที่สว่างขึ้น และเงาที่เข้มขึ้น
ดูวิธีที่วิดีโอ HDR จับภาพพระอาทิตย์ตกได้อย่างละเอียดและสดใสยิ่งขึ้น
ข้อกำหนดเบื้องต้นของอุปกรณ์
อุปกรณ์ Android บางรุ่นไม่รองรับการบันทึกวิดีโอ HDR ก่อนบันทึกวิดีโอ HDR ในแอป ให้ตรวจสอบว่าอุปกรณ์มีคุณสมบัติตรงตามข้อกำหนดเบื้องต้นต่อไปนี้
- กำหนดเป้าหมายเป็น Android 13 (ระดับ API 33)
- มีเซ็นเซอร์กล้องที่รองรับ 10 บิตขึ้นไป ดูข้อมูลเพิ่มเติมเกี่ยวกับการรองรับ HDR ได้ที่ ตรวจสอบการรองรับ HDR
เนื่องจากอุปกรณ์บางรุ่นไม่มีคุณสมบัติตรงตามข้อกำหนดเบื้องต้น คุณจึงเพิ่มเส้นทางโค้ดแยกต่างหากได้เมื่อตั้งค่าการบันทึกวิดีโอ HDR ในแอป ซึ่งจะช่วยให้แอปกลับไปใช้ SDR ในอุปกรณ์ที่ไม่เข้ากันได้ นอกจากนี้ ให้พิจารณาเพิ่มตัวเลือก UI สำหรับ SDR ด้วย จากนั้นผู้ใช้จะสลับระหว่าง SDR กับ HDR ได้ตามความต้องการในการบันทึกวิดีโอ
สถาปัตยกรรมการบันทึก HDR
แผนภาพต่อไปนี้แสดงคอมโพเนนต์หลักของสถาปัตยกรรมการบันทึก HDR
เมื่ออุปกรณ์กล้องจับภาพเฟรมใน HDR เฟรมเวิร์ก Camera2 จะจัดสรรบัฟเฟอร์ที่จัดเก็บเอาต์พุตเซ็นเซอร์กล้องที่ประมวลผลแล้ว
นอกจากนี้ยังแนบข้อมูลเมตา HDR ที่เกี่ยวข้องหากโปรไฟล์ HDR กำหนดไว้
จากนั้นเฟรมเวิร์ก Camera2 จะจัดคิวบัฟเฟอร์ที่ป้อนข้อมูลแล้วสำหรับพื้นผิวเอาต์พุต
ที่อ้างอิงใน 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) | ข้อมูลเมตา | ตัวแปลงรหัส | ความลึกของบิต |
|---|---|---|---|---|
| HLG10 | HLG | ไม่ | HEVC | 10 บิต |
| HDR10 | PQ | คงที่ | HEVC | 10 บิต |
| HDR10+ | PQ | ไดนามิก | HEVC | 10 บิต |
| Dolby Vision 8.4 | HLG | ไดนามิก | HEVC | 10 บิต |
แหล่งข้อมูล
หากต้องการดูแอปที่ใช้งานได้ซึ่งมีฟังก์ชันการบันทึกวิดีโอ HDR ให้ดูตัวอย่าง Camera2Video ใน GitHub