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

অ্যান্ড্রয়েড ১০-এ ঐচ্ছিক ক্যামেরা HAL3 বাফার ম্যানেজমেন্ট এপিআই চালু করা হয়েছে, যা আপনাকে ক্যামেরা HAL বাস্তবায়নে বিভিন্ন মেমরি ও ক্যাপচার ল্যাটেন্সির মধ্যে ভারসাম্য অর্জনের জন্য বাফার ম্যানেজমেন্ট লজিক প্রয়োগ করার সুযোগ দেয়।

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

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

চিত্র ১-এ অ্যান্ড্রয়েড ৯ এবং এর পূর্ববর্তী সংস্করণ চালিত ডিভাইসগুলোর ক্যামেরা HAL ইন্টারফেসের একটি ডায়াগ্রাম দেখানো হয়েছে। চিত্র ২-এ অ্যান্ড্রয়েড ১০-এর ক্যামেরা HAL ইন্টারফেসটি দেখানো হয়েছে, যেখানে ক্যামেরা HAL3 বাফার ম্যানেজমেন্ট API-গুলো বাস্তবায়ন করা হয়েছে।

৯ বা তার কম বাফার ব্যবস্থাপনা

চিত্র ১. অ্যান্ড্রয়েড ৯ এবং এর পূর্ববর্তী সংস্করণগুলিতে ক্যামেরা এইচএএল ইন্টারফেস

অ্যান্ড্রয়েড ১০-এ বাফার ব্যবস্থাপনা

চিত্র ২. বাফার ম্যানেজমেন্ট এপিআই ব্যবহার করে অ্যান্ড্রয়েড ১০-এর ক্যামেরা এইচএএল ইন্টারফেস

বাফার ম্যানেজমেন্ট এপিআইগুলো বাস্তবায়ন করুন

বাফার ম্যানেজমেন্ট এপিআইগুলো বাস্তবায়ন করতে, ক্যামেরা HAL-কে অবশ্যই:

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

অনুরোধ স্ট্রিম বাফার

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

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

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

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

রিটার্নস্ট্রিমবাফার

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

সিগন্যালস্ট্রিমফ্লাশ

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

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

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

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

দেরিতে আসা কলগুলি পরিচালনা করা

চিত্র ৩. দেরিতে আসা signalStreamFlush কলগুলো ক্যামেরা HAL কীভাবে শনাক্ত ও পরিচালনা করবে

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

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

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

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

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

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

বাফার ব্যবস্থাপনা কৌশল

বাফার ম্যানেজমেন্ট এপিআইগুলো বিভিন্ন ধরনের বাফার ম্যানেজমেন্ট কৌশল বাস্তবায়নের সুযোগ দেয়। এর কয়েকটি উদাহরণ হলো:

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

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

বাহ্যিক ক্যামেরা HAL-এ নমুনা বাস্তবায়ন

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