Framerate

Mit der Framerate API können Apps die Android-Plattform über den beabsichtigten Frame informieren. und ist nur für Apps verfügbar, die auf Android 11 (API-Level 30) oder höher ausgerichtet sind. Bisher haben die meisten Geräte nur eine Aktualisierungsrate eines Displays unterstützt. normalerweise bei 60 Hz, aber das hat sich geändert. Viele Geräte unterstützen jetzt zusätzliche Aktualisierungsraten wie 90 Hz oder 120 Hz. Einige Geräte unterstützen eine nahtlose Aktualisierungsrate. während andere kurz einen schwarzen Bildschirm zeigen (normalerweise eine Sekunde lang).

Der Hauptzweck der API besteht darin, Apps zu ermöglichen, alle die unterstützten Aktualisierungsraten für das Display. Beispiel: Eine App spielt ein 24-Hz-Video ab. über die setFrameRate() aufgerufen wird, kann das dazu führen, dass auf dem Gerät das Display gewechselt wird. von 60 Hz auf 120 Hz aktualisiert. Die neue Aktualisierungsrate ermöglicht ruckelfreie Wiedergabe von 24-Hz-Videos, ohne dass ein 3:2-Pulldown-Menü erforderlich ist. erforderlich, um dasselbe Video auf einem 60-Hz-Display wiederzugeben. Dies führt zu einer besseren User Experience Nutzererfahrung.

Grundlegende Nutzung

Android bietet verschiedene Möglichkeiten, auf Oberflächen zuzugreifen und diese zu steuern, Versionen der setFrameRate() API Jede Version der API verwendet den und funktioniert genauso wie die anderen:

Die App berücksichtigt nicht die tatsächlich unterstützten Display-Aktualisierungsraten, Rufen Sie dazu den folgenden Befehl auf: Display.getSupportedModes(), um setFrameRate() sicher anzurufen. Selbst wenn das Gerät nur 60 Hz unterstützt, rufe setFrameRate() mit der von deiner App bevorzugten Framerate auf. Geräte, die nicht genau an die Framerate der App angepasst sind, bleiben mit die aktuelle Aktualisierungsrate des Displays.

Um zu sehen, ob ein Aufruf von setFrameRate() zu einer Änderung der Displayaktualisierung führt und melden Sie sich für Benachrichtigungen zu Displayänderungen an, indem Sie DisplayManager.registerDisplayListener() oder AChoreographer_registerRefreshRateCallback().

Beim Aufrufen von setFrameRate() ist es am besten, die genaue Framerate zu übergeben, als das Runden auf eine ganze Zahl. Zum Beispiel beim Rendern eines Videos, das 29,97 Hz wird bei 29,97 ausgegeben und nicht auf 30 gerundet.

Für Video-Apps sollte der an setFrameRate() übergebene Kompatibilitätsparameter festgelegt werden an Surface.FRAME_RATE_COMPATIBILITY_FIXED_SOURCE, um einen zusätzlichen Hinweis für die Android-Plattform, die die App verwendet, um sie an eine nicht übereinstimmende Aktualisierungsrate des Displays. Dies führt zu Ruckeln.

In einigen Fällen sendet die Videooberfläche zwar keine Frames mehr, aber sie bleibt unverändert. einige Zeit auf dem Bildschirm sichtbar sind. Häufige Szenarien sind die Wiedergabe das Ende des Videos erreicht oder der Nutzer die Wiedergabe anhält. In diesen Fällen Rufen Sie setFrameRate() auf und setzen Sie den Framerate-Parameter auf 0, um die Framerate auf den Standardwert zurückgesetzt. Framerate-Einstellung löschen ist nicht notwendig, wenn die Oberfläche zerstört oder weil der Nutzer zu einer anderen App wechselt. Framerate löschen wenn die Oberfläche sichtbar bleibt und nicht verwendet wird.

Nicht nahtloser Wechsel der Framerate

Auf einigen Geräten kann es beim Umschalten der Aktualisierungsrate zu visuellen Unterbrechungen wie einem schwarzen ein oder zwei Sekunden lang. Dies geschieht in der Regel bei Set-Top-Boxen, TV-Panels und ähnliche Geräte. Standardmäßig wechselt das Android-Framework nicht den Modus wenn der Surface.setFrameRate() API aufgerufen, um solche optischen Unterbrechungen zu vermeiden.

