SurfaceTexture

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 instance SurfaceTexture untuk menerima frame dari kamera, mengonversinya menjadi tekstur GLES eksternal.
  • SurfaceFlinger — Aplikasi mendeklarasikan instance SurfaceView untuk menampilkan frame.
  • MediaServer — Konfigurasi encoder MediaCodec 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).

Aktivitas perekaman berkelanjutan

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:

  1. Mendapatkan frame.
  2. Menyediakan frame sebagai tekstur GLES.
  3. Merender frame dengan perintah GLES.
  4. 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).

Pemutaran Video Tekstur yang Aman

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).