Android 10 में, camera HAL3 के लिए बफ़र मैनेजमेंट एपीआई का विकल्प दिया गया है. इन एपीआई की मदद से, बफ़र मैनेजमेंट लॉजिक लागू किया जा सकता है. इससे, कैमरा HAL लागू करने के दौरान, अलग-अलग मेमोरी और कैप्चर में लगने वाले समय में बदलाव किया जा सकता है.
कैमरा एचएएल को अपनी पाइपलाइन में, N अनुरोधों (जहां N, पाइपलाइन की गहराई के बराबर है) की ज़रूरत होती है. हालांकि, अक्सर उसे आउटपुट बफ़र के सभी N सेट की एक साथ ज़रूरत नहीं होती.
उदाहरण के लिए, हो सकता है कि एचएएल में पाइपलाइन में आठ अनुरोध हों, लेकिन उसे पाइपलाइन के आखिरी चरणों में सिर्फ़ दो अनुरोधों के लिए आउटपुट बफ़र की ज़रूरत हो. Android 9 और इससे पहले के वर्शन वाले डिवाइसों पर, कैमरा फ़्रेमवर्क, अनुरोध को एचएएल में कतार में लगाने पर बफ़र को ऐलोकेट करता है. इसलिए, एचएएल में ऐसे छह बफ़र सेट हो सकते हैं जिनका इस्तेमाल नहीं किया जा रहा है. Android 10 में, कैमरा HAL3 बफ़र मैनेजमेंट एपीआई की मदद से, आउटपुट बफ़र को अलग किया जा सकता है, ताकि बफ़र के छह सेट खाली किए जा सकें. इससे, बेहतर डिवाइसों पर सैकड़ों मेगाबाइट की मेमोरी बच सकती है. साथ ही, कम मेमोरी वाले डिवाइसों के लिए भी यह फ़ायदेमंद हो सकता है.
पहली इमेज में, Android 9 और उससे पहले के वर्शन पर काम करने वाले डिवाइसों के लिए, कैमरा एचएएल इंटरफ़ेस का डायग्राम दिखाया गया है. दूसरे चित्र में, Android 10 में कैमरा एचएएल इंटरफ़ेस दिखाया गया है. इसमें कैमरा एचएएल3 बफ़र मैनेजमेंट एपीआई लागू किए गए हैं.
पहली इमेज. Android 9 और उससे पहले के वर्शन में Camera HAL इंटरफ़ेस
दूसरी इमेज. Android 10 में, बफ़र मैनेजमेंट एपीआई का इस्तेमाल करके Camera HAL इंटरफ़ेस
बफ़र मैनेजमेंट एपीआई लागू करना
बफ़र मैनेजमेंट एपीआई लागू करने के लिए, कैमरा एचएएल को:
- HIDL
ICameraDevice@3.5
लागू करें. - कैमरे की विशेषताओं वाले पासकोड को
HIDL_DEVICE_3_5
पर सेट करें.android.info.supportedBufferManagementVersion
कैमरा एचएएल, बफ़र का अनुरोध करने और उन्हें दिखाने के लिए, 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
कैमरा फ़्रेमवर्क में अतिरिक्त बफ़र वापस करने के लिए, 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
, एकतरफ़ा HIDL तरीका है. इसका मतलब है कि HAL को signalStreamFlush
कॉल मिलने से पहले, कैमरा फ़्रेमवर्क अन्य ब्लॉकिंग एपीआई को कॉल कर सकता है. इसका मतलब है कि signalStreamFlush
तरीका और अन्य तरीके (खास तौर पर configureStreams
तरीका), कैमरा एचएएल में उस क्रम से नहीं आ सकते जिस क्रम में उन्हें कैमरा फ़्रेमवर्क में बुलाया गया था. सिंक न होने की इस समस्या को हल करने के लिए, streamConfigCounter
फ़ील्ड को StreamConfiguration
में जोड़ा गया और signalStreamFlush
तरीके में आर्ग्युमेंट के तौर पर जोड़ा गया. कैमरा एचएएल लागू करने के लिए, streamConfigCounter
आर्ग्युमेंट का इस्तेमाल करके यह तय किया जाना चाहिए कि signalStreamFlush
कॉल, उससे जुड़े configureStreams
कॉल के बाद आता है या नहीं. उदाहरण के लिए, तीसरा चित्र देखें.
तीसरी इमेज. कैमरा एचएएल को देर से आने वाले signalStreamFlush कॉल का पता कैसे लगाना चाहिए और उन्हें कैसे मैनेज करना चाहिए
बफ़र मैनेजमेंट एपीआई लागू करने पर, काम करने का तरीका बदल जाता है
बफ़र मैनेजमेंट लॉजिक को लागू करने के लिए, बफ़र मैनेजमेंट एपीआई का इस्तेमाल करते समय, कैमरे और कैमरे के एचएएल के लागू होने के व्यवहार में इन संभावित बदलावों पर विचार करें:
कैमरा एचएएल पर कैप्चर के अनुरोध तेज़ी से और बार-बार आते हैं: बफ़र मैनेजमेंट एपीआई के बिना, कैमरा फ़्रेमवर्क, कैमरा एचएएल पर कैप्चर का अनुरोध भेजने से पहले, हर कैप्चर के अनुरोध के लिए आउटपुट बफ़र का अनुरोध करता है. बफ़र मैनेजमेंट एपीआई का इस्तेमाल करने पर, कैमरा फ़्रेमवर्क को अब बफ़र के लिए इंतज़ार नहीं करना पड़ता. इसलिए, वह कैमरा एचएएल को कैप्चर करने के अनुरोध पहले भेज सकता है.
साथ ही, बफ़र मैनेजमेंट एपीआई के बिना, कैमरा फ़्रेमवर्क कैप्चर करने के अनुरोध भेजना बंद कर देता है. ऐसा तब होता है, जब कैप्चर करने के अनुरोध की किसी आउटपुट स्ट्रीम में, ज़्यादा से ज़्यादा बफ़र की वह संख्या पूरी हो जाती है जो एचएएल एक बार में होल्ड कर सकता है. यह वैल्यू, कैमरा एचएएल से
configureStreams
कॉल की रिटर्न वैल्यू मेंHalStream::maxBuffers
फ़ील्ड में तय की जाती है. बफ़र मैनेजमेंट एपीआई की मदद से, अब यह व्यवहार नहीं होता. साथ ही, जब HAL में कैप्चर करने के बहुत ज़्यादा अनुरोध कतार में हों, तब कैमरा एचएएल कोprocessCaptureRequest
कॉल स्वीकार नहीं करने चाहिए.requestStreamBuffers
कॉल के इंतज़ार का समय काफ़ी अलग-अलग होता है:requestStreamBuffers
कॉल में औसत से ज़्यादा समय लगने की कई वजहें हो सकती हैं. उदाहरण के लिए:- नई स्ट्रीम के शुरुआती कुछ बफ़र के लिए, कॉल में ज़्यादा समय लग सकता है. इसकी वजह यह है कि डिवाइस को मेमोरी को ऐलोकेट करना पड़ता है.
- हर कॉल में अनुरोध किए गए बफ़र की संख्या के हिसाब से, अनुमानित इंतज़ार का समय बढ़ता है.
- ऐप्लिकेशन, बफ़र को होल्ड कर रहा है और उसे प्रोसेस कर रहा है. इस वजह से, बफ़र के अनुरोध धीमे हो सकते हैं या टाइम आउट हो सकता है. ऐसा, बफ़र की कमी या सीपीयू के व्यस्त होने की वजह से होता है.
बफ़र मैनेजमेंट की रणनीतियां
बफ़र मैनेजमेंट एपीआई की मदद से, बफ़र मैनेजमेंट की अलग-अलग रणनीतियां लागू की जा सकती हैं. इसके कुछ उदाहरण यहां दिए गए हैं:
- पिछले वर्शन के साथ काम करने वाला: HAL,
processCaptureRequest
कॉल के दौरान कैप्चर करने के अनुरोध के लिए बफ़र का अनुरोध करता है. इस रणनीति से, मेमोरी में कोई बचत नहीं होती. हालांकि, यह बफ़र मैनेजमेंट एपीआई को लागू करने का पहला तरीका हो सकता है. इसके लिए, मौजूदा कैमरा एचएएल में कोड में बहुत कम बदलाव करने की ज़रूरत होती है. - ज़्यादा से ज़्यादा स्टोरेज बचाना: कैमरा एचएएल, आउटपुट बफ़र का अनुरोध सिर्फ़ तब करता है, जब उसे भरने की ज़रूरत होती है. इस रणनीति से, ज़्यादा से ज़्यादा मेमोरी सेव की जा सकती है. हालांकि, इससे कैमरा पाइपलाइन में ज़्यादा रुकावट आ सकती है. ऐसा तब होता है, जब बफ़र करने के अनुरोधों को पूरा होने में बहुत ज़्यादा समय लगता है.
- कैश मेमोरी में सेव: कैमरा एचएएल कुछ बफ़र को कैश मेमोरी में सेव करता है, ताकि कभी-कभी बफ़र के अनुरोध में होने वाली देरी से, कैमरे पर कम असर पड़े.
कैमरा एचएएल, अलग-अलग तरह के इस्तेमाल के उदाहरणों के लिए अलग-अलग रणनीतियां अपना सकता है. उदाहरण के लिए, ज़्यादा मेमोरी इस्तेमाल करने वाले इस्तेमाल के उदाहरणों के लिए, ज़्यादा से ज़्यादा मेमोरी बचाने की रणनीति का इस्तेमाल करना और दूसरे इस्तेमाल के उदाहरणों के लिए, पुराने सिस्टम के साथ काम करने वाली रणनीति का इस्तेमाल करना.
बाहरी कैमरे के एचएएल में सैंपल लागू करना
बाहरी कैमरे के लिए एचएएल को Android 9 में लॉन्च किया गया था. इसे सोर्स ट्री में hardware/interfaces/camera/device/3.5/
पर देखा जा सकता है.
Android 10 में, इसे अपडेट किया गया है, ताकि इसमें ExternalCameraDeviceSession.cpp
शामिल किया जा सके. यह बफ़र मैनेजमेंट एपीआई का एक वर्शन है. यह एक्सटर्नल कैमरा एचएएल, बफ़र मैनेजमेंट की रणनीतियों में बताई गई, ज़्यादा से ज़्यादा मेमोरी सेव करने की रणनीति को लागू करता है. इसके लिए, यह C++ कोड की कुछ सौ लाइनों का इस्तेमाल करता है.