Einige Nutzende bevorzugen eine visuelle Unterbrechung am Anfang und am Ende von längeren Videos. Dadurch wird die Aktualisierungsrate des Bildschirms Video-Framerate ändern und Framerate-Konvertierungsartefakte wie 3:2 vermeiden Pulldown-Menü zur Wiedergabe des Films.

Aus diesem Grund kann der Wechsel der nicht nahtlosen Aktualisierungsrate aktiviert werden, wenn sowohl die Opt-in für Nutzer und Apps:

Wir empfehlen, immer CHANGE_FRAME_RATE_ALWAYS zu verwenden für Videos mit langer Ausführungszeit (z. B. Filme). Das liegt daran, dass der Vorteil die Framerate des Videos überwiegt die Unterbrechung, die beim Ändern der Aktualisierungsrate.

Weitere Empfehlungen

Beachten Sie bei häufigen Szenarien die folgenden Empfehlungen.

Mehrere Oberflächen

Die Android-Plattform ist darauf ausgelegt, auf mehreren Oberflächen mit unterschiedlichen Framerate-Einstellungen. Wenn Ihre App mehrere Oberflächen mit unterschiedlichen Frame-Rates verwenden, rufen Sie setFrameRate() mit dem Frame-Rate für die jeweilige Oberfläche. Auch wenn auf dem Gerät mehrere Apps Mit dem Splitscreen-Modus oder dem Bild-im-Bild-Modus kann jede App setFrameRate() für ihre eigenen Oberflächen.

Die Plattform ändert sich nicht an der Framerate der App.

Auch wenn das Gerät die Framerate unterstützt, die von der App in einem Aufruf von setFrameRate(), es gibt Fälle, in denen das Display das Display nicht wechselt die Aktualisierungsrate erhöhen. Beispielsweise kann eine Oberfläche mit höherer Priorität oder das Gerät befindet sich möglicherweise im Energiesparmodus (Einstellung Einschränkung der Aktualisierungsrate des Displays, um den Akku zu schonen). Die App muss immer noch ordnungsgemäß funktioniert, wenn das Gerät die Aktualisierungsrate des Displays nicht auf die der Framerate der App, auch wenn das Gerät im normalen Modus wechselt. Situation.

Die App entscheidet selbst, wie sie reagieren soll, wenn die Aktualisierungsrate des Displays nicht mit der Framerate der App übereinstimmt. Bei Videos ist die Framerate fest auf die von Quellvideo und Pulldown-Menü zur Anzeige des Video-Contents erforderlich. A wird das Spiel stattdessen mit der Aktualisierungsrate des Displays und dabei die bevorzugte Frame-Rate beibehalten. Der Wert sollte von der App nicht geändert werden. je nach Funktion der Plattform an setFrameRate() übergibt. Sie sollte eingestellt bleiben die bevorzugte Framerate der App anpassen, unabhängig davon, wie die App mit Fällen umgeht, die Plattform sich nicht an die Anforderungen der App anpasst. Auf diese Weise können Sie Bedingungen geändert werden, sodass zusätzliche Aktualisierungsraten für das Display verwendet werden können. Plattform die richtigen Informationen hat, um zum bevorzugten Frame der App zu wechseln zu zahlen.

Falls die App nicht mit der Aktualisierungsrate des Displays ausgeführt werden kann, zeigt die App Präsentationszeitstempel für jeden Frame angeben. Verwenden Sie dazu einen der Mechanismen der Plattform zum Festlegen von Präsentationszeitstempeln:

Wenn Sie diese Zeitstempel verwenden, kann die Plattform auch keinen App-Frame präsentieren was zu unnötigem Rumpf führen würde. Richtige Verwendung des Frames die Zeitstempel von Präsentationen ist ein bisschen kompliziert. Informationen zu Spielen findest du in unserer Leitfaden zur Taktung von Frames findest du weitere Informationen zur Vermeidung von Rauschen. Außerdem kannst du Android Frame Pacing Library.

In einigen Fällen wechselt die Plattform zu einem Vielfachen der Framerate der App. angegeben in setFrameRate(). Eine App kann z. B. setFrameRate() aufrufen mit 60 Hz und das Gerät schaltet das Display auf 120 Hz um. Ein Grund dafür, tritt auf, wenn eine andere App eine Oberfläche mit einer Framerate von 24 Hz hat. In Bei einem Display mit 120 Hz sind sowohl die 60-Hz-Oberfläche als auch 24-Hz-Oberfläche ohne Pull-down-Verfahren.

Wenn der Bildschirm mit einem Vielfachen der Framerate der App ausgeführt wird, zeigt die App sollten Präsentationszeitstempel für jeden Frame angeben, um unnötige Richtig schlecht. Bei Spielen hilft die Android Frame Pacing Library, die Zeitstempel der Frame-Präsentation.

