Подтвердить что ты не робот

Действительно ли доступна дружба "Android + FFMpeg"?

Вопрос не означает, что меня интересует, можно ли использовать код ffmpeg для Andoid. Я знаю, что это возможно. Я просто спрашиваю, есть ли у кого-то реальный прогресс в производительности. Я задал вопрос после нескольких недель экспериментов с материалом, и у меня было достаточно... Я не хочу писать в ветки, где люди даже не говорят, какое видео они декодируют (разрешение, кодек) и говорят только о некоторых мистических FPS. Я просто не понимаю, что они хотят делать. Также я не собираюсь разрабатывать приложение только для своего телефона или для телефонов Android 2.2 ++, которые имеют некоторые расширенные функции OpenGL. У меня довольно популярный телефон HTC Desire, так что если приложение не работает на нем, то что дальше?

Ну, что у меня есть?

  • Источник FFMpeg из последней ветки HEAD. На самом деле я не мог вытащить его с NDK5, поэтому решил использовать украденный.

  • Bambuser build script (bash) с соответствующим источником ffmpeg ([web]: http://bambuser.com/r/opensource/ffmpeg-4f7d2fe-android-2011-03-07.tar.gz). Он хорошо работает после некоторых исправлений с помощью NDK5.

  • Rockplayer генерирует исходный код ffmpeg с огромным Android.mk в качестве сборки script ([web]: http://www.rockplayer.com/download/rockplayer_ffmpeg_git_20100418.zip). Он строит NDK3 и NDK5 после некоторых исправлений. Rockplayer - это, наверное, самый классный медиаплеер для Android, и я предполагал, что у меня будут некоторые преимущества, связанные с его построением.

У меня было подходящее видео для проекта (не большой и не маленький): 600x360 H.264.

Обе библиотеки, которые мы получили из пунктов 2 и 3, дают нам возможность получать кадры из видео (по кадру, искать и т.д.). Я не пытался получить звуковую дорожку, потому что мне не нужен был проект. Я не публикую здесь свой источник, потому что считаю это традиционным и легко найти.

Ну, какие результаты с видео? HTC Desire, Android 2.2 600x360, H.264 декодирование и рендеринг в разных потоках

  • Bambuser (NDK5 buld для armv5te, RGBA8888): 33 мс/кадр в среднем.
  • Rockplayer (сборка NDK3 для неона, RGB565): 27 мс/кадр в среднем.

Это не плохо для первого взгляда, но просто подумайте, что это результаты только для декодирования кадров. Если у кого-то есть лучшие результаты с временем декодирования, дайте мне знать.

Самое сложное для видео - рендеринг. Если у нас есть растровое изображение 600x360, мы должны как-то масштабировать его до рисования, потому что разные телефоны имеют разные размеры экрана, и мы не можем ожидать, что наше видео будет иметь тот же размер, что и экран.

Какими параметрами мы должны перемасштабировать фрейм, чтобы он подходил к экрану? Я смог проверить (тот же телефон и источник видео) те случаи:

  • Функция sws_scale() C в сборке Bambuser: 70 мс/фрейм. Неприемлемо.
  • Глупое масштабирование растрового изображения в Android (Bitmap.createScaledBitmap): 65 мс/фрейм. Неприемлемо.
  • OpenGL рендеринг в ортопроекции на текстурированном квад. В этом случае мне не нужно было масштабировать рамку. Мне просто нужно было подготовить текстуру 1024x512 (в моем случае это был RGBA8888) содержать пиксели кадра кадра, а не загружать их в GPU (gl.glTexImage2D). Результат: ~ 220 мс/кадр для рендеринга. Неприемлемо. Я не ожидал, что glTexImage2D просто засасывает процессор Snapdragon.

Это все. Я знаю, что есть какой-то способ использовать шейдер фрагмента для преобразования пикселей YUV с использованием графического процессора, но мы будем иметь одинаковые glTexImage2D и 200 мс только для загрузки текстур.

Но это еще не конец.... мой единственный друг конец...:) Это не безнадежное состояние.

Пытаясь использовать RockPlayer, вы определенно будете удивляться, как они делают это проклятое масштабирование кадров так быстро. Я полагаю, что у них действительно хороший опыт в архитектуре ARM. Скорее всего, они используют avcodec_decode_video2, а не img_convert (как и в версии RP), но затем они используют некоторые трюки (зависит от версии ARM) для масштабирования. Возможно, у них также есть некоторая "магическая" конфигурация для ffmpeg, уменьшающая время декодирования, но Android.mk, которую они опубликовали, - это не Android.mk, который они используют. Незнайка...

Итак, теперь похоже, что вы не можете просто пропустить легкий мост JNI для ffmpeg и иметь настоящий медиаплеер для платформы Android. Вы можете сделать это, только если у вас есть подходящее видео, которое вам не нужно масштабировать.

Любые идеи? Я надеюсь на вас;)

4b9b3361

Ответ 1

Я скомпилировал ffmpeg на Android. С этого момента воспроизводимое видео зависит исключительно от реализации, поэтому никакая точка измерения задержек на вещи не может быть сильно оптимизирована в нужном месте и не используется стандартным swscale. И да, вы можете создать простой JNI-мост и использовать его в NDK для выполнения вызовов ffmpeg, но это уже будет код игрока.

Ответ 2

По моему опыту, преобразование YUV в RGB всегда было узким местом. Поэтому с использованием шейдера OpenGL, чтобы это значительно повысило уровень.

Ответ 3

Я использую http://writingminds.github.io/ffmpeg-android-java/ для моего проекта. Существует некоторое обходное решение с сложными командами, но для простых команд обертка работает очень хорошо для меня.