別のスレッドからフラッターエンジンメソッドを呼び出す方法


9

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();これは、メインのスレッドから強制的に実行されるイベントディスパッチャーを配置できる唯一の場所です。私はこの考えが好きではありません。RunEventLoopWithTimeout存在していても、タイムアウトを設定し、MarkTextureFrameAvailable呼び出しのキューにチェックインし続ける必要があります。これは最適ではないと思います。

ではMarkTextureFrameAvailable、メインスレッドからどのように呼び出す必要がありますか?

私はの使用例見つかっMarkTextureFrameAvailableここ:https://github.com/cloudwebrtc/flutter-webrtc/blob/desktop/common/src/flutter_video_renderer.cc#L90をして、それはそれを呼び出す別のスレッドのように見えます。どのようにして可能ですか?実行するとFATALエラーが発生しますが、エラーは発生しますか?

この例でOnFrameを呼び出すスレッドを見つけるために2日間費やしましたが、googleのwebrtcを使用するhttps://github.com/flutter-webrtc/libwebrtcを使用しているため、見つけることができませんでした:https : //github.com/ JumpingYang001 / webrtcは、OnFrameの呼び出し元を見つけるには大きすぎます。しかし、それは糸から私でなければなりません。どのように可能ですか?


メインランループで定期的なタスクを実行するためにタイムアウトを使用する代わりの方法が必要な場合は、FlutterエンジンPRを送信して、ラッパーを介してglfwPostEmptyEventを公開できます。メインランループを起動する方法があることは、GLFW埋め込みAPIへの合理的な追加です。
smorgan

@smorgan私はそれを試してみますが、この例にびっくりしています。彼はメインスレッドをでブロックしているのでflutter_controller.RunEventLoop()、確かにMarkTextureFrameAvailable別のスレッドから呼び出されている必要があり、これは不可能です!
ルーカスZanella

私のコメントの前の注意点-Flutterについて聞いたことがない、Linuxについてほとんど知らない、そして私はモバイルを使用しているので、現在コードを調べていません。うまくいけば、私はまだ助けになることができます。:)あなたが与えた例では、ビデオレンダラーがメインのフラッターレンダラーインスタンスのように見えるものから継承しています。これらOnRenderはFlutterの仮想オーバーライドであるため、Flutterスレッドによって呼び出されます。
ピクルスリック

回答:


3

この回答の警告については、私のコメントを参照してください。あなたが提供したサンプルプロジェクトは、簡単なトリックでこれを実現しているようです。それらは、フラッターレンダラークラスを継承する新しいクラスを作成し、OnFrameとりわけオーバーライドします。そのオーバーライドが呼び出されると、Flutterスレッドのコンテキスト内にあるため、期待どおりに機能します。


支援にご尽力いただき、誠にありがとうございます。ただし、FlutterのサブクラスでTexture,あるクラスには、onFrameメソッドがありません。そのonFrameメソッドは、RTCVideoRendererFlutterとは何の関係もありません。
Lucas Zanella

こちらをご覧ください。Flutterをオーバーライドし、サポートされているプラ​​グインシステムを使用している可能性があります。私の最善のアドバイスはFlutterのドキュメントを読むことです。BPをOnFrameに配置した場合、期待どおりにFlutterスレッドのコンテキストになると思います。
ピクルスリック

私はすでにプラグインシステムを使用しており、ドキュメントを読みましたが、onFrameメソッドはありません。FlutterVideoRendererクラスのFlutterからの唯一のものは、onFrameメソッドを持たないTextureです。実際には、onFrameが定義されている場所を見つけました。これは、WebRTCライブラリからのものです。github.com/ JumpingYang001 / webrtc /…
Lucas Zanella

@LucasZanella Pickle Rickは正解で、(16行目)と(17行目)の2つのクラスからFlutterVideoRenderer 継承し(C ++では多重継承が可能)、メソッドをオーバーライドしています(24行目)。ときにイベントが発生し、それはあなたのメインスレッドのコンテキストで実行されます。TextureRTCVideoRenderer<scoped_refptr<RTCVideoFrame>>OnFrameOnFrame
4LegsDrivenCat

@ 4LegsDrivenCatですが、OnFrameはFlutterからのものではなく、
RTCVideoRenderer
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.