Camera HAL3 বাফার ম্যানেজমেন্ট API

Android 10 ঐচ্ছিক ক্যামেরা HAL3 বাফার ম্যানেজমেন্ট API নিয়ে এসেছে যা আপনাকে ক্যামেরা HAL ইমপ্লিমেন্টেশনে আলাদা মেমরি ও ক্যাপচার লেটেন্সি ট্রেডঅফ পাওয়ার জন্য বাফার ম্যানেজমেন্ট লজিক ইমপ্লিমেন্ট করতে দেয়।

ক্যামেরা HAL-এর পাইপলাইনে N সংখ্যক অনুরোধ (যেখানে N হল পাইপলাইন ডেপথ-এর সমান) সারিবদ্ধভাবে থাকতে হয়, তবে একই সময়ে আউটপুট বাফারের সব N সেট প্রয়োজন হয় না।

যেমন, HAL-এর পাইপলাইনে আটটি অনুরোধ সারিবদ্ধ থাকতে পারে, কিন্তু পাইপলাইনের শেষ দুটি অনুরোধের জন্য শুধুমাত্র আউটপুট বাফার প্রয়োজন। Android 9 ও তার আগের যেকোনও ভার্সনে চলা ডিভাইসে, HAL-এ অনুরোধ সারিবদ্ধ করা হলে ক্যামেরা ফ্রেমওয়ার্ক বাফার বরাদ্দ করে, তাই HAL-এ ছয়টি সেট বাফার থাকতে পারে যা ব্যবহার করা হচ্ছে না। Android 10-এ, ক্যামেরা HAL3 বাফার ম্যানেজমেন্ট API, আউটপুট বাফারকে ডিকাপেল করার অনুমতি দেয় যাতে ছয়টি বাফার সেট ফ্রি করা যায়। এর ফলে হাই-এন্ড ডিভাইসে শত শত মেগাবাইট মেমরি সেভ করা যায় এবং কম মেমরিযুক্ত ডিভাইসের ক্ষেত্রেও এটি সহায়ক হতে পারে।

ছবি ১-এ Android 9 ও এর আগের যেকোনও ভার্সনে চলছে এমন ডিভাইসের জন্য ক্যামেরা HAL ইন্টারফেসের ডায়াগ্রাম দেখানো হয়েছে। ছবি ২-এ Android 10-এ ক্যামেরা HAL ইন্টারফেস দেখানো হয়েছে, যেখানে ক্যামেরা HAL3 বাফার ম্যানেজমেন্ট API প্রয়োগ করা হয়েছে।

৯ বা তার আগের ভার্সনে বাফার ম্যানেজমেন্ট

ছবি ১. Android 9 ও তার আগের ভার্সনে ক্যামেরা HAL ইন্টারফেস

Android 10-এ বাফার ম্যানেজমেন্ট

ছবি ২. Android 10-এ বাফার ম্যানেজমেন্ট API ব্যবহার করে ক্যামেরা HAL ইন্টারফেস

বাফার ম্যানেজমেন্ট API প্রয়োগ করা

বাফার ম্যানেজমেন্ট API প্রয়োগ করতে, ক্যামেরা HAL-কে অবশ্যই:

ক্যামেরা HAL, বাফার অনুরোধ করতে ও ফেরত দিতে requestStreamBuffers এবং returnStreamBuffers মেথড ব্যবহার করে। ICameraDeviceCallback.hal ক্যামেরা HAL-কে বাফার ফেরত দেওয়ার জন্য সিগন্যাল দিতে, HAL-কে অবশ্যই signalStreamFlush পদ্ধতি ICameraDeviceSession.hal ইমপ্লিমেন্ট করতে হবে।

requestStreamBuffers

ক্যামেরা ফ্রেমওয়ার্ক থেকে বাফার অনুরোধ করতে requestStreamBuffers মেথড ব্যবহার করুন। ক্যামেরা HAL3 বাফার ম্যানেজমেন্ট API ব্যবহার করার সময়, ক্যামেরা ফ্রেমওয়ার্ক থেকে ক্যাপচার করা অনুরোধে কোনও আউটপুট বাফার থাকে না, অর্থাৎ, bufferId ফিল্ডে StreamBuffer 0 থাকে। তাই, ক্যামেরা ফ্রেমওয়ার্ক থেকে বাফারের অনুরোধ করতে ক্যামেরা HAL-কে অবশ্যই requestStreamBuffers ব্যবহার করতে হবে।

