Android 10 میاناهای برنامهسازی کاربردی مدیریت میانگیر HAL3 دوربین اختیاری را معرفی میکند که به شما امکان میدهد منطق مدیریت میانگیر را برای دستیابی به مبادلات مختلف حافظه و تأخیر ضبط در پیادهسازیهای HAL دوربین پیادهسازی کنید.
«لایه انتزاع سختافزار» دوربین به N درخواست نیاز دارد (که N برابر با عمق خط لوله) صفبندیشده در خط لوله آن است، اما اغلب به همه N مجموعه بافرهای برونداد بهطور همزمان نیاز ندارد.
برای مثال، ممکن است HAL هشت درخواست در صف خط لوله داشته باشد، اما فقط به بافرهای برونداد برای دو درخواست در مراحل آخر خط لوله نیاز دارد. در دستگاههای دارای Android 9 و نسخههای پایینتر، چارچوب دوربین بافرها را زمانی که درخواست در HAL در صف قرار میگیرد اختصاص میدهد، بنابراین ممکن است شش مجموعه بافر در HAL وجود داشته باشد که درحال استفاده نیستند. در Android 10، میاناهای برنامهسازی کاربردی مدیریت بافر HAL3 دوربین امکان جداسازی بافرهای برونداد را فراهم میکنند تا شش مجموعه بافر آزاد شود. این کار میتواند به صرفهجویی صدها مگابایت حافظه در دستگاههای پیشرفته منجر شود و همچنین میتواند برای دستگاههای با حافظه کم مفید باشد.
شکل ۱ نمودار میانای HAL دوربین را برای دستگاههای دارای Android 9 و نسخههای پایینتر نشان میدهد. شکل ۲ میانای HAL دوربین در Android 10 را با پیادهسازی واسطهای برنامهنویسی کاربردی مدیریت بافر HAL دوربین ۳ نشان میدهد.
شکل ۱. میانای Camera HAL در Android 9 و نسخههای پایینتر
شکل ۲. میانای Camera HAL در Android 10 بااستفاده از میاناهای برنامهسازی کاربردی مدیریت بافر
پیادهسازی میاناهای برنامهسازی کاربردی مدیریت میانگیری
برای پیادهسازی میاناهای برنامهسازی کاربردی مدیریت میانگیر، دوربین HAL باید:
- پیادهسازی HIDL
ICameraDevice@3.5. - کلید مشخصات دوربین
android.info.supportedBufferManagementVersionرا رویHIDL_DEVICE_3_5تنظیم کنید.
«لایه انتزاعی سختافزار» دوربین از روشهای
requestStreamBuffers
و
returnStreamBuffers
در
ICameraDeviceCallback.hal
برای درخواست و برگرداندن میانگیرها استفاده میکند. HAL همچنین باید روش
signalStreamFlush
را در
ICameraDeviceSession.hal
پیادهسازی کند تا به HAL دوربین سیگنال دهد که میانگیرها را برگرداند.
requestStreamBuffers
از روش
requestStreamBuffers
برای درخواست میانگیر از چارچوب دوربین استفاده کنید. هنگام استفاده از APIهای مدیریت بافر HAL3 دوربین، درخواستهای ضبط از چارچوب دوربین حاوی بافرهای خروجی نیستند، یعنی فیلد bufferId در StreamBuffer برابر با 0 است. بنابراین، Camera HAL باید از requestStreamBuffers برای درخواست
میانگیر از چارچوب دوربین استفاده کند.
روش requestStreamBuffers به تماسگیرنده امکان میدهد در یک تماس، چندین میانگیر
از چندین جاریسازی برونداد درخواست کند و درنتیجه تعداد تماسهای HIDL IPC
کاهش یابد. بااینحال، وقتی بافر بیشتری بهطور همزمان درخواست شود، تماسها زمان بیشتری میبرند و این ممکن است بر تأخیر کلی درخواست تا نتیجه تأثیر منفی بگذارد.
همچنین، ازآنجاییکه تماسهای requestStreamBuffers در سرویس دوربین
سریالسازی میشوند، توصیه میشود که HAL دوربین از یک رشته با اولویت بالا
اختصاصی برای درخواست میانگیرها استفاده کند.
اگر درخواست میانگیر ناموفق باشد، HAL دوربین باید بتواند خطاهای غیرمهلک را بهدرستی مدیریت کند. فهرست زیر دلایل رایج ناموفق بودن درخواستهای میانگیری و نحوه مدیریت آنها توسط HAL دوربین را شرح میدهد.
- برنامه از جاریسازی برونداد قطع میشود:
این یک خطای غیرمهلک است. «لایه انتزاعی سختافزار» دوربین باید
ERROR_REQUESTبرای هر درخواست ضبط که یک جاریسازی قطعشده را هدف قرار میدهد ارسال کند و آماده پردازش درخواستهای بعدی بهطور معمول باشد. - مهلت زمانی: این اتفاق زمانی رخ میدهد که برنامه درحال انجام پردازش سنگین باشد و از برخیاز میانگیرها استفاده کند. HAL دوربین باید
ERROR_REQUESTرا برای درخواستهای ضبطی که بهدلیل خطای وقفه زمانی تکمیل نمیشوند ارسال کند و برای پردازش عادی درخواستهای بعدی آماده باشد. - چارچوب دوربین درحال آمادهسازی پیکربندی جاری جدیدی است:
HAL دوربین باید تا تکمیل شدن تماس بعدی
configureStreamsمنتظر بماند و سپس دوباره باrequestStreamBuffersتماس بگیرد. - HAL دوربین به
حد میانگیر
(فیلد
maxBuffers) رسیده است: HAL دوربین باید منتظر بماند تا حداقل یک میانگیر از جاریسازی را قبلاز فراخوانی مجددrequestStreamBuffersبرگرداند.
returnStreamBuffers
از روش
returnStreamBuffers
برای برگرداندن بافرهای اضافی به چارچوب دوربین استفاده کنید. Camera HAL معمولاً بافرها را ازطریق روش
processCaptureResult
به چارچوب دوربین برمیگرداند، اما فقط میتواند درخواستهای ضبطی را که به
Camera HAL ارسال شدهاند درنظر بگیرد. با روش requestStreamBuffers، پیادهسازی HAL دوربین میتواند بافرهای بیشتری نسبتبه آنچه چارچوب دوربین درخواست کرده است حفظ کند. در این زمان باید از روش returnStreamBuffers استفاده شود. اگر پیادهسازی HAL هرگز بافرهای بیشتری از آنچه درخواست شده است نگه نمیدارد، پیادهسازی HAL دوربین نیازی به فراخوانی روش returnStreamBuffers ندارد.
signalStreamFlush
چارچوب دوربین روش
signalStreamFlush
را فراخوانی میکند تا به HAL دوربین اطلاع دهد که همه میانگیرهای موجود را برگرداند. این تابع معمولاً زمانی فراخوانده میشود که چارچوب دوربین درآستانه فراخواندن
configureStreams
باشد و باید خط لوله ضبط دوربین را تخلیه کند. مشابه روش returnStreamBuffers
، اگر پیادهسازی HAL دوربین بافر بیشتری نسبتبه
درخواستشده نداشته باشد، ممکن است پیادهسازی این روش خالی باشد.
پساز اینکه چارچوب دوربین
signalStreamFlush را فراخوانی میکند،
چارچوب تا زمانی که همه
میانگیرها به چارچوب دوربین برگردانده شوند، ارسال درخواستهای ضبط جدید به Camera HAL را متوقف میکند. وقتی همه میانگیرها برگردانده میشوند، فراخوانیهای روش requestStreamBuffers ناموفق میشوند و چارچوب دوربین میتواند کار خود را در وضعیت تمیز ادامه دهد. چارچوب دوربین سپس
روش
configureStreams
یا
processCaptureRequest
را فرا میخواند. اگر چارچوب دوربین متد configureStreams را فراخوانی کند، دوربین
HAL میتواند پساز اینکه فراخوانی configureStreams با موفقیت برگردانده شد،
دوباره درخواست بافر کند. اگر چارچوب دوربین روش processCaptureRequest را فراخوانی کند،
HAL دوربین میتواند درطول فراخوانی processCaptureRequest
درخواست میانگیرها را شروع کند.
معناشناسی برای روش signalStreamFlush و روش
flush
متفاوت است. وقتی روش flush فراخوانده میشود، «لایه انتزاعی سختافزار» میتواند درخواستهای ضبط معلقه را با ERROR_REQUEST لغو کند تا خط لوله را در اسرع وقت تخلیه کند. وقتی روش signalStreamFlush فراخوانی میشود، HAL باید همه درخواستهای
ضبط معلقه را بهطور معمول تکمیل کند و همه بافرها را به چارچوب دوربین برگرداند.
تفاوت دیگر بین روش signalStreamFlush و روشهای دیگر این است که signalStreamFlush یک روش HIDL یکطرفه است، به این معنی که چارچوب دوربین ممکن است قبلاز اینکه HAL تماس signalStreamFlush را دریافت کند، با دیگر APIهای مسدودکننده تماس بگیرد. این یعنی
روش signalStreamFlush و روشهای دیگر (بهویژه
روش configureStreams) ممکن است با ترتیبی متفاوت از ترتیبی که در چارچوب دوربین فراخوانی شدهاند
به HAL دوربین برسند. برای رفع این مشکل ناهمگامی، فیلد streamConfigCounter به StreamConfiguration اضافه شد و بهعنوان آرگومان به روش signalStreamFlush اضافه شد. پیادهسازی HAL دوربین باید از آرگومان streamConfigCounter
برای تعیین اینکه آیا تماس signalStreamFlush دیرتر از تماس configureStreams مربوط به آن میرسد یا نه استفاده کند. برای مثال، «شکل ۳» را ببینید.
شکل ۳. چگونه HAL دوربین باید تماسهای signalStreamFlush را که دیر میرسند شناسایی و مدیریت کند
تغییرات رفتار هنگام پیادهسازی «میاناهای برنامهسازی کاربردی مدیریت بافر»
هنگام استفاده از میاناهای برنامهسازی کاربردی مدیریت میانگیر برای پیادهسازی منطق مدیریت میانگیر، تغییرات احتمالی زیر را در رفتار دوربین و پیادهسازی HAL دوربین درنظر بگیرید:
درخواستهای ضبط سریعتر و بیشتر به HAL دوربین میرسند: بدون میانای برنامهسازی کاربردی مدیریت میانگیر، چارچوب دوربین قبلاز ارسال درخواست ضبط به HAL دوربین، میانگیرهای خروجی را برای هر درخواست ضبط درخواست میکند. هنگام استفاده از میاناهای برنامهسازی کاربردی مدیریت میانگیر، چارچوب دوربین دیگر نیازی به انتظار برای میانگیرها ندارد و بنابراین میتواند درخواستهای ضبط را زودتر به HAL دوربین ارسال کند.
همچنین، بدون APIهای مدیریت میانگیر، اگر یکی از جاریسازیهای برونداد درخواست ضبط به حداکثر تعداد میانگیرهایی که HAL میتواند در یک زمان نگه دارد برسد، چارچوب دوربین ارسال درخواستهای ضبط را متوقف میکند (این مقدار توسط Camera HAL در فیلد
HalStream::maxBuffersدر مقدار برگشتی تماسconfigureStreamsتعیین میشود). با میانای برنامهسازی کاربردی مدیریت میانگیر، این رفتار محدودسازی دیگر وجود ندارد و پیادهسازی HAL دوربین نباید فراخوانیهایprocessCaptureRequestرا وقتی HAL درخواستهای ضبط زیادی در صف دارد بپذیرد.تأخیر تماس
requestStreamBuffersبهطور قابلتوجهی متفاوت است: دلایل زیادی وجود دارد که چرا تماسrequestStreamBuffersممکن است بیشتر از میانگین طول بکشد. برای مثال:- برای چند بافر اول جاریسازی تازه ایجادشده، تماسها ممکن است بیشتر طول بکشند زیرا دستگاه باید حافظه اختصاص دهد.
- تأخیر موردانتظار متناسب با تعداد میانگیرهای درخواستشده در هر فراخوانی افزایش مییابد.
- برنامه درحال نگهداری میانگیرها است و مشغول پردازش است. این میتواند باعث کند شدن درخواستهای میانگیر یا اتمام مهلت بهدلیل کمبود میانگیر یا مشغول بودن واحد پردازش مرکزی شود.
استراتژیهای مدیریت میانگیر
میاناهای برنامهسازی کاربردی مدیریت بافر امکان پیادهسازی انواع مختلف استراتژیهای مدیریت بافر را فراهم میکنند. چند مثال:
- سازگار با نسخه قدیمی: HAL میانگیرها را برای درخواست ضبط
درطول تماس
processCaptureRequestدرخواست میکند. این راهبرد هیچگونه صرفهجویی در حافظه ارائه نمیدهد، اما میتواند بهعنوان اولین پیادهسازی میاناهای برنامهسازی کاربردی مدیریت میانگیر عمل کند و به تغییرات کد بسیار کمی در HAL دوربین موجود نیاز دارد. - صرفهجویی حداکثری در حافظه: Camera HAL فقط درست قبلاز اینکه نیاز به پر کردن بافر خروجی باشد، بافر خروجی را درخواست میکند. این استراتژی امکان صرفهجویی حداکثری در حافظه را فراهم میکند. نکته منفی احتمالی این است که وقتی درخواستهای میانگیر زمان غیرعادی طولانی برای تکمیل شدن نیاز دارند، پرش خط لوله دوربین بیشتر میشود.
- ذخیره در حافظه نهان: «لایه انتزاع سختافزار دوربین» چند بافر را در حافظه نهان ذخیره میکند تا احتمال تحتتأثیر قرار گرفتن آن توسط درخواست بافر کند گاهبهگاه کمتر شود.
«لایه انتزاع سختافزار» دوربین میتواند استراتژیهای مختلفی را برای موارد استفاده خاص اتخاذ کند، برای مثال، استفاده از استراتژی حداکثر صرفهجویی در حافظه برای موارد استفادهای که از حافظه زیادی استفاده میکنند و استفاده از استراتژی سازگار با نسخههای قبلی برای سایر موارد استفاده.
پیادهسازی نمونه در HAL دوربین خارجی
HAL دوربین خارجی در Android 9 معرفی شد و در درخت منبع در
hardware/interfaces/camera/device/3.5/
قابل مشاهده است.
در Android 10، این مورد بهروزرسانی شده است تا شامل
ExternalCameraDeviceSession.cpp،
پیادهسازی میانای برنامهسازی کاربردی مدیریت میانگیر، شود. این HAL دوربین خارجی
استراتژی بیشینهسازی صرفهجویی در حافظه را که در استراتژیهای مدیریت میانگیر ذکر شده است در چند صد خط کد ++C پیادهسازی میکند.