Cara memanggil metode mesin flutter dari utas lainnya

9

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?

Lucas Zanella
sumber
Jika Anda ingin alternatif untuk menggunakan batas waktu untuk menjalankan tugas-tugas berkala di runloop utama, Anda bisa mengirimkan mesin Flutter PR untuk mengekspos glfwPostEmptyEvent melalui pembungkus. Memiliki cara untuk membangun runloop utama adalah tambahan yang masuk akal untuk API penyematan GLFW.
smorgan
@smorgan Saya akan mencobanya, tapi saya heran bagaimana contoh ini: github.com/cloudwebrtc/flutter-webrtc/blob/desktop/common/src/… tidak tanpa RunEventLoopWithTimeOut. Karena dia memblokir utas utama flutter_controller.RunEventLoop(), maka pastinya MarkTextureFrameAvailabledipanggil dari utas lain, yang seharusnya tidak mungkin!
Lucas Zanella
Peringatan cepat sebelum komentar saya - tidak pernah mendengar tentang Flutter, tahu sedikit tentang Linux, dan saya menggunakan ponsel jadi pasti tidak melihat kode sekarang. Semoga saya masih bisa membantu. :) Contoh yang Anda berikan memiliki renderer videonya mewarisi dari apa yang tampak seperti instance rutterer flutter utama. Mereka OnRenderadalah menimpa Flutter virtual sehingga dipanggil oleh benang Flutter.
Pickle Rick

Jawaban:

3

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 OnFrameantara lain. Ketika penimpaan itu dipanggil itu dalam konteks benang Flutter dan berfungsi seperti yang diharapkan.

Acar Rick
sumber
Terima kasih banyak atas upaya Anda untuk membantu! Namun, kelas dari Flutter yang subclass Texture,-nya tidak memiliki metode onFrame. Metode onFrame itu RTCVideoRenderertidak ada hubungannya dengan Flutter.
Lucas Zanella
Lihat di sini . Sepertinya mereka menimpa Flutter, dan mungkin menggunakan sistem plugin yang didukung. Saran terbaik saya adalah membaca dokumentasi Flutter. Saya akan berani bertaruh jika Anda menempatkan BP di OnFrame itu akan berada dalam konteks untaian Flutter seperti yang diharapkan.
Pickle Rick
Saya aleady menggunakan sistem plugin dan saya sudah membaca dokumentasi, tidak ada metode onFrame. Satu-satunya hal dari Flutter di kelas FlutterVideoRenderer adalah Tekstur, yang tidak memiliki metode onFrame. Sebenarnya saya menemukan di mana onFrame didefinisikan, dan merupakan sesuatu dari perpustakaan WebRTC seperti yang Anda lihat di sini github.com/JumpingYang001/webrtc/…
Lucas Zanella
@LucasZanella Pickle Rick benar, FlutterVideoRenderer mewarisi dari dua kelas - Texture(baris 16) dan RTCVideoRenderer<scoped_refptr<RTCVideoFrame>>(baris 17) (C ++ memungkinkan multiple inheritance) dan kemudian menimpa OnFramemetode (baris 24). Ketika OnFrameacara dipecat, itu dijalankan dalam konteks utas utama Anda.
4LegsDrivenCat
@ 4LegsDrivenCat tetapi OnFrame bukan dari Flutter, ini dari RTCVideoRenderer yang bukan dari Flutter
Lucas Zanella