Kare hızı

Kare hızı API'si, uygulamaların Android platformuna istedikleri kare hakkında bilgi vermesini sağlar oranıdır ve Android 11 (API düzeyi 30) veya sonraki sürümleri hedefleyen uygulamalarda kullanılabilir. Önceden çoğu cihaz yalnızca tek bir ekran yenileme hızını destekliyordu. ancak bu değer değişti. Birçok cihaz artık 90 Hz veya 120 Hz gibi yenileme hızları. Bazı cihazlar sorunsuz yenileme hızını destekler diğerlerinde ise kısa bir süre, genellikle bir saniye süren siyah bir ekran görüntülenmektedir.

API'nin birincil amacı, uygulamaların tüm Android platformlarından daha iyi desteklenen ekran yenileme hızlarını ayarlar. Örneğin, 24 Hz video oynatan bir uygulama setFrameRate() çağrısı yapıldığında cihaz, ekranı değiştirebilir yenileme hızı: 60 Hz ile 120 Hz arasında. Bu yeni yenileme hızı sayesinde kesintisiz, 24 Hz videoyu titremeden ve olduğu gibi 3:2 aşağı çekme gerekmeden oynatın aynı videoyu 60 Hz ekranda oynatmak için gereklidir. Bu şekilde daha iyi bir kullanıcı deneyimi sağlanır sahip olacaksınız.

Temel kullanım

Android, yüzeylere erişmek ve bunları kontrol etmek için çeşitli yöntemler sunduğundan setFrameRate() API'nin çeşitli sürümlerinden yararlanabilirsiniz. API'nin her sürümü ve diğerleriyle aynı şekilde çalışır:

Uygulamanın, desteklenen gerçek ekran yenileme hızlarını dikkate almasına gerek yoktur; numaralı telefonu arayarak edinebilirsiniz. Display.getSupportedModes() setFrameRate() numaralı telefonu güvenli bir şekilde aramanız gerekiyor. Örneğin, cihaz yalnızca 60 Hz'i destekliyorsa setFrameRate() uygulamasını uygulamanızın tercih ettiği kare hızıyla arayın. Uygulamanın kare hızı için daha iyi bir eşleşmeye sahip olmayan cihazlar yenileme hızına ayarlanır.

setFrameRate() için yapılan bir çağrının ekran yenilemesinde bir değişikliğe yol açıp açmadığını görmek için oran, görüntüleme değişikliği bildirimleri için kaydolun DisplayManager.registerDisplayListener() veya AChoreographer_registerRefreshRateCallback().

setFrameRate() çağrılırken, bunun yerine tam kare hızında geçiş yapılması en iyisidir tam sayıya yuvarlamaktan daha iyidir. Örneğin, şu tarihte kaydedilmiş bir videoyu oluştururken: 29,97 Hz, 30'a yuvarlamak yerine 29,97'de geçin.

Video uygulamaları için setFrameRate() öğesine iletilen uyumluluk parametresi ayarlanmalıdır Surface.FRAME_RATE_COMPATIBILITY_FIXED_SOURCE öğesine ek ipucu vermek için Uygulamanın eşleşmeyen bir uygulamaya uyum sağlamak için açılan menüyü kullanacağı Android platformu yenileme hızına neden olur (titremeye neden olur).

Bazı senaryolarda video yüzeyi, kare göndermeyi durdurur ancak bu şekilde kalır. ekranda bir süre görünür. Sık karşılaşılan senaryolar oynatma sırasında ortaya çıkar Kullanıcı videonun sonuna ulaştığında veya kullanıcı oynatmayı duraklattığında. Böyle durumlarda yüzeyin temizlenmesine yardımcı olmak için kare hızı parametresini 0'a ayarlayarak setFrameRate() kare hızı ayarını varsayılan değere geri döndürün. Kare hızı ayarı temizleniyor Örneğin, yüzeyleri yok ederken veya yüzey düzlemi çalışırken kullanıcı farklı bir uygulamaya geçtiği için gizlidir. Kare hızını temizle yalnızca yüzey kullanılmadan görünür kaldığında ayarlanır.

Kesintisiz olmayan kare hızı anahtarı

Bazı cihazlarda, yenileme hızı geçişinde siyah gibi görsel kesintiler olabilir bir iki saniyeliğine ekranda kalır. Bu genellikle set üstü kutularda, TV panellerinde, ve benzeri cihazlar. Android çerçevesi varsayılan olarak modları değiştirmez Surface.setFrameRate() Bu tür görsel kesintileri önlemek için API çağrılır.

Bazı kullanıcılar başlangıçta görsel bir kesintiyi uzun videoların sonu gelir. Bu, ekranın yenileme hızının eşleşmesini sağlar Video kare hızını değiştirmeyin ve 3:2 gibi kare hızı dönüştürme eserlerinden kaçının. titremesini kullanabilirsiniz.

