Saya menggunakan flutter desktop untuk linux. Saya memanggil metode yang disebut MarkTextureFrameAvailableyang seharusnya menandai tekstur yang akan dirender ulang oleh mesin. Karena saya memprogram pemutar video, saya perlu menelepon MarkTextureFrameAvailabledari utas pemain. Masalahnya adalah bahwa mesin memaksa saya untuk memanggil MarkTextureFrameAvailable(dan metode mesin lainnya) dari utas yang menciptakan mesin.
Anda dapat melihat bahwa semua panggilan ke mesin berakhir di shell yang selalu melakukan pemeriksaan untuk melihat apakah panggilan dibuat dari utas yang sama yang membuat panggilan:
task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread()
( https://github.com/flutter/engine/blob/master/shell/common/shell.cc#L838 )
Inilah cara saya membuat mesin flutter:
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;
}
seperti yang Anda lihat, utas yang membuat mesin terhalang oleh flutter_controller.RunEventLoop();yang merupakan satu-satunya tempat saya bisa menempatkan dispatcher acara yang memaksa hal-hal untuk dieksekusi dari utas utama. Saya tidak suka ide ini. Meskipun RunEventLoopWithTimeoutada, saya harus membuat batas waktu dan terus memeriksa dalam antrian untuk MarkTextureFrameAvailablepanggilan. Saya rasa ini tidak optimal.
Jadi bagaimana saya harus menelepon MarkTextureFrameAvailabledari utas utama?
Saya menemukan contoh penggunaan di MarkTextureFrameAvailablesini: https://github.com/cloudwebrtc/flutter-webrtc/blob/desktop/common/src/flutter_video_renderer.cc#L90 dan sepertinya itu adalah utas lain yang menyebutnya. Bagaimana itu mungkin? Ketika saya melakukannya, saya mendapatkan kesalahan FATAL, tetapi ia melakukannya dan berfungsi?
Saya menghabiskan dua hari untuk mencari tahu thread mana yang memanggil OnFrame pada contoh ini tetapi tidak bisa mengetahuinya karena menggunakan https://github.com/flutter-webrtc/libwebrtc yang menggunakan webrtc google: https://github.com/ JumpingYang001 / webrtc yang terlalu besar bagi saya untuk menemukan dari mana OnFrame dipanggil. Tapi itu harus saya dari utas. Bagaimana itu mungkin?
flutter_controller.RunEventLoop(), maka pastinya MarkTextureFrameAvailabledipanggil dari utas lain, yang seharusnya tidak mungkin!
OnRenderadalah menimpa Flutter virtual sehingga dipanggil oleh benang Flutter.