Задержка видео и падение FPS на Android Lollipop при касании экрана

Я использую MediaCodec для воспроизведения видео 1080p@60fps. Это бесплатная платформа SabreSD с Android Lollipop 5.1.

Изначально из-за синхронного режима BufferQueue частота кадров была намного ниже 60. Теперь я мог играть со скоростью 70 кадров в секунду, изменив BufferQueue на асинхронный, как в JB.

Теперь следующая проблема, с которой я сталкиваюсь, — это задержки видео и резкое падение FPS до 40, когда я начинаю взаимодействовать с экраном (опускаю панель уведомлений, нажимаю кнопку громкости и т. д.).

Итак, я запустил rafika MultiSurfaceActivity и Record GL, я вижу, что все тесты проходят гладко, когда экран не трогают и не трогают, но как только я начинаю прокручивать панель уведомлений сверху и продолжаю это в течение длительного времени, fps снижается до 35 -40 кадров в секунду.

Я подтвердил тот же тест на Kitkat 4.4.2 и JB 4.2.2, и они, кажется, работают нормально.

Такое же поведение при воспроизведении MP4 из Галереи. Видео зависает и сильно отстает, когда мы начинаем играть с панелью уведомлений.

Кто-нибудь может объяснить, что изменилось с Kitkat на Lollipop, что может вызвать эту проблему (VSync, тройная буферизация?).


person Gurtaj    schedule 15.04.2016    source источник


Ответы (1)


Немного повторений из системы отслеживания ошибок Grafika:

Прыгающий мяч визуализируется программно, поэтому все, что поглощает процессорное время, замедляет его. На устройствах со средними процессорами и большими дисплеями (например, Nexus 10) частота кадров никогда не приближается к 60 кадрам в секунду. Таким образом, замедление когда вы играете с панелью навигации, меня не удивляет, но если оно продолжает быть медленным даже после того, как вы прекращаете играть с панелью навигации, то это немного странно.

Воспроизведение видео должно быть меньше затронуто, так как оно меньше влияет на ЦП.

Исследование таких проблем обычно начинается с использования systrace для захвата трассировок в "хорошем" состоянии. и «плохие» состояния и их сравнение.

Ключевым моментом «асинхронного режима» BufferQueue является разрешение пропускать кадры, если потребитель не может идти в ногу с производителем. В первую очередь это предназначено для SurfaceTexture, где производитель и потребитель находятся в одном приложении, потенциально в одном потоке, поэтому задержка производителя в ожидании потребителя может привести к зависанию программы. Я не уверен, что вы имеете в виду, говоря, что вам нужно, чтобы частота кадров превышала 60 кадров в секунду, но я предполагаю, что вы выбрасываете кадры на дисплей быстрее, чем он может их отобразить ... так что вы на самом деле не увеличиваете частоту кадров, вы просто используйте BufferQueue для удаления кадров вместо использования Choreographer, чтобы решить, когда вам нужно их удалить самостоятельно.

В любом случае, я ушел из Google еще в июне 2014 года, задолго до того, как Lollipop был завершен. Если что-то работает правильно на KitKat, но странно работает на Lollipop, боюсь, я не смогу дать много информации. Если вы можете легко воспроизвести поведение, возможно, стоит снять видео, демонстрирующее проблему (наведите второй смартфон на устройство, демонстрирующее проблему, чтобы они могли видеть, как вы манипулируете устройством) и зарегистрировать ошибку на http://b.android.com/.


Некоторые трассировки, загруженные OP:

Глядя на трассировку kitkat, в SurfaceFlinger происходит что-то странное. Основной поток сидит в postFrameBuffer очень долго (23-32 мс). В конце концов он просыпается, и строка ЦП предполагает, что он ожидал активности от «демона galcore», с которым я не знаком (кажется, особенно для Vivante GPU).

Трассировки леденцов показывают только строки ЦП, как если бы захват был сделан без необходимых тегов. Я не верю, что команда захвата systrace значительно изменилась между kitkat и lollipop, поэтому я озадачен тем, почему ведение журнала, инициированное пользовательским пространством, исчезло, но материал планирования потоков ядра остался. Убедитесь, что вы указали sched gfx view.


Более новые трассировки леденцов имеют только около секунды хороших данных. Когда вы видите «Did Not Finish», это означает, что у «начальной» записи нет соответствующей «конечной» записи. Вы можете увеличить размер буфера журнала systrace с помощью флага -b. Я думаю, что там достаточно.

Глядя на строку /system/bin/surfaceflinger, вы можете видеть, что в "хорошей" трассе postFrameBuffer обычно завершается примерно через 16 мс, но все еще ожидает galcore. Увеличьте масштаб до 388 мс (используйте клавиши WASD). На 388,196 мс в строке CPU 2 видно, что galcore что-то делает. Сразу после завершения тонкая линия в верхней части ряда поверхностных метателей меняет цвет со светло-серого (спящий) на зеленый (бегущий). На 388,548 мс, снова на ЦП 2, снова запускается galcore, и сразу после этого в строке surfaceflinger вы видите, что queueBuffer начинает выполняться.

"Плохая" трассировка выглядит идентично. Например, вы можете увидеть два выполнения galcore на 101,146 мс и 101,666 мс, с похожими эффектами в строке Surfaceflinger. Ключевое отличие заключается во времени, проведенном в postFrameBuffer, которое составляет около 16 мс для «хорошего» и около 30 мс для «плохого».

Так что это не похоже на поведенческий сдвиг; скорее, дела затягиваются, а сроки срываются.

Насколько я могу судить, SurfaceFlinger поддерживается демоном galcore. Это верно как в «хорошем», так и в «плохом» случаях. Чтобы увидеть, как должна выглядеть синхронизация, вы можете запустить systrace на устройстве Nexus или сравнить с трассировками с других устройств (например, с трассировкой в ​​этот пример или это ТАК вопрос). Если вы увеличите масштаб, вы увидите, что doComposition выполняется за несколько миллисекунд, а postFrameBuffer завершается за несколько десятых миллисекунд.

Подводя итог: у вас нет хорошего и плохого, у вас есть плохое и хуже. :-) Я не знаю, что такое galcore, но вам, вероятно, придется поговорить с OEM-производителем графического процессора.

person fadden    schedule 17.04.2016
comment
Да, я использовал все вышеперечисленные теги при съемке в kitkat и lollipop, а также подписался на []community.freescale.com /thread/380812, чтобы включить всю трассировку в ядре, но пропустил CONFIG_SCHED_TRACER, я включу это и дам вам знать, если выходные данные systrace изменятся - person Gurtaj; 17.04.2016
comment
Если бы это была проблема с конфигурацией ядра, я бы ожидал, что sched будет отсутствовать, а все содержимое пользовательского пространства будет там. Ваша трассировка наоборот, как будто код ftrace работает, но игнорирует содержимое пользовательского пространства. - person fadden; 17.04.2016
comment
Привет @fadden Обновленные дампы системной трассы: dropbox.com/s/hnebmkkghp534iy/lp_bad .zip?dl=0 и dropbox.com/s /zr3dwibj4yb89h7/lp_good.zip?dl=0 . Проблема заключалась в разрешении debugfs, которое не позволяло другим процессам регистрироваться в дампе systrace. - person Gurtaj; 18.04.2016
comment
Да, я вижу, что демон galcore требует больше времени по сравнению с версией kitkat 4.4.2 на том же оборудовании. Galcore — это модуль графического процессора Vivanta, я буду заниматься этим с командой freescale и сообщу вам как можно скорее. Спасибо за быстрый ответ, очень ценю вашу помощь :) - person Gurtaj; 18.04.2016