setFrameRate() im Vergleich zu PreferredDisplayModeId

WindowManager.LayoutParams.preferredDisplayModeId ist eine weitere Möglichkeit, wie Apps ihre Framerate an die Plattform senden können. Einige Apps nur die Aktualisierungsrate des Displays ändern, statt andere Einstellungen für den Anzeigemodus wie z. B. die Bildschirmauflösung. Verwenden Sie im Allgemeinen setFrameRate() statt preferredDisplayModeId. Das setFrameRate() ist einfacher zu nutzen, da die App nicht die der Anzeigemodi, um einen Modus mit einer bestimmten Framerate zu finden.

setFrameRate() bietet der Plattform mehr Möglichkeiten, eine kompatible in Szenarien mit mehreren Oberflächen, die auf unterschiedliche Frame-Rates. Stellen Sie sich beispielsweise ein Szenario vor, bei dem zwei Apps auf einem Pixel 4 im Splitscreen-Modus, wobei eine App ein 24-Hz-Video abspielt und eine scrollbare Liste. Pixel 4 unterstützt zwei Display-Aktualisierungsraten: 60 Hz und 90 Hz. Mit der preferredDisplayModeId API wird gezwungen, entweder 60 Hz oder 90 Hz auszuwählen. Durch den Anruf setFrameRate() mit 24 Hz bietet die Videooberfläche der Plattform mehr zur Framerate des Quellvideos, sodass die Plattform wählen Sie für die Aktualisierungsrate des Displays 90 Hz aus. Das ist hier besser als 60 Hz Szenario.

Es gibt jedoch Szenarien, in denen preferredDisplayModeId verwendet werden sollte statt setFrameRate(). Beispiel:

  • Wenn die App die Auflösung oder andere Einstellungen für den Anzeigemodus ändern möchte, preferredDisplayModeId verwenden.
  • Die Plattform wechselt nur als Reaktion auf einen Aufruf von setFrameRate(), wenn der Moduswechsel leicht ist, dies jedoch unwahrscheinlich ist für die Nutzenden erkennbar sind. Wenn die App die Displayaktualisierung bevorzugt, auch wenn ein intensiver Moduswechsel erforderlich ist (z. B. auf einem Android TV-Gerät). Gerät), verwenden Sie preferredDisplayModeId.
  • Apps, die den Bildschirm nicht verarbeiten können, der in einem Vielfachen der App-Frames ausgeführt wird bei dem für jeden Frame ein Zeitstempel für die Präsentation festgelegt werden muss, preferredDisplayModeId verwenden.

setFrameRate() im Vergleich zu PreferredRefreshRate

WindowManager.LayoutParams#preferredRefreshRate legt eine bevorzugte Frame-Rate im App-Fenster fest und die Rate gilt für alle Oberflächen des Fensters. In der App sollte die bevorzugte Framerate unabhängig von den unterstützten Bildwiederholraten des Geräts, ähnlich wie setFrameRate(), um dem Planer einen besseren Eindruck davon zu vermitteln, Frame-Rate.

preferredRefreshRate wird bei Oberflächen, die setFrameRate() verwenden, ignoriert. In Verwende nach Möglichkeit allgemein setFrameRate().

bevorzugte Aktualisierungsrate im Vergleich zu PreferredDisplayModeId

Wenn Apps nur die bevorzugte Aktualisierungsrate ändern möchten, empfiehlt sich die Verwendung von preferredRefreshRate statt preferredDisplayModeId.

Zu häufiges Aufrufen von setFrameRate() vermeiden

Obwohl der setFrameRate()-Aufruf in Bezug auf die Leistung nicht sehr teuer ist, Apps sollten setFrameRate() nicht in jedem Frame oder mehrmals pro Frame aufrufen. 2. Aufrufe an setFrameRate() führen wahrscheinlich zu einer Änderung des Aktualisierungsrate des Bildschirms, was zu einem Rückgang der Frame während des Übergangs führen kann. Sie sollten die richtige Framerate im Voraus ermitteln und dann setFrameRate() einmal.

Nutzung für Spiele und andere Apps ohne Video

