Tekstur permukaan

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

SurfaceTexture berisi instance BufferQueue yang aplikasinya adalah konsumennya. Callback onFrameAvailable() memberi tahu aplikasi saat produsen mengantri buffer baru. Kemudian, aplikasi memanggil updateTexImage() , yang melepaskan buffer yang disimpan sebelumnya, mengambil buffer baru dari antrean, dan melakukan panggilan EGL agar buffer tersebut tersedia bagi 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 merender poligon bertekstur langsung dari data yang diterima dari BufferQueue .
  • Perender tekstur eksternal dikonfigurasi secara berbeda dibandingkan 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 . Instans SurfaceTexture menyetel tanda penggunaan konsumen ke GRALLOC_USAGE_HW_TEXTURE saat membuat instance BufferQueue untuk tekstur eksternal guna memastikan 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 tersebut ada di thread pemanggil. Untuk informasi selengkapnya lihat dokumentasi kelas SurfaceTexture .

Stempel waktu dan transformasi

Instance SurfaceTexture mencakup 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, sumber data mungkin berada pada orientasi yang salah bagi konsumen. Daripada memutar data sebelum mengirimkannya ke konsumen, kirimkan data sesuai 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, ketika setPreviewTexture() menghubungkan antarmuka produser ke output kamera, bingkai dari kamera dapat digunakan untuk membuat video. Setiap frame harus memiliki stempel waktu presentasi sejak frame diambil, bukan sejak aplikasi menerima frame. Kode kamera menyetel stempel waktu yang disediakan bersama buffer, sehingga menghasilkan rangkaian stempel waktu yang lebih konsisten.

Studi kasus: Pengambilan gambar secara terus-menerus di Grafika

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

Aktivitas pengambilan berkelanjutan 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 instance SurfaceTexture untuk menerima bingkai dari kamera, mengubahnya menjadi tekstur GLES eksternal.
  • SurfaceFlinger — Aplikasi mendeklarasikan instance SurfaceView untuk menampilkan bingkai.
  • MediaServer — Konfigurasikan encoder MediaCodec dengan permukaan input untuk membuat video.

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

Aktivitas penangkapan berkelanjutan Grafika

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 instance BufferQueue ditangani dengan satu konteks EGL di aplikasi sementara operasi GLES dilakukan di thread UI. Penanganan data yang dikodekan (mengelola buffer melingkar dan menulisnya ke disk) dilakukan pada thread terpisah.

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

Thread encoder kemudian menarik output yang dikodekan dari MediaCodec dan menyimpannya di memori.

Pemutaran video tekstur yang aman

Android mendukung pasca-pemrosesan GPU untuk konten video yang dilindungi. Hal ini memungkinkan aplikasi menggunakan GPU untuk efek video nonlinier 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 Aman

Gambar 2. Pemutaran video tekstur 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 mengantri ke SurfaceFlinger dan menyediakan permukaan video yang dilindungi untuk digunakan dalam konteks yang dilindungi. Hal ini dilakukan dengan mengatur bit konsumen yang dilindungi ( GRALLOC_USAGE_PROTECTED ) pada permukaan yang dibuat dalam konteks terlindungi (diverifikasi oleh ACodec).

Pemutaran video tekstur yang aman menetapkan landasan bagi penerapan 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.

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