다른 스레드에서 flutter 엔진 메소드를 호출하는 방법


9

리눅스에 flutter desktop을 사용하고 있습니다. MarkTextureFrameAvailable엔진에 의해 다시 렌더링 될 텍스처를 표시해야하는 메소드를 호출 합니다. 비디오 플레이어를 프로그래밍하고 MarkTextureFrameAvailable있으므로 플레이어의 스레드에서 전화해야합니다 . 문제는 엔진이 MarkTextureFrameAvailable엔진을 생성 한 스레드에서 (및 다른 엔진 메소드)를 강제로 호출한다는 것 입니다.

엔진에 대한 모든 호출은 항상 셸에서 끝나며 호출을 생성 한 동일한 스레드에서 호출이 이루어 졌는지 항상 확인합니다.

task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread()

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

이것이 내가 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;
}

보시다시피, 엔진을 생성하는 스레드가 차단됩니다 flutter_controller.RunEventLoop();. 메인 스레드에서 사물을 강제로 실행시키는 이벤트 디스패처를 배치 할 수있는 유일한 곳입니다. 이 아이디어가 마음에 들지 않습니다. RunEventLoopWithTimeout존재 하지만 시간 초과를 설정하고 MarkTextureFrameAvailable통화 대기열을 계속 확인해야 합니다. 나는 이것이 최적이라고 생각하지 않습니다.

그렇다면 MarkTextureFrameAvailable메인 스레드에서 어떻게 전화해야 합니까?

나는의 사용의 예를 발견 MarkTextureFrameAvailable여기에 : https://github.com/cloudwebrtc/flutter-webrtc/blob/desktop/common/src/flutter_video_renderer.cc#L90을 하고 그것을 호출하는 다른 스레드의 것 같습니다. 그게 어떻게 가능해? 내가 할 때, 치명적 오류가 발생하지만, 그는 작동하지만 작동합니까?

이 예제에서 어떤 스레드가 OnFrame을 호출하는지 알아 내려고 2 일을 보냈지 만 Google의 webrtc를 사용 하는 https://github.com/flutter-webrtc/libwebrtc 를 사용 하기 때문에 찾을 수 없었 습니다 : https://github.com/ OnFrame 이 어디에서 호출되는지 찾기에 너무 큰 JumpingYang001 / webrtc . 그러나 그것은 실에서 나와야합니다. 그게 어떻게 가능해?


기본 런 루프에서 시간 초과를 사용하여 주기적 작업을 실행하는 대안을 원하는 경우 래퍼를 통해 glfwPostEmptyEvent를 노출하도록 Flutter 엔진 PR을 제출할 수 있습니다. 메인 런 루프를 깨울 수있는 방법이 GLFW 임베딩 API에 합리적으로 추가됩니다.
smorgan

@ smorgan 나는 그것을 시도 할 것이지만,이 예제가 어떻게 놀랐습니다 : github.com/cloudwebrtc/flutter-webrtc/blob/desktop/common/src/… RunEventLoopWithTimeOut 없이 수행합니다. 그는 블록 이후에 메인 쓰레드 flutter_controller.RunEventLoop()다음 확실히, MarkTextureFrameAvailable불가능해야 다른 스레드에서 호출되는되어야합니다!
Lucas Zanella 1

내 의견 전의 빠른 경고-Flutter에 대해 들어 본 적이 없으며 Linux에 대해 거의 알지 못하며 모바일을 사용하고 있으므로 코드를 살펴 보지 않아도됩니다. 잘만되면 나는 여전히 도움이 될 수 있습니다. :) 당신이 준 예제는 그들의 비디오 렌더러가 메인 플러터 렌더러 인스턴스처럼 보이는 것을 상속받습니다. 그것들 OnRender은 Flutter의 가상 재정의이므로 Flutter 스레드에 의해 호출됩니다.
Pickle Rick

답변:


3

이 답변에 대한주의 사항에 대한 내 의견을 참조하십시오. 제공 한 예제 프로젝트는 간단한 트릭 으로이 작업을 수행하는 것으로 보입니다. 그들은 flutter 렌더러 클래스를 상속 하여 OnFrame다른 것들보다 우선 하는 새로운 클래스를 만듭니다 . 해당 재정의가 호출되면 Flutter 스레드의 컨텍스트에 있으므로 예상대로 작동합니다.


도와 주셔서 감사합니다! 그러나 Flutter의 하위 클래스는 Texture,onFrame 메서드가없는 클래스입니다 . 그 onFrame 메소드는 RTCVideoRendererFlutter와 관련이 없습니다.
Lucas Zanella

여기를 참조 하십시오 . Flutter를 재정의하고 지원되는 플러그인 시스템을 사용하는 것 같습니다. 가장 좋은 조언은 Flutter 문서를 읽는 것입니다. OnFrame에 BP를 배치하면 예상대로 Flutter 스레드의 컨텍스트에있을 것입니다.
Pickle Rick

플러그인 시스템을 사용하고 있으며 설명서를 읽었으며 onFrame 메서드가 없습니다. FlutterVideoRenderer 클래스의 Flutter에서 유일한 것은 onFrame 메서드가없는 Texture입니다. 실제로 onFrame이 정의 된 곳을 찾았으며 WebRTC 라이브러리에서 확인할 수 있습니다. github.com/JumpingYang001/webrtc/…
Lucas Zanella

@LucasZanella 클 릭 오른쪽이다 FlutterVideoRenderer 상속 - 두 클래스에서 Texture(라인 16) 및 RTCVideoRenderer<scoped_refptr<RTCVideoFrame>>(17 행) (C ++은 다중 상속 있도록), 그리고이 겹쳐 OnFrame있어서 (24 줄). OnFrame이벤트가 발생 하면 메인 스레드의 컨텍스트에서 실행됩니다.
4LegsDrivenCat

@ 4LegsDrivenCat하지만 OnFrame가 플러터에서하지, 그것은 플러터에서하지 RTCVideoRenderer에서의
루카스 ZANELLA
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.