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