টেক্সচারভিউ,টেক্সচারভিউ,টেক্সচারভিউ,টেক্সচারভিউ

TextureView ক্লাসটি একটি ভিউ অবজেক্ট যা একটি ভিউ এবং একটি SurfaceTexture-কে একত্রিত করে।

OpenGL ES দিয়ে রেন্ডার করুন

একটি TextureView অবজেক্ট একটি SurfaceTexture-কে আবৃত করে রাখে, যা কলব্যাকে সাড়া দেয় এবং নতুন বাফার সংগ্রহ করে। যখন একটি TextureView অবজেক্ট নতুন বাফার সংগ্রহ করে, তখন TextureView একটি ভিউ ইনভ্যালিডেট অনুরোধ জারি করে এবং সর্বাধুনিক বাফারের বিষয়বস্তুকে তার ডেটা সোর্স হিসেবে ব্যবহার করে অঙ্কন করে; এবং ভিউ স্টেট যেভাবে ও যেখানে রেন্ডার করার নির্দেশ দেয়, সেভাবেই তা সম্পন্ন হয়।

OpenGL ES (GLES) একটি TextureView অবজেক্টে রেন্ডার করতে পারে EGL ক্রিয়েশন কলে SurfaceTexture পাস করার মাধ্যমে, কিন্তু এটি একটি সমস্যা তৈরি করে। যখন GLES একটি TextureView তে রেন্ডার করে, তখন BufferQueue-এর প্রডিউসার এবং কনজিউমাররা একই থ্রেডে থাকে, যার ফলে বাফার সোয়াপ কলটি আটকে যেতে বা ব্যর্থ হতে পারে। উদাহরণস্বরূপ, যদি কোনো প্রডিউসার UI থ্রেড থেকে দ্রুত পরপর কয়েকটি বাফার সাবমিট করে, তাহলে EGL বাফার সোয়াপ কলটির BufferQueue থেকে একটি বাফার ডি-কিউ করার প্রয়োজন হয়। কিন্তু, যেহেতু কনজিউমার এবং প্রডিউসার একই থ্রেডে থাকে, তাই কোনো বাফার উপলব্ধ থাকে না এবং সোয়াপ কলটি আটকে যায় বা ব্যর্থ হয়।

বাফার সোয়াপ স্টল প্রতিরোধ করার জন্য, বাফারকিউ-তে ডিকিউ করার জন্য সর্বদা একটি বাফার উপলব্ধ থাকা প্রয়োজন। এটি করার জন্য, যখন একটি নতুন বাফার কিউ-তে যুক্ত করা হয়, তখন বাফারকিউ পূর্বে অধিগ্রহণ করা বাফারের বিষয়বস্তু বাতিল করে দেয়। এটি সর্বনিম্ন এবং সর্বোচ্চ বাফার সংখ্যার উপরও সীমাবদ্ধতা আরোপ করে, যাতে কোনো কনজিউমার একবারে সমস্ত বাফার ব্যবহার করতে না পারে।

সারফেসভিউ অথবা টেক্সচারভিউ বেছে নিন

SurfaceView এবং TextureView একই ধরনের ভূমিকা পালন করে এবং উভয়ই ভিউ হায়ারার্কির অংশ। তবে, SurfaceView এবং TextureView বাস্তবায়ন ভিন্ন। একটি SurfaceView অবজেক্ট অন্যান্য ভিউয়ের মতোই প্যারামিটার গ্রহণ করে, কিন্তু রেন্ডার করার সময় SurfaceView বিষয়বস্তু স্বচ্ছ থাকে।

SurfaceView চেয়ে TextureView আলফা এবং রোটেশন হ্যান্ডলিং ভালো, কিন্তু ভিডিওর উপর লেয়ার করা UI এলিমেন্ট কম্পোজিট করার ক্ষেত্রে SurfaceView পারফরম্যান্সগত সুবিধা রয়েছে। যখন কোনো ক্লায়েন্ট একটি SurfaceView অবজেক্ট দিয়ে রেন্ডার করে, তখন SurfaceView ক্লায়েন্টকে একটি আলাদা কম্পোজিশন লেয়ার প্রদান করে। ডিভাইসটি সমর্থিত হলে SurfaceFlinger সেই আলাদা লেয়ারটিকে একটি হার্ডওয়্যার ওভারলে হিসেবে কম্পোজ করে। যখন কোনো ক্লায়েন্ট TextureView দিয়ে রেন্ডার করে, তখন UI টুলকিট GPU-এর সাহায্যে TextureView অবজেক্টের কন্টেন্টকে ভিউ হায়ারার্কিতে কম্পোজিট করে। কন্টেন্টের আপডেটের কারণে অন্যান্য ভিউ এলিমেন্টগুলো পুনরায় আঁকা হতে পারে, উদাহরণস্বরূপ, যদি অন্য ভিউগুলো TextureView এর উপরে অবস্থান করে। ভিউ রেন্ডারিং সম্পন্ন হওয়ার পর, SurfaceFlinger অ্যাপের UI লেয়ার এবং অন্য সব লেয়ারকে কম্পোজিট করে, যাতে প্রতিটি দৃশ্যমান পিক্সেল দুইবার কম্পোজিট হয়।

