Como chamar métodos de mecanismo de vibração de outro segmento

9

Estou usando o flutter desktop para linux. Estou chamando um método chamado MarkTextureFrameAvailableque deve marcar uma textura a ser renderizada novamente pelo mecanismo. Como estou programando um player de vídeo, preciso ligar MarkTextureFrameAvailabledo thread do player. O problema é que o mecanismo me obriga a chamar MarkTextureFrameAvailable(e qualquer outro método de mecanismo) do thread que criou o mecanismo.

Você pode ver que todas as chamadas para o mecanismo terminam no shell, que sempre verifica se as chamadas estão sendo feitas no mesmo encadeamento que a criou:

task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread()

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

É assim que estou criando o mecanismo de vibração:

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;
}

como você pode ver, o encadeamento que cria o mecanismo é bloqueado, flutter_controller.RunEventLoop();e é o único lugar em que eu poderia colocar um distribuidor de eventos que forçava a execução de itens a partir do encadeamento principal. Eu não gosto dessa ideia. Mesmo que RunEventLoopWithTimeoutexista, eu preciso colocar um tempo limite e continuar fazendo o check-in em uma fila para receber MarkTextureFrameAvailablechamadas. Eu não acho que isso é ótimo.

Então, como devo ligar a MarkTextureFrameAvailablepartir do thread principal?

Encontrei um exemplo de uso MarkTextureFrameAvailableaqui: https://github.com/cloudwebrtc/flutter-webrtc/blob/desktop/common/src/flutter_video_renderer.cc#L90 e parece que é outro segmento que o chama. Como isso é possível? Quando eu faço, recebo um erro FATAL, mas ele faz e funciona?

Passei dois dias tentando descobrir qual thread chama o OnFrame neste exemplo, mas não consegui descobrir porque ele usa https://github.com/flutter-webrtc/libwebrtc, que usa o webrtc do google: https://github.com/ JumpingYang001 / webrtc, que é grande demais para eu descobrir de onde o OnFrame é chamado. Mas deve-me de uma discussão. Como isso é possível?

Lucas Zanella
fonte
Se você quiser uma alternativa ao uso de um tempo limite para executar tarefas periódicas no ciclo de execução principal, envie um PR do mecanismo Flutter para expor o glfwPostEmptyEvent por meio de um wrapper. Ter uma maneira de ativar o runloop principal é uma adição razoável à API de incorporação do GLFW.
smorgan
@smorgan Vou tentar isso, mas estou surpreso com o exemplo: github.com/cloudwebrtc/flutter-webrtc/blob/desktop/common/src/… sem o RunEventLoopWithTimeOut. Como ele bloqueia o thread principal flutter_controller.RunEventLoop(), com certeza MarkTextureFrameAvailabledeve ser chamado de outro thread, o que deve ser impossível!
Lucas Zanella
Advertência rápida antes do meu comentário - nunca ouvi falar de Flutter, sei muito pouco sobre Linux, e eu estou no celular, então definitivamente não estou olhando o código agora. Espero que ainda possa ser útil. :) O exemplo que você deu tem seu renderizador de vídeo herdado da aparência principal da instância do renderizador flutuante. Como OnRenderé uma substituição virtual do Flutter, ele é chamado pelo thread do Flutter.
Pickle Rick

Respostas:

3

Veja meu comentário para a ressalva a esta resposta. Parece que o projeto de exemplo que você forneceu realiza isso com um truque simples. Eles criam uma nova classe que herda a classe de renderizador flutuante, substituindo OnFrameentre outras coisas. Quando essa substituição é chamada, ela está no contexto do segmento Flutter e, portanto, funciona conforme o esperado.

Pickle Rick
fonte
Muito obrigado pelo seu esforço para ajudar! No entanto, a classe de Flutter que é subclasse é a Texture,que não possui o método onFrame. Esse método onFrame é do RTCVideoRendererqual nada tem a ver com Flutter.
Lucas Zanella
Veja aqui . Parece que eles substituem o Flutter e, possivelmente, usando um sistema de plug-in suportado. Meu melhor conselho seria ler a documentação do Flutter. Eu estaria disposto a apostar que, se você colocasse um BP no OnFrame, ele estaria no contexto do segmento Flutter conforme o esperado.
Pickle Rick
Já estou usando o sistema de plug-ins e li a documentação, não há método onFrame. A única coisa de Flutter na classe FlutterVideoRenderer é Texture, que não possui o método onFrame. Na verdade, eu encontrei onde onFrame é definido, e é uma coisa da biblioteca WebRTC como você pode ver aqui github.com/JumpingYang001/webrtc/...
Lucas Zanella
@LucasZanella Pickle Rick está certo, FlutterVideoRenderer herda de duas classes - Texture(linha 16) e RTCVideoRenderer<scoped_refptr<RTCVideoFrame>>(linha 17) (o C ++ permite herança múltipla) e depois substitui o OnFramemétodo (linha 24). Quando o OnFrameevento é disparado, ele é executado no contexto do seu encadeamento principal.
LegsDrivenCat
@ 4LegsDrivenCat mas OnFrame não é de vibração, que é de RTCVideoRenderer que não é de Flutter
Lucas Zanella