يقدم Android 10 واجهات برمجة تطبيقات إدارة المخزن المؤقت HAL3 للكاميرا الاختيارية التي تسمح لك بتنفيذ منطق إدارة المخزن المؤقت لتحقيق ذاكرة مختلفة والتقاط مقايضات زمن الاستجابة في تطبيقات HAL للكاميرا.
تتطلب كاميرا HAL عدد N من الطلبات (حيث N يساوي عمق خط الأنابيب ) في قائمة الانتظار في خط الأنابيب الخاص بها، ولكنها غالبًا لا تتطلب جميع مجموعات N من مخازن الإخراج المؤقتة في نفس الوقت.
على سبيل المثال، قد يكون لـ HAL ثمانية طلبات في قائمة الانتظار في التدفق، ولكنها تتطلب فقط مخازن مؤقتة للإخراج للطلبين في المراحل الأخيرة من التدفق. على الأجهزة التي تعمل بنظام التشغيل Android 9 والإصدارات الأقدم، يخصص إطار عمل الكاميرا المخازن المؤقتة عندما يتم وضع الطلب في قائمة الانتظار في طبقة HAL، لذلك يمكن أن تكون هناك ست مجموعات من المخازن المؤقتة في طبقة HAL غير قيد الاستخدام. في Android 10، تسمح واجهات برمجة التطبيقات لإدارة المخزن المؤقت للكاميرا HAL3 بفصل المخازن المؤقتة للإخراج لتحرير المجموعات الست من المخازن المؤقتة. يمكن أن يؤدي ذلك إلى توفير مئات الميغابايت من الذاكرة على الأجهزة المتطورة ويمكن أن يكون مفيدًا أيضًا للأجهزة ذات الذاكرة المنخفضة.
يوضح الشكل 1 رسمًا تخطيطيًا لواجهة HAL للكاميرا للأجهزة التي تعمل بنظام Android 9 والإصدارات الأقدم. يوضح الشكل 2 واجهة HAL للكاميرا في Android 10 مع تنفيذ واجهات برمجة التطبيقات لإدارة المخزن المؤقت للكاميرا HAL3.
الشكل 1. واجهة الكاميرا HAL في Android 9 والإصدارات الأقدم
الشكل 2. واجهة الكاميرا HAL في Android 10 باستخدام واجهات برمجة التطبيقات لإدارة المخزن المؤقت
تنفيذ واجهات برمجة التطبيقات لإدارة المخزن المؤقت
لتنفيذ واجهات برمجة تطبيقات إدارة المخزن المؤقت، يجب على HAL للكاميرا:
- تنفيذ HIDL
ICameraDevice@3.5
. - قم بتعيين مفتاح خصائص الكاميرا
android.info.supportedBufferManagementVersion
علىHIDL_DEVICE_3_5
.
يستخدم HAL للكاميرا أساليب requestStreamBuffers
و returnStreamBuffers
في ICameraDeviceCallback.hal
لطلب المخازن المؤقتة وإرجاعها. يجب على HAL أيضًا تنفيذ أسلوب signalStreamFlush
في ICameraDeviceSession.hal
لإشارة HAL للكاميرا لإرجاع المخازن المؤقتة.
requestStreamBuffers
استخدم طريقة requestStreamBuffers
لطلب المخازن المؤقتة من إطار عمل الكاميرا. عند استخدام واجهات برمجة تطبيقات إدارة المخزن المؤقت HAL3 للكاميرا، لا تحتوي طلبات الالتقاط من إطار عمل الكاميرا على مخازن مؤقتة للإخراج، أي أن حقل bufferId
في StreamBuffer
هو 0
. لذلك، يجب على HAL للكاميرا استخدام requestStreamBuffers
لطلب المخازن المؤقتة من إطار عمل الكاميرا.
يسمح أسلوب requestStreamBuffers
للمتصل بطلب مخازن مؤقتة متعددة من تدفقات إخراج متعددة في مكالمة واحدة، مما يسمح بعدد أقل من مكالمات HIDL IPC. ومع ذلك، تستغرق المكالمات وقتًا أطول عندما يتم طلب المزيد من المخازن المؤقتة في نفس الوقت وقد يؤثر ذلك سلبًا على إجمالي زمن وصول الطلب إلى النتيجة. وأيضًا، نظرًا لأن الاستدعاءات الواردة إلى requestStreamBuffers
يتم تسلسلها في خدمة الكاميرا، فمن المستحسن أن يستخدم HAL للكاميرا مؤشر ترابط مخصص عالي الأولوية لطلب المخازن المؤقتة.
إذا فشل طلب المخزن المؤقت، يجب أن يكون HAL للكاميرا قادرًا على معالجة الأخطاء غير الفادحة بشكل صحيح. تصف القائمة التالية الأسباب الشائعة لفشل طلبات المخزن المؤقت وكيفية التعامل معها بواسطة الكاميرا HAL.
- قطع اتصال التطبيق بتدفق الإخراج: هذا خطأ غير فادح. يجب أن يرسل HAL للكاميرا
ERROR_REQUEST
لأي طلب التقاط يستهدف دفقًا غير متصل وأن يكون جاهزًا لمعالجة الطلبات اللاحقة بشكل طبيعي. - المهلة: يمكن أن يحدث هذا عندما يكون التطبيق مشغولاً بإجراء معالجة مكثفة أثناء الاحتفاظ ببعض المخازن المؤقتة. يجب أن يرسل HAL للكاميرا
ERROR_REQUEST
لطلبات الالتقاط التي لا يمكن تنفيذها بسبب خطأ انتهاء المهلة وتكون جاهزة لمعالجة الطلبات اللاحقة بشكل طبيعي. - يقوم إطار عمل الكاميرا بإعداد تكوين دفق جديد: يجب أن تنتظر طبقة HAL الخاصة بالكاميرا حتى اكتمال استدعاء
configureStreams
التالي قبل استدعاءrequestStreamBuffers
مرة أخرى. - وصل HAL للكاميرا إلى حد المخزن المؤقت الخاص به (حقل
maxBuffers
): يجب أن تنتظر HAL للكاميرا حتى تقوم بإرجاع مخزن مؤقت واحد على الأقل للتدفق قبل استدعاءrequestStreamBuffers
مرة أخرى.
returnStreamBuffers
استخدم طريقة returnStreamBuffers
لإرجاع المخازن المؤقتة الإضافية إلى إطار عمل الكاميرا. تقوم كاميرا HAL عادةً بإرجاع المخازن المؤقتة إلى إطار عمل الكاميرا من خلال طريقة processCaptureResult
، ولكنها يمكنها فقط حساب طلبات الالتقاط التي تم إرسالها إلى الكاميرا HAL. باستخدام طريقة requestStreamBuffers
، من الممكن لتطبيق HAL للكاميرا أن يحتفظ بمخازن مؤقتة أكثر مما طلبه إطار عمل الكاميرا. هذا هو الوقت الذي يجب فيه استخدام طريقة returnStreamBuffers
. إذا لم يحتفظ تطبيق HAL أبدًا بمخازن مؤقتة أكثر مما هو مطلوب، فلن يحتاج تطبيق HAL للكاميرا إلى استدعاء أسلوب returnStreamBuffers
.
com.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 أحادية الاتجاه ، مما يعني أن إطار عمل الكاميرا قد يستدعي واجهات برمجة تطبيقات الحظر الأخرى قبل أن يتلقى HAL استدعاء signalStreamFlush
. هذا يعني أن طريقة signalStreamFlush
والطرق الأخرى (خاصة طريقة configureStreams
) قد تصل إلى HAL للكاميرا بترتيب مختلف عن الترتيب الذي تم استدعاؤهم في إطار عمل الكاميرا. لمعالجة مشكلة عدم التزامن هذه، تمت إضافة حقل streamConfigCounter
إلى StreamConfiguration
وإضافته كوسيطة إلى أسلوب signalStreamFlush
. يجب أن يستخدم تطبيق HAL للكاميرا الوسيطة streamConfigCounter
لتحديد ما إذا كان استدعاء signalStreamFlush
سيصل في وقت لاحق عن استدعاء configureStreams
المقابل له. انظر الشكل 3 للحصول على مثال.
الشكل 3. كيف يجب على HAL للكاميرا اكتشاف ومعالجة مكالمات signalStreamFlush التي تصل متأخرة
يتغير السلوك عند تنفيذ واجهات برمجة تطبيقات إدارة المخزن المؤقت
عند استخدام واجهات برمجة تطبيقات إدارة المخزن المؤقت لتنفيذ منطق إدارة المخزن المؤقت، ضع في اعتبارك تغييرات السلوك المحتملة التالية على الكاميرا وتنفيذ HAL للكاميرا:
تصل طلبات الالتقاط إلى HAL للكاميرا بشكل أسرع وأكثر تكرارًا: بدون واجهات برمجة تطبيقات إدارة المخزن المؤقت، يطلب إطار عمل الكاميرا مخازن مؤقتة للإخراج لكل طلب التقاط قبل إرسال طلب التقاط إلى HAL للكاميرا. عند استخدام واجهات برمجة التطبيقات لإدارة المخزن المؤقت، لم يعد إطار عمل الكاميرا بحاجة إلى انتظار المخازن المؤقتة، وبالتالي يمكنه إرسال طلبات الالتقاط إلى HAL للكاميرا في وقت سابق.
أيضًا، بدون واجهات برمجة تطبيقات إدارة المخزن المؤقت، يتوقف إطار عمل الكاميرا عن إرسال طلبات الالتقاط إذا وصل أحد تدفقات الإخراج لطلب الالتقاط إلى الحد الأقصى لعدد المخازن المؤقتة التي يمكن لـ HAL الاحتفاظ بها في وقت واحد (يتم تعيين هذه القيمة بواسطة HAL للكاميرا في حقل
HalStream::maxBuffers
في القيمة المرجعة لاستدعاءconfigureStreams
). باستخدام واجهات برمجة تطبيقات إدارة المخزن المؤقت، لم يعد سلوك الاختناق هذا موجودًا ويجب ألا يقبل تنفيذ طبقة تناظرية سطح الأرض (HAL) للكاميرا استدعاءاتprocessCaptureRequest
عندما يكون هناك عدد كبير جدًا من طلبات الالتقاط في قائمة الانتظار.يختلف زمن استجابة
requestStreamBuffers
بشكل كبير: هناك العديد من الأسباب التي قد تجعل استدعاءrequestStreamBuffers
وقتًا أطول من المتوسط. على سبيل المثال:- بالنسبة للمخازن المؤقتة القليلة الأولى للتدفق الذي تم إنشاؤه حديثًا، يمكن أن تستغرق المكالمات وقتًا أطول لأن الجهاز يحتاج إلى تخصيص الذاكرة.
- يزداد زمن الوصول المتوقع بما يتناسب مع عدد المخازن المؤقتة المطلوبة في كل مكالمة.
- يحتوي التطبيق على مخازن مؤقتة وهو مشغول بالمعالجة. يمكن أن يتسبب هذا في إبطاء طلبات المخزن المؤقت أو انتهاء المهلة بسبب نقص المخازن المؤقتة أو وحدة المعالجة المركزية المزدحمة.
استراتيجيات إدارة المخزن المؤقت
تسمح واجهات برمجة التطبيقات لإدارة المخزن المؤقت بتنفيذ أنواع مختلفة من استراتيجيات إدارة المخزن المؤقت. بعض الأمثلة هي:
- متوافق مع الإصدارات السابقة: يطلب HAL مخازن مؤقتة لطلب التقاط أثناء استدعاء
processCaptureRequest
. لا توفر هذه الإستراتيجية أي توفير للذاكرة، ولكن يمكن أن تكون بمثابة التنفيذ الأول لواجهات برمجة تطبيقات إدارة المخزن المؤقت، مما يتطلب تغييرات قليلة جدًا في التعليمات البرمجية على HAL للكاميرا الموجودة. - الحد الأقصى من توفير الذاكرة: تطلب كاميرا HAL فقط المخازن المؤقتة للإخراج مباشرة قبل الحاجة إلى تعبئتها. تتيح هذه الإستراتيجية توفير الحد الأقصى من الذاكرة. الجانب السلبي المحتمل هو المزيد من الخلل في مسار الكاميرا عندما تستغرق طلبات المخزن المؤقت وقتًا طويلاً بشكل غير معتاد حتى تنتهي.
- ذاكرة تخزين مؤقت: يقوم HAL الخاص بالكاميرا بتخزين عدد قليل من المخازن المؤقتة بحيث تقل احتمالية تأثرها بطلب المخزن المؤقت البطيء في بعض الأحيان.
يمكن لـ HAL للكاميرا اعتماد إستراتيجيات مختلفة لحالات استخدام معينة، على سبيل المثال، استخدام إستراتيجية توفير الذاكرة القصوى لحالات الاستخدام التي تستخدم قدرًا كبيرًا من الذاكرة واستخدام الإستراتيجية المتوافقة مع الإصدارات السابقة لحالات الاستخدام الأخرى.
نموذج التنفيذ في الكاميرا الخارجية HAL
تم تقديم الكاميرا الخارجية HAL في نظام التشغيل Android 9 ويمكن العثور عليها في شجرة المصدر على hardware/interfaces/camera/device/3.5/
. في Android 10، تم تحديثه ليشمل ExternalCameraDeviceSession.cpp
، وهو تطبيق لواجهة برمجة تطبيقات إدارة المخزن المؤقت. تنفذ هذه الكاميرا الخارجية HAL استراتيجية توفير الذاكرة القصوى المذكورة في استراتيجيات إدارة المخزن المؤقت في بضع مئات من الأسطر من كود C++.