कैमरा HAL3 बफ़र मैनेजमेंट एपीआई

Android 10 में, camera HAL3 के लिए बफ़र मैनेजमेंट एपीआई का विकल्प दिया गया है. इन एपीआई की मदद से, बफ़र मैनेजमेंट लॉजिक लागू किया जा सकता है. इससे, कैमरा HAL लागू करने के दौरान, अलग-अलग मेमोरी और कैप्चर में लगने वाले समय में बदलाव किया जा सकता है.

कैमरा एचएएल को अपनी पाइपलाइन में, N अनुरोधों (जहां N, पाइपलाइन की गहराई के बराबर है) की ज़रूरत होती है. हालांकि, अक्सर उसे आउटपुट बफ़र के सभी N सेट की एक साथ ज़रूरत नहीं होती.

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

पहली इमेज में, Android 9 और उससे पहले के वर्शन पर काम करने वाले डिवाइसों के लिए, कैमरा एचएएल इंटरफ़ेस का डायग्राम दिखाया गया है. दूसरे चित्र में, Android 10 में कैमरा एचएएल इंटरफ़ेस दिखाया गया है. इसमें, कैमरा एचएएल3 बफ़र मैनेजमेंट एपीआई लागू किए गए हैं.

Android 9 या इससे पहले के वर्शन में बफ़र मैनेजमेंट

पहली इमेज. Android 9 और उससे पहले के वर्शन में Camera HAL इंटरफ़ेस

Android 10 में बफ़र मैनेजमेंट

दूसरी इमेज. Android 10 में, बफ़र मैनेजमेंट एपीआई का इस्तेमाल करके कैमरा एचएएल इंटरफ़ेस

बफ़र मैनेजमेंट एपीआई लागू करना

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

कैमरा एचएएल, बफ़र का अनुरोध करने और उन्हें दिखाने के लिए, ICameraDeviceCallback.hal में requestStreamBuffers और returnStreamBuffers तरीकों का इस्तेमाल करता है. कैमरे के एचएएल को बफ़र दिखाने का सिग्नल देने के लिए, एचएएल को ICameraDeviceSession.hal में signalStreamFlush तरीका भी लागू करना होगा.

requestStreamBuffers

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

requestStreamBuffers तरीके की मदद से, कॉल करने वाला व्यक्ति एक ही कॉल में कई आउटपुट स्ट्रीम से कई बफ़र का अनुरोध कर सकता है. इससे, HIDL IPC कॉल की संख्या कम हो जाती है. हालांकि, एक ही समय पर ज़्यादा बफ़र का अनुरोध करने पर, कॉल में ज़्यादा समय लगता है. इससे, अनुरोध से लेकर नतीजे मिलने में लगने वाले कुल समय पर बुरा असर पड़ सकता है. साथ ही, कैमरा सेवा में requestStreamBuffers में किए गए कॉल को क्रम से लगाया जाता है. इसलिए, यह सुझाव दिया जाता है कि कैमरा एचएएल बफ़र का अनुरोध करने के लिए, ज़्यादा प्राथमिकता वाले थ्रेड का इस्तेमाल करे.

अगर बफ़र करने का अनुरोध पूरा नहीं होता है, तो कैमरा एचएएल को ग़ैर-घातक गड़बड़ियों को ठीक से मैनेज करना चाहिए. नीचे दी गई सूची में, बफ़र करने के अनुरोधों के अस्वीकार होने की सामान्य वजहों के बारे में बताया गया है. साथ ही, यह भी बताया गया है कि कैमरा एचएएल को इन वजहों को कैसे मैनेज करना चाहिए.

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

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

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

signalStreamFlush

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

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

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

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

देर से आने वाले कॉल मैनेज करना

तीसरी इमेज. कैमरा एचएएल को देर से आने वाले signalStreamFlush कॉल का पता कैसे लगाना चाहिए और उन्हें कैसे मैनेज करना चाहिए

बफ़र मैनेजमेंट एपीआई लागू करने पर, काम करने का तरीका बदल जाता है

बफ़र मैनेजमेंट लॉजिक को लागू करने के लिए, बफ़र मैनेजमेंट एपीआई का इस्तेमाल करते समय, कैमरे और कैमरे के एचएएल लागू करने के व्यवहार में इन संभावित बदलावों पर विचार करें:

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

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

  • requestStreamBuffers कॉल के इंतज़ार का समय काफ़ी अलग-अलग होता है: requestStreamBuffers कॉल में औसत से ज़्यादा समय लगने की कई वजहें हो सकती हैं. उदाहरण के लिए:

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

बफ़र मैनेजमेंट से जुड़ी रणनीतियां

बफ़र मैनेजमेंट एपीआई की मदद से, बफ़र मैनेजमेंट की अलग-अलग रणनीतियां लागू की जा सकती हैं. इसके कुछ उदाहरण यहां दिए गए हैं:

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

कैमरा एचएएल, अलग-अलग तरह के इस्तेमाल के उदाहरणों के लिए अलग-अलग रणनीतियां अपना सकता है. उदाहरण के लिए, ज़्यादा मेमोरी इस्तेमाल करने वाले इस्तेमाल के उदाहरणों के लिए, ज़्यादा से ज़्यादा मेमोरी बचाने की रणनीति का इस्तेमाल करना और दूसरे इस्तेमाल के उदाहरणों के लिए, पुराने सिस्टम के साथ काम करने वाली रणनीति का इस्तेमाल करना.

एक्सटर्नल कैमरा एचएएल में सैंपल लागू करने की सुविधा

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