SurfaceTexture হল একটি পৃষ্ঠ এবং একটি OpenGL ES (GLES) টেক্সচারের সংমিশ্রণ। SurfaceTexture ইনস্ট্যান্সগুলি GLES টেক্সচারে আউটপুট প্রদানের জন্য ব্যবহৃত হয়।
SurfaceTexture BufferQueue এর একটি উদাহরণ রয়েছে যার জন্য অ্যাপগুলি গ্রাহক। onFrameAvailable() কলব্যাক অ্যাপগুলিকে সূচিত করে যখন প্রযোজক একটি নতুন বাফার সারিবদ্ধ করে। তারপর, অ্যাপগুলি updateTexImage() কল করে, যা পূর্বে ধরে রাখা বাফারটি প্রকাশ করে, সারি থেকে নতুন বাফারটি অর্জন করে এবং GLES-এর কাছে একটি বহিরাগত টেক্সচার হিসাবে বাফারটি উপলব্ধ করার জন্য EGL কল করে।
বাহ্যিক GLES টেক্সচার
বাহ্যিক GLES টেক্সচার ( GL_TEXTURE_EXTERNAL_OES ) নিম্নলিখিত উপায়ে স্ট্যান্ডার্ড GLES টেক্সচার ( GL_TEXTURE_2D ) থেকে আলাদা:
- বাহ্যিক টেক্সচারগুলি
BufferQueueথেকে প্রাপ্ত ডেটা থেকে সরাসরি টেক্সচার্ড বহুভুজ রেন্ডার করে। - বাহ্যিক টেক্সচার রেন্ডারারগুলি স্ট্যান্ডার্ড GLES টেক্সচার রেন্ডারারের চেয়ে আলাদাভাবে কনফিগার করা হয়।
- বাহ্যিক টেক্সচারগুলি সমস্ত স্ট্যান্ডার্ড GLES টেক্সচার কার্যকলাপ সম্পাদন করতে পারে না।
বাহ্যিক টেক্সচারের প্রধান সুবিধা হল BufferQueue ডেটা থেকে সরাসরি রেন্ডার করার ক্ষমতা। SurfaceTexture ইনস্ট্যান্সগুলি যখন বাহ্যিক টেক্সচারের জন্য BufferQueue ইনস্ট্যান্স তৈরি করে তখন গ্রাহক ব্যবহারের পতাকাগুলিকে GRALLOC_USAGE_HW_TEXTURE এ সেট করে যাতে বাফারের ডেটা GLES দ্বারা স্বীকৃত হয় কিনা তা যাচাই করা যায়।
যেহেতু SurfaceTexture ইনস্ট্যান্সগুলি একটি EGL কনটেক্সটের সাথে ইন্টারঅ্যাক্ট করে, তাই একটি অ্যাপ কেবল তখনই তার পদ্ধতিগুলিকে কল করতে পারে যখন টেক্সচারের মালিক EGL কনটেক্সটটি কলিং থ্রেডে বর্তমান থাকে। আরও তথ্যের জন্য, SurfaceTexture ক্লাস ডকুমেন্টেশন দেখুন।
টাইমস্ট্যাম্প এবং রূপান্তর
SurfaceTexture ইনস্ট্যান্সের মধ্যে রয়েছে getTimeStamp() পদ্ধতি, যা একটি টাইমস্ট্যাম্প পুনরুদ্ধার করে এবং getTransformMatrix() পদ্ধতি, যা একটি ট্রান্সফর্মেশন ম্যাট্রিক্স পুনরুদ্ধার করে। updateTexImage() কল করলে টাইমস্ট্যাম্প এবং ট্রান্সফর্মেশন ম্যাট্রিক্স উভয়ই সেট হয়। BufferQueue যে প্রতিটি বাফার পাস করে তাতে ট্রান্সফর্মেশন প্যারামিটার এবং একটি টাইমস্ট্যাম্প থাকে।
দক্ষতার জন্য রূপান্তর প্যারামিটারগুলি কার্যকর। কিছু ক্ষেত্রে, উৎস ডেটা গ্রাহকের জন্য ভুল ওরিয়েন্টেশনে থাকতে পারে। গ্রাহকের কাছে ডেটা পাঠানোর আগে এটি ঘোরানোর পরিবর্তে, ডেটাটিকে তার ওরিয়েন্টেশনে এমন একটি ট্রান্সফর্ম দিয়ে পাঠান যা এটিকে সংশোধন করে। ডেটা ব্যবহার করার সময় ট্রান্সফর্মেশন ম্যাট্রিক্সকে অন্যান্য ট্রান্সফর্মেশনের সাথে একত্রিত করা যেতে পারে, যার ফলে ওভারহেড কম হয়।
টাইমস্ট্যাম্পটি সময় নির্ভর বাফার সোর্সগুলির জন্য কার্যকর। উদাহরণস্বরূপ, যখন setPreviewTexture() ক্যামেরার আউটপুটের সাথে প্রডিউসার ইন্টারফেস সংযুক্ত করে, তখন ক্যামেরার ফ্রেমগুলি একটি ভিডিও তৈরি করতে ব্যবহার করা যেতে পারে। প্রতিটি ফ্রেমে ফ্রেমটি ক্যাপচার করার সময় থেকে একটি উপস্থাপনা টাইমস্ট্যাম্প থাকা প্রয়োজন, অ্যাপটি ফ্রেমটি কখন পেয়েছে তা থেকে নয়। ক্যামেরা কোডটি বাফারের সাথে প্রদত্ত টাইমস্ট্যাম্প সেট করে, যার ফলে টাইমস্ট্যাম্পগুলির একটি আরও সামঞ্জস্যপূর্ণ সিরিজ তৈরি হয়।
কেস স্টাডি: গ্রাফিকার ক্রমাগত ক্যাপচার
গ্রাফিকার ক্রমাগত ক্যাপচারের মধ্যে রয়েছে একটি ডিভাইসের ক্যামেরা থেকে ফ্রেম রেকর্ড করা এবং সেই ফ্রেমগুলিকে স্ক্রিনে প্রদর্শন করা। ফ্রেম রেকর্ড করার জন্য, MediaCodec ক্লাসের createInputSurface() পদ্ধতি ব্যবহার করে একটি সারফেস তৈরি করুন এবং সারফেসটি ক্যামেরায় প্রেরণ করুন। ফ্রেম প্রদর্শনের জন্য, SurfaceView এর একটি ইনস্ট্যান্স তৈরি করুন এবং সারফেসটি setPreviewDisplay() এ প্রেরণ করুন। মনে রাখবেন যে ফ্রেম রেকর্ড করা এবং একই সাথে প্রদর্শন করা একটি আরও জটিল প্রক্রিয়া।
ভিডিও রেকর্ড করার সময় ক্যামেরা থেকে ক্রমাগত ক্যাপচার অ্যাক্টিভিটি ভিডিও প্রদর্শন করে। এই ক্ষেত্রে, এনকোডেড ভিডিও মেমরির একটি বৃত্তাকার বাফারে লেখা হয় যা যেকোনো সময় ডিস্কে সংরক্ষণ করা যেতে পারে।
এই প্রবাহে তিনটি বাফার সারি জড়িত:
-
App— অ্যাপটি ক্যামেরা থেকে ফ্রেম গ্রহণ করার জন্য একটিSurfaceTextureইনস্ট্যান্স ব্যবহার করে, সেগুলিকে একটি বহিরাগত GLES টেক্সচারে রূপান্তর করে। -
SurfaceFlinger— ফ্রেমগুলি প্রদর্শনের জন্য অ্যাপটি একটিSurfaceViewইনস্ট্যান্স ঘোষণা করে। -
MediaServer— ভিডিও তৈরির জন্য একটি ইনপুট সারফেস সহ একটিMediaCodecএনকোডার কনফিগার করুন।
নিচের চিত্রে, তীরগুলি ক্যামেরা থেকে ডেটা প্রচার নির্দেশ করে। BufferQueue উদাহরণগুলি দেখানো হয়েছে, যেখানে চাক্ষুষ নির্দেশকগুলি উৎপাদক (টিল) এবং ভোক্তা (সবুজ) এর মধ্যে পার্থক্য করে।

