Tekstur permukaan

SurfaceTexture adalah kombinasi dari permukaan dan tekstur OpenGL ES (GLES) . SurfaceTexture digunakan untuk menyediakan permukaan yang menghasilkan tekstur GLES.

SurfaceTexture berisi instance BufferQueue yang aplikasinya merupakan konsumen. onFrameAvailable() memberi tahu aplikasi saat produser mengantre buffer baru. Kemudian, aplikasi memanggil updateTexImage() , yang melepaskan buffer yang ditahan sebelumnya, memperoleh buffer baru dari antrean, dan membuat panggilan EGL untuk membuat buffer tersedia untuk GLES sebagai tekstur eksternal.

Tekstur GLES eksternal

Tekstur GLES eksternal ( GL_TEXTURE_EXTERNAL_OES ) berbeda dari tekstur GLES tradisional ( GL_TEXTURE_2D ) dalam hal berikut:

  • Tekstur eksternal membuat poligon bertekstur langsung dari data yang diterima dari BufferQueue .
  • Perender tekstur eksternal dikonfigurasi secara berbeda dari 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 . SurfaceTexture menyetel flag penggunaan konsumen ke GRALLOC_USAGE_HW_TEXTURE saat membuat BufferQueue untuk tekstur eksternal guna memastikan bahwa data dalam buffer dapat dikenali oleh GLES.

Karena instans SurfaceTexture berinteraksi dengan konteks EGL, aplikasi hanya dapat memanggil metodenya sementara konteks EGL yang memiliki tekstur saat ini ada di utas panggilan. Untuk informasi selengkapnya, lihat dokumentasi kelas SurfaceTexture .

Stempel waktu dan transformasi

SurfaceTexture menyertakan metode getTimeStamp() , yang mengambil stempel waktu, dan metode getTransformMatrix() , yang mengambil matriks transformasi. Memanggil updateTexImage() menyetel stempel waktu dan matriks transformasi. Setiap buffer yang dilewati BufferQueue menyertakan parameter transformasi dan stempel waktu.

Parameter transformasi berguna untuk efisiensi. Dalam beberapa kasus, data sumber mungkin berada dalam orientasi yang salah bagi konsumen. Alih-alih memutar data sebelum mengirimnya ke konsumen, kirim data dalam orientasinya dengan transformasi yang memperbaikinya. Matriks transformasi dapat digabungkan dengan transformasi lain ketika data digunakan, meminimalkan overhead.

Stempel waktu berguna untuk sumber buffer yang bergantung pada waktu. Misalnya, ketika setPreviewTexture() menghubungkan antarmuka produser ke output kamera, bingkai dari kamera dapat digunakan untuk membuat video. Setiap bingkai harus memiliki stempel waktu presentasi dari saat bingkai diambil, bukan dari saat aplikasi menerima bingkai. Kode kamera menyetel stempel waktu yang disediakan dengan buffer, menghasilkan rangkaian stempel waktu yang lebih konsisten.

Studi kasus: Pengambilan gambar Grafika yang berkelanjutan

Pengambilan gambar terus-menerus Grafika melibatkan perekaman bingkai dari kamera perangkat dan menampilkan bingkai tersebut di layar. Untuk merekam bingkai, buat permukaan dengan metode createInputSurface createInputSurface() kelas MediaCodec dan teruskan permukaan ke kamera. Untuk menampilkan bingkai, buat instance SurfaceView dan teruskan permukaan ke setPreviewDisplay() . Perhatikan bahwa merekam bingkai dan menampilkannya pada saat yang sama adalah proses yang lebih rumit.

Aktivitas pengambilan terus menerus menampilkan video dari kamera saat video sedang direkam. Dalam hal ini, video yang dikodekan ditulis ke buffer melingkar di memori yang dapat disimpan ke disk kapan saja.

Aliran ini melibatkan tiga antrian buffer:

  • App — Aplikasi menggunakan instans SurfaceTexture untuk menerima bingkai dari kamera, mengonversinya menjadi tekstur GLES eksternal.
  • SurfaceFlinger — Aplikasi mendeklarasikan instance SurfaceView untuk menampilkan frame.
  • MediaServer — Mengonfigurasi encoder MediaCodec dengan permukaan input untuk membuat video.