requestStreamBuffers পদ্ধতিতে, কলার একটি কলে একাধিক আউটপুট স্ট্রিম থেকে একাধিক বাফার অনুরোধ করতে পারে, যার ফলে HIDL IPC কলের সংখ্যা কমে যায়। তবে, একই সময়ে আরও বেশি বাফারের অনুরোধ করা হলে, কল করতে আরও বেশি সময় লাগে এবং এটি মোট অনুরোধ-থেকে-ফলাফল লেটেন্সির উপর নেতিবাচক প্রভাব ফেলতে পারে। এছাড়াও, requestStreamBuffers-এ কল ক্যামেরা পরিষেবায় সিরিয়ালাইজ করা হয় বলে, ক্যামেরা HAL-কে বাফার অনুরোধ করার জন্য একটি ডেডিকেটেড হাই-প্রায়োরিটি থ্রেড ব্যবহার করার সাজেশন দেওয়া হয়।

কোনও বাফার অনুরোধ ব্যর্থ হলে, ক্যামেরা HAL-কে অবশ্যই অমারাত্মক সমস্যা সঠিকভাবে ম্যানেজ করতে হবে। নিচের তালিকায়, বাফার অনুরোধ ব্যর্থ হওয়ার সাধারণ কারণ এবং ক্যামেরা HAL-কে সেগুলি কীভাবে ম্যানেজ করতে হবে তা বর্ণনা করা হয়েছে।

  • আউটপুট স্ট্রিম থেকে অ্যাপ ডিসকানেক্ট হয়ে যায়: এটি কোনও মারাত্মক সমস্যা নয়। ডিসকানেক্ট করা স্ট্রিমকে টার্গেট করে যেকোনও ক্যাপচার অনুরোধের জন্য ক্যামেরা HAL-কে ERROR_REQUEST পাঠাতে হবে এবং পরবর্তী অনুরোধগুলি স্বাভাবিকভাবে প্রসেস করার জন্য প্রস্তুত থাকতে হবে।
  • টাইমআউট: কোনও অ্যাপ কিছু বাফার ধরে রেখে ইনটেনসিভ প্রসেসিং করার কাজে ব্যস্ত থাকলে এটি হতে পারে। ক্যামেরা HAL-কে পাঠাতে ERROR_REQUEST হবে। টাইম-আউট সমস্যার কারণে যেসব ক্যাপচার অনুরোধ পূরণ করা যায় না, সেগুলির জন্য এটি করতে হবে এবং পরবর্তী অনুরোধগুলি স্বাভাবিকভাবে প্রসেস করার জন্য রেডি থাকতে হবে।
  • ক্যামেরা ফ্রেমওয়ার্ক নতুন স্ট্রিম কনফিগারেশন তৈরি করছে: ক্যামেরা HAL-কে পরবর্তী configureStreams কল সম্পূর্ণ হওয়া পর্যন্ত অপেক্ষা করতে হবে, তারপরেই requestStreamBuffers আবার কল করা যাবে।
  • ক্যামেরা HAL তার বাফার সীমায় (maxBuffers ফিল্ড) পৌঁছে গেছে: ক্যামেরা HAL-কে অপেক্ষা করতে হবে যতক্ষণ না এটি requestStreamBuffers আবার কল করার আগে স্ট্রিমের অন্তত একটি বাফার ফিরিয়ে দেয়।

returnStreamBuffers

