SurfaceTexture
adalah kombinasi platform dan tekstur
OpenGL ES (GLES). Instance SurfaceTexture
digunakan untuk menyediakan platform yang menghasilkan output ke tekstur
GLES.
SurfaceTexture
berisi instance BufferQueue
yang
aplikasinya adalah konsumen. Callback onFrameAvailable()
memberi tahu aplikasi saat produsen mengantrekan buffer baru. Kemudian, aplikasi memanggil
updateTexImage()
, yang melepaskan buffer yang sebelumnya disimpan,
mendapatkan buffer baru dari antrean, dan melakukan panggilan EGL untuk membuat buffer tersedia untuk GLES sebagai tekstur eksternal.
Tekstur GLES eksternal
Tekstur GLES eksternal (GL_TEXTURE_EXTERNAL_OES
) berbeda
dengan tekstur GLES tradisional (GL_TEXTURE_2D
) dengan cara
berikut:
- Tekstur eksternal merender poligon bertekstur langsung dari data yang diterima
dari
BufferQueue
. - Perender tekstur eksternal dikonfigurasi secara berbeda dengan perender tekstur GLES tradisional.
- Tekstur eksternal tidak dapat melakukan semua aktivitas tekstur GLES tradisional.
Manfaat utama tekstur eksternal adalah
kemampuannya untuk merender langsung dari data BufferQueue
. Instance SurfaceTexture
menetapkan flag penggunaan konsumen ke GRALLOC_USAGE_HW_TEXTURE
saat membuat
instance BufferQueue
untuk tekstur eksternal guna memastikan bahwa data dalam buffering
dapat dikenali oleh GLES.
Karena instance SurfaceTexture
berinteraksi dengan konteks EGL, aplikasi hanya dapat memanggil
metodenya saat konteks EGL yang memiliki tekstur saat ini berada di
thread panggilan. Untuk informasi selengkapnya, lihat dokumentasi class SurfaceTexture
.
Stempel waktu dan transformasi
Instance SurfaceTexture
mencakup metode getTimeStamp()
, yang
mengambil stempel waktu, dan metode getTransformMatrix()
, yang
mengambil matriks transformasi. Memanggil updateTexImage()
akan menetapkan stempel waktu dan matriks transformasi. Setiap buffering yang
diteruskan BufferQueue
menyertakan parameter transformasi dan stempel waktu.
Parameter transformasi berguna untuk efisiensi. Dalam beberapa kasus, data sumber mungkin memiliki orientasi yang salah untuk konsumen. Daripada memutar data sebelum mengirimkannya ke konsumen, kirim data dalam orientasinya dengan transformasi yang mengoreksinya. Matriks transformasi dapat digabungkan dengan transformasi lain saat data digunakan, sehingga meminimalkan overhead.
Stempel waktu berguna untuk sumber buffering yang bergantung pada waktu. Misalnya, saat setPreviewTexture()
menghubungkan
antarmuka produsen ke output kamera, frame dari kamera dapat
digunakan untuk membuat video. Setiap frame harus memiliki stempel waktu
presentasi sejak frame diambil, bukan sejak aplikasi menerima
frame. Kode kamera menetapkan stempel waktu yang disediakan dengan buffering,
sehingga menghasilkan serangkaian stempel waktu yang lebih konsisten.
Studi kasus: Perekaman berkelanjutan Grafika
Perekaman berkelanjutan Grafika melibatkan perekaman frame
dari kamera perangkat dan menampilkan frame tersebut di layar.
Untuk merekam frame, buat platform dengan
metode createInputSurface()
class MediaCodec dan teruskan platform ke kamera. Untuk
menampilkan frame, buat instance SurfaceView
dan teruskan platform ke
setPreviewDisplay()
. Perhatikan bahwa merekam frame dan menampilkannya
secara bersamaan adalah proses yang lebih rumit.
Aktivitas perekaman berkelanjutan menampilkan video dari kamera saat video direkam. Dalam hal ini, video yang dienkode ditulis ke buffer melingkar dalam memori yang dapat disimpan ke disk kapan saja.
Alur ini melibatkan tiga antrean buffering:
App
— Aplikasi menggunakan instanceSurfaceTexture
untuk menerima frame dari kamera, mengonversinya menjadi tekstur GLES eksternal.SurfaceFlinger
— Aplikasi mendeklarasikan instanceSurfaceView
untuk menampilkan frame.MediaServer
— Mengonfigurasi encoderMediaCodec
dengan platform input untuk membuat video.
Pada gambar di bawah, panah menunjukkan penyebaran data dari kamera.
Instance BufferQueue
berwarna (produser berwarna hijau kebiruan, konsumen berwarna hijau).

