Ответ 1
Фон сначала...
Когда вы вызываете eglCreateWindowSurface()
, обертка EGL для Android деструктор поверхности вызывает native_window_api_disconnect()
, чтобы отключить поверхность EGL от BufferQueue
. Поверхность EGL подсчитывается по ссылке, при этом refcount увеличивается, когда поверхность передается на eglMakeCurrent()
, поэтому для уничтожения должны произойти две вещи:
-
eglDestroySurface()
следует называть - поверхность EGL не должна быть "текущей" в любом потоке.
Второй элемент требует вызова eglMakeCurrent()
с другой поверхностью EGL (или EGL_NO_SURFACE
) или вызовом eglReleaseThread()
для любого потока, который ранее использовал поверхность. Один из быстрых способов подтвердить, что это делается, - добавить регистрацию до вызовов на eglMakeCurrent()
, когда поверхность сделана текущей и неточной, и сравните идентификаторы потоков, просмотрев вывод logcat с помощью adb logcat -v threadtime
. Также может быть полезно использовать запросы EGL, такие как eglGetCurrentSurface(EGL_DRAW)
, чтобы подтвердить, что вы выполняете ток в потоке, который сделал поверхность текущей.
Если поверхность EGL не разрушена, она не будет отключена от Surface
, и попытки подключения нового производителя (путем вызова eglCreateWindowSurface
с новой поверхностью EGL) будут отклонены с помощью "уже подключенного".
Обновление: Моя реализация теперь доступна в тестовом проекте Grafika. Если вы установите это, выберите "Показать + захватить камеру", начните запись, переключите питание, а затем прекратите запись, у вас должен быть полный фильм с длинной паузой посередине. Вы можете отступить, выбрать "Воспроизвести видео" и выбрать "camera-test.mp4", чтобы просмотреть его.