SurfaceTexture
, किसी सतह और OpenGL ES (GLES) टेक्स्चर का कॉम्बिनेशन होता है. SurfaceTexture
इंस्टेंस का इस्तेमाल, GLES टेक्स्चर में आउटपुट करने वाले सरफ़ेस उपलब्ध कराने के लिए किया जाता है.
SurfaceTexture
में BufferQueue
का एक इंस्टेंस है, जिसके लिए ऐप्लिकेशन उपभोक्ता हैं. जब प्रोड्यूसर कोई नया बफ़र कतार में जोड़ता है, तो onFrameAvailable()
कॉलबैक ऐप्लिकेशन को सूचना देता है. इसके बाद, ऐप्लिकेशन updateTexImage()
को कॉल करते हैं. यह पहले से सेव किए गए बफ़र को रिलीज़ करता है और सूची से नया बफ़र हासिल करता है. साथ ही, EGL को कॉल करके, बफ़र को बाहरी टेक्सचर के तौर पर GLES के लिए उपलब्ध कराता है.
बाहरी 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()
, प्रोड्यूसर इंटरफ़ेस को कैमरे के आउटपुट से कनेक्ट करता है, तो कैमरे के फ़्रेम का इस्तेमाल वीडियो बनाने के लिए किया जा सकता है. हर फ़्रेम में, फ़्रेम कैप्चर होने के समय का प्रज़ेंटेशन टाइमस्टैंप होना चाहिए, न कि ऐप्लिकेशन को फ़्रेम मिलने के समय का. कैमरा कोड, बफ़र के साथ दिए गए टाइमस्टैंप को सेट करता है. इससे टाइमस्टैंप की सीरीज़ ज़्यादा बेहतर तरीके से बनती है.
केस स्टडी: Grafika की मदद से लगातार कैप्चर करना
Grafika की लगातार कैप्चर करने की सुविधा में, डिवाइस के कैमरे से फ़्रेम रिकॉर्ड करना और उन फ़्रेम को स्क्रीन पर दिखाना शामिल है.
फ़्रेम रिकॉर्ड करने के लिए, MediaCodec क्लास के createInputSurface()
तरीके से एक सरफ़ेस बनाएं और सरफ़ेस को कैमरे को पास करें. फ़्रेम दिखाने के लिए, SurfaceView
का एक इंस्टेंस बनाएं और setPreviewDisplay()
को प्लैटफ़ॉर्म पास करें. ध्यान दें कि फ़्रेम रिकॉर्ड करने और उन्हें एक ही समय पर दिखाने की प्रोसेस ज़्यादा मुश्किल है.
लगातार कैप्चर गतिविधि, कैमरे से रिकॉर्ड किए जा रहे वीडियो को दिखाती है. इस मामले में, एन्कोड किया गया वीडियो, मेमोरी में मौजूद सर्कुलर बफ़र में लिखा जाता है. इसे किसी भी समय डिस्क में सेव किया जा सकता है.
इस फ़्लो में तीन बफ़र कतारें शामिल हैं:
App
— ऐप्लिकेशन, कैमरे से फ़्रेम पाने के लिएSurfaceTexture
इंस्टेंस का इस्तेमाल करता है. साथ ही, उन्हें बाहरी GLES टेक्सचर में बदलता है.SurfaceFlinger
— फ़्रेम दिखाने के लिए, ऐप्लिकेशन एकSurfaceView
इंस्टेंस का एलान करता है.MediaServer
— वीडियो बनाने के लिए, किसी इनपुट प्लैटफ़ॉर्म के साथMediaCodec
एन्कोडर को कॉन्फ़िगर करें.
नीचे दिए गए इलस्ट्रेशन में, ऐरो से कैमरे से डेटा भेजने की प्रोसेस के बारे में बताया गया है.
BufferQueue
के इंस्टेंस रंग में हैं (प्रोड्यूसर नीले रंग में हैं, उपभोक्ता हरे रंग में हैं).

