Ich benutze Flutter Desktop für Linux. Ich rufe eine Methode namens aufMarkTextureFrameAvailable
, die eine Textur markieren soll, die von der Engine erneut gerendert werden soll. Da ich einen Videoplayer programmiere, muss ich über MarkTextureFrameAvailable
den Thread des Players aufrufen . Das Problem ist, dass die Engine mich zwingt, MarkTextureFrameAvailable
(und jede andere Engine-Methode) von dem Thread aus aufzurufen, der die Engine erstellt hat.
Sie können sehen, dass alle Aufrufe der Engine in der Shell landen, die immer prüft, ob die Aufrufe von demselben Thread stammen, der den Aufruf erstellt hat:
task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread()
( https://github.com/flutter/engine/blob/master/shell/common/shell.cc#L838 )
So erstelle ich die Flatter-Engine:
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;
}
Wie Sie sehen können, wird der Thread, der die Engine erstellt, blockiert. flutter_controller.RunEventLoop();
Dies ist der einzige Ort, an dem ich einen Ereignis-Dispatcher platzieren kann, der die Ausführung von Dingen aus dem Haupt-Thread erzwingt. Diese Idee gefällt mir nicht. Obwohl RunEventLoopWithTimeout
vorhanden, muss ich eine Zeitüberschreitung festlegen und weiterhin in einer Warteschlange nach MarkTextureFrameAvailable
Anrufen suchen . Ich denke nicht, dass dies optimal ist.
Wie soll ich MarkTextureFrameAvailable
vom Haupt-Thread aus aufrufen ?
Ich habe hier ein Anwendungsbeispiel MarkTextureFrameAvailable
gefunden: https://github.com/cloudwebrtc/flutter-webrtc/blob/desktop/common/src/flutter_video_renderer.cc#L90 und es sieht so aus, als wäre es ein anderer Thread, der es aufruft. Wie ist es möglich? Wenn ich das tue, bekomme ich einen FATAL-Fehler, aber er tut es und es funktioniert?
Ich habe zwei Tage lang versucht herauszufinden, welcher Thread OnFrame in diesem Beispiel aufruft, konnte es aber nicht herausfinden, da er https://github.com/flutter-webrtc/libwebrtc verwendet, das Googles Webrtc verwendet: https://github.com/ JumpingYang001 / webrtc, das zu groß für mich ist, um herauszufinden, woher OnFrame kommt. Aber es muss mir aus einem Thread. Wie ist es möglich?
quelle
flutter_controller.RunEventLoop()
,MarkTextureFrameAvailable
muss er sicher von einem anderen Thread aufgerufen werden, was unmöglich sein sollte!OnRender
handelt sich um eine virtuelle Überschreibung von Flutter, sodass es vom Flutter-Thread aufgerufen wird.Antworten:
Siehe meinen Kommentar für die Einschränkung dieser Antwort. Es scheint, dass das von Ihnen bereitgestellte Beispielprojekt dies mit einem einfachen Trick erreicht. Sie erstellen eine neue Klasse, die die Flatter-Renderer-Klasse erbt und
OnFrame
unter anderem überschreibt . Wenn diese Überschreibung aufgerufen wird, befindet sie sich im Kontext des Flutter-Threads und funktioniert wie erwartet.quelle
Texture,
, verfügt jedoch nicht über die onFrame-Methode. Diese onFrame-MethodeRTCVideoRenderer
hat nichts mit Flutter zu tun.FlutterVideoRenderer
erbt von zwei Klassen -Texture
(Zeile 16) undRTCVideoRenderer<scoped_refptr<RTCVideoFrame>>
(Zeile 17) (C ++ erlaubt Mehrfachvererbung) und überschreibt dann dieOnFrame
Methode (Zeile 24). Wenn einOnFrame
Ereignis ausgelöst wird, wird es im Kontext Ihres Hauptthreads ausgeführt.