Pada gambar di bawah, panah menunjukkan propagasi data dari kamera. BufferQueue berwarna (produsen berwarna teal, konsumen berwarna hijau).

Grafika aktivitas penangkapan terus menerus

Gambar 1. Aktivitas penangkapan berkelanjutan Grafika

Video H.264 yang dikodekan masuk ke buffer melingkar di RAM dalam proses aplikasi. Saat pengguna menekan tombol ambil, kelas MediaMuxer menulis video yang disandikan ke file MP4 di disk.

Semua BufferQueue ditangani dengan konteks EGL tunggal di aplikasi sementara operasi GLES dilakukan di thread UI. Penanganan data yang dikodekan (mengelola buffer melingkar dan menulisnya ke disk) dilakukan pada utas terpisah.

Saat menggunakan kelas SurfaceView , callback surfaceCreated() membuat EGLContext dan EGLSurface untuk tampilan dan encoder video. Saat bingkai baru tiba, SurfaceTexture melakukan empat aktivitas:
  1. Memperoleh bingkai.
  2. Membuat bingkai tersedia sebagai tekstur GLES.
  3. Merender frame dengan perintah GLES.
  4. Meneruskan transformasi dan stempel waktu untuk setiap instance EGLSurface .

Utas encoder kemudian menarik output yang disandikan dari MediaCodec dan menyimpannya di memori.

Pemutaran video tekstur aman

Android mendukung pemrosesan pasca GPU dari konten video yang dilindungi. Hal ini memungkinkan aplikasi menggunakan GPU untuk efek video nonlinier yang kompleks (seperti warps), memetakan konten video yang dilindungi ke tekstur untuk digunakan dalam adegan grafis umum (misalnya, menggunakan GLES), dan virtual reality (VR).

Pemutaran Video Tekstur Aman

Gambar 2. Pemutaran video tekstur yang aman

Dukungan diaktifkan menggunakan dua ekstensi berikut:

  • Ekstensi EGL — ( EGL_EXT_protected_content ) Memungkinkan pembuatan konteks dan permukaan GL yang dilindungi, yang keduanya dapat beroperasi pada konten yang dilindungi.
  • Ekstensi GLES — ( GL_EXT_protected_textures ) Mengaktifkan penandaan tekstur sebagai dilindungi sehingga dapat digunakan sebagai lampiran tekstur framebuffer.

Android mengaktifkan SurfaceTexture dan ACodec ( libstagefright.so ) untuk mengirim konten yang dilindungi meskipun permukaan jendela tidak mengantre ke SurfaceFlinger dan menyediakan permukaan video yang dilindungi untuk digunakan dalam konteks yang dilindungi. Ini dilakukan dengan menyetel bit konsumen yang dilindungi ( GRALLOC_USAGE_PROTECTED ) pada permukaan yang dibuat dalam konteks yang dilindungi (diverifikasi oleh ACodec).

Pemutaran video tekstur yang aman menetapkan dasar 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, mencegah kasus penggunaan VR penting seperti menonton konten yang dilindungi DRM di VR.

AOSP menyertakan kode kerangka kerja untuk pemutaran video tekstur yang aman. Dukungan driver terserah OEM. Pelaksana perangkat harus menerapkan ekstensi EGL_EXT_protected_content dan GL_EXT_protected_textures extensions . Saat menggunakan pustaka codec Anda sendiri (untuk menggantikan libstagefright ), perhatikan perubahan di /frameworks/av/media/libstagefright/SurfaceUtils.cpp yang memungkinkan buffer yang ditandai dengan GRALLOC_USAGE_PROTECTED untuk dikirim ke ANativeWindow (bahkan jika ANativeWindow tidak mengantre langsung ke window composer) selama bit penggunaan konsumen mengandung GRALLOC_USAGE_PROTECTED . Untuk dokumentasi terperinci tentang penerapan ekstensi, lihat registri Khronos ( EGL_EXT_protected_content , dan GL_EXT_protected_textures ).