ক্যামেরা ফ্রেমওয়ার্কে অতিরিক্ত বাফার ফেরত দিতে returnStreamBuffers পদ্ধতি ব্যবহার করুন। ক্যামেরা HAL সাধারণত processCaptureResult পদ্ধতির মাধ্যমে ক্যামেরা ফ্রেমওয়ার্কে বাফার ফেরত পাঠায়, তবে এটি শুধুমাত্র ক্যামেরা HAL-এ পাঠানো ক্যাপচার অনুরোধের জন্য অ্যাকাউন্ট করতে পারে। requestStreamBuffers পদ্ধতির মাধ্যমে, ক্যামেরা HAL ইমপ্লিমেন্টেশনের জন্য ক্যামেরা ফ্রেমওয়ার্কের অনুরোধ করা বাফারের চেয়ে বেশি বাফার রিটেন করা সম্ভব। এইসব ক্ষেত্রে returnStreamBuffers পদ্ধতি ব্যবহার করা উচিত। HAL প্রয়োগ যদি কখনও অনুরোধ করা বাফারের চেয়ে বেশি বাফার হোল্ড না করে, তাহলে ক্যামেরা HAL প্রয়োগকে returnStreamBuffers মেথড কল করতে হবে না।

signalStreamFlush

ক্যামেরা HAL-কে হাতে থাকা সব বাফার ফেরত দেওয়ার কথা জানানোর জন্য ক্যামেরা ফ্রেমওয়ার্ক signalStreamFlush পদ্ধতিকে কল করে। ক্যামেরা ফ্রেমওয়ার্ক যখন configureStreams কল করতে চলেছে এবং ক্যামেরা ক্যাপচার পাইপলাইন ড্রেন করতে হবে, তখন সাধারণত এটি কল করা হয়। returnStreamBuffers পদ্ধতির মতো, কোনও ক্যামেরা HAL ইমপ্লিমেন্টেশন যদি অনুরোধ করা বফার থেকে বেশি বফার না ধরে রাখে, তাহলে এই পদ্ধতির একটি খালি ইমপ্লিমেন্টেশন থাকা সম্ভব।

ক্যামেরা ফ্রেমওয়ার্ক signalStreamFlush কল করার পরে, ক্যামেরা ফ্রেমওয়ার্কে সব বাফার ফেরত না দেওয়া পর্যন্ত ফ্রেমওয়ার্ক ক্যামেরা HAL-এ নতুন ক্যাপচার অনুরোধ পাঠানো বন্ধ করে দেয়। সব বাফার ফেরত দেওয়া হলে, requestStreamBuffers মেথড কল ব্যর্থ হয় এবং ক্যামেরা ফ্রেমওয়ার্ক পরিষ্কার অবস্থায় কাজ চালিয়ে যেতে পারে। ক্যামেরা ফ্রেমওয়ার্ক তারপরে configureStreams অথবা processCaptureRequest মেথড কল করে। ক্যামেরা ফ্রেমওয়ার্ক configureStreams মেথড কল করলে, ক্যামেরা HAL configureStreams কল সফলভাবে রিটার্ন করার পরে আবার বাফার অনুরোধ করা শুরু করতে পারে। ক্যামেরা ফ্রেমওয়ার্ক processCaptureRequest মেথড কল করলে, processCaptureRequest কল চলাকালীন ক্যামেরা HAL বাফার অনুরোধ করা শুরু করতে পারে।

signalStreamFlush পদ্ধতি এবং flush পদ্ধতির জন্য শব্দার্থ আলাদা। flush মেথড কল করা হলে, HAL, যত তাড়াতাড়ি সম্ভব পাইপলাইন খালি করার জন্য ERROR_REQUEST ব্যবহার করে বাকি থাকা ক্যাপচার অনুরোধ বাতিল করতে পারে। signalStreamFlush পদ্ধতি কল করা হলে, HAL-কে অবশ্যই সব বাকি থাকা ক্যাপচার অনুরোধ স্বাভাবিকভাবে শেষ করতে হবে এবং ক্যামেরা ফ্রেমওয়ার্কে সব বাফার ফিরিয়ে দিতে হবে।

