Comment appeler les méthodes du moteur de flutter à partir d'un autre thread


9

J'utilise Flutter Desktop pour Linux. MarkTextureFrameAvailableJ'appelle une méthode appelée qui est censée marquer une texture à restituer par le moteur. Étant donné que je programme un lecteur vidéo, je dois appeler à MarkTextureFrameAvailablepartir du fil du lecteur. Le problème est que le moteur me force à appeler MarkTextureFrameAvailable(et toute autre méthode de moteur) à partir du thread qui a créé le moteur.

Vous pouvez voir que tous les appels au moteur se retrouvent dans le shell qui vérifie toujours si les appels sont effectués à partir du même thread qui a créé l'appel:

task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread()

( https://github.com/flutter/engine/blob/master/shell/common/shell.cc#L838 )

Voici comment je crée le moteur de flutter:

int main(int argc, char **argv) {
  //..

  flutter::FlutterWindowController flutter_controller(icu_data_path);

  // Start the engine.
  if (!flutter_controller.CreateWindow(800, 600, "Flutter WebRTC Demo", assets_path,
                                       arguments)) {
    return EXIT_FAILURE;
  }

  // Register any native plugins.
  FlutterWebRTCPluginRegisterWithRegistrar(
      flutter_controller.GetRegistrarForPlugin("FlutterWebRTCPlugin"));

  // Run until the window is closed.
  flutter_controller.RunEventLoop();
  return EXIT_SUCCESS;
}

comme vous pouvez le voir, le thread qui crée le moteur est bloqué, flutter_controller.RunEventLoop();ce qui est le seul endroit où je pourrais mettre un répartiteur d'événements qui a forcé les choses à être exécutées à partir du thread principal. Je n'aime pas cette idée. Même s'il RunEventLoopWithTimeoutexiste, je dois mettre un délai d'attente et continuer à vérifier dans une file d'attente pour les MarkTextureFrameAvailableappels. Je ne pense pas que ce soit optimal.

Alors, comment dois-je appeler à MarkTextureFrameAvailablepartir du thread principal?

J'ai trouvé un exemple d'utilisation MarkTextureFrameAvailableici: https://github.com/cloudwebrtc/flutter-webrtc/blob/desktop/common/src/flutter_video_renderer.cc#L90 et il semble que ce soit un autre fil qui l'appelle. Comment est-ce possible? Quand je le fais, j'obtiens une erreur FATAL, mais il le fait et cela fonctionne?

J'ai passé deux jours à essayer de comprendre quel fil appelle OnFrame sur cet exemple, mais je n'ai pas pu le savoir car il utilise https://github.com/flutter-webrtc/libwebrtc qui utilise le webrtc de Google: https://github.com/ JumpingYang001 / webrtc qui est trop gros pour que je trouve d'où OnFrame est appelé. Mais il me faut d'un fil. Comment est-ce possible?


Si vous souhaitez une alternative à l'utilisation d'un délai d'expiration pour exécuter des tâches périodiques dans la boucle d'exécution principale, vous pouvez soumettre un PR de moteur Flutter pour exposer glfwPostEmptyEvent via un wrapper. Avoir un moyen de réveiller la boucle d'exécution principale est un ajout raisonnable à l'API d'intégration GLFW.
smorgan

@smorgan Je vais essayer ça, mais je suis étonné de voir comment cet exemple: github.com/cloudwebrtc/flutter-webrtc/blob/desktop/common/src/… fait sans RunEventLoopWithTimeOut. Puisqu'il bloque le thread principal avec flutter_controller.RunEventLoop(), alors à coup sûr MarkTextureFrameAvailabledoit être appelé à partir d'un autre thread, ce qui devrait être impossible!
Lucas Zanella

Mise en garde rapide avant mon commentaire - je n'ai jamais entendu parler de Flutter, je sais très peu de choses sur Linux et je suis sur mobile, donc je ne regarde pas le code en ce moment. J'espère que je pourrai encore être utile. :) L'exemple que vous avez donné a son rendu vidéo hérité de ce qui ressemble à l'instance principale du rendu Flutter. Il OnRenders'agit d'un remplacement virtuel de Flutter, il est donc invoqué par le thread Flutter.
Pickle Rick

Réponses:


3

Voir mon commentaire pour la mise en garde à cette réponse. Il semble que l'exemple de projet que vous avez fourni accomplisse cela avec une astuce simple. Ils créent une nouvelle classe qui hérite de la classe de rendu Flutter, remplaçant OnFrameentre autres choses. Lorsque ce remplacement est appelé, il se situe dans le contexte du thread Flutter et fonctionne donc comme prévu.


Merci beaucoup par vos efforts pour nous aider! Cependant, la classe de Flutter qu'elle sous-classe est Texture,qui n'a pas de méthode onFrame. Cette méthode onFrame est à partir de RTCVideoRendererlaquelle n'a rien à voir avec Flutter.
Lucas Zanella

Voyez ici . Il semble qu'ils remplacent Flutter et utilisent éventuellement un système de plug-ins pris en charge. Mon meilleur conseil serait de lire la documentation Flutter. Je serais prêt à parier que si vous placez un BP dans OnFrame, ce serait dans le contexte du thread Flutter comme prévu.
Pickle Rick

J'utilise déjà le système de plugins et j'ai lu la documentation, il n'y a pas de méthode onFrame. La seule chose de Flutter dans la classe FlutterVideoRenderer est Texture, qui n'a pas de méthode onFrame. En fait, j'ai trouvé où onFrame est défini, et c'est une chose de la bibliothèque WebRTC comme vous pouvez le voir ici github.com/JumpingYang001/webrtc/…
Lucas Zanella

@LucasZanella Pickle Rick a raison, FlutterVideoRenderer hérite de deux classes - Texture(ligne 16) et RTCVideoRenderer<scoped_refptr<RTCVideoFrame>>(ligne 17) (C ++ permet l'héritage multiple), puis il remplace la OnFrameméthode (ligne 24). Lorsqu'un OnFrameévénement est déclenché, il est exécuté dans le contexte de votre thread principal.
4LegsDrivenCat

@ 4LegsDrivenCat mais OnFrame n'est pas de Flutter, c'est de RTCVideoRenderer qui n'est pas de Flutter
Lucas Zanella
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.