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

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

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

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

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

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

पहली इमेज. Android 9 और इससे पहले के वर्शन में कैमरा एचएएल इंटरफ़ेस

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

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

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

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

कैमरा 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++ कोड की कुछ सौ लाइनें इस्तेमाल की जाती हैं.