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