Video ist zwar der primäre Anwendungsfall für die setFrameRate() API, kann aber auch die für andere Apps verwendet werden. Beispiel: Ein Spiel, das nicht mehr als 60 Hz (um den Stromverbrauch zu reduzieren und längere Spielsitzungen zu erreichen) kann Anrufe Surface.setFrameRate(60, Surface.FRAME_RATE_COMPATIBILITY_DEFAULT) In dieser Geräte, die standardmäßig mit 90 Hz laufen, stattdessen mit 60 Hz, während der das Spiel aktiv ist. Dadurch wird verhindert, dass der Nutzer ruckelt, wenn das Spiel das Spiel bei 60 Hz, das Display bei 90 Hz.

Verwendung von FRAME_RATE_COMPATIBILITY_FIXED_SOURCE

FRAME_RATE_COMPATIBILITY_FIXED_SOURCE ist nur für Video-Apps vorgesehen. Für nicht für Videos: FRAME_RATE_COMPATIBILITY_DEFAULT verwenden.

Strategie zum Ändern der Framerate auswählen

  • Wenn Apps mit langer Laufzeit wie z. B. Filme, setFrameRate(fps, FRAME_RATE_COMPATIBILITY_FIXED_SOURCE, CHANGE_FRAME_RATE_ALWAYS) anrufen wobei fps für die Frame-Rate des Videos steht.
  • Wir raten dringend davon ab, Apps setFrameRate() mit CHANGE_FRAME_RATE_ALWAYS aufzurufen wenn die Videowiedergabe höchstens mehrere Minuten dauern soll.

Beispielintegration für Apps zur Videowiedergabe

Wir empfehlen die folgenden Schritte zum Integrieren von Schaltern für die Aktualisierungsrate in Apps zur Videowiedergabe:

  1. Legen Sie die changeFrameRateStrategy fest: <ph type="x-smartling-placeholder">
      </ph>
    1. Wenn Sie ein Video mit langer Laufzeit, z. B. einen Film, abspielen möchten, verwenden Sie MATCH_CONTENT_FRAMERATE_ALWAYS.
    2. Verwende CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS, wenn du ein kurzes Video abspielst, z. B. einen Move-Trailer
  2. Wenn changeFrameRateStrategy CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS ist , fahren Sie mit Schritt 4 fort.
  3. Prüfen Sie, ob ein Wechsel der Aktualisierungsrate bei einer nicht nahtlosen Aktualisierung bevorsteht. dass diese beiden Fakten wahr sind: <ph type="x-smartling-placeholder">
      </ph>
    1. Bei der aktuellen Aktualisierungsrate ist ein Wechsel in den nahtlosen Modus nicht möglich. C) zur Framerate des Videos hinzu (wir nennen es V). Dadurch wird wenn C und V unterschiedlich sind und Display.getMode().getAlternativeRefreshRates kein Vielfaches von V enthält.
    2. Der Nutzer hat der nahtlosen Änderung der Aktualisierungsrate zugestimmt. Sie können indem Sie prüfen, ob DisplayManager.getMatchContentFrameRateUserPreference gibt zurück: MATCH_CONTENT_FRAMERATE_ALWAYS
  4. Wenn der Wechsel reibungslos verläuft, gehen Sie so vor: <ph type="x-smartling-placeholder">
      </ph>
    1. setFrameRate anrufen und übergeben es fps, FRAME_RATE_COMPATIBILITY_FIXED_SOURCE, und changeFrameRateStrategy, wobei fps die Framerate des Videos ist.
    2. Videowiedergabe starten
  5. Wenn eine Änderung des nicht nahtlosen Modus bevorsteht, gehen Sie so vor: <ph type="x-smartling-placeholder">
      </ph>
    1. Zeigen Sie die UX, um den Nutzer zu benachrichtigen. Wir empfehlen, eine Methode zu implementieren, Nutzende zu schließen und die zusätzliche Verzögerung in Schritt 5.d zu überspringen. Dies ist da die von uns empfohlene Verzögerung auf Bildschirmen größer als erforderlich ist, schnellere Wechselzeiten aufweisen.
    2. setFrameRate anrufen und übergeben es fps, FRAME_RATE_COMPATIBILITY_FIXED_SOURCE, und CHANGE_FRAME_RATE_ALWAYS Dabei ist fps die Framerate des Videos.
    3. Warten Sie, bis die onDisplayChanged Callback des Nutzers an.
    4. Warten Sie zwei Sekunden, bis der Moduswechsel abgeschlossen ist.
    5. Videowiedergabe starten

Der Pseudocode, der ausschließlich den nahtlosen Wechsel unterstützt, lautet wie folgt:

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

Der oben beschriebene Pseudocode zur Unterstützung des nahtlosen und nahtlosen Wechsels lautet wie folgt:

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();
}