Я использую настольный компьютер для Linux. Я MarkTextureFrameAvailable
вызываю метод, который должен пометить текстуру, которая должна быть обработана движком. Поскольку я программирую видеоплеер, мне нужно позвонить MarkTextureFrameAvailable
из ветки плеера. Проблема в том, что двигатель заставляет меня вызывать MarkTextureFrameAvailable
(и любой другой метод двигателя) из потока, который создал двигатель.
Вы можете видеть, что все вызовы механизма заканчиваются в оболочке, которая всегда проверяет, выполняются ли вызовы из того же потока, который создал вызов:
task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread()
( https://github.com/flutter/engine/blob/master/shell/common/shell.cc#L838 )
Вот как я создаю движок флаттера:
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;
}
Как вы можете видеть, поток, который создает движок, блокируется, и flutter_controller.RunEventLoop();
это единственное место, где я мог бы разместить диспетчер событий, который заставлял вещи выполняться из потока main. Мне не нравится эта идея. Несмотря на то RunEventLoopWithTimeout
, что существует, мне нужно поставить тайм-аут и продолжать проверять в очереди на MarkTextureFrameAvailable
звонки. Я не думаю, что это оптимально.
Так как мне звонить MarkTextureFrameAvailable
из основного потока?
Я нашел пример использования MarkTextureFrameAvailable
здесь: https://github.com/cloudwebrtc/flutter-webrtc/blob/desktop/common/src/flutter_video_renderer.cc#L90, и похоже, что это другой поток, который вызывает его. Как это возможно? Когда я делаю, я получаю ФАТАЛЬНУЮ ошибку, но он делает, и это работает?
Я потратил два дня, пытаясь выяснить, какой поток вызывает OnFrame в этом примере, но не смог выяснить, потому что он использует https://github.com/flutter-webrtc/libwebrtc, который использует webrtc Google: https://github.com/ JumpingYang001 / webrtc, который слишком велик, чтобы я мог найти, откуда вызывается OnFrame. Но это должен я из нити. Как это возможно?
источник
flutter_controller.RunEventLoop()
, то навернякаMarkTextureFrameAvailable
должен быть вызван из другого потока, что должно быть невозможно!OnRender
виртуальное переопределение флаттера поэтому он получает вызывается нитью Flutter.Ответы:
Смотрите мой комментарий для предупреждения к этому ответу. Похоже, что пример проекта, который вы предоставили, выполняет это с помощью простого трюка. Они создают новый класс, который наследует класс отрисовки флаттера, переопределяя
OnFrame
среди прочего. Когда вызывается это переопределение, это происходит в контексте потока Flutter и работает так, как ожидалось.источник
Texture,
которому относятся его подклассы , не имеет метода onFrame. Этот метод onFrame неRTCVideoRenderer
имеет ничего общего с Flutter.FlutterVideoRenderer
наследует от двух классов -Texture
(строка 16) иRTCVideoRenderer<scoped_refptr<RTCVideoFrame>>
(строка 17) (C ++ допускает множественное наследование), а затем переопределяетOnFrame
метод (строка 24). КогдаOnFrame
событие запускается, оно выполняется в контексте вашего основного потока.