Bu nedenle, kesintisiz olmayan yenileme hızı anahtarları hem kullanıcı ve uygulama etkinleştirmesi:

Her zaman CHANGE_FRAME_RATE_ALWAYS kullanmanızı öneririz. filmler gibi uzun süreli videolar için. Çünkü eşlemenin faydaları video kare hızı, video kare hızı değiştirildiğinde ortaya çıkan kesintiden daha ağır basar. yenileme hızı.

Ek öneriler

Sık karşılaşılan senaryolar için bu önerileri uygulayın.

Birden fazla yüzey

Android platformu, mobil cihazlarda bir sürü Farklı kare hızı ayarlarına sahip birden fazla yüzey Uygulamanızda birden fazla farklı kare hızlarına sahip yüzeyler için setFrameRate() çağırarak doğru her yüzeyin kare hızını artırabilirsiniz. Cihaz, birden fazla uygulamayı çalıştırsa bile Bölünmüş ekran veya pencere içinde pencere modunu kullanarak her uygulama telefonunuzu bir kez güvenle arayabilir Kendi yüzeylerinde setFrameRate().

Platform, uygulamanın kare hızına göre değişmez

Cihaz, uygulamanın bir çağrıda belirttiği kare hızını desteklese bile setFrameRate(), cihazın ekranı yenileme hızında gösterilir. Örneğin, daha yüksek öncelikli bir yüzey farklı bir kare hızı ayarına bağlı olarak veya cihaz pil tasarrufu modunda (bir ekran yenileme hızında bir kısıtlama olmaksızın). Uygulama yine de Cihaz, ekran yenileme hızını cihaz normalin altında geçiş yapsa bile uygulamanın kare hızı ayarına koşullar.

Ekran yenileme hızına nasıl yanıt vereceğine uygulamaya karar verir uygulamanın kare hızıyla eşleşmiyor. Videonun kare hızı şuna sabittir: video içeriğini göstermek için kaynak video ve açılan liste gerekir. CEVAP Bunun yerine oyun, yerine ekranın yenileme hızında tercih ettiği kare hızında kalmaya devam eder. Uygulama, değeri değiştirmemelidir. platformun ne yaptığına bağlı olarak setFrameRate() için geçilir. Ayarlanmış durumda kalmalıdır uygulamanın tercih edilen kare hızına Platform, uygulamanın isteğiyle eşleşecek şekilde ayarlanmaz. Bu şekilde cihazın ek ekran yenileme hızlarının kullanılmasına izin verecek şekilde değişirse, platform, uygulamanın tercih edilen çerçevesine geçmek için doğru bilgilere sahip oranıdır.

Uygulama, ekran yenileme hızında çalışmadığı veya çalıştırılamadığı durumlarda, platformun sunum zaman damgalarını ayarlamak için kullandığı mekanizmalar:

Bu zaman damgalarının kullanılması, platformun bir uygulama çerçevesi sunmasını da durdurur bu durum gereksiz titremelere neden olur. Karenin doğru kullanımı sunum zaman damgaları biraz karmaşık. Oyunlar için şuraya bakın: kare ilerleme hızı rehberi göz atabilirsiniz. Android Çerçeve İlerleme Hızı kitaplığı.

Bazı durumlarda platform, uygulamanın kare hızının katlarından birine geçiş yapabilir setFrameRate() içinde belirtilir. Örneğin, bir uygulama setFrameRate() çağırabilir yapabilir ve cihaz ekranı 120 Hz'e geçirebilir. Bunun nedenlerinden biri, başka bir uygulamanın yüzeyi 24 Hz kare hızı ayarına sahip olduğunda görülür. İçinde Bu durumda, ekranı 120 Hz'de çalıştırmak hem 60 Hz'lik yüzeye hem de Aşağı çekme gerekmeden çalışacak 24 Hz yüzey.

Ekran, uygulamanın kare hızının katlarından birinde çalışırken uygulama gereksiz olmaması için her kare için sunum zaman damgaları belirtmelidir titriyor. Oyunlarda Android Frame Pacing kitaplığını doğru çerçeve sunumu zaman damgalarını ayarlayabilirsiniz.

setFrameRate() ve PreferredDisplayModeId karşılaştırması

WindowManager.LayoutParams.preferredDisplayModeId uygulamaların kare hızlarını platforma bildirmelerinin başka bir yoludur. Biraz uygulamalar diğer seçenekleri değiştirmek yerine yalnızca ekran yenileme hızını değiştirmek istiyor ekran çözünürlüğü gibi ekran modu ayarlarını değiştirebilirsiniz. Genel olarak, preferredDisplayModeId yerine setFrameRate(). setFrameRate() işlevinin kullanılması daha kolaydır, çünkü uygulamanın belirli bir kare hızına sahip modu bulmak için görüntü modları listesinden yararlanın.

