Android 10 เปิดตัว API การจัดการบัฟเฟอร์ camera HAL3 ที่ไม่บังคับ ซึ่งช่วยให้คุณ ใช้ตรรกะการจัดการบัฟเฟอร์เพื่อให้ได้การแลกเปลี่ยนความหน่วงของหน่วยความจำและการจับภาพที่แตกต่างกัน ในการติดตั้งใช้งาน HAL ของกล้อง
HAL ของกล้องต้องมีคำขอ N รายการ (โดยที่ N เท่ากับความลึกของไปป์ไลน์) ที่คิวในไปป์ไลน์ แต่โดยทั่วไปแล้วไม่จำเป็นต้องมีบัฟเฟอร์เอาต์พุตทั้ง N ชุดพร้อมกัน
ตัวอย่างเช่น HAL อาจมีคำขอ 8 รายการที่อยู่ในคิวของไปป์ไลน์ แต่ ต้องใช้บัฟเฟอร์เอาต์พุตสำหรับคำขอ 2 รายการในขั้นตอนสุดท้ายของ ไปป์ไลน์เท่านั้น ในอุปกรณ์ที่ใช้ Android 9 และต่ำกว่า เฟรมเวิร์กกล้องจะจัดสรรบัฟเฟอร์เมื่อมีการจัดคิวคำขอใน HAL ดังนั้นจึงอาจมีบัฟเฟอร์ 6 ชุดใน HAL ที่ไม่ได้ใช้งาน ใน Android 10 API การจัดการบัฟเฟอร์ HAL3 ของกล้องจะช่วยให้แยกบัฟเฟอร์เอาต์พุต เพื่อเพิ่มพื้นที่ว่างให้กับบัฟเฟอร์ทั้ง 6 ชุดได้ ซึ่งจะช่วยประหยัดหน่วยความจำได้หลายร้อยเมกะไบต์ในอุปกรณ์ระดับไฮเอนด์ และยังเป็นประโยชน์ต่ออุปกรณ์ที่มีหน่วยความจำต่ำด้วย
รูปที่ 1 แสดงแผนภาพของอินเทอร์เฟซ HAL ของกล้องสำหรับอุปกรณ์ที่ใช้ Android 9 และต่ำกว่า รูปที่ 2 แสดงอินเทอร์เฟซ HAL ของกล้องใน Android 10 ที่มีการใช้งาน API การจัดการบัฟเฟอร์ HAL3 ของกล้อง
รูปที่ 1 อินเทอร์เฟซ HAL ของกล้องใน Android 9 และต่ำกว่า
รูปที่ 2 อินเทอร์เฟซ HAL ของกล้องใน Android 10 โดยใช้ API การจัดการบัฟเฟอร์
ใช้ API การจัดการบัฟเฟอร์
หากต้องการใช้ API การจัดการบัฟเฟอร์ HAL ของกล้องต้องมีคุณสมบัติดังนี้
- ใช้ HIDL
ICameraDevice@3.5
- ตั้งค่าคีย์ลักษณะกล้อง
android.info.supportedBufferManagementVersion
เป็นHIDL_DEVICE_3_5
HAL ของกล้องใช้วิธี
requestStreamBuffers
และ
returnStreamBuffers
ใน
ICameraDeviceCallback.hal
เพื่อขอและส่งคืนบัฟเฟอร์ นอกจากนี้ HAL ต้องใช้เมธอด
signalStreamFlush
ใน
ICameraDeviceSession.hal
เพื่อส่งสัญญาณให้ HAL ของกล้องส่งบัฟเฟอร์กลับ
requestStreamBuffers
ใช้เมธอด
requestStreamBuffers
เพื่อขอรับบัฟเฟอร์จากเฟรมเวิร์กของกล้อง เมื่อใช้ Camera HAL3
API การจัดการบัฟเฟอร์ คำขอจับภาพจากเฟรมเวิร์กกล้องจะไม่มีบัฟเฟอร์เอาต์พุต นั่นคือฟิลด์ bufferId
ใน
StreamBuffer
คือ 0
ดังนั้น HAL ของกล้องต้องใช้ requestStreamBuffers
เพื่อขอ
บัฟเฟอร์จากเฟรมเวิร์กของกล้อง
เมธอด requestStreamBuffers
ช่วยให้ผู้เรียกขอหลายบัฟเฟอร์จากสตรีมเอาต์พุตหลายรายการในการเรียกครั้งเดียวได้ ซึ่งจะช่วยลดการเรียก HIDL IPC
อย่างไรก็ตาม การเรียกใช้จะใช้เวลานานขึ้นเมื่อมีการขอบัฟเฟอร์หลายรายการพร้อมกัน และอาจส่งผลเสียต่อเวลาในการตอบสนองรวมตั้งแต่คำขอจนถึงผลลัพธ์
นอกจากนี้ เนื่องจากมีการจัดลำดับการเรียกใช้ใน requestStreamBuffers
ในบริการกล้อง
เราจึงขอแนะนำให้ HAL ของกล้องใช้เธรดที่มีลำดับความสำคัญสูงโดยเฉพาะ
เพื่อขอรับบัฟเฟอร์
หากคำขอบัฟเฟอร์ไม่สำเร็จ HAL ของกล้องต้องจัดการข้อผิดพลาดที่ไม่ร้ายแรงได้อย่างถูกต้อง รายการต่อไปนี้อธิบายสาเหตุที่พบบ่อยซึ่งทำให้คำขอ buffer ล้มเหลว และวิธีที่ HAL ของกล้องควรจัดการ
- แอปตัดการเชื่อมต่อจากสตรีมเอาต์พุต:
นี่เป็นข้อผิดพลาดที่ไม่ร้ายแรง HAL ของกล้องควรส่ง
ERROR_REQUEST
สำหรับคำขอจับภาพใดๆ ที่กำหนดเป้าหมายไปยังสตรีมที่ยกเลิกการเชื่อมต่อ และพร้อมประมวลผลคำขอที่ตามมา ตามปกติ - หมดเวลา: กรณีนี้อาจเกิดขึ้นเมื่อแอปกำลังประมวลผลอย่างหนักขณะที่ถือบัฟเฟอร์บางส่วนไว้ HAL ของกล้องควร
ส่ง
ERROR_REQUEST
สำหรับคำขอจับภาพที่ดำเนินการไม่ได้เนื่องจาก ข้อผิดพลาดเกี่ยวกับไทม์เอาต์ และพร้อมประมวลผลคำขอที่ตามมาตามปกติ - เฟรมเวิร์กของกล้องกำลังเตรียมการกำหนดค่าสตรีมใหม่
HAL ของกล้องควรรอจนกว่าการเรียกใช้
configureStreams
ครั้งถัดไปจะเสร็จสมบูรณ์ก่อนที่จะเรียกใช้requestStreamBuffers
อีกครั้ง - HAL ของกล้องถึง
ขีดจำกัดของบัฟเฟอร์
(ฟิลด์
maxBuffers
) แล้ว HAL ของกล้องควรรอ จนกว่าจะส่งคืนบัฟเฟอร์ของสตรีมอย่างน้อย 1 รายการก่อนที่จะเรียกใช้requestStreamBuffers
อีกครั้ง
returnStreamBuffers
ใช้วิธี
returnStreamBuffers
เพื่อส่งบัฟเฟอร์พิเศษกลับไปยังเฟรมเวิร์กของกล้อง โดยปกติแล้ว HAL ของกล้องจะส่งบัฟเฟอร์กลับไปยังเฟรมเวิร์กของกล้องผ่านเมธอด processCaptureResult
แต่จะพิจารณาได้เฉพาะคำขอจับภาพที่ส่งไปยัง HAL ของกล้องเท่านั้น วิธี requestStreamBuffers
ช่วยให้การใช้งาน HAL ของกล้องสามารถเก็บรักษาบัฟเฟอร์ได้มากกว่าที่เฟรมเวิร์กของกล้องร้องขอ ช่วงนี้ควรใช้วิธี returnStreamBuffers
หากการใช้งาน HAL ไม่เคยมีบัฟเฟอร์มากกว่าที่ขอ การใช้งาน HAL ของกล้องก็ไม่จำเป็นต้องเรียกใช้เมธอด returnStreamBuffers
signalStreamFlush
เฟรมเวิร์กของกล้องจะเรียกใช้เมธอด
signalStreamFlush
เพื่อแจ้งให้ HAL ของกล้องส่งคืนบัฟเฟอร์ทั้งหมด
ที่พร้อมใช้งาน โดยปกติแล้วจะเรียกใช้เมื่อเฟรมเวิร์กของกล้องกำลังจะ
เรียก
configureStreams
และต้องระบายข้อมูลในไปป์ไลน์การจับภาพของกล้อง เช่นเดียวกับreturnStreamBuffers
หากการใช้งาน HAL ของกล้องไม่มีบัฟเฟอร์มากกว่าที่
ขอ ก็อาจมีการใช้งานที่ว่างเปล่าของเมธอดนี้
หลังจากเฟรมเวิร์กของกล้องเรียก signalStreamFlush
เฟรมเวิร์กจะหยุดส่งคำขอจับภาพใหม่ไปยัง HAL ของกล้องจนกว่าบัฟเฟอร์ทั้งหมดจะกลับไปยังเฟรมเวิร์กของกล้อง เมื่อส่งคืนบัฟเฟอร์ทั้งหมดแล้ว การเรียกใช้เมธอด requestStreamBuffers
จะล้มเหลว และเฟรมเวิร์กกล้องจะทำงานต่อในสถานะที่สะอาดได้ จากนั้นเฟรมเวิร์กของกล้องจะเรียกใช้เมธอด
configureStreams
หรือ
processCaptureRequest
หากเฟรมเวิร์กของกล้องเรียกใช้เมธอด configureStreams
HAL ของกล้องจะเริ่มขอรับบัฟเฟอร์อีกครั้งได้หลังจากที่การเรียกใช้ configureStreams
กลับมาเป็น
สำเร็จ หากเฟรมเวิร์กของกล้องเรียกใช้เมธอด processCaptureRequest
HAL ของกล้องจะเริ่มขอรับบัฟเฟอร์ได้ในระหว่างการเรียกใช้ processCaptureRequest
ความหมายของsignalStreamFlush
เมธอดและflush
เมธอดจะแตกต่างกัน
เมื่อมีการเรียกใช้เมธอด flush
HAL จะยกเลิกคำขอจับภาพที่รอดำเนินการได้ด้วย ERROR_REQUEST
เพื่อระบายข้อมูลในไปป์ไลน์โดยเร็วที่สุด เมื่อมีการเรียกใช้เมธอด signalStreamFlush
HAL ต้องดำเนินการตามคำขอจับภาพที่รอดำเนินการทั้งหมดตามปกติและส่งบัฟเฟอร์ทั้งหมดไปยังเฟรมเวิร์กของกล้อง
ความแตกต่างอีกอย่างระหว่างsignalStreamFlush
กับวิธีอื่นๆ คือ
signalStreamFlush
เป็นวิธี HIDL แบบทางเดียว ซึ่งหมายความว่าเฟรมเวิร์กของกล้อง
อาจเรียกใช้ API อื่นๆ ที่บล็อกก่อนที่ HAL จะได้รับการเรียกsignalStreamFlush
ซึ่งหมายความว่าsignalStreamFlush
method และวิธีอื่นๆ (โดยเฉพาะ configureStreams
method) อาจไปถึง HAL ของกล้องในลำดับที่แตกต่างจากลำดับที่เรียกใช้ในเฟรมเวิร์กของกล้อง เราได้เพิ่มฟิลด์ streamConfigCounter
ลงใน StreamConfiguration
และเพิ่มเป็นอาร์กิวเมนต์ในเมธอด signalStreamFlush
เพื่อแก้ไขปัญหาความไม่พร้อมกันนี้
การติดตั้งใช้งาน HAL ของกล้องควรใช้streamConfigCounter
อาร์กิวเมนต์เพื่อพิจารณาว่าการเรียกใช้ signalStreamFlush
มาถึงช้ากว่าการเรียกใช้ configureStreams
ที่เกี่ยวข้องหรือไม่ ดูตัวอย่างได้ที่รูปที่ 3
รูปที่ 3 วิธีที่ HAL ของกล้องควรตรวจจับและจัดการการเรียก signalStreamFlush ที่มาถึงช้า
การเปลี่ยนแปลงลักษณะการทำงานเมื่อใช้ API การจัดการบัฟเฟอร์
เมื่อใช้ API การจัดการบัฟเฟอร์เพื่อใช้ตรรกะการจัดการบัฟเฟอร์ ให้พิจารณาการเปลี่ยนแปลงลักษณะการทำงานที่อาจเกิดขึ้นต่อไปนี้ในกล้อง และการใช้งาน HAL ของกล้อง
คำขอจับภาพจะไปถึง HAL ของกล้องได้เร็วขึ้นและบ่อยขึ้น: หากไม่มี API การจัดการบัฟเฟอร์ เฟรมเวิร์กของกล้องจะขอเอาต์พุตบัฟเฟอร์สำหรับคำขอจับภาพแต่ละรายการก่อนที่จะส่งคำขอจับภาพไปยัง HAL ของกล้อง เมื่อใช้ API การจัดการบัฟเฟอร์ เฟรมเวิร์กของกล้อง ไม่จำเป็นต้องรอให้บัฟเฟอร์พร้อมใช้งานอีกต่อไป จึงสามารถส่งคำขอแคปเจอร์ ไปยัง HAL ของกล้องได้เร็วขึ้น
นอกจากนี้ หากไม่มี API การจัดการบัฟเฟอร์ เฟรมเวิร์กของกล้องจะหยุด ส่งคำขอจับภาพหากสตรีมเอาต์พุตรายการใดรายการหนึ่งของคำขอจับภาพ มีบัฟเฟอร์ถึงจำนวนสูงสุดที่ HAL สามารถเก็บไว้ได้ใน ครั้งเดียว (ค่านี้กำหนดโดย HAL ของกล้องในฟิลด์
HalStream::maxBuffers
ในค่าที่ส่งคืนของฟังก์ชันconfigureStreams
) API การจัดการบัฟเฟอร์จะทำให้ลักษณะการจำกัดนี้ไม่มีอยู่อีกต่อไป และการใช้งาน HAL ของกล้องต้องไม่ยอมรับการเรียกprocessCaptureRequest
เมื่อ HAL มีคำขอแคปเจอร์ที่คิวมากเกินไปrequestStreamBuffers
เวลาในการตอบสนองของการโทรแตกต่างกันอย่างมาก: มีหลายสาเหตุที่requestStreamBuffers
การโทรอาจใช้เวลานานกว่าค่าเฉลี่ย เช่น- สำหรับบัฟเฟอร์ 2-3 รายการแรกของสตรีมที่สร้างขึ้นใหม่ การเรียกใช้ อาจใช้เวลานานขึ้นเนื่องจากอุปกรณ์ต้องจัดสรรหน่วยความจำ
- เวลาในการตอบสนองที่คาดไว้จะเพิ่มขึ้นตามสัดส่วนของจำนวนบัฟเฟอร์ที่ขอในการเรียกใช้แต่ละครั้ง
- แอปกำลังเก็บข้อมูลบัฟเฟอร์และประมวลผล ซึ่งอาจทำให้คำขอที่บัฟเฟอร์ทำงานช้าลงหรือหมดเวลาเนื่องจาก ไม่มีบัฟเฟอร์หรือ CPU ทำงานหนัก
กลยุทธ์การจัดการบัฟเฟอร์
API การจัดการบัฟเฟอร์ช่วยให้สามารถใช้กลยุทธ์การจัดการบัฟเฟอร์ประเภทต่างๆ ได้ ตัวอย่างเช่น
- เข้ากันได้แบบย้อนหลัง: HAL จะขอที่เก็บข้อมูลสำหรับคำขอแคปเจอร์
ระหว่างการเรียกใช้
processCaptureRequest
กลยุทธ์นี้ไม่ได้ช่วยประหยัดหน่วยความจำ แต่สามารถใช้เป็นการติดตั้งใช้งาน API การจัดการบัฟเฟอร์ครั้งแรกได้ โดยต้องมีการเปลี่ยนแปลงโค้ดใน HAL ของกล้องที่มีอยู่น้อยมาก - ประหยัดหน่วยความจำได้สูงสุด: HAL ของกล้องจะขอเฉพาะบัฟเฟอร์เอาต์พุต ก่อนที่จะต้องกรอกข้อมูล กลยุทธ์นี้ช่วยให้ประหยัดหน่วยความจำได้สูงสุด ข้อเสียที่อาจเกิดขึ้นคือไปป์ไลน์ของกล้องอาจทำงานช้าลงเมื่อคำขอบัฟเฟอร์ใช้เวลานานผิดปกติจึงจะเสร็จสิ้น
- แคช: HAL ของกล้องจะแคชบัฟเฟอร์ 2-3 รายการเพื่อลดโอกาสที่บัฟเฟอร์จะได้รับผลกระทบจากคำขอที่ช้าเป็นครั้งคราว
HAL ของกล้องสามารถใช้กลยุทธ์ต่างๆ สำหรับกรณีการใช้งานที่เฉพาะเจาะจงได้ เช่น ใช้กลยุทธ์การประหยัดหน่วยความจำสูงสุดสำหรับกรณีการใช้งานที่ใช้หน่วยความจำจำนวนมาก และใช้กลยุทธ์ที่เข้ากันได้แบบย้อนหลังสำหรับกรณีการใช้งานอื่นๆ
ตัวอย่างการใช้งานใน HAL ของกล้องภายนอก
HAL กล้องภายนอกเปิดตัวใน Android 9 และอยู่ใน
โครงสร้างแหล่งข้อมูลที่
hardware/interfaces/camera/device/3.5/
ใน Android 10 มีการอัปเดตให้รวม
ExternalCameraDeviceSession.cpp
การใช้งาน API การจัดการบัฟเฟอร์ HAL กล้องภายนอกนี้
ใช้กลยุทธ์การประหยัดหน่วยความจำสูงสุดที่กล่าวถึงในกลยุทธ์การจัดการบัฟเฟอร์ในโค้ด C++ เพียงไม่กี่ร้อยบรรทัด