SurfaceTexture

SurfaceTexture হল সারফেস ও OpenGL ES (GLES) টেক্সচারের কম্বিনেশন। GLES টেক্সচারে আউটপুট প্রদান করে এমন সারফেস প্রদান করতে SurfaceTexture ইনস্ট্যান্স ব্যবহার করা হয়।

SurfaceTexture-এ BufferQueue-এর একটি ইনস্ট্যান্স আছে যার জন্য অ্যাপগুলি গ্রাহক। প্রোডিউসার নতুন বাফার সারিবদ্ধ করলে onFrameAvailable() কলব্যাক অ্যাপকে বিজ্ঞপ্তি দেয়। তারপরে, অ্যাপ updateTexImage()-কে কল করে, যা আগে হোল্ড করা বাফার রিলিজ করে, কিউ থেকে নতুন বাফার অ্যাকোয়ার করে এবং EGL কল করে GLES-এর জন্য বাফারকে এক্সটার্নাল টেক্সচার হিসেবে উপলভ্য করে তোলে।

এক্সটার্নাল GLES টেক্সচার

এক্সটার্নাল GLES টেক্সচার (GL_TEXTURE_EXTERNAL_OES) নিম্নলিখিত উপায়ে স্ট্যান্ডার্ড GLES টেক্সচার (GL_TEXTURE_2D) থেকে আলাদা:

  • BufferQueue থেকে পাওয়া ডেটা থেকে এক্সটার্নাল টেক্সচার সরাসরি টেক্সচারযুক্ত বহুভুজ রেন্ডার করে।
  • এক্সটার্নাল টেক্সচার রেন্ডারার স্ট্যান্ডার্ড GLES টেক্সচার রেন্ডারারের থেকে আলাদাভাবে কনফিগার করা হয়।
  • এক্সটার্নাল টেক্সচার সব স্ট্যান্ডার্ড GLES টেক্সচার অ্যাক্টিভিটি পারফর্ম করতে পারে না।

এক্সটার্নাল টেক্সচারের প্রধান সুবিধা হল, এটি BufferQueue ডেটা থেকে সরাসরি রেন্ডার করতে পারে। SurfaceTexture ইনস্ট্যান্স, GRALLOC_USAGE_HW_TEXTURE-এ কনজিউমার ব্যবহারের ফ্ল্যাগ সেট করে, যখন এটি এক্সটার্নাল টেক্সচারের জন্য BufferQueue ইনস্ট্যান্স তৈরি করে, যাতে যাচাই করা যায় যে বাফারের ডেটা GLES-এর মাধ্যমে শনাক্ত করা যায়।

যেহেতু SurfaceTexture ইনস্ট্যান্স EGL কনটেক্সটের সাথে ইন্টার‍্যাক্ট করে, তাই কোনও অ্যাপ শুধুমাত্র তখনই এর মেথড কল করতে পারে যখন টেক্সচারের মালিকানা থাকা EGL কনটেক্সট কলিং থ্রেডে বর্তমান থাকে। আরও তথ্যের জন্য, SurfaceTexture ক্লাস ডকুমেন্টেশন দেখুন।

টাইমস্ট্যাম্প ও ট্রান্সফর্মেশন

SurfaceTexture ইনস্ট্যান্সের মধ্যে getTimeStamp() মেথড অন্তর্ভুক্ত, যা টাইমস্ট্যাম্প এবং getTransformMatrix() মেথড পুনরুদ্ধার করে, যা ট্রান্সফর্মেশন ম্যাট্রিক্স পুনরুদ্ধার করে। কলিং updateTexImage() টাইমস্ট্যাম্প ও ট্রান্সফরমেশন ম্যাট্রিক্স, দুটিই সেট করে। BufferQueue-এর পাস করা প্রতিটি বাফারে ট্রান্সফর্মেশন প্যারামিটার এবং টাইমস্ট্যাম্প অন্তর্ভুক্ত থাকে।

দক্ষতার জন্য ট্রান্সফর্মেশন প্যারামিটার সহায়ক। কিছু ক্ষেত্রে, সোর্স ডেটা গ্রাহকের জন্য ভুল ওরিয়েন্টেশনে থাকতে পারে। গ্রাহকের কাছে পাঠানোর আগে ডেটা রোটেট করার পরিবর্তে, ডেটা তার ওরিয়েন্টেশনে পাঠান, সাথে একটি ট্রান্সফর্ম পাঠান যা এটিকে ঠিক করে। ডেটা ব্যবহার করার সময় ট্রান্সফর্মেশন ম্যাট্রিক্স অন্যান্য ট্রান্সফর্মেশনের সাথে মার্জ করা যেতে পারে, যা ওভারহেড কম করে।

টাইমস্ট্যাম্প, সময় নির্ভর বাফার সোর্সের জন্য উপযোগী। যেমন, setPreviewTexture() যখন ক্যামেরা আউটপুটের সাথে প্রডিউসার ইন্টারফেস কানেক্ট করে, তখন ক্যামেরার ফ্রেম ব্যবহার করে ভিডিও তৈরি করা যায়। প্রতিটি ফ্রেমে প্রেজেন্টেশন টাইমস্ট্যাম্প থাকতে হবে, যা ফ্রেমটি ক্যাপচার করার সময় থেকে শুরু হয়, অ্যাপটি ফ্রেমটি পাওয়ার সময় থেকে নয়। ক্যামেরা কোড বাফারের সাথে দেওয়া টাইমস্ট্যাম্প সেট করে, এর ফলে টাইমস্ট্যাম্পের আরও সামঞ্জস্যপূর্ণ সিরিজ তৈরি হয়।

কেস স্টাডি: Grafika-র নিরবচ্ছিন্ন ক্যাপচার

Grafika-এর একটানা ক্যাপচার-এর মধ্যে ডিভাইসের ক্যামেরা থেকে ফ্রেম রেকর্ড করা এবং স্ক্রিনে সেইসব ফ্রেম দেখানো অন্তর্ভুক্ত। ফ্রেম রেকর্ড করতে, MediaCodec ক্লাসের createInputSurface() মেথড ব্যবহার করে একটি সারফেস তৈরি করুন এবং সারফেসটি ক্যামেরায় পাস করুন। ফ্রেম দেখাতে, SurfaceView-এর একটি ইনস্ট্যান্স তৈরি করুন এবং setPreviewDisplay()-এ সারফেস পাস করুন। মনে রাখবেন, ফ্রেম রেকর্ড করা এবং একই সাথে সেগুলি দেখানো একটি আরও জটিল প্রসেস।

অবিচ্ছিন্ন ক্যাপচার অ্যাক্টিভিটি, ক্যামেরা থেকে ভিডিও দেখায় কারণ ভিডিও রেকর্ড করা হচ্ছে। এই ক্ষেত্রে, এনকোড করা ভিডিও মেমরিতে একটি বৃত্তাকার বাফারে লেখা হয় যা যেকোনও সময় ডিস্কে সেভ করা যেতে পারে।

এই ফ্লোতে তিনটি বাফার কিউ থাকে:

  • App — অ্যাপটি ক্যামেরা থেকে ফ্রেম রিসিভ করার জন্য SurfaceTexture ইনস্ট্যান্স ব্যবহার করে, সেগুলিকে এক্সটার্নাল GLES টেক্সচারে কনভার্ট করে।
  • SurfaceFlinger — ফ্রেম দেখানোর জন্য অ্যাপ একটি SurfaceView ইনস্ট্যান্স ঘোষণা করে।
  • MediaServer — ভিডিও তৈরি করার জন্য ইনপুট সারফেস সহ MediaCodec এনকোডার কনফিগার করুন।

নিচের ছবিতে, তীরচিহ্নগুলি ক্যামেরা থেকে ডেটা প্রোপাগেশন নির্দেশ করে। BufferQueue ইনস্ট্যান্স দেখানো হয়, যেখানে প্রযোজকদের (টিয়াল) থেকে গ্রাহকদের (সবুজ) আলাদা করার জন্য ভিজ্যুয়াল ইন্ডিকেটর ব্যবহার করা হয়।

Grafika continuous
ক্যাপচার অ্যাক্টিভিটি

ছবি ১. Grafika-র অবিরাম ক্যাপচার অ্যাক্টিভিটি

এনকোড করা H.264 ভিডিও অ্যাপ প্রসেসে RAM-এর সার্কুলার বাফারে যায়। ব্যবহারকারী ক্যাপচার বোতামে প্রেস করলে, MediaMuxer class ডিস্কে MP4 ফাইলে এনকোড করা ভিডিও লেখে।

অ্যাপে একটিমাত্র EGL কনটেক্সট দিয়ে সব BufferQueue ইনস্ট্যান্স ম্যানেজ করা হয় এবং UI থ্রেডে GLES অপারেশন করা হয়। এনকোড করা ডেটা ম্যানেজ করার (সার্কুলার বাফার ম্যানেজ করা এবং ডিস্কে লেখা) কাজটি আলাদা থ্রেডে করা হয়।

SurfaceView ক্লাস ব্যবহার করার সময়, surfaceCreated() কলব্যাক ডিসপ্লে ও ভিডিও এনকোডারের জন্য EGLContext ও EGLSurface ইনস্ট্যান্স তৈরি করে। নতুন ফ্রেম এলে, SurfaceTexture চারটি অ্যাক্টিভিটি করে:

  1. ফ্রেমটি অ্যাকোয়ার করে।
  2. GLES টেক্সচার হিসেবে ফ্রেম উপলভ্য করে।
  3. GLES কমান্ডের মাধ্যমে ফ্রেম রেন্ডার করে।
  4. EGLSurface-এর প্রতিটি ইনস্ট্যান্সের জন্য ট্রান্সফর্ম ও টাইমস্ট্যাম্প ফরওয়ার্ড করে।

এনকোডার থ্রেডটি MediaCodec থেকে এনকোড করা আউটপুটটি নেয় এবং মেমরিতে সেভ করে।

নিরাপদ টেক্সচার ভিডিও প্লেব্যাক

সুরক্ষিত ভিডিও কন্টেন্টের GPU পোস্ট-প্রসেসিং Android-এ কাজ করে। এর ফলে, অ্যাপগুলি জটিল, নন-লিনিয়ার ভিডিও এফেক্টের (যেমন, ওয়ার্প) জন্য GPU ব্যবহার করতে পারে, সাধারণ গ্রাফিক্স দৃশ্যে ব্যবহারের জন্য টেক্সচারে সুরক্ষিত ভিডিও কন্টেন্ট ম্যাপ করতে পারে (যেমন, GLES ব্যবহার করা) এবং ভার্চুয়াল রিয়ালিটি (VR) ব্যবহার করতে পারে।

নিরাপদ টেক্সচার ভিডিও প্লেব্যাক

ছবি ২. নিরাপদ টেক্সচার ভিডিও প্লেব্যাক

নিম্নলিখিত দুটি এক্সটেনশন ব্যবহার করে সহায়তা চালু করা হয়েছে:

  • EGL এক্সটেনশন — (EGL_EXT_protected_content) সুরক্ষিত GL কনটেক্সট ও সারফেস তৈরি করার সুবিধা চালু করে, যা দু'টিই সুরক্ষিত কন্টেন্টে কাজ করতে পারে।
  • GLES এক্সটেনশন — (GL_EXT_protected_textures) প্রটেক্টেড হিসেবে টেক্সচার ট্যাগ করার সুবিধা চালু করে যাতে সেগুলি ফ্রেমবাফার টেক্সচার অ্যাটাচমেন্ট হিসেবে ব্যবহার করা যায়।

উইন্ডোর সারফেস SurfaceFlinger-এ না থাকলেও, Android SurfaceTexture এবং ACodec (libstagefright.so) সুরক্ষিত কন্টেন্ট পাঠাতে পারে এবং সুরক্ষিত কন্টেক্সটের মধ্যে ব্যবহারের জন্য একটি সুরক্ষিত ভিডিও সারফেস প্রদান করে। সুরক্ষিত কনটেক্সটে (ACodec দ্বারা যাচাই করা) তৈরি করা সারফেসে সুরক্ষিত কনজিউমার বিট (GRALLOC_USAGE_PROTECTED) সেট করে এটি করা হয়।

নিরাপদ টেক্সচার ভিডিও প্লেব্যাক OpenGL ES এনভায়রনমেন্টে শক্তিশালী ডিজিটাল রাইটস ম্যানেজমেন্ট (DRM) প্রয়োগের ভিত্তি স্থাপন করে। Widevine লেভেল ১-এর মতো শক্তিশালী DRM প্রয়োগ না করা হলে, অনেক কন্টেন্ট প্রদানকারী OpenGL ES এনভায়রনমেন্টে তাদের উচ্চ-মূল্যের কন্টেন্ট রেন্ডার করার অনুমতি দেয় না, এর ফলে VR-এ DRM-সুরক্ষিত কন্টেন্ট দেখার মতো গুরুত্বপূর্ণ VR ব্যবহারের ক্ষেত্রে বাধা সৃষ্টি হয়।

Android ওপেন সোর্স প্রজেক্টে (AOSP) সুরক্ষিত টেক্সচার ভিডিও প্লেব্যাকের জন্য ফ্রেমওয়ার্ক কোড অন্তর্ভুক্ত থাকে। ড্রাইভার সংক্রান্ত সহায়তা OEM-এর উপর নির্ভর করে। ডিভাইস ইমপ্লিমেন্টারদের অবশ্যই EGL_EXT_protected_content এবং GL_EXT_protected_textures এক্সটেনশন প্রয়োগ করতে হবে। আপনার নিজস্ব কোডেক লাইব্রেরি (libstagefright-এর পরিবর্তে) ব্যবহার করার সময়, /frameworks/av/media/libstagefright/SurfaceUtils.cpp-এ হওয়া পরিবর্তনগুলি /frameworks/av/media/libstagefright/SurfaceUtils.cpp লক্ষ্য করুন যেগুলি GRALLOC_USAGE_PROTECTED চিহ্নিত করা বাফারকে ANativeWindow-এ পাঠানোর ANativeWindow অনুমতি দেয় (এমনকি ANativeWindow সরাসরি উইন্ডো কম্পোজারে কিউ না করলেও) যতক্ষণ না কনজিউমার ব্যবহারের বিট GRALLOC_USAGE_PROTECTED ধারণ করে। এক্সটেনশন প্রয়োগ করার বিষয়ে বিস্তারিত ডকুমেন্টেশনের জন্য, Khronos রেজিস্ট্রি ( EGL_EXT_protected_content) ও ( GL_EXT_protected_textures) দেখুন।