Come chiamare i metodi del motore flutter da un altro thread


9

Sto usando Flutter Desktop per Linux. Sto chiamando un metodo chiamato MarkTextureFrameAvailableche dovrebbe contrassegnare una trama che deve essere renderizzata dal motore. Dal momento che sto programmando un lettore video, devo chiamare MarkTextureFrameAvailabledal thread del lettore. Il problema è che il motore mi costringe a chiamare MarkTextureFrameAvailable(e qualsiasi altro metodo del motore) dal thread che ha creato il motore.

Puoi vedere che tutte le chiamate al motore finiscono nella shell, che controlla sempre se le chiamate vengono fatte dallo stesso thread che ha creato la chiamata:

task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread()

( https://github.com/flutter/engine/blob/master/shell/common/shell.cc#L838 )

Ecco come sto creando il motore 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;
}

come puoi vedere, il thread che crea il motore viene bloccato da flutter_controller.RunEventLoop();quale è l'unico posto in cui potrei mettere un dispatcher di eventi che costringe le cose ad essere eseguite dal thread di main. Non mi piace questa idea. Anche se RunEventLoopWithTimeoutesiste, devo mettere un timeout e continuare a controllare in coda per le MarkTextureFrameAvailablechiamate. Non penso sia ottimale.

Quindi, come dovrei chiamare MarkTextureFrameAvailabledal thread principale?

Ho trovato un esempio di utilizzo MarkTextureFrameAvailablequi: https://github.com/cloudwebrtc/flutter-webrtc/blob/desktop/common/src/flutter_video_renderer.cc#L90 e sembra che sia un altro thread che lo chiama. Come è possibile? Quando lo faccio, ricevo un errore FATAL, ma lo fa e funziona?

Ho trascorso due giorni a cercare di capire quale thread chiama OnFrame in questo esempio ma non sono riuscito a scoprirlo perché utilizza https://github.com/flutter-webrtc/libwebrtc che utilizza il webrtc di google: https://github.com/ JumpingYang001 / webrtc che è troppo grande per me per trovare da dove viene chiamato OnFrame. Ma devo da un filo. Come è possibile?


Se si desidera un'alternativa all'utilizzo di un timeout per eseguire attività periodiche nel runloop principale, è possibile inviare un PR del motore Flutter per esporre glfwPostEmptyEvent tramite un wrapper. Avere un modo per riattivare il runloop principale è un'aggiunta ragionevole all'API di incorporamento GLFW.
smorgan,

@smorgan Ci proverò, ma mi stupisco di come questo esempio: github.com/cloudwebrtc/flutter-webrtc/blob/desktop/common/src/… fa senza RunEventLoopWithTimeOut. Dato che blocca il thread principale con flutter_controller.RunEventLoop(), allora sicuramente MarkTextureFrameAvailabledeve essere chiamato da un altro thread, il che dovrebbe essere impossibile!
Lucas Zanella,

Un rapido avvertimento prima del mio commento: non ho mai sentito parlare di Flutter, so ben poco di Linux, e sono mobile, quindi sicuramente non sto guardando il codice in questo momento. Spero di poter ancora essere d'aiuto. :) L'esempio che hai fornito ha il suo renderer video ereditato da quella che sembra l'istanza principale del renderer flutter. Il loro OnRenderè un override virtuale di Flutter, quindi viene invocato dal thread Flutter.
Pickle Rick,

Risposte:


3

Vedi il mio commento per l'avvertimento a questa risposta. Sembra che il progetto di esempio che hai fornito compia questo con un semplice trucco. Creano una nuova classe che eredita la classe del renderer flutter, prevalente OnFrametra le altre cose. Quando tale override viene chiamato è nel contesto del thread Flutter e quindi funziona come previsto.


Grazie mille per il tuo sforzo di aiutare! Tuttavia, la classe di Flutter che subclasse è Texture,che non ha il metodo onFrame. Quel metodo onFrame è da RTCVideoRenderercui non ha nulla a che fare con Flutter.
Lucas Zanella,

Vedi qui . Sembra che abbiano la precedenza su Flutter, e possibilmente usando un sistema di plugin supportato. Il mio miglior consiglio sarebbe di leggere la documentazione di Flutter. Sarei disposto a scommettere che se hai inserito un BP in OnFrame sarebbe nel contesto del thread Flutter come previsto.
Pickle Rick,

Sto già usando il sistema di plugin e ho letto la documentazione, non esiste un metodo onFrame. L'unica cosa di Flutter nella classe FlutterVideoRenderer è Texture, che non ha un metodo onFrame. In realtà ho scoperto dove è definito onFrame, ed è una cosa della libreria WebRTC come puoi vedere qui github.com/JumpingYang001/webrtc/…
Lucas Zanella,

@LucasZanella Pickle Rick ha ragione, FlutterVideoRenderer eredita da due classi: Texture(riga 16) e RTCVideoRenderer<scoped_refptr<RTCVideoFrame>>(riga 17) (C ++ consente l'ereditarietà multipla) e quindi ignora il OnFramemetodo (riga 24). Quando l' OnFrameevento viene generato, viene eseguito nel contesto del thread principale.
4LegsDrivenCat

@ 4LegsDrivenCat ma OnFrame non è di Flutter, ma di RTCVideoRenderer che non di Flutter
Lucas Zanella,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.