setFrameRate(), uyumlu bir seçim yapması için platforma daha fazla fırsat sunar birden fazla yüzeyin olduğu senaryolarda kare hızı farklı kare hızlarında görüntülenebilir. Örneğin, iki uygulamanın aynı olduğu bir senaryoyu Pixel 4'te bölünmüş ekran modunda çalışan (bir uygulamanın 24 Hz video oynattığı) diğeri ise kullanıcıya kaydırılabilir bir liste gösteriyor. Pixel 4 iki cihazı destekler görüntü yenileme hızları: 60 Hz ve 90 Hz. preferredDisplayModeId API'yi kullanarak, video yüzeyi 60 Hz veya 90 Hz seçilmeye zorlanır. Şu numarayı arayarak setFrameRate(), 24 Hz'lik video yüzeyiyle platforma daha fazla değer veriyor. kaynak videonun kare hızı hakkında bilgi edinerek platformun, ekran yenileme hızı için 90 Hz'i seçin. Bu değerde 60 Hz'den iyidir. senaryoyu izler.

Bununla birlikte, preferredDisplayModeId işlevinin kullanılması gereken senaryolar da vardır. yerine setFrameRate() kullanabilirsiniz. Örneğin:

  • Uygulama, çözünürlük veya diğer görüntü modu ayarlarını değiştirmek isterse preferredDisplayModeId kullanın.
  • Platform yalnızca şu çağrıya yanıt olarak görüntü modlarını değiştirir: Mod anahtarı hafifse ve çok düşük değilse setFrameRate() fark edebilirsiniz. Uygulama, ekranı yenilemeyi tercih ederse yoğun mod anahtarı gerektirse bile (örneğin, Android TV'de cihaz) preferredDisplayModeId kullanın.
  • Uygulamanın çerçevesinin birden fazla noktasında ekranı işleyemeyen uygulamalar her karede sunum zaman damgalarının ayarlanmasını gerektiren preferredDisplayModeId kullanın.

setFrameRate() ve PreferredRefreshRate karşılaştırması

WindowManager.LayoutParams#preferredRefreshRate Uygulama penceresinde tercih edilen bir kare hızı ayarlar ve hız geçerliyse tüm yüzeylere doğru uygulayabilirsiniz. Uygulama, tercih edilen desteklenen yenileme hızlarından bağımsız olarak, setFrameRate(), planlayıcıya uygulamanın tasarımına dair daha iyi bir ipucu verir kare hızı.

preferredRefreshRate, setFrameRate() kullanan yüzeyler için yoksayılır. İçinde genel kullanım için setFrameRate() kullanın.

PreferredRefreshRate ve PreferredDisplayModeId karşılaştırması

Uygulamalar yalnızca tercih edilen yenileme hızını değiştirmek istiyorsa preferredDisplayModeId yerine preferredRefreshRate.

setFrameRate() işlevini çok sık çağırmaktan kaçınma

setFrameRate() çağrısı, performans açısından çok maliyetli olmasa da uygulamalar her karede veya her karede birden fazla setFrameRate() çağrısı yapmaktan kaçınmalıdır tıklayın. setFrameRate() numaralı telefona yapılan aramaların, yenileme hızında gösterilir. Bu da geçiş sırasında kare sayısında düşüşe yol açabilir. Doğru kare hızını önceden belirlemeniz ve Bir kez setFrameRate().

Oyunlar veya video dışı diğer uygulamalar için kullanım

setFrameRate() API'nin başlıca kullanım alanı video olsa da diğer uygulamalar için kullanılır. Örneğin, şu süreden daha yüksek yayınlanmayacak şekilde bir oyun: 60 Hz (güç kullanımını azaltmak ve daha uzun oynatma oturumları sağlamak için) çağırabilir. Surface.setFrameRate(60, Surface.FRAME_RATE_COMPATIBILITY_DEFAULT) Burada Bu durumda, varsayılan olarak 90 Hz'de çalışan bir cihaz, Böylece, oyunun etkin olması durumunda aksi takdirde yaşanabilecek titremelerden oyun 60 Hz'de çalışırken ekran 90 Hz'de çalışıyordu.

FRAME_RATE_COMPATIBILITY_FIXED_SOURCE kullanımı

FRAME_RATE_COMPATIBILITY_FIXED_SOURCE yalnızca video uygulamaları için tasarlanmıştır. Örneğin, video dışı kullanım için FRAME_RATE_COMPATIBILITY_DEFAULT kullanın.

Kare hızını değiştirmek için strateji seçme

  • Aşağıdaki gibi uzun süreli videoları görüntülerken uygulamaların filmler, setFrameRate(fps, FRAME_RATE_COMPATIBILITY_FIXED_SOURCE, CHANGE_FRAME_RATE_ALWAYS)'yi ara Burada fps, videonun kare hızıdır.
  • CHANGE_FRAME_RATE_ALWAYS ile setFrameRate() çağıran uygulamaları kesinlikle önermeyiz Video oynatmanın birkaç dakika veya daha kısa sürmesini beklediğiniz durumlarda.

Video oynatma uygulamaları için örnek entegrasyon

Video oynatma uygulamalarına yenileme hızı anahtarlarını entegre etmek için aşağıdaki adımları uygulamanız önerilir:

  1. changeFrameRateStrategy ile ilgili karar verin:
    1. Film gibi uzun süre devam eden bir video oynatıyorsanız MATCH_CONTENT_FRAMERATE_ALWAYS kullanın.
    2. Film fragmanı gibi kısa bir video oynatıyorsanız CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS düğmesini kullanın.
  2. changeFrameRateStrategy CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS ise için 4. adıma gidin.
  3. Kesintisiz olmayan yenileme hızı değişiminin gerçekleşip gerçekleşmediğini kontrol ederek iki gerçeğin de doğru olduğunu
    1. Geçerli yenileme hızından itibaren kesintisiz mod geçişi yapılamaz ( C) videonun kare hızına (V diyelim). Bu, C ve V farklı ve Display.getMode().getAlternativeRefreshRates V'nin katlarını içermez.
    2. Kullanıcı, kesintisiz olmayan yenileme hızı değişikliklerini etkinleştirdi. Google'da DisplayManager.getMatchContentFrameRateUserPreference MATCH_CONTENT_FRAMERATE_ALWAYS değerini döndürür
  4. Geçiş sorunsuz olacaksa aşağıdakileri yapın:
    1. setFrameRate numaralı telefonu arayın ve fps, FRAME_RATE_COMPATIBILITY_FIXED_SOURCE, ve changeFrameRateStrategy (burada fps, videonun kare hızıdır).
    2. Video oynatmayı başlat
  5. Sorunsuz olmayan bir mod değişikliği gerçekleşmek üzereyse aşağıdakileri yapın:
    1. Kullanıcıyı bilgilendirmek için kullanıcı deneyimini gösterin. Şunun için bir yöntem uygulamanızı önerdiğimizi unutmayın: kullanıcının bu kullanıcı deneyimini kapatmasını ve 5.d adımındaki ek gecikmeyi atlamasını sağlayın. Bu çünkü önerilen gecikme süresi, daha kısa geçiş süreleri sağlar.
    2. setFrameRate numaralı telefonu arayın ve fps, FRAME_RATE_COMPATIBILITY_FIXED_SOURCE, ve CHANGE_FRAME_RATE_ALWAYS Burada fps videonun kare hızıdır.
    3. onDisplayChanged e-posta adresini bekleyin. geri arama.
    4. Mod geçişinin tamamlanması için 2 saniye bekleyin.
    5. Video oynatmayı başlat

Yalnızca sorunsuz geçişi destekleyen sözde kod aşağıdaki gibidir:

SurfaceControl.Transaction transaction = new SurfaceControl.Transaction();
transaction.setFrameRate(surfaceControl,
    contentFrameRate,
    FRAME_RATE_COMPATIBILITY_FIXED_SOURCE,
    CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS);
transaction.apply();
beginPlayback();

Yukarıda açıklandığı gibi, sorunsuz ve kesintisiz olmayan geçişi destekleyen sözde kod aşağıdaki gibidir:

SurfaceControl.Transaction transaction = new SurfaceControl.Transaction();
if (isSeamlessSwitch(contentFrameRate)) {
  transaction.setFrameRate(surfaceControl,
      contentFrameRate,
      FRAME_RATE_COMPATIBILITY_FIXED_SOURCE,
      CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS);
  transaction.apply();
  beginPlayback();
} else if (displayManager.getMatchContentFrameRateUserPreference()
      == MATCH_CONTENT_FRAMERATE_ALWAYS) {
  showRefreshRateSwitchUI();
  sleep(shortDelaySoUserSeesUi);
  displayManager.registerDisplayListener(…);
  transaction.setFrameRate(surfaceControl,
      contentFrameRate,
      FRAME_RATE_COMPATIBILITY_FIXED_SOURCE,
      CHANGE_FRAME_RATE_ALWAYS);
  transaction.apply();
  waitForOnDisplayChanged();
  sleep(twoSeconds);
  hideRefreshRateSwitchUI();
  beginPlayback();
}