Estou usando o flutter desktop para linux. Estou chamando um método chamado MarkTextureFrameAvailable
que deve marcar uma textura a ser renderizada novamente pelo mecanismo. Como estou programando um player de vídeo, preciso ligar MarkTextureFrameAvailable
do 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 RunEventLoopWithTimeout
exista, eu preciso colocar um tempo limite e continuar fazendo o check-in em uma fila para receber MarkTextureFrameAvailable
chamadas. Eu não acho que isso é ótimo.
Então, como devo ligar a MarkTextureFrameAvailable
partir do thread principal?
Encontrei um exemplo de uso MarkTextureFrameAvailable
aqui: 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?
fonte
flutter_controller.RunEventLoop()
, com certezaMarkTextureFrameAvailable
deve ser chamado de outro thread, o que deve ser impossível!OnRender
é uma substituição virtual do Flutter, ele é chamado pelo thread do Flutter.Respostas:
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
OnFrame
entre outras coisas. Quando essa substituição é chamada, ela está no contexto do segmento Flutter e, portanto, funciona conforme o esperado.fonte
Texture,
que não possui o método onFrame. Esse método onFrame é doRTCVideoRenderer
qual nada tem a ver com Flutter.FlutterVideoRenderer
herda de duas classes -Texture
(linha 16) eRTCVideoRenderer<scoped_refptr<RTCVideoFrame>>
(linha 17) (o C ++ permite herança múltipla) e depois substitui oOnFrame
método (linha 24). Quando oOnFrame
evento é disparado, ele é executado no contexto do seu encadeamento principal.