कैमरा HAL3 बफर प्रबंधन API

एंड्रॉइड 10 वैकल्पिक कैमरा HAL3 बफर प्रबंधन एपीआई पेश करता है जो आपको कैमरा HAL कार्यान्वयन में विभिन्न मेमोरी प्राप्त करने और विलंबता ट्रेडऑफ़ को कैप्चर करने के लिए बफर प्रबंधन तर्क को लागू करने की अनुमति देता है।

कैमरा एचएएल को अपनी पाइपलाइन में कतारबद्ध एन अनुरोधों (जहां एन पाइपलाइन की गहराई के बराबर है) की आवश्यकता होती है, लेकिन इसे अक्सर एक ही समय में आउटपुट बफर के सभी एन सेट की आवश्यकता नहीं होती है।

उदाहरण के लिए, एचएएल के पास पाइपलाइन में आठ अनुरोध कतारबद्ध हो सकते हैं, लेकिन उसे पाइपलाइन के अंतिम चरण में केवल दो अनुरोधों के लिए आउटपुट बफ़र्स की आवश्यकता होती है। एंड्रॉइड 9 और उससे नीचे चलने वाले उपकरणों पर, एचएएल में अनुरोध कतारबद्ध होने पर कैमरा फ्रेमवर्क बफ़र्स आवंटित करता है, इसलिए एचएएल में बफ़र्स के छह सेट हो सकते हैं जो उपयोग में नहीं हैं। एंड्रॉइड 10 में, कैमरा HAL3 बफ़र प्रबंधन एपीआई बफ़र्स के छह सेटों को मुक्त करने के लिए आउटपुट बफ़र्स को अलग करने की अनुमति देता है। इससे हाई-एंड डिवाइस पर सैकड़ों मेगाबाइट मेमोरी की बचत हो सकती है और कम मेमोरी वाले डिवाइस के लिए भी यह फायदेमंद हो सकता है।

चित्र 1 एंड्रॉइड 9 और उससे पहले के संस्करण चलाने वाले उपकरणों के लिए कैमरा एचएएल इंटरफ़ेस का एक आरेख दिखाता है। चित्र 2 एंड्रॉइड 10 में कैमरा एचएएल इंटरफ़ेस दिखाता है जिसमें कैमरा एचएएल3 बफर प्रबंधन एपीआई लागू किया गया है।

9 या उससे कम में बफर प्रबंधन

चित्र 1. एंड्रॉइड 9 और उससे पहले के संस्करणों में कैमरा एचएएल इंटरफ़ेस

एंड्रॉइड 10 में बफ़र प्रबंधन

चित्र 2. बफ़र प्रबंधन एपीआई का उपयोग करके एंड्रॉइड 10 में कैमरा एचएएल इंटरफ़ेस

बफ़र प्रबंधन एपीआई लागू करना

बफ़र प्रबंधन एपीआई लागू करने के लिए, कैमरा एचएएल को यह करना होगा:

कैमरा HAL बफ़र्स का अनुरोध करने और वापस करने के लिए ICameraDeviceCallback.hal में requestStreamBuffers और returnStreamBuffers विधियों का उपयोग करता है। कैमरा HAL को बफ़र्स लौटाने का संकेत देने के लिए HAL को ICameraDeviceSession.hal में signalStreamFlush विधि भी लागू करनी होगी।

requestStreamBuffers

कैमरा फ्रेमवर्क से बफ़र्स का अनुरोध करने के लिए requestStreamBuffers विधि का उपयोग करें। कैमरा HAL3 बफ़र प्रबंधन API का उपयोग करते समय, कैमरा फ्रेमवर्क से कैप्चर अनुरोधों में आउटपुट बफ़र्स नहीं होते हैं, अर्थात StreamBuffer में bufferId फ़ील्ड 0 है। इसलिए, कैमरा एचएएल को कैमरा फ्रेमवर्क से बफ़र्स का अनुरोध करने के लिए requestStreamBuffers उपयोग करना चाहिए।

