Разработка аппаратного декодера H264 для Android — Stagefright или OpenMax IL?

Я разрабатываю ускоренный видеодекодер H264 H/W для Android. До сих пор я работал с некоторыми библиотеками MediaCodec, Stagefright, OpenMax IL, OpenMax AL и FFmpeg. После небольшого исследования я обнаружил, что -

  1. Я нашел отличный ресурс по использованию stagefright с FFmpeg, но я не могу использовать FFmpeg из-за его лицензии, она довольно ограничительна для распространяемого программного обеспечения. (Или можно отказаться от FFmpeg из этого подхода?)

  2. Я не могу использовать MediaCodec в качестве Java API, и мне приходится вызывать его через слой JNI из C++, что относительно медленно, и мне это не разрешено.

  3. Я не могу использовать OpenMax AL, так как он поддерживает только декодирование транспортного потока MPEG-2 через буферную очередь. Это исключает передачу необработанных NALU h264 или других медиаформатов.

  4. Остались только stagefright и OpenMax IL. Я узнал, что stagefright использует интерфейс OpenMax(OMX). Что мне выбрать: stagefright или OpenMax IL? Что будет перспективнее?

Кроме того, я узнал, что ускоренный декодер Android H/W зависит от поставщика, и у каждого поставщика есть свои собственные интерфейсные API OMX. Это правда? Если да, нужно ли мне писать аппаратную реализацию конкретного поставщика в случае OpenMax IL? Как насчет боязни сцены? - Является ли это аппаратно-независимым или аппаратно-зависимым? Если нет возможности аппаратно-зависимой реализации с использованием stagefright или OpenMax IL, мне нужно поддерживать как минимум Qualcomm Snapdragon, Samsung Exynos и Tegra-4.

Обратите внимание, что мне нужно декодировать поток Приложения B H264 и ожидать декодированные данные после декодирования, которые я отправлю в свой конвейер рендеринга видео. В общем, мне нужен только модуль декодера.

Я действительно очень смущен. Пожалуйста, помогите мне поставить в правильном направлении. Заранее спасибо!

РЕДАКТИРОВАТЬ

Мое программное обеспечение предназначено для коммерческих целей, а исходный код также является частным. И я также ограничен в использовании ffmpeg клиентом. :)


person Kaidul    schedule 06.09.2015    source источник


Ответы (2)


Вы действительно должны пойти на MediaCodec. Вызов java-методов через JNI имеет некоторые накладные расходы, но вы должны помнить, какого порядка величины накладные расходы. Если бы вы вызывали функцию для каждого пикселя, накладные расходы на вызовы JNI могли бы быть проблематичными. Но при использовании MediaCodec вы выполняете всего несколько вызовов функций на кадр, и накладные расходы здесь незначительны.

См., например. http://git.videolan.org/?p=vlc.git;a=blob;f=modules/codec/omxil/mediacodec_jni.c;h=57df9889c97706436823a4960206e323565e221c;hb=b31df501269b56c65327be181cdca3df4894 используя MediaCodec из кода C, используя JNI. Поскольку другие тоже пошли по этому пути, я могу заверить вас, что накладные расходы JNI не являются причиной для рассмотрения других API, кроме MediaCodec.

Использование stagefright или OMX напрямую проблематично; ABI отличается для каждой версии платформы (так что вы можете либо ориентироваться только на одну версию, либо скомпилировать несколько раз, ориентируясь на разные версии, упаковывая все это в один пакет), и вам придется иметь дело с множеством особенностей конкретных устройств, в то время как MediaCodec должен (и в современных версиях работает) работать одинаково на всех устройствах.

person mstorsjo    schedule 07.09.2015
comment
Спасибо за Ваш ответ! Мне предлагали MediaCodec в нескольких темах, но я избегал советов. Теперь я собираюсь сделать быстрый тест и посмотреть, как производительность. - person Kaidul; 07.09.2015
comment
Я видел, что оболочка vlc mediacodec jni использует специальные заголовки OMX, нужны ли они мне, чтобы просто вызывать методы уровня Java mediacodec на собственном уровне? - person Kaidul; 13.10.2015
comment
Вам не нужны специальные заголовки OMX, но в VLC они используются для удобства, так как есть некоторый общий код. Единственное, что является общим, — это обработка интерпретации цветового формата MediaCodec, которая оказывается такой же, как и для OMX. (То есть MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar эквивалентно OMX_COLOR_FormatYUV420SemiPlanar; существует общий код для копирования данных из буферов MediaCodec/OMX в собственные изображения VLC с разными кодовыми путями для разных цветовых форматов.) - person mstorsjo; 13.10.2015
comment
Спасибо! Существует функция с именем MediaCodec_getName() git.videolan.org/?p=vlc.git;a=blob;f=modules/codec/omxil/, который содержит все OMX* материала. Могу ли я пропустить это, вызвав MediaCodec.getName() API более низкого уровня java? - person Kaidul; 13.10.2015
comment
Функция MediaCodec_getName(), с которой вы связались, представляет собой более сложную версию выполнения MediaCodec.createDecoderByType путем ручного перебора MediaCodecList. Это позволяет пропустить некоторые декодеры, которые, как известно, не работают для варианта использования VLC. - person mstorsjo; 13.10.2015
comment
Спасибо! Последний вопрос. Могу ли я обернуть все методы MediaCodec пользовательским методом Java и вызвать пользовательский метод с помощью JNI? Я имею в виду - тогда все функции медиакодека будут вызываться внутри функции. Есть ли разница между этим подходом и вызовом функций медиакодека по одной с использованием JNI? - person Kaidul; 14.10.2015
comment
Это должно быть так же хорошо, на самом деле нет никакой разницы. Накладные расходы на вызов методов JNI не так велики, как могли бы иметь значение, но они, вероятно, могут сделать ваш код немного чище и легче для чтения. - person mstorsjo; 14.10.2015

Я нашел отличный ресурс по использованию stagefright с FFmpeg, но я не могу использовать FFmpeg из-за его лицензии, она довольно ограничительна для распространяемого программного обеспечения. (Или можно отказаться от FFmpeg из этого подхода?)

Это не правда. FFmpeg находится под лицензией LGPL, поэтому вы можете просто использовать его в своем распространяемом на коммерческой основе приложении.

Однако вы можете использовать модули FFmpeg под лицензией GPL, например libx264. В этом случае ваша программа должна быть совместима с GPL.

Но даже это не плохо для распространения программного обеспечения — это просто означает, что вы должны предоставить своим клиентам (которые в любом случае должны быть королями) доступ к исходному коду приложения, за которое они платят, и вам не разрешается ограничивать их свободы. Не плохой вариант, ИМХО.

Кроме того, я узнал, что ускоренный декодер Android H/W зависит от поставщика, и у каждого поставщика есть свои собственные интерфейсные API OMX. Это правда?

Очевидно, да. Если вам нужно аппаратное ускорение, кто-то должен написать программу, которая ускоряет что-то на вашем конкретном оборудовании.

person Marcus Müller    schedule 06.09.2015