Cómo llamar a los métodos del motor flutter desde otro hilo

9

Estoy usando flutter desktop para linux. Llamo a un método llamado MarkTextureFrameAvailableque se supone que marca una textura para que el motor la vuelva a procesar. Como estoy programando un reproductor de video, necesito llamar MarkTextureFrameAvailabledesde el hilo del reproductor. El problema es que el motor me obliga a llamar MarkTextureFrameAvailable(y cualquier otro método del motor) desde el hilo que creó el motor.

Puede ver que todas las llamadas al motor terminan en el shell, que siempre verifica si las llamadas se realizan desde el mismo hilo que creó la llamada:

task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread()

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

Así es como estoy creando el motor de aleteo:

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

Como puede ver, el subproceso que crea el motor se bloquea, flutter_controller.RunEventLoop();que es el único lugar en el que podría colocar un despachador de eventos que obligó a las cosas a ejecutarse desde el subproceso de main. No me gusta esta idea. Aunque RunEventLoopWithTimeoutexista, necesito poner un tiempo de espera y seguir revisando una cola para MarkTextureFrameAvailablellamadas. No creo que esto sea óptimo.

Entonces, ¿cómo debo llamar MarkTextureFrameAvailabledesde el hilo principal?

Encontré un ejemplo de uso MarkTextureFrameAvailableaquí: https://github.com/cloudwebrtc/flutter-webrtc/blob/desktop/common/src/flutter_video_renderer.cc#L90 y parece que es otro hilo que lo llama. ¿Como es posible? Cuando lo hago, me sale un error FATAL, pero él lo hace y funciona.

Pasé dos días tratando de averiguar qué hilo llama a OnFrame en este ejemplo, pero no pude averiguarlo porque usa https://github.com/flutter-webrtc/libwebrtc que usa el webrtc de google: https://github.com/ JumpingYang001 / webrtc, que es demasiado grande para que yo pueda encontrar de dónde se llama a OnFrame. Pero me debe de un hilo. ¿Como es posible?

Lucas Zanella
fuente
Si desea una alternativa al uso de un tiempo de espera para ejecutar tareas periódicas en el runloop principal, puede enviar un PR del motor Flutter para exponer glfwPostEmptyEvent a través de un contenedor. Tener una manera de activar el runloop principal es una adición razonable a la API de incrustación GLFW.
smorgan
@smorgan Lo intentaré, pero estoy asombrado de cómo funciona este ejemplo: github.com/cloudwebrtc/flutter-webrtc/blob/desktop/common/src/… sin RunEventLoopWithTimeOut. Dado que bloquea el hilo principal flutter_controller.RunEventLoop(), entonces seguramente MarkTextureFrameAvailabledebe ser llamado desde otro hilo, ¡lo que debería ser imposible!
Lucas Zanella
Advertencia rápida antes de mi comentario: nunca escuché sobre Flutter, sé muy poco sobre Linux y estoy en el móvil, así que definitivamente no estoy mirando el código en este momento. Espero poder seguir siendo de ayuda. :) El ejemplo que diste tiene su renderizador de video heredado de lo que parece ser la instancia principal del renderizador de flutter. Existe OnRenderuna anulación virtual de Flutter, por lo que es invocado por el hilo Flutter.
Pickle Rick

Respuestas:

3

Vea mi comentario para la advertencia de esta respuesta. Parece que el proyecto de ejemplo que proporcionó logra esto con un simple truco. Crean una nueva clase que hereda la clase del procesador de aleteo, anulando OnFrameentre otras cosas. Cuando se llama a esa anulación, está en el contexto del hilo Flutter y funciona como se esperaba.

Pickle Rick
fuente
¡Muchas gracias por tu esfuerzo por ayudar! Sin embargo, la clase de Flutter que subclasifica es la Texture,que no tiene el método onFrame. Ese método onFrame es el RTCVideoRendererque no tiene nada que ver con Flutter.
Lucas Zanella
Ver aquí . Parece que anulan Flutter y posiblemente usan un sistema de complemento compatible. Mi mejor consejo sería leer la documentación de Flutter. Estaría dispuesto a apostar si colocaras un BP en OnFrame, sería en el contexto del hilo Flutter como se esperaba.
Pickle Rick
Ya estoy usando el sistema de complementos y he leído la documentación, no hay un método onFrame. Lo único de Flutter en la clase FlutterVideoRenderer es Texture, que no tiene método onFrame. En realidad, encontré dónde se define onFrame, y es algo de la biblioteca WebRTC como puede ver aquí github.com/JumpingYang001/webrtc/…
Lucas Zanella
@LucasZanella Pickle Rick tiene razón, FlutterVideoRenderer hereda de dos clases: Texture(línea 16) y RTCVideoRenderer<scoped_refptr<RTCVideoFrame>>(línea 17) (C ++ permite herencia múltiple) y luego anula el OnFramemétodo (línea 24). Cuando OnFramese dispara el evento, se ejecuta en el contexto de su hilo principal.
4LegsDrivenCat
@ 4LegsDrivenCat pero OnFrame no es de Flutter, es de RTCVideoRenderer que no es de Flutter
Lucas Zanella