SurfaceTexture
adalah kombinasi dari platform dan tekstur OpenGL ES (GLES).
Instance SurfaceTexture
digunakan untuk menyediakan platform yang menghasilkan output
ke tekstur GLES.
SurfaceTexture
berisi instance BufferQueue
yang merupakan konsumen aplikasi. Callback onFrameAvailable()
memberi tahu aplikasi saat produsen mengantrekan buffer baru. Kemudian, aplikasi memanggil
updateTexImage()
, yang melepaskan buffer yang sebelumnya ditahan,
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 standar (GL_TEXTURE_2D
) dalam hal berikut:
- Tekstur eksternal merender poligon bertekstur langsung dari data yang diterima
dari
BufferQueue
. - Perender tekstur eksternal dikonfigurasi secara berbeda dengan perender tekstur GLES standar.
- Tekstur eksternal tidak dapat melakukan semua aktivitas tekstur GLES standar.
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 memverifikasi bahwa
data dalam buffer 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 mengetahui 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 buffer yang diteruskan BufferQueue
mencakup
parameter transformasi dan stempel waktu.
Parameter transformasi berguna untuk efisiensi. Dalam beberapa kasus, data sumber mungkin dalam orientasi yang salah untuk konsumen. Daripada memutar data sebelum mengirimkannya ke konsumen, kirimkan data dalam orientasinya dengan transformasi yang memperbaikinya. Matriks transformasi dapat digabungkan dengan transformasi lain saat data digunakan, sehingga meminimalkan overhead.
Stempel waktu berguna untuk sumber buffer 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 dari saat frame
direkam, bukan dari saat aplikasi menerima frame. Kode kamera menetapkan
stempel waktu yang diberikan dengan buffer, sehingga menghasilkan serangkaian
stempel waktu yang lebih konsisten.
Studi kasus: Pengambilan berkelanjutan Grafika
Pengambilan gambar 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 buffer:
App
— Aplikasi menggunakan instanceSurfaceTexture
untuk menerima frame dari kamera, mengonversinya menjadi tekstur GLES eksternal.SurfaceFlinger
— Aplikasi mendeklarasikan instanceSurfaceView
untuk menampilkan frame.MediaServer
— Konfigurasi encoderMediaCodec
dengan input surface untuk membuat video.
Pada gambar berikut, panah menunjukkan propagasi data dari
kamera. Instance BufferQueue
ditampilkan, dengan indikator visual yang membedakan produsen (teal) dari konsumen (hijau).

Gambar 1. Aktivitas pengambilan berkelanjutan Grafika
Video H.264 yang dienkode masuk ke buffer melingkar di RAM dalam proses aplikasi.
Saat pengguna menekan tombol pengambilan, class MediaMuxer
akan menulis video yang dienkode ke file MP4 di disk.
Semua instance BufferQueue
ditangani dengan satu konteks EGL
di aplikasi, sementara operasi GLES dilakukan di thread UI. Penanganan data yang dienkode (mengelola buffer melingkar dan menuliskannya ke disk) dilakukan di thread terpisah.
Saat menggunakan class SurfaceView
, callback surfaceCreated()
membuat instance EGLContext
dan EGLSurface
untuk encoder video dan tampilan. Saat frame baru tiba,
SurfaceTexture
melakukan empat aktivitas:
- Mendapatkan frame.
- Menyediakan frame sebagai tekstur GLES.
- Merender frame dengan perintah GLES.
- Meneruskan transformasi dan stempel waktu untuk setiap instance
EGLSurface
.
Kemudian, thread encoder menarik output yang dienkode dari MediaCodec
dan menyimpannya di memori.
Pemutaran video tekstur yang aman
Android mendukung pemrosesan pasca-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 adegan 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 keduanya dapat beroperasi pada konten yang dilindungi. - Ekstensi GLES —
(
GL_EXT_protected_textures
) Memungkinkan pemberian tag pada tekstur sebagai yang 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 permukaan
video yang dilindungi untuk digunakan dalam konteks yang dilindungi. Hal ini dilakukan dengan menyetel bit konsumen yang dilindungi (GRALLOC_USAGE_PROTECTED
) pada platform yang dibuat dalam konteks yang dilindungi (diverifikasi oleh ACodec).
Pemutaran video tekstur yang aman menjadi dasar untuk penerapan Manajemen Hak Digital (DRM) yang kuat di lingkungan OpenGL ES. Tanpa penerapan 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.
Proyek Open Source Android (AOSP) mencakup kode framework untuk pemutaran video tekstur yang aman. Dukungan driver diserahkan kepada OEM. Pelaksana perangkat harus menerapkan ekstensi EGL_EXT_protected_content
dan GL_EXT_protected_textures
. Saat menggunakan library codec Anda sendiri (untuk menggantikan libstagefright
), perhatikan perubahan di /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 penerapan ekstensi, lihat registry Khronos (
EGL_EXT_protected_content
) dan (
GL_EXT_protected_textures
).