কেস স্টাডি: গ্রাফিকার প্লে ভিডিও

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

SurfaceView স্কেল করতে FrameLayout-এর একটি কাস্টম ইমপ্লিমেন্টেশন প্রয়োজন। WindowManager-কে SurfaceFlinger-এর কাছে একটি নতুন উইন্ডো পজিশন এবং নতুন সাইজের মান পাঠাতে হয়। একটি TextureView অবজেক্টের SurfaceTexture-কে স্কেল করতে TextureView#setTransform() ব্যবহার করে একটি ট্রান্সফরমেশন ম্যাট্রিক্স কনফিগার করতে হয়।

সঠিক অ্যাস্পেক্ট রেশিও উপস্থাপন করার পর, উভয় ইমপ্লিমেন্টেশনই একই প্যাটার্ন অনুসরণ করে। যখন SurfaceView বা TextureView সারফেসটি তৈরি করে, তখন অ্যাপ কোড প্লেব্যাক চালু করে। যখন একজন ব্যবহারকারী 'প্লে' ট্যাপ করেন, তখন এটি একটি ভিডিও ডিকোডিং থ্রেড শুরু করে, যার আউটপুট টার্গেট হিসেবে থাকে সারফেসটি। এরপর, অ্যাপ কোড আর কিছুই করে না—কম্পোজিশন এবং ডিসপ্লের কাজটি SurfaceFlinger ( SurfaceView এর জন্য) অথবা TextureView দ্বারা সম্পন্ন হয়।

কেস স্টাডি: গ্রাফিকার ডাবল ডিকোড

গ্রাফিকার ডাবল ডিকোড ফাংশনটি TextureView ভিতরে SurfaceTexture-এর ম্যানিপুলেশন প্রদর্শন করে।

গ্রাফিকার ডাবল ডিকোড একজোড়া TextureView অবজেক্ট ব্যবহার করে পাশাপাশি দুটি ভিডিও প্লে করে, যা একটি ভিডিও কনফারেন্সিং অ্যাপের অনুকরণ করে। যখন স্ক্রিনের ওরিয়েন্টেশন পরিবর্তিত হয় এবং অ্যাক্টিভিটি পুনরায় চালু হয়, তখন MediaCodec ডিকোডারগুলো বন্ধ হয় না, যা একটি রিয়েল-টাইম ভিডিও স্ট্রিমের প্লেব্যাকের অনুকরণ করে। কার্যকারিতা বাড়ানোর জন্য, ক্লায়েন্টের উচিত সারফেসটিকে সচল রাখা। সারফেসটি হলো SurfaceTexture-এর BufferQueue-তে থাকা প্রডিউসার ইন্টারফেসের একটি হ্যান্ডেল। যেহেতু TextureView অবজেক্টটি SurfaceTexture-কে পরিচালনা করে, তাই সারফেসটিকে সচল রাখতে ক্লায়েন্টকে SurfaceTexture-টিকে সচল রাখতে হয়।

SurfaceTexture-কে সচল রাখতে, Grafika-র Double Decode ফাংশনটি TextureView অবজেক্টগুলো থেকে SurfaceTexture-এর রেফারেন্স সংগ্রহ করে এবং সেগুলোকে একটি স্ট্যাটিক ফিল্ডে সংরক্ষণ করে। এরপর, SurfaceTexture-এর ধ্বংস রোধ করার জন্য Grafika-র Double Decode ফাংশনটি TextureView.SurfaceTextureListener#onSurfaceTextureDestroyed() থেকে false রিটার্ন করে। এরপর TextureView , onSurfaceTextureDestroyed() ফাংশনে এমন একটি SurfaceTexture পাস করে যা অ্যাক্টিভিটি কনফিগারেশন পরিবর্তনের পরেও বজায় রাখা যায়, এবং ক্লায়েন্ট এই SurfaceTexture-টিকে setSurfaceTexture() মাধ্যমে নতুন TextureView অবজেক্টে পাঠিয়ে দেয়।

প্রতিটি ভিডিও ডিকোডার আলাদা থ্রেড দ্বারা পরিচালিত হয়। মিডিয়াসার্ভার ডিকোড করা আউটপুটসহ বাফারগুলো সারফেসটেক্সচার (BufferQueue-এর গ্রাহক)-এর কাছে পাঠায়। টেক্সচারভিউ অবজেক্টগুলো রেন্ডারিংয়ের কাজ করে এবং UI থ্রেডে তা কার্যকর হয়।

TextureView তুলনায় SurfaceView দিয়ে গ্রাফিকার ডাবল ডিকোড প্রয়োগ করা আরও কঠিন, কারণ ওরিয়েন্টেশন পরিবর্তনের সময় SurfaceView অবজেক্টগুলো সারফেস নষ্ট করে দেয়। এছাড়াও, SurfaceView অবজেক্ট ব্যবহার করলে দুটি লেয়ার যুক্ত হয়, যা হার্ডওয়্যারে উপলব্ধ ওভারলে-র সংখ্যার সীমাবদ্ধতার কারণে আদর্শ নয়।