signalStreamFlush পদ্ধতি ও অন্যান্য পদ্ধতির মধ্যে আরেকটি পার্থক্য হল signalStreamFlush হল একটি একমুখী HIDL পদ্ধতি, যার অর্থ হল HAL signalStreamFlush কল পাওয়ার আগে ক্যামেরা ফ্রেমওয়ার্ক অন্যান্য ব্লকিং API-কে কল করতে পারে। এর অর্থ হল, signalStreamFlush পদ্ধতি এবং অন্যান্য পদ্ধতি (বিশেষ করে configureStreams পদ্ধতি) ক্যামেরা ফ্রেমওয়ার্কে যেভাবে কল করা হয়েছে তার থেকে আলাদা ক্রমে ক্যামেরা HAL-এ পৌঁছাতে পারে। এই অ্যাসিঙ্ক্রোনাস সমস্যা সমাধানের জন্য, streamConfigCounter ফিল্ডকে StreamConfiguration-এ যোগ করা হয়েছে এবং signalStreamFlush মেথডে আর্গুমেন্ট হিসেবে যোগ করা হয়েছে। ক্যামেরা HAL ইমপ্লিমেন্টেশনের ক্ষেত্রে streamConfigCounter আর্গুমেন্ট ব্যবহার করা উচিত যাতে নির্ধারণ করা যায় যে signalStreamFlush কল তার সংশ্লিষ্ট configureStreams কলের পরে আসছে কিনা। উদাহরণ হিসেবে ছবি ৩ দেখুন।

দেরিতে আসা কল হ্যান্ডেল করা

ছবি ৩. ক্যামেরা HAL কীভাবে signalStreamFlush কল শনাক্ত ও ম্যানেজ করবে যা দেরিতে আসে

বাফার ম্যানেজমেন্ট API প্রয়োগ করার সময় আচরণে পরিবর্তন

বাফার ম্যানেজমেন্ট লজিক প্রয়োগ করার জন্য বাফার ম্যানেজমেন্ট API ব্যবহার করার সময়, ক্যামেরা ও ক্যামেরা HAL প্রয়োগ করার ক্ষেত্রে সম্ভাব্য আচরণগত পরিবর্তনগুলি বিবেচনা করুন:

  • ক্যামেরা HAL-এ ক্যাপচার সংক্রান্ত অনুরোধ আরও দ্রুত এবং ঘন ঘন আসে: বাফার ম্যানেজমেন্ট API ছাড়া, ক্যামেরা ফ্রেমওয়ার্ক ক্যামেরা HAL-এ ক্যাপচার সংক্রান্ত অনুরোধ পাঠানোর আগে প্রতিটি ক্যাপচার সংক্রান্ত অনুরোধের জন্য আউটপুট বাফার অনুরোধ করে। বাফার ম্যানেজমেন্ট API ব্যবহার করার সময়, ক্যামেরা ফ্রেমওয়ার্ককে বাফারের জন্য আর অপেক্ষা করতে হয় না এবং তাই এটি ক্যামেরা HAL-এ ক্যাপচার করার অনুরোধ আগে পাঠাতে পারে।

    এছাড়াও, বাফার ম্যানেজমেন্ট API না থাকলে, ক্যামেরা ফ্রেমওয়ার্ক ক্যাপচার অনুরোধ পাঠানো বন্ধ করে দেয়, যদি ক্যাপচার অনুরোধের আউটপুট স্ট্রিমগুলির মধ্যে একটি, HAL একসাথে যতগুলি বাফার হোল্ড করতে পারে তার সর্বাধিক সংখ্যায় পৌঁছে যায় (এই ভ্যালু ক্যামেরা HAL দ্বারা configureStreams কলের রিটার্ন ভ্যালুতে HalStream::maxBuffers ফিল্ডে ডেজিগনেট করা হয়)। বাফার ম্যানেজমেন্ট API-এর মাধ্যমে, এই থ্রটলিং আচরণ আর থাকে না এবং HAL-এ অনেক বেশি ক্যাপচার অনুরোধ কিউতে থাকলে, ক্যামেরা HAL ইমপ্লিমেন্টেশনকে processCaptureRequest কল গ্রহণ করতে হবে না।

  • requestStreamBuffers কল লেটেন্সি উল্লেখযোগ্যভাবে পরিবর্তিত হয়: requestStreamBuffers কল গড় সময়ের চেয়ে বেশি সময় নেওয়ার অনেক কারণ আছে। যেমন:

    • নতুন তৈরি করা স্ট্রিমের প্রথম কয়েকটি বাফারের জন্য, কল করতে বেশি সময় লাগতে পারে কারণ ডিভাইসকে মেমরি অ্যালোকেট করতে হয়।
    • প্রতিটি কলে অনুরোধ করা বাফারের সংখ্যার অনুপাতে প্রত্যাশিত লেটেন্সি বৃদ্ধি পায়।
    • অ্যাপটি বাফার হোল্ড করছে এবং প্রসেসিংয়ে ব্যস্ত আছে। এর ফলে বাফার অনুরোধের গতি কমে যেতে পারে বা বাফারের অভাব অথবা ব্যস্ত CPU-এর কারণে টাইমআউট হতে পারে।