requestStreamBuffers विधि कॉल करने वाले को एक ही कॉल में कई आउटपुट स्ट्रीम से कई बफ़र्स का अनुरोध करने की अनुमति देती है, जिससे कम एचआईडीएल आईपीसी कॉल की अनुमति मिलती है। हालाँकि, जब एक ही समय में अधिक बफ़र्स का अनुरोध किया जाता है तो कॉल में अधिक समय लगता है और यह कुल अनुरोध-से-परिणाम विलंबता को नकारात्मक रूप से प्रभावित कर सकता है। साथ ही, क्योंकि requestStreamBuffers में कॉल को कैमरा सेवा में क्रमबद्ध किया जाता है, इसलिए यह अनुशंसा की जाती है कि कैमरा एचएएल बफ़र्स का अनुरोध करने के लिए एक समर्पित उच्च-प्राथमिकता वाले थ्रेड का उपयोग करे।

यदि बफ़र अनुरोध विफल हो जाता है, तो कैमरा HAL को गैर-घातक त्रुटियों को ठीक से संभालने में सक्षम होना चाहिए। निम्नलिखित सूची बफ़र अनुरोधों के विफल होने के सामान्य कारणों का वर्णन करती है और उन्हें कैमरा HAL द्वारा कैसे संभाला जाना चाहिए।

  • ऐप आउटपुट स्ट्रीम से डिस्कनेक्ट हो जाता है: यह एक गैर-घातक त्रुटि है। कैमरे HAL को डिस्कनेक्ट किए गए स्ट्रीम को लक्षित करने वाले किसी भी कैप्चर अनुरोध के लिए ERROR_REQUEST भेजना चाहिए और बाद के अनुरोधों को सामान्य रूप से संसाधित करने के लिए तैयार रहना चाहिए।
  • टाइमआउट: यह तब हो सकता है जब कोई ऐप कुछ बफ़र्स को पकड़कर गहन प्रसंस्करण करने में व्यस्त हो। कैमरा एचएएल को कैप्चर अनुरोधों के लिए ERROR_REQUEST भेजना चाहिए जो टाइमआउट त्रुटि के कारण पूरा नहीं किया जा सकता है और बाद के अनुरोधों को सामान्य रूप से संसाधित करने के लिए तैयार रहना चाहिए।
  • कैमरा फ्रेमवर्क एक नया स्ट्रीम कॉन्फ़िगरेशन तैयार कर रहा है: कैमरा एचएएल को requestStreamBuffers फिर से कॉल करने से पहले अगली configureStreams कॉल पूरी होने तक इंतजार करना चाहिए।
  • कैमरा HAL अपनी बफ़र सीमा ( maxBuffers फ़ील्ड) तक पहुँच गया है: कैमरा HAL को requestStreamBuffers फिर से कॉल करने से पहले तब तक इंतजार करना चाहिए जब तक कि वह स्ट्रीम का कम से कम एक बफ़र वापस न कर दे।

रिटर्नस्ट्रीमबफ़र्स

कैमरा फ्रेमवर्क में अतिरिक्त बफ़र्स वापस करने के लिए returnStreamBuffers विधि का उपयोग करें। कैमरा HAL आम तौर पर processCaptureResult विधि के माध्यम से कैमरा फ्रेमवर्क में बफ़र्स लौटाता है, लेकिन यह केवल उन कैप्चर अनुरोधों के लिए जिम्मेदार हो सकता है जो कैमरा HAL को भेजे गए हैं। requestStreamBuffers विधि के साथ, कैमरा एचएएल कार्यान्वयन के लिए कैमरा फ्रेमवर्क द्वारा अनुरोध किए गए से अधिक बफ़र्स बनाए रखना संभव है। यह तब होता है जब returnStreamBuffers विधि का उपयोग किया जाना चाहिए। यदि एचएएल कार्यान्वयन कभी भी अनुरोध से अधिक बफ़र्स नहीं रखता है, तो कैमरा एचएएल कार्यान्वयन को returnStreamBuffers विधि को कॉल करने की आवश्यकता नहीं है।

सिग्नलस्ट्रीमफ्लश

signalStreamFlush विधि को कैमरा फ्रेमवर्क द्वारा कैमरा एचएएल को सभी बफ़र्स को वापस करने के लिए सूचित करने के लिए बुलाया जाता है। इसे आम तौर पर तब कॉल किया जाता है जब कैमरा फ्रेमवर्क configureStreams कॉल करने वाला होता है और कैमरा कैप्चर पाइपलाइन को खत्म करना होता है। returnStreamBuffers विधि के समान, यदि कैमरा एचएएल कार्यान्वयन अनुरोध से अधिक बफ़र्स नहीं रखता है, तो इस विधि का एक खाली कार्यान्वयन संभव है।

