Вопрос не означает, что меня интересует, можно ли использовать код 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. Вы можете сделать это, только если у вас есть подходящее видео, которое вам не нужно масштабировать.
Любые идеи? Я надеюсь на вас;)