Używam trzepotania pulpitu dla Linuksa. Nazywam metodę o nazwie, MarkTextureFrameAvailable
która ma oznaczać teksturę do ponownego wysłania przez silnik. Ponieważ programuję odtwarzacz wideo, muszę dzwonić MarkTextureFrameAvailable
z wątku odtwarzacza. Problem polega na tym, że silnik zmusza mnie do wywołania MarkTextureFrameAvailable
(i dowolnej innej metody silnika) z wątku, który utworzył silnik.
Możesz zobaczyć, że wszystkie wywołania silnika kończą się w powłoce, która zawsze sprawdza, czy połączenia są wykonywane z tego samego wątku, który utworzył połączenie:
task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread()
( https://github.com/flutter/engine/blob/master/shell/common/shell.cc#L838 )
Oto jak tworzę silnik trzepotania:
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;
}
jak widać, wątek tworzący silnik zostaje zablokowany przez flutter_controller.RunEventLoop();
to jedyne miejsce, w którym mogłem umieścić dyspozytora zdarzeń, który wymusił wykonanie rzeczy z wątku głównego. Nie podoba mi się ten pomysł. Mimo że RunEventLoopWithTimeout
istnieje, muszę ustawić limit czasu i sprawdzać kolejkę MarkTextureFrameAvailable
połączeń. Nie sądzę, żeby to było optymalne.
Jak mam zadzwonić MarkTextureFrameAvailable
z głównego wątku?
Znalazłem przykład użycia MarkTextureFrameAvailable
tutaj: https://github.com/cloudwebrtc/flutter-webrtc/blob/desktop/common/src/flutter_video_renderer.cc#L90 i wygląda na to, że to kolejny wątek, który to nazywa. Jak to jest możliwe? Kiedy to robię, pojawia się FATALNY błąd, ale on robi i to działa?
Spędziłem dwa dni, próbując dowiedzieć się, który wątek wywołuje OnFrame w tym przykładzie, ale nie mogłem się dowiedzieć, ponieważ używa https://github.com/flutter-webrtc/libwebrtc, który używa Google webrtc: https://github.com/ JumpingYang001 / webrtc, który jest dla mnie za duży, aby znaleźć skąd pochodzi OnFrame. Ale to musi mnie z wątku. Jak to jest możliwe?
źródło
flutter_controller.RunEventLoop()
, to na pewnoMarkTextureFrameAvailable
musi zostać wywołany z innego wątku, co powinno być niemożliwe!OnRender
jest wirtualnym zastąpieniem Fluttera, więc jest wywoływany przez wątek Fluttera.Odpowiedzi:
Zobacz mój komentarz dotyczący zastrzeżenia do tej odpowiedzi. Wygląda na to, że przykładowy projekt, który podałeś, realizuje to w prosty sposób. Tworzą nową klasę, która dziedziczy klasę renderującą trzepotanie, zastępując
OnFrame
między innymi. Wywołanie tego zastąpienia następuje w kontekście wątku Flutter i działa zgodnie z oczekiwaniami.źródło
Texture,
, które nie mają onFrame metody. Ta metoda onFrameRTCVideoRenderer
nie ma nic wspólnego z Flutter.FlutterVideoRenderer
dziedziczy z dwóch klas -Texture
(linia 16) iRTCVideoRenderer<scoped_refptr<RTCVideoFrame>>
(linia 17) (C ++ pozwala na wielokrotne dziedziczenie), a następnie zastępujeOnFrame
metodę (linia 24). PoOnFrame
uruchomieniu zdarzenia jest ono wykonywane w kontekście głównego wątku.