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?
fuente

flutter_controller.RunEventLoop(), entonces seguramenteMarkTextureFrameAvailabledebe ser llamado desde otro hilo, ¡lo que debería ser imposible!OnRenderuna anulación virtual de Flutter, por lo que es invocado por el hilo Flutter.Respuestas:
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.fuente
Texture,que no tiene el método onFrame. Ese método onFrame es elRTCVideoRendererque no tiene nada que ver con Flutter.FlutterVideoRendererhereda de dos clases:Texture(línea 16) yRTCVideoRenderer<scoped_refptr<RTCVideoFrame>>(línea 17) (C ++ permite herencia múltiple) y luego anula elOnFramemétodo (línea 24). CuandoOnFramese dispara el evento, se ejecuta en el contexto de su hilo principal.