TextureView

TextureView sınıfı, bir görünümü SurfaceTexture ile birleştiren bir görünüm nesnesi.

OpenGL ES ile oluşturma

TextureView nesnesi, geri çağırmalara yanıt veren ve yeni arabellekler edinen bir SurfaceTexture sarmalayıcısıdır. TextureView yeni arabellekler edindiğinde bir görünüm geçersiz kılma isteği gönderir ve veri kaynağı olarak en yeni arabelleğin içeriğini kullanarak çizim yapar. Bu işlem, görünüm durumunun belirttiği yerde ve şekilde oluşturulur.

OpenGL ES (GLES), SurfaceTexture'yi EGL oluşturma çağrısına ileterek bir TextureView'da oluşturabilir ancak bu işlem bir soruna yol açar. GLES bir TextureView'da oluşturma işlemi gerçekleştirirken BufferQueue üreticileri ve tüketicileri aynı iş parçacığındadır. Bu durum, arabellek takas çağrısının duraklamasına veya başarısız olmasına neden olabilir. Örneğin, bir üretici kullanıcı arayüzü iş parçacığında art arda birkaç arabellek gönderirse EGL arabellek takas çağrısının, arabellek kuyruğundan bir arabellek çıkarması gerekir. Ancak tüketici ve üretici aynı iş parçacığında olduğu için kullanılacak arabellek olmaz ve takas çağrısı askıya alınır veya başarısız olur.

Arabellek takaşının durmaması için BufferQueue'ın her zaman sıra dışı bir arabelleğe ihtiyacı vardır. BufferQueue bunu uygulamak için yeni bir arabellek sıraya eklendiğinde daha önce edinilen arabelleğin içeriğini atar ve tüketicinin tüm arabellekleri aynı anda kullanmasını önlemek için minimum ve maksimum arabellek sayılarına kısıtlamalar uygular.

SurfaceView veya TextureView'ı seçme

SurfaceView ve TextureView benzer rollere sahiptir ve her ikisi de görüntü hiyerarşisinin bir parçasıdır. Ancak SurfaceView ve TextureView'ın farklı uygulamaları vardır. SurfaceView, diğer görünümlerle aynı parametreleri alır ancak SurfaceView içeriği oluşturulurken şeffaftır.

TextureView, SurfaceView'a kıyasla daha iyi alfa ve döndürme işlemleri gerçekleştirir ancak SurfaceView, videoların üzerine katman halinde yerleştirilen kullanıcı arayüzü öğelerini birleştirirken performans avantajlarına sahiptir. Bir istemci SurfaceView ile oluşturma işlemi gerçekleştirdiğinde SurfaceView, istemciye ayrı bir kompozisyon katmanı sağlar. SurfaceFlinger, cihaz tarafından destekleniyorsa ayrı katmanı donanım yer paylaşımı olarak oluşturur. Bir istemci TextureView ile oluşturma işlemi gerçekleştirdiğinde kullanıcı arayüzü araç seti, TextureView'ın içeriğini GPU ile görüntü hiyerarşisinde birleştirir. İçerikte yapılan güncellemeler, diğer görünüm öğelerinin yeniden çizilmesine neden olabilir (ör. diğer görünümler bir TextureView'ın üzerine yerleştirilmişse). Görünüm oluşturma işlemi tamamlandıktan sonra SurfaceFlinger, uygulama kullanıcı arayüzü katmanını ve diğer tüm katmanları birleştirir. Böylece her görünür piksel iki kez birleştirilir.

Örnek Olay: Grafika'nın Play Videosu

Grafika'nın Play Video, biri TextureView ile, diğeri SurfaceView ile uygulanmış bir çift video oynatıcı içerir. Etkinliğin videoyu kod çözme bölümü, MediaCodec'ten hem TextureView hem de SurfaceView için bir yüzeye kare gönderir. Uygulamalar arasındaki en büyük fark, doğru en boy oranını sunmak için gereken adımlardır.

SurfaceView'ı ölçeklendirmek için FrameLayout'ın özel bir uygulaması gerekir. WindowManager'ın SurfaceFlinger'a yeni bir pencere konumu ve yeni boyut değerleri göndermesi gerekir. Bir TextureView'ın SurfaceTexture'unu ölçeklendirmek için TextureView#setTransform() ile bir dönüşüm matrisi yapılandırmanız gerekir.

Doğru en boy oranını sunduktan sonra her iki uygulama da aynı kalıbı izler. SurfaceView/TextureView yüzeyi oluşturduğunda uygulama kodu oynatmayı etkinleştirir. Kullanıcı oynat'a dokunduğunda, çıkış hedefi olarak yüzeyin kullanıldığı bir video kod çözme iş parçacığı başlatılır. Bundan sonra uygulama kodu hiçbir şey yapmaz. Oluşturma ve görüntüleme işlemleri SurfaceFlinger (SurfaceView için) veya TextureView tarafından gerçekleştirilir.

Örnek Olay: Grafika'nın Çift Kod Çözme

Grafika'nın Çift Kod Çözme, bir TextureView içindeki SurfaceTexture'nin değiştirilmesini gösterir.

Grafika'nın Çift Kod Çözme özelliği, yan yana oynatılan iki videoyu göstermek için bir çift TextureView nesnesi kullanarak video konferans uygulamasını simüle eder. Ekranın yönü değiştiğinde ve etkinlik yeniden başlatıldığında MediaCodec kod çözücüler durmaz ve gerçek zamanlı video akışının oynatılmasını simüle eder. Müşteri, verimliliği artırmak için yüzeyi canlı tutmalıdır. Yüzey, SurfaceTexture'un BufferQueue'sındaki üretici arayüzünün bir tutamacıdır. TextureView, SurfaceTexture'yi yönettiğinden istemcinin yüzeyi canlı tutmak için SurfaceTexture'yi canlı tutması gerekir.

Grafika'nın Çift Kod Çözme özelliği, SurfaceTexture'nin etkin kalmasını sağlamak için TextureView nesnelerinden SurfaceTexture referansları alır ve bunları statik bir alana kaydeder. Ardından Grafika'nın Çift Kod Çözme işlevi, SurfaceTexture'un yok edilmesini önlemek için TextureView.SurfaceTextureListener#onSurfaceTextureDestroyed() kaynağından false döndürür. Ardından TextureView, etkinlik yapılandırması değişikliği sırasında korunabilecek bir SurfaceTexture'yi onSurfaceTextureDestroyed()'e iletir. İstemci, bu SurfaceTexture'yi setSurfaceTexture() aracılığıyla yeni TextureView'a iletir.

Her video kod çözücü ayrı bir iş parçacığı tarafından çalıştırılır. Mediaserver, kod çözülmüş çıkışı içeren arabellekleri BufferQueue tüketicileri olan SurfaceTexture'lere gönderir. TextureView nesneleri oluşturma işlemini gerçekleştirir ve kullanıcı arayüzü iş parçacığında yürütür.

Grafika'nın Çift Kod Çözme özelliğini SurfaceView ile uygulamak, TextureView ile uygulamaktan daha zordur. Bunun nedeni, SurfaceView nesnelerinin yön değişiklikleri sırasında yüzeyleri yok etmesidir. Ayrıca, SurfaceView nesneleri kullanıldığında iki katman eklenir. Bu, donanımda kullanılabilen yer paylaşımı sayısındaki sınırlamalar nedeniyle ideal değildir.