Estoy usando flutter desktop para linux. Llamo a un método llamado MarkTextureFrameAvailable
que se supone que marca una textura para que el motor la vuelva a procesar. Como estoy programando un reproductor de video, necesito llamar MarkTextureFrameAvailable
desde 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 RunEventLoopWithTimeout
exista, necesito poner un tiempo de espera y seguir revisando una cola para MarkTextureFrameAvailable
llamadas. No creo que esto sea óptimo.
Entonces, ¿cómo debo llamar MarkTextureFrameAvailable
desde el hilo principal?
Encontré un ejemplo de uso MarkTextureFrameAvailable
aquí: 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 seguramenteMarkTextureFrameAvailable
debe ser llamado desde otro hilo, ¡lo que debería ser imposible!OnRender
una 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
OnFrame
entre 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 elRTCVideoRenderer
que no tiene nada que ver con Flutter.FlutterVideoRenderer
hereda de dos clases:Texture
(línea 16) yRTCVideoRenderer<scoped_refptr<RTCVideoFrame>>
(línea 17) (C ++ permite herencia múltiple) y luego anula elOnFrame
método (línea 24). CuandoOnFrame
se dispara el evento, se ejecuta en el contexto de su hilo principal.