Я делаю проект Android о работе с видеокадрами, мне нужно обработать каждый кадр, прежде чем отобразить его. Процесс включает масштабирование кадров с разрешения 1920×1080 до разрешения 2560×1440, преобразование цветового пространства и некоторую необходимую обработку изображений на основе RGB, и все эти работы должны быть завершены в течение 33 мс ~ 40 мс.
Я оптимизировал yuv-> rgb и другую обработку с помощью arm neon, они работали хорошо. Но мне нужно сначала масштабировать кадр с разрешения 1080p до 2k, теперь это узкое место в производительности.
Мой вопрос заключается в том, как эффективно масштабировать изображение с разрешения 1080p до 2k в течение 20 мс, у меня нет большого опыта работы с алгоритмом масштабирования, поэтому любые предложения полезны.
Могу ли я использовать arm neon для оптимизации существующего алгоритма?
Аппаратная среда:
Обновить:
Я опишу процесс декодирования, я использую MediaCodec для декодирования обычного видео (H.264) в YUV (NV12), декодер по умолчанию аппаратный, он очень быстрый. Затем я использую arm neon для конвертации NV12 в RGBW, а затем отправляю кадр RGBW на Surfaceflinger для отображения. Я просто использую обычный SurfaceView, а не GLSurfaceView.
Узким местом является быстрое увеличение YUV с 1080p до 2K.
Я считаю, что примеры работают хорошо, поэтому позвольте мне привести эту программу, которая использует шейдеры OpenGL для преобразования из YUV -> RGB: http://www.fourcc.org/source/YUV420P-OpenGL-GLSLang.c
Что я представляю для вашей программы:
Здесь может быть что-то вроде кривой обучения, но я думаю, что это выполнимо, учитывая описание вашей проблемы. Делайте это по одному шагу за раз: установите платформу OpenGL на место, попробуйте загрузить только текстуру Y и написать шейдер наивного фрагмента, который просто излучает пиксель в оттенках серого на основе образца Y, затем перейдите к правильному преобразованию изображения, а затем получите действительно наивный upsampler работает, а затем вводит в действие более сложный upsampler.
Я бы также порекомендовал opengles, в основном из-за проекта, над которым я сейчас работаю, а также воспроизведения видео. Для меня дисплей 1920 x 1080, поэтому я использую текстуру 2048 x 1024. Я получаю примерно 35 кадров в секунду на четырехъядерном плече7.
Используйте GLSurfaceView и свой собственный рендер. Если вы используете ffmpeg, то после декодирования видеокадров используйте sws_scale для масштабирования кадра, а затем просто загрузите его в текстуру opengl. Чем больше ваша текстура / дисплей, тем меньше кадров в секунду вы получите, поскольку загрузка каждого изображения в графический процессор занимает много времени.
В зависимости от ваших потребностей для декодирования вашего видеовхода вам придется исследовать. Для меня мне пришлось скомпилировать ffmpeg для Android и начать оттуда.
мои извинения за то, что поставили это в ответ. У меня недостаточно очков, чтобы комментировать.
Я хотел бы добавить, что вы можете столкнуться с ограничениями текстур OGL. Я пытался использовать OGL для противоположной проблемы; уменьшение масштаба с камеры в режиме реального времени. проблема в том, что максимальная текстура OGL составляет 2048×2048. Не уверен, что это верно для всех устройств. это ограничение было справедливо для новых комплектов, таких как N72013 и LG2. в конце концов, мне пришлось писать в NDK без OGL, оптимизируя его вручную.
удачи, хотя