Saya menggunakan flutter desktop untuk linux. Saya memanggil metode yang disebut MarkTextureFrameAvailable
yang seharusnya menandai tekstur yang akan dirender ulang oleh mesin. Karena saya memprogram pemutar video, saya perlu menelepon MarkTextureFrameAvailable
dari 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 RunEventLoopWithTimeout
ada, saya harus membuat batas waktu dan terus memeriksa dalam antrian untuk MarkTextureFrameAvailable
panggilan. Saya rasa ini tidak optimal.
Jadi bagaimana saya harus menelepon MarkTextureFrameAvailable
dari utas utama?
Saya menemukan contoh penggunaan di MarkTextureFrameAvailable
sini: 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?
sumber
flutter_controller.RunEventLoop()
, maka pastinyaMarkTextureFrameAvailable
dipanggil dari utas lain, yang seharusnya tidak mungkin!OnRender
adalah menimpa Flutter virtual sehingga dipanggil oleh benang Flutter.Jawaban:
Lihat komentar saya untuk peringatan untuk jawaban ini. Tampaknya proyek contoh yang Anda berikan menyelesaikan ini dengan trik sederhana. Mereka membuat kelas baru yang mewarisi kelas penyair flutter, mengesampingkan
OnFrame
antara lain. Ketika penimpaan itu dipanggil itu dalam konteks benang Flutter dan berfungsi seperti yang diharapkan.sumber
Texture,
-nya tidak memiliki metode onFrame. Metode onFrame ituRTCVideoRenderer
tidak ada hubungannya dengan Flutter.FlutterVideoRenderer
mewarisi dari dua kelas -Texture
(baris 16) danRTCVideoRenderer<scoped_refptr<RTCVideoFrame>>
(baris 17) (C ++ memungkinkan multiple inheritance) dan kemudian menimpaOnFrame
metode (baris 24). KetikaOnFrame
acara dipecat, itu dijalankan dalam konteks utas utama Anda.