Каков наилучший способ визуализации видеокадров?
Какой лучший выбор для рендеринга видеокадров, полученных из декодера в комплекте с моим приложением (FFmpeg и т.д.)?
Я, естественно, хотел бы выбрать OpenGL, как указано в Android-видеоплеере с использованием NDK, OpenGL ES и FFmpeg.
Но в OpenGL в Android для отображения видео комментарий отмечает, что OpenGL - не лучший способ для рендеринга видео.
Что тогда? Собственная библиотека jnigraphics? И не-GL SurfaceView?
Обратите внимание, что я хотел бы использовать собственный API для рендеринга фреймов, таких как OpenGL или jnigraphics. Но Java-код для настройки SurfaceView и т.д. В порядке.
PS: MediaPlayer здесь не имеет значения, я говорю об декодировании и отображении кадров самостоятельно. Я не могу полагаться на кодеки Android по умолчанию.
Ответы
Ответ 1
Я собираюсь попытаться обобщить ответы и обобщить ответы здесь, основываясь на моем собственном опыте.
Почему openGL
Когда люди думают об рендеринге видео с помощью openGL, большинство из них пытается использовать графический процессор для преобразования цветового пространства и альфа-смешивания.
Например, конвертирование видеокадров YV12 в RGB. Преобразования цветового пространства, такие как YV12 → RGB, требуют, чтобы вы вычисляли значение каждого пикселя отдельно. Представьте себе, что для кадра размером 1280 x 720 пикселей количество операций заканчивается.
То, что я только что описал, действительно то, что было сделано SIMD, - параллельное выполнение одной операции с несколькими частями данных. Графический процессор является естественным решением для преобразования цветового пространства.
Почему! openGL
Недостатком является процесс, с помощью которого вы получаете данные текстуры в графический процессор. Учтите, что для каждого кадра вы должны Загрузить данные текстуры в память (операция ЦП), а затем вы должны скопировать данные текстуры в графический процессор (работа ЦП). Именно эта загрузка/копирование может сделать использование openGL медленнее, чем альтернативы.
Если вы воспроизводите видео с низким разрешением, я полагаю, что вы не увидите разницу в скорости, потому что ваш процессор не будет узким местом. Однако, если вы попытаетесь использовать HD, вы, скорее всего, столкнетесь с этим узким местом и заметите значительный удар по производительности.
Способ, которым традиционно работал этот узкий слой, заключается в использовании Pixel Buffer Objects (выделение памяти GPU для хранения текстурных нагрузок). К сожалению, у GLES2 нет объектов Pixel Buffer.
Другие параметры
По вышеуказанным причинам многие выбрали использование программного декодирования в сочетании с доступными расширениями ЦП, такими как NEON для преобразования цветового пространства. Реализация YUV 2 RGB для NEON существует здесь. Средства, с помощью которых вы рисуете рамки, SDL vs openGL не должны иметь значения для RGB, поскольку вы копируете одинаковое количество пикселей в обоих случаях.
Вы можете определить, поддерживает ли ваше целевое устройство усовершенствования NEON, запустив cat /proc/cpuinfo
из оболочки adb и ищет NEON в выходе функций.
Ответ 2
Я уже пропустил путь FFmpeg/OpenGLES, и это не очень весело.
Вы можете попробовать перенести ffplay.c из проекта FFmpeg, который был выполнен до использования порта Android SDL. Таким образом, вы не создаете свой декодер с нуля, и вам не придется иметь дело с idiosyncracies AudioTrack
, который является аудио API, уникальным для Android.
В любом случае, неплохо было бы сделать как можно меньше развития NDK и полагаться на портирование, поскольку опыт отладки ndk-gdb на мой взгляд довольно отвратителен.
Говоря, я думаю, что производительность OpenGLES является наименьшей из ваших забот. Я обнаружил, что производительность в порядке, хотя я признаю, что тестирую только на нескольких устройствах. Сам декодирование довольно интенсивный, и я не смог сделать очень агрессивную буферизацию (с SD-карты) во время воспроизведения видео.
Ответ 3
На самом деле я развернул пользовательскую систему видеопроигрывателя, и почти все мои работы были выполнены на стороне NDK. Мы получаем полноформатное видео 720P и выше, включая нашу собственную систему DRM. OpenGL - это не ваш ответ, так как на Android Pixbuffers не поддерживается, поэтому вы базово взрываете свои текстуры в каждом кадре и закручиваете систему кэширования OpenGLES. Вам, честно говоря, нужно засунуть видеоролики через поддерживаемый радом Bitmap на Froyo и выше. Перед тем, как Фройо запустил тебя. Я также написал много свойств NEON для преобразования цвета, масштабирования и т.д., Чтобы увеличить пропускную способность. Я могу нажать 50-60 кадров через эту модель на HD Video.