कैमरा फ्रेमवर्क signalStreamFlush को कॉल करने के बाद, फ्रेमवर्क कैमरा एचएएल को नए कैप्चर अनुरोध भेजना बंद कर देता है जब तक कि सभी बफ़र्स कैमरा फ्रेमवर्क में वापस नहीं आ जाते। जब सभी बफ़र्स वापस कर दिए जाते हैं, तो requestStreamBuffers विधि कॉल विफल हो जाती है, और कैमरा फ्रेमवर्क एक साफ़ स्थिति में अपना काम जारी रख सकता है। इसके बाद कैमरा फ्रेमवर्क या तो configureStreams या processCaptureRequest विधि को कॉल करता है। यदि कैमरा फ्रेमवर्क configureStreams विधि को कॉल करता है, तो configureStreams कॉल सफलतापूर्वक वापस आने के बाद कैमरा एचएएल फिर से बफ़र्स का अनुरोध करना शुरू कर सकता है। यदि कैमरा फ्रेमवर्क processCaptureRequest विधि को कॉल करता है, तो कैमरा एचएएल processCaptureRequest कॉल के दौरान बफ़र्स का अनुरोध करना शुरू कर सकता है।

signalStreamFlush विधि और flush विधि के लिए शब्दार्थ अलग-अलग हैं। जब flush विधि को बुलाया जाता है, तो एचएएल पाइपलाइन को जल्द से जल्द खत्म करने के लिए ERROR_REQUEST के साथ लंबित कैप्चर अनुरोधों को निरस्त कर सकता है। जब signalStreamFlush विधि को कॉल किया जाता है, तो एचएएल को सभी लंबित कैप्चर अनुरोधों को सामान्य रूप से पूरा करना होगा और सभी बफ़र्स को कैमरा फ्रेमवर्क में वापस करना होगा।

signalStreamFlush विधि और अन्य विधियों के बीच एक और अंतर यह है कि signalStreamFlush एक-तरफ़ा एचआईडीएल विधि है, जिसका अर्थ है कि एचएएल को signalStreamFlush कॉल प्राप्त होने से पहले कैमरा फ्रेमवर्क अन्य अवरोधक एपीआई में कॉल कर सकता है। इसका मतलब यह है कि signalStreamFlush विधि और अन्य विधियां (विशेष रूप से configureStreams विधि) कैमरा एचएएल पर उस क्रम से भिन्न क्रम में पहुंच सकती हैं, जिस क्रम में उन्हें कैमरा फ्रेमवर्क में बुलाया गया था। इस एसिंक्रोनी समस्या को संबोधित करने के लिए, streamConfigCounter फ़ील्ड को StreamConfiguration में जोड़ा गया था और signalStreamFlush विधि में एक तर्क के रूप में जोड़ा गया था। कैमरा एचएएल कार्यान्वयन को यह निर्धारित करने के लिए streamConfigCounter तर्क का उपयोग करना चाहिए कि signalStreamFlush कॉल उसके संबंधित configureStreams कॉल की तुलना में बाद में आती है या नहीं। उदाहरण के लिए चित्र 3 देखें.

देर से आने वाली कॉलों को संभालना

चित्र 3. कैमरे एचएएल को देर से आने वाली सिग्नलस्ट्रीमफ्लश कॉलों का पता कैसे लगाना चाहिए और उन्हें कैसे संभालना चाहिए

बफ़र प्रबंधन एपीआई लागू करते समय व्यवहार बदल जाता है