বাফার ম্যানেজমেন্ট স্ট্র্যাটেজি

বাফার ম্যানেজমেন্ট API, বিভিন্ন ধরনের বাফার ম্যানেজমেন্ট স্ট্র্যাটেজি প্রয়োগ করার অনুমতি দেয়। কিছু উদাহরণ হল:

  • ব্যাকওয়ার্ড কম্প্যাটিবল: processCaptureRequest কল চলাকালীন ক্যাপচার অনুরোধের জন্য HAL বাফার অনুরোধ করে। এই স্ট্র্যাটেজি কোনও মেমরি সেভিং প্রদান করে না, তবে এটি বাফার ম্যানেজমেন্ট API-এর প্রথম প্রয়োগ হিসেবে কাজ করতে পারে, যার জন্য বর্তমান ক্যামেরা HAL-এ খুব কম কোড পরিবর্তন করতে হয়।
  • সর্বাধিক মেমরি সাশ্রয়: ক্যামেরা HAL শুধুমাত্র আউটপুট বাফার পূরণ করার ঠিক আগে অনুরোধ করে। এই স্ট্র্যাটেজি সর্বাধিক মেমরি সেভ করার অনুমতি দেয়। সম্ভাব্য অসুবিধা হল, বাফার অনুরোধ সম্পূর্ণ হতে অস্বাভাবিকভাবে বেশি সময় লাগলে, আরও বেশি ক্যামেরা পাইপলাইন জ্যাঙ্ক হতে পারে।
  • ক্যাশে করা: ক্যামেরা HAL কয়েকটি বাফার ক্যাশে করে যাতে মাঝে মাঝে ধীর গতির বাফার অনুরোধের কারণে এটি প্রভাবিত হওয়ার সম্ভাবনা কম থাকে।

ক্যামেরা HAL নির্দিষ্ট ব্যবহারের ক্ষেত্রে বিভিন্ন কৌশল অবলম্বন করতে পারে, যেমন, যেসব ব্যবহারের ক্ষেত্রে প্রচুর মেমরি ব্যবহার করা হয় সেগুলির জন্য সর্বাধিক মেমরি সাশ্রয়ী কৌশল ব্যবহার করা এবং অন্যান্য ব্যবহারের ক্ষেত্রে ব্যাকওয়ার্ড কম্প্যাটিবল কৌশল ব্যবহার করা।

এক্সটার্নাল ক্যামেরা HAL-এ স্যাম্পেল ইমপ্লিমেন্টেশন

এক্সটার্নাল ক্যামেরা HAL, Android 9-এ প্রথম চালু করা হয় এবং এটি hardware/interfaces/camera/device/3.5/-এ সোর্স ট্রিতে খুঁজে পাওয়া যাবে। Android 10-এ, এটি আপডেট করে ExternalCameraDeviceSession.cpp, বাফার ম্যানেজমেন্ট API-এর একটি ইমপ্লিমেন্টেশন অন্তর্ভুক্ত করা হয়েছে। এই এক্সটার্নাল ক্যামেরা HAL বাফার ম্যানেজমেন্ট কৌশল-এ উল্লেখ করা সর্বাধিক মেমরি সেভিং কৌশলটি কয়েকশো লাইনের C++ কোডে প্রয়োগ করে।