SurfaceTexture

SurfaceTexture, एक सर्फ़ेस और OpenGL ES (GLES) टेक्सचर का कॉम्बिनेशन होता है. SurfaceTexture इंस्टेंस का इस्तेमाल, ऐसे सरफ़ेस उपलब्ध कराने के लिए किया जाता है जो GLES टेक्सचर को आउटपुट करते हैं.

SurfaceTexture में BufferQueue का एक उदाहरण शामिल है. इसके लिए, ऐप्लिकेशन उपभोक्ता हैं. onFrameAvailable() कॉलबैक, ऐप्लिकेशन को तब सूचना देता है, जब प्रोड्यूसर किसी नए बफ़र को कतार में लगाता है. इसके बाद, ऐप्लिकेशन updateTexImage() को कॉल करते हैं. इससे पहले से होल्ड किया गया बफ़र रिलीज़ हो जाता है. साथ ही, यह बफ़र को क्यू से हासिल करता है और EGL को कॉल करता है, ताकि बफ़र को GLES के लिए बाहरी टेक्सचर के तौर पर उपलब्ध कराया जा सके.

बाहरी GLES टेक्सचर

बाहरी जीएलईएस टेक्सचर (GL_TEXTURE_EXTERNAL_OES) और स्टैंडर्ड जीएलईएस टेक्सचर (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 की लगातार कैप्चर करने वाली गतिविधि

पहली इमेज. Grafika की लगातार कैप्चर करने वाली गतिविधि

H.264 में एन्कोड किया गया वीडियो, ऐप्लिकेशन प्रोसेस में RAM के सर्कुलर बफ़र में जाता है. जब कोई उपयोगकर्ता कैप्चर बटन दबाता है, तो MediaMuxer क्लास, एन्कोड किए गए वीडियो को डिस्क पर मौजूद MP4 फ़ाइल में लिखता है.

ऐप्लिकेशन में सभी BufferQueue इंस्टेंस को एक ही ईजीएल कॉन्टेक्स्ट से मैनेज किया जाता है. वहीं, जीएलईएस ऑपरेशन, यूज़र इंटरफ़ेस (यूआई) थ्रेड पर किए जाते हैं. एन्कोड किए गए डेटा को मैनेज करने (सर्कुलर बफ़र को मैनेज करना और उसे डिस्क पर लिखना) का काम, अलग थ्रेड पर किया जाता है.

SurfaceView क्लास का इस्तेमाल करने पर, surfaceCreated() कॉलबैक, डिसप्ले और वीडियो एन्कोडर के लिए EGLContext और EGLSurface इंस्टेंस बनाता है. जब कोई नया फ़्रेम आता है, तो SurfaceTexture ये चार काम करता है:

  1. इससे फ़्रेम मिलता है.
  2. इससे फ़्रेम, GLES टेक्सचर के तौर पर उपलब्ध हो जाता है.
  3. यह GLES कमांड की मदद से फ़्रेम को रेंडर करता है.
  4. यह 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 Level 1 जैसे मज़बूत DRM को लागू किए बिना, कई कॉन्टेंट प्रोवाइडर OpenGL ES एनवायरमेंट में अपने कीमती कॉन्टेंट को रेंडर करने की अनुमति नहीं देते हैं. इससे VR के ज़रूरी इस्तेमाल के मामलों को रोका जाता है. जैसे, VR में DRM से सुरक्षित कॉन्टेंट देखना.

Android ओपन सोर्स प्रोजेक्ट (AOSP) में, सुरक्षित टेक्सचर वीडियो चलाने के लिए फ़्रेमवर्क कोड शामिल होता है. ड्राइवर से जुड़ी सहायता, ओईएम पर निर्भर करती है. डिवाइस बनाने वाली कंपनियों को EGL_EXT_protected_content और GL_EXT_protected_textures एक्सटेंशन लागू करने होंगे. libstagefright को बदलने के लिए, अपनी कोडेक लाइब्रेरी का इस्तेमाल करते समय, /frameworks/av/media/libstagefright/SurfaceUtils.cpp में हुए बदलावों पर ध्यान दें. इन बदलावों की वजह से, GRALLOC_USAGE_PROTECTED के तौर पर मार्क किए गए बफ़र को ANativeWindow पर भेजा जा सकता है. भले ही, ANativeWindow सीधे तौर पर विंडो कंपोज़र को कतार में न लगाता हो. ऐसा तब तक किया जा सकता है, जब तक उपभोक्ता के इस्तेमाल से जुड़े बिट में GRALLOC_USAGE_PROTECTED शामिल हो. एक्सटेंशन लागू करने के बारे में ज़्यादा जानकारी के लिए, Khronos registries ( EGL_EXT_protected_content) और ( GL_EXT_protected_textures) देखें.