Як викликати трепетні методи двигуна з іншої нитки


9

Я використовую робочий стіл Flutter для 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 на цьому прикладі, але не змогла дізнатися, оскільки він використовує https://github.com/flutter-webrtc/libwebrtc, який використовує webrtc google: https://github.com/ JumpingYang001 / webrtc, який для мене занадто великий, щоб знайти, звідки викликається OnFrame. Але це повинно мені з нитки. Як це можливо?


Якщо ви хочете отримати альтернативу використанню тайм-ауту для виконання періодичних завдань у головному запуску, ви можете надіслати PR-механізм Flutter для викриття glfwPostEmptyEvent через обгортку. Наявність способу розбудити основний цикл - це розумне доповнення до вбудовування API GLFW.
smorgan

@smorgan Я спробую це, але я здивований тим, як цей приклад: github.com/cloudwebrtc/flutter-webrtc/blob/desktop/common/src/… обходиться без RunEventLoopWithTimeOut. Оскільки він блокує основну нитку за допомогою flutter_controller.RunEventLoop(), то точно MarkTextureFrameAvailableпотрібно викликати її з іншої нитки, що має бути неможливим!
Лукас

Швидкий застереження перед моїм коментарем - ніколи не чув про Flutter, дуже мало знаю про Linux, і я на мобільному, так що зараз точно не переглядаю код. Сподіваюся, я все ще можу допомогти. :) Приклад, який ви подали, має їх відеорендері, успадковані від того, що схоже на основний екземпляр трепетного рендерінгу. Їх OnRenderвіртуальне переповнення Flutter, тому воно викликається потоком Flutter.
Pickle Rick

Відповіді:


3

Дивіться мій коментар щодо застереження до цієї відповіді. Схоже, що наведений вами прикладний проект виконує це простою хитрістю. Вони створюють новий клас, який успадковує клас трепетного рендерінгу, переважаючи OnFrameсеред іншого. Коли це перевизначення називається, це відбувається в контексті потоку Flutter і так працює, як очікувалося.


Дякую вам дуже за ваші зусилля, щоб допомогти! Однак клас Flutter, що в ньому є підкласи Texture,, не має методу onFrame. Цей метод onFrame - це той, в RTCVideoRendererякому немає нічого спільного з Flutter.
Лукас

Дивіться тут . Схоже, вони перекривають Flutter і, можливо, використовують підтримувану систему плагінів. Моєю найкращою порадою було б прочитати документацію Flutter. Я хотів би зробити ставку, якби ви розмістили ВР в OnFrame, це було б у контексті потоку Flutter, як очікувалося.
Рік

Я aleady використовую систему плагінів, і я прочитав документацію, немає методу onFrame. Єдине, що з класу Flutter у FlutterVideoRenderer - це Texture, в якому немає методу onFrame. Насправді я знайшов там, де визначено onFrame, і це річ з бібліотеки WebRTC, як ви можете побачити тут github.com/JumpingYang001/webrtc/…
Лукас

@LucasZanella Pickle Рік має рацію, FlutterVideoRenderer успадковує два класи - Texture(рядок 16) та RTCVideoRenderer<scoped_refptr<RTCVideoFrame>>(рядок 17) (C ++ дозволяє множинне успадкування), а потім він замінює OnFrameметод (рядок 24). Коли OnFrameподія запускається, вона виконується в контексті вашої основної теми.
4LegsDrivenCat

@ 4LegsDrivenCat, але OnFrame не з Flutter, це від RTCVideoRenderer, який не з Flutter
Lucas Zanella
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.