Gambar 1. Aktivitas pengambilan berkelanjutan Grafika
Video H.264 yang dienkode akan masuk ke buffer melingkar di RAM dalam proses aplikasi.
Saat pengguna menekan tombol rekam, class MediaMuxer
akan menulis video yang dienkode ke file MP4 di disk.
Semua instance BufferQueue
ditangani dengan satu konteks EGL dalam
aplikasi saat operasi GLES dilakukan pada thread UI. Penanganan
data yang dienkode (mengelola buffer melingkar dan menulisnya ke disk) dilakukan
di thread terpisah.
SurfaceView
, callback surfaceCreated()
akan membuat
instance EGLContext
dan EGLSurface
untuk encoder
layar dan video. Saat frame baru tiba, SurfaceTexture
akan melakukan empat aktivitas:
- Mendapatkan frame.
- Membuat frame tersedia sebagai tekstur GLES.
- Merender frame dengan perintah GLES.
- Meneruskan transformasi dan stempel waktu untuk setiap instance
EGLSurface
.
Thread encoder kemudian mengambil output yang dienkode dari MediaCodec
dan menyimpannya
dalam memori.
Pemutaran video tekstur yang aman
Android mendukung pascapemrosesan GPU untuk konten video yang dilindungi. Hal ini memungkinkan aplikasi menggunakan GPU untuk efek video non-linear yang kompleks (seperti warp), memetakan konten video yang dilindungi ke tekstur untuk digunakan dalam tampilan grafis umum (misalnya, menggunakan GLES), dan virtual reality (VR).

Gambar 2. Pemutaran video tekstur yang aman
Dukungan diaktifkan menggunakan dua ekstensi berikut:
- Ekstensi EGL —
(
EGL_EXT_protected_content
) Memungkinkan pembuatan konteks dan platform GL yang dilindungi, yang dapat beroperasi pada konten yang dilindungi. - Ekstensi GLES —
(
GL_EXT_protected_textures
) Memungkinkan pemberian tag pada tekstur sebagai dilindungi sehingga dapat digunakan sebagai lampiran tekstur framebuffer.
Android memungkinkan SurfaceTexture
dan ACodec
(libstagefright.so
) mengirim konten yang dilindungi meskipun
permukaan jendela tidak mengantre ke SurfaceFlinger
dan menyediakan platform video yang dilindungi untuk digunakan dalam konteks yang dilindungi. Tindakan ini
dilakukan dengan menetapkan bit konsumen yang dilindungi
(GRALLOC_USAGE_PROTECTED
) pada platform yang dibuat dalam konteks
yang dilindungi (diverifikasi oleh ACodec).
Pemutaran video tekstur yang aman menetapkan fondasi untuk implementasi DRM yang kuat di lingkungan OpenGL ES. Tanpa implementasi DRM yang kuat, seperti Widevine Level 1, banyak penyedia konten tidak mengizinkan rendering konten bernilai tinggi mereka di lingkungan OpenGL ES, sehingga mencegah kasus penggunaan VR yang penting seperti menonton konten yang dilindungi DRM di VR.
AOSP menyertakan kode framework untuk pemutaran video tekstur yang aman. Dukungan
driver bergantung pada OEM. Implementator perangkat harus mengimplementasikan
EGL_EXT_protected_content
dan
GL_EXT_protected_textures extensions
. Saat menggunakan library codec
Anda sendiri (untuk mengganti libstagefright
), perhatikan perubahan dalam
/frameworks/av/media/libstagefright/SurfaceUtils.cpp
yang memungkinkan
buffer yang ditandai dengan GRALLOC_USAGE_PROTECTED
dikirim ke
ANativeWindow
(meskipun ANativeWindow
tidak mengantre langsung ke composer
jendela) selama bit penggunaan konsumen berisi
GRALLOC_USAGE_PROTECTED
. Untuk dokumentasi mendetail tentang cara menerapkan ekstensi, lihat registry Khronos (EGL_EXT_protected_content
, dan GL_EXT_protected_textures
).