बफर प्रबंधन तर्क को लागू करने के लिए बफर प्रबंधन एपीआई का उपयोग करते समय, कैमरा और कैमरा एचएएल कार्यान्वयन में निम्नलिखित संभावित व्यवहार परिवर्तनों पर विचार करें:

  • कैप्चर अनुरोध कैमरा एचएएल पर तेजी से और अधिक बार पहुंचते हैं: बफर प्रबंधन एपीआई के बिना, कैमरा फ्रेमवर्क कैमरा एचएएल को कैप्चर अनुरोध भेजने से पहले प्रत्येक कैप्चर अनुरोध के लिए आउटपुट बफर का अनुरोध करता है। बफ़र प्रबंधन एपीआई का उपयोग करते समय, कैमरा फ्रेमवर्क को अब बफ़र्स के लिए प्रतीक्षा करने की आवश्यकता नहीं होती है और इसलिए वह कैमरा एचएएल को पहले कैप्चर अनुरोध भेज सकता है।

    इसके अलावा, बफर प्रबंधन एपीआई के बिना, कैमरा फ्रेमवर्क कैप्चर अनुरोध भेजना बंद कर देता है यदि कैप्चर अनुरोध की आउटपुट स्ट्रीम में से एक बफर की अधिकतम संख्या तक पहुंच गया है जिसे एचएएल एक समय में रख सकता है (यह मान कैमरा एचएएल द्वारा निर्दिष्ट किया गया है) configureStreams कॉल के रिटर्न मान में HalStream::maxBuffers फ़ील्ड)। बफ़र प्रबंधन एपीआई के साथ, यह थ्रॉटलिंग व्यवहार अब मौजूद नहीं है और जब एचएएल के पास बहुत अधिक कैप्चर अनुरोध कतारबद्ध हैं तो कैमरा एचएएल कार्यान्वयन को processCaptureRequest कॉल स्वीकार नहीं करना चाहिए।

  • requestStreamBuffers कॉल विलंबता काफी भिन्न होती है: ऐसे कई कारण हैं जिनकी वजह से requestStreamBuffers कॉल में औसत से अधिक समय लग सकता है। उदाहरण के लिए:

    • नव निर्मित स्ट्रीम के पहले कुछ बफ़र्स के लिए, कॉल में अधिक समय लग सकता है क्योंकि डिवाइस को मेमोरी आवंटित करने की आवश्यकता होती है।
    • प्रत्येक कॉल में अनुरोधित बफ़र्स की संख्या के अनुपात में अपेक्षित विलंबता बढ़ जाती है।
    • ऐप में बफ़र्स हैं और वह प्रोसेसिंग में व्यस्त है। इससे बफ़र्स की कमी या व्यस्त CPU के कारण बफ़र अनुरोध धीमा हो सकते हैं या टाइमआउट हो सकता है।

बफ़र प्रबंधन रणनीतियाँ

बफ़र प्रबंधन एपीआई विभिन्न प्रकार की बफ़र प्रबंधन रणनीतियों को लागू करने की अनुमति देते हैं। कुछ उदाहरण निम्न हैं:

  • बैकवर्ड संगत: एचएएल processCaptureRequest कॉल के दौरान कैप्चर अनुरोध के लिए बफ़र्स का अनुरोध करता है। यह रणनीति कोई मेमोरी बचत प्रदान नहीं करती है, लेकिन बफर प्रबंधन एपीआई के पहले कार्यान्वयन के रूप में काम कर सकती है, जिसके लिए मौजूदा कैमरा एचएएल में बहुत कम कोड परिवर्तन की आवश्यकता होती है।
  • अधिकतम मेमोरी बचत: कैमरा एचएएल केवल आउटपुट बफ़र्स को भरने से ठीक पहले अनुरोध करता है। यह रणनीति अधिकतम मेमोरी बचत की अनुमति देती है। जब बफ़र अनुरोधों को समाप्त होने में असामान्य रूप से लंबा समय लगता है तो संभावित नकारात्मक पक्ष अधिक कैमरा पाइपलाइन जंक है।
  • कैश्ड: कैमरा एचएएल कुछ बफ़र्स को कैश करता है ताकि कभी-कभार धीमे बफ़र अनुरोध से इसके प्रभावित होने की संभावना कम हो।

कैमरा एचएएल विशेष उपयोग के मामलों के लिए अलग-अलग रणनीतियों को अपना सकता है, उदाहरण के लिए, बहुत अधिक मेमोरी का उपयोग करने वाले उपयोग के मामलों के लिए अधिकतम मेमोरी सेविंग रणनीति का उपयोग करना और अन्य उपयोग के मामलों के लिए बैकवर्ड-संगत रणनीति का उपयोग करना।

बाहरी कैमरे एचएएल में नमूना कार्यान्वयन

बाहरी कैमरा HAL को Android 9 में पेश किया गया था और hardware/interfaces/camera/device/3.5/ पर स्रोत ट्री में पाया जा सकता है। एंड्रॉइड 10 में, इसे बफ़र प्रबंधन एपीआई के कार्यान्वयन, ExternalCameraDeviceSession.cpp शामिल करने के लिए अद्यतन किया गया है। यह बाहरी कैमरा HAL C++ कोड की कुछ सौ पंक्तियों में बफ़र प्रबंधन रणनीतियों में उल्लिखित अधिकतम मेमोरी बचत रणनीति को लागू करता है।