2013-12-04 3 views
3

У меня есть пример приложения (full source), который кодирует кадры камеры с MediaCodec, показывая их на GLSurfaceView.Проблемы с частотой кадров в GLSurfaceView на Nexus 5

Systrace подтверждает 30 чертежных вызовов выполняются каждую секунду:

Systrace screenshot

Однако запись screenrecord (.mp4, YouTube) показывает очевидный фреймрейт быть значительно ниже.

В двух словах, моя кодирование & петля дисплея выполняет следующие действия:

  • Делает MediaCodec входной поверхность EGL контекста текущего
  • рисует рамку камеры к поверхности MediaCodec EGL
  • Делает GLSurfaceView EGL Контекст тока
  • рисует один и тот же кадр камеры к GLSurfaceView

На Galaxy Nexus LTE и Nexus 7 (оба с AOSP 4.4) приложение работает так, как ожидалось. Пока только Nexus 5 испытывает это несоответствие между количеством кадров, нарисованных на экране, и количеством видимых кадров ...

Я молюсь, чтобы я не был сумасшедшим.

+0

Команда 'screenrecord' добавляет значительные накладные расходы - для поверхностного рисования необходимо собрать все слои для виртуального дисплея с использованием GLES - что может негативно повлиять на частоту кадров. Взгляните на systrace, пока запущен 'screenrecord'. – fadden

+0

Я испытываю проблему без screenrecord. Это абсолютно ночь и день между N5 и другими устройствами, которые я пробовал. – dbro

+0

Анимированная стрелка в верхнем левом углу, кажется, оживляет чаще, чем дисплей камеры, поэтому это не проблема композиции. Я пытаюсь исследовать некоторые ужасающие результаты glReadPixels() в http://bigflake.com/mediacodec/#ExtractMpegFramesTest на Nexus 5 (177 мс для одного кадра 720p, который уменьшается до 6 мс, если видеодекодер не является участвует); возможно, это связано. – fadden

ответ

8

Я смог воспроизвести поведение, и мой помощник по макету GL выяснил проблему.

В принципе, один из контекстов EGL не замечает, что содержимое текстуры изменилось, поэтому оно сохраняет рендеринг старых данных. Мы думаем, что он получает периодические обновления, потому что у него есть набор буферов, которые он циклически проходит, поэтому в итоге он снова использует буфер, на который вы смотрите.

Я был в состоянии решить эту проблему в моем коде, обновив класс текстуры рендерер, это изменить:

GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, mTextureID); 

к этому:

GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, 0); 
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, mTextureID); 

-ООН связывают и повторно связывают причины водитель забрать правильный буфер.

Смежные вопросы