पहली इमेज. Grafika की लगातार कैप्चर करने की गतिविधि
एन्कोड किया गया H.264 वीडियो, ऐप्लिकेशन प्रोसेस में रैम के सर्कुलर बफ़र में चला जाता है.
जब कोई उपयोगकर्ता कैप्चर बटन दबाता है, तो MediaMuxer
क्लास, डिस्क पर मौजूद एमपी4 फ़ाइल में एन्कोड किए गए वीडियो को लिखता है.
ऐप्लिकेशन में सभी BufferQueue
इंस्टेंस, एक ही EGL कॉन्टेक्स्ट के साथ मैनेज किए जाते हैं. वहीं, GLES ऑपरेशन, यूज़र इंटरफ़ेस (यूआई) थ्रेड पर किए जाते हैं. एन्क्रिप्ट किए गए डेटा को मैनेज करने (सर्कुलर बफ़र को मैनेज करने और उसे डिस्क पर लिखने) का काम, एक अलग थ्रेड पर किया जाता है.
SurfaceView
क्लास का इस्तेमाल करते समय, surfaceCreated()
कॉलबैक डिसप्ले और वीडियो एन्कोडर के लिए EGLContext
और EGLSurface
इंस्टेंस बनाता है. नया फ़्रेम आने पर, SurfaceTexture
चार गतिविधियां करता है:
- फ़्रेम हासिल करता है.
- फ़्रेम को GLES टेक्सचर के तौर पर उपलब्ध कराता है.
- GLES कमांड की मदद से फ़्रेम को रेंडर करता है.
EGLSurface
के हर इंस्टेंस के लिए, ट्रांसफ़ॉर्म और टाइमस्टैंप को फ़ॉरवर्ड करता है.
इसके बाद, एन्कोडर थ्रेड, MediaCodec
से एन्कोडेड आउटपुट खींचता है और उसे मेमोरी में सेव करता है.
सुरक्षित टेक्स्चर वीडियो चलाना
Android, सुरक्षित किए गए वीडियो कॉन्टेंट को जीपीयू की मदद से पोस्ट-प्रोसेस करता है. इससे ऐप्लिकेशन, जटिल और नॉन-लीनियर वीडियो इफ़ेक्ट (जैसे, वॉर्प) के लिए जीपीयू का इस्तेमाल कर सकते हैं. साथ ही, सामान्य ग्राफ़िक सीन (उदाहरण के लिए, GLES का इस्तेमाल करके) और वर्चुअल रिएलिटी (वीआर) में इस्तेमाल करने के लिए, सुरक्षित किए गए वीडियो कॉन्टेंट को टेक्सचर पर मैप कर सकते हैं.

दूसरी इमेज. सुरक्षित टेक्स्चर वीडियो चलाना
सहायता पाने के लिए, इन दो एक्सटेंशन का इस्तेमाल किया जा सकता है:
- EGL एक्सटेंशन —
(
EGL_EXT_protected_content
) इसकी मदद से, सुरक्षित GL कॉन्टेक्स्ट और प्लैटफ़ॉर्म बनाए जा सकते हैं. ये दोनों, सुरक्षित कॉन्टेंट पर काम कर सकते हैं. - GLES एक्सटेंशन —
(
GL_EXT_protected_textures
) टेक्स्चर को 'सुरक्षित' के तौर पर टैग करने की सुविधा देता है, ताकि उनका इस्तेमाल फ़्रेमबर्डर टेक्स्चर अटैचमेंट के तौर पर किया जा सके.
Android, SurfaceTexture
और ACodec (libstagefright.so
) को सुरक्षित कॉन्टेंट भेजने की अनुमति देता है. भले ही, विंडो का प्लैटफ़ॉर्म SurfaceFlinger
के लिए कतार में न हो और सुरक्षित कॉन्टेक्स्ट में इस्तेमाल करने के लिए, सुरक्षित वीडियो प्लैटफ़ॉर्म उपलब्ध कराए. ऐसा करने के लिए, सुरक्षित कॉन्टेक्स्ट (ACodec की पुष्टि की गई) में बनाए गए प्लैटफ़ॉर्म पर, सुरक्षित उपभोक्ता बिट (GRALLOC_USAGE_PROTECTED
) सेट किया जाता है.
सुरक्षित टेक्स्चर वीडियो चलाने की सुविधा, OpenGL ES एनवायरमेंट में डीआरएम को बेहतर तरीके से लागू करने की बुनियाद तैयार करती है. Widevine लेवल 1 जैसे बेहतर डीआरएम लागू किए बिना, कई कॉन्टेंट उपलब्ध कराने वाली कंपनियां, OpenGL ES एनवायरमेंट में अपने अहम कॉन्टेंट को रेंडर करने की अनुमति नहीं देती हैं. इससे, वीआर के इस्तेमाल के अहम उदाहरणों को रोका जा सकता है. जैसे, वीआर में डीआरएम से सुरक्षित कॉन्टेंट देखना.
AOSP में, सुरक्षित टेक्स्चर वीडियो चलाने के लिए फ़्रेमवर्क कोड शामिल है. ड्राइवर के लिए सहायता, OEMs के पास होती है. डिवाइस पर लागू करने वाले लोगों को EGL_EXT_protected_content
और GL_EXT_protected_textures extensions
लागू करने होंगे. libstagefright
को बदलने के लिए, अपनी कोडेक लाइब्रेरी का इस्तेमाल करते समय, /frameworks/av/media/libstagefright/SurfaceUtils.cpp
में हुए उन बदलावों पर ध्यान दें जिनकी वजह से GRALLOC_USAGE_PROTECTED
के साथ मार्क किए गए बफ़र को ANativeWindow
पर भेजा जा सकता है. भले ही, ANativeWindow
सीधे विंडो कंपोजर में लाइन में न लगाए. ऐसा तब तक किया जा सकता है, जब तक कि उपभोक्ता के इस्तेमाल के बिट में GRALLOC_USAGE_PROTECTED
मौजूद हो. एक्सटेंशन लागू करने के बारे में ज़्यादा जानकारी के लिए, Khronos रजिस्ट्री (EGL_EXT_protected_content
और GL_EXT_protected_textures
) देखें.