চিত্র ১. গ্রাফিকার ক্রমাগত ক্যাপচার কার্যকলাপ
অ্যাপ প্রক্রিয়ায় এনকোডেড H.264 ভিডিওটি RAM-এর একটি বৃত্তাকার বাফারে যায়। যখন একজন ব্যবহারকারী ক্যাপচার বোতাম টিপে, তখন MediaMuxer ক্লাস এনকোডেড ভিডিওটি ডিস্কের একটি MP4 ফাইলে লিখে।
সমস্ত BufferQueue ইনস্ট্যান্স অ্যাপে একটি একক EGL প্রেক্ষাপট ব্যবহার করে পরিচালনা করা হয়, যখন GLES অপারেশনগুলি UI থ্রেডে সম্পাদিত হয়। এনকোডেড ডেটা পরিচালনা (একটি বৃত্তাকার বাফার পরিচালনা এবং ডিস্কে লেখা) একটি পৃথক থ্রেডে করা হয়।
SurfaceView ক্লাস ব্যবহার করার সময়, surfaceCreated() কলব্যাক ডিসপ্লে এবং ভিডিও এনকোডারের জন্য EGLContext এবং EGLSurface ইনস্ট্যান্স তৈরি করে। যখন একটি নতুন ফ্রেম আসে, SurfaceTexture চারটি কার্যকলাপ সম্পাদন করে:
- ফ্রেমটি অর্জন করে।
- ফ্রেমটিকে GLES টেক্সচার হিসেবে উপলব্ধ করে।
- GLES কমান্ড ব্যবহার করে ফ্রেম রেন্ডার করে।
-
EGLSurfaceএর প্রতিটি উদাহরণের জন্য রূপান্তর এবং টাইমস্ট্যাম্প ফরোয়ার্ড করে।
এরপর এনকোডার থ্রেডটি MediaCodec থেকে এনকোডেড আউটপুট টেনে মেমোরিতে সংরক্ষণ করে।
নিরাপদ টেক্সচার ভিডিও প্লেব্যাক
অ্যান্ড্রয়েড সুরক্ষিত ভিডিও কন্টেন্টের GPU পোস্ট-প্রসেসিং সমর্থন করে। এটি অ্যাপগুলিকে জটিল, নন-লিনিয়ার ভিডিও ইফেক্ট (যেমন ওয়ার্পস), সাধারণ গ্রাফিক্স দৃশ্যে ব্যবহারের জন্য টেক্সচারে সুরক্ষিত ভিডিও কন্টেন্ট ম্যাপ করার জন্য GPU ব্যবহার করতে দেয় (উদাহরণস্বরূপ, GLES ব্যবহার করে), এবং ভার্চুয়াল রিয়েলিটি (VR)।

চিত্র ২. সুরক্ষিত টেক্সচার ভিডিও প্লেব্যাক
নিম্নলিখিত দুটি এক্সটেনশন ব্যবহার করে সমর্থন সক্রিয় করা হয়েছে:
- EGL এক্সটেনশন — (
EGL_EXT_protected_content) সুরক্ষিত GL প্রসঙ্গ এবং পৃষ্ঠতল তৈরি করতে সক্ষম করে, যা সুরক্ষিত সামগ্রী উভয়ের উপরই কাজ করতে পারে। - GLES এক্সটেনশন — (
GL_EXT_protected_textures) টেক্সচারগুলিকে সুরক্ষিত হিসেবে ট্যাগ করা সক্ষম করে যাতে সেগুলিকে ফ্রেমবাফার টেক্সচার সংযুক্তি হিসেবে ব্যবহার করা যায়।
অ্যান্ড্রয়েড SurfaceTexture এবং ACodec ( libstagefright.so ) কে সুরক্ষিত কন্টেন্ট পাঠাতে সক্ষম করে, এমনকি যদি উইন্ডোর পৃষ্ঠটি SurfaceFlinger এ সারিবদ্ধ না হয় এবং একটি সুরক্ষিত প্রেক্ষাপটের মধ্যে ব্যবহারের জন্য একটি সুরক্ষিত ভিডিও পৃষ্ঠ সরবরাহ করে। এটি একটি সুরক্ষিত প্রেক্ষাপটে তৈরি পৃষ্ঠগুলিতে (ACodec দ্বারা যাচাইকৃত) সুরক্ষিত গ্রাহক বিট ( GRALLOC_USAGE_PROTECTED ) সেট করে করা হয়।
নিরাপদ টেক্সচার ভিডিও প্লেব্যাক OpenGL ES পরিবেশে শক্তিশালী ডিজিটাল রাইটস ম্যানেজমেন্ট (DRM) বাস্তবায়নের ভিত্তি স্থাপন করে। Widevine Level 1 এর মতো শক্তিশালী DRM বাস্তবায়ন ছাড়া, অনেক কন্টেন্ট প্রদানকারী OpenGL ES পরিবেশে তাদের উচ্চ-মূল্যের কন্টেন্ট রেন্ডার করার অনুমতি দেয় না, যার ফলে VR-তে DRM-সুরক্ষিত কন্টেন্ট দেখার মতো গুরুত্বপূর্ণ VR ব্যবহারের ক্ষেত্রে বাধা সৃষ্টি হয়।
অ্যান্ড্রয়েড ওপেন সোর্স প্রজেক্ট (AOSP) নিরাপদ টেক্সচার ভিডিও প্লেব্যাকের জন্য ফ্রেমওয়ার্ক কোড অন্তর্ভুক্ত করে। ড্রাইভার সাপোর্ট OEM-এর উপর নির্ভর করে। ডিভাইস ইমপ্লিমেন্টারদের অবশ্যই EGL_EXT_protected_content এবং GL_EXT_protected_textures এক্সটেনশন বাস্তবায়ন করতে হবে। আপনার নিজস্ব কোডেক লাইব্রেরি ব্যবহার করার সময় ( libstagefright প্রতিস্থাপন করতে), /frameworks/av/media/libstagefright/SurfaceUtils.cpp এর পরিবর্তনগুলি লক্ষ্য করুন যা GRALLOC_USAGE_PROTECTED চিহ্নিত বাফারগুলিকে ANativeWindow এ পাঠানোর অনুমতি দেয় (যদিও ANativeWindow সরাসরি উইন্ডো কম্পোজারের সাথে সারিবদ্ধ না হয়) যতক্ষণ না গ্রাহক ব্যবহারের বিটগুলিতে GRALLOC_USAGE_PROTECTED থাকে। এক্সটেনশনগুলি বাস্তবায়নের বিস্তারিত ডকুমেন্টেশনের জন্য, Khronos রেজিস্ট্রিগুলি ( EGL_EXT_protected_content ) এবং ( GL_EXT_protected_textures ) দেখুন।