หมายเหตุ: หน้านี้เกี่ยวข้องกับแพ็กเกจ camera2 เราขอแนะนำให้ใช้ CameraX เว้นแต่แอปของคุณต้องใช้ฟีเจอร์ระดับต่ำที่เฉพาะเจาะจงจาก Camera2 ทั้ง CameraX และ Camera2 รองรับ Android 5.0 (API ระดับ 21) ขึ้นไป
การรองรับ camera2 API การบันทึกวิดีโอ High Dynamic Range (HDR) ซึ่งช่วยให้คุณดูตัวอย่างและ บันทึกเนื้อหาวิดีโอ HDR โดยใช้กล้อง เปรียบเทียบกับไดนามิกมาตรฐาน ช่วง (SDR) HDR มีช่วงสีที่กว้างกว่าและเพิ่มไดนามิก ช่วงของคอมโพเนนต์ความสว่าง (ตั้งแต่ 100 cd/m2 ในปัจจุบัน ถึง 1,000 วินาทีของ cd/m2) วิธีนี้ทำให้คุณภาพวิดีโอใกล้เคียงกับในชีวิตจริงมากขึ้น โดย สีที่เข้มขึ้น ไฮไลต์ที่สว่างขึ้น และเงาที่เข้มขึ้น
ดูวิธีที่วิดีโอ HDR บันทึกพระอาทิตย์ตกแบบละเอียดมากขึ้น
![](https://developer.android.google.cn/static/images/training/camera/camera2/sdr_comparison.png?authuser=9&hl=th)
![](https://developer.android.google.cn/static/images/training/camera/camera2/hdr_comparison.png?authuser=9&hl=th)
ข้อกำหนดเบื้องต้นของอุปกรณ์
อุปกรณ์ Android บางรุ่นไม่รองรับการจับภาพวิดีโอ HDR ก่อนจับภาพวิดีโอ HDR ในแอป ให้ตรวจสอบว่าอุปกรณ์ของคุณเป็นไปตามข้อกำหนดหรือไม่ ข้อกำหนดเบื้องต้นต่อไปนี้
- กำหนดเป้าหมายเป็น Android 13 (API ระดับ 33)
- มีเซ็นเซอร์กล้องที่รองรับความละเอียด 10 บิตขึ้นไป ดูข้อมูลเพิ่มเติมเกี่ยวกับ HDR โปรดดูการสนับสนุนที่หัวข้อตรวจหาการรองรับ HDR
เนื่องจากอุปกรณ์บางเครื่องมีคุณสมบัติไม่ตรงตามเกณฑ์เบื้องต้น คุณจึงใส่รหัสแยกต่างหากได้ เมื่อตั้งค่าการจับภาพวิดีโอ HDR ในแอป ซึ่งจะช่วยให้แอปของคุณกลับไปใช้ SDR ในอุปกรณ์ที่เข้ากันไม่ได้ นอกจากนี้ ให้พิจารณาเพิ่มตัวเลือก UI สำหรับ SDR ด้วย จากนั้นผู้ใช้จึงจะสลับ ระหว่าง SDR และ HDR เมื่อต้องการบันทึกวิดีโอ
สถาปัตยกรรมการจับภาพ HDR
แผนภาพต่อไปนี้แสดงส่วนประกอบหลักของสถาปัตยกรรมการจับภาพ HDR
![แผนภาพสถาปัตยกรรมการจับภาพ HDR](https://developer.android.google.cn/static/images/training/camera/camera2/hdr_capture_architecture_diagram.png?authuser=9&hl=th)
เมื่ออุปกรณ์กล้องจับภาพเฟรมในรูปแบบ 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