2015-04-03 4 views
0

Мы пытаемся декодировать потоки битов AVC/h264 с использованием нового API NdkMediaCodec. В то время как декодирование работает отлично, мы изо всех сил пытаемся найти содержимое декодированного видеокадра , отображаемого в GLES2 для рендеринга. API позволяет передавать ANativeWindow во время настройки, но мы хотим контролировать планирование рендеринга видео и в конечном итоге просто предоставлять N текстур, которые заполняются с данными декодированного кадра.Android MediaCodec/NdkMediaCodec GLES2 interop

Все попытки сопоставить память, возвращаемую getOutputBuffer(), в GLES vie eglCreateImageKHR/внешнее изображение не удались. NdkMediaCodec, похоже, использует libstagefright/OMX внутри. Итак, выходные буферы, скорее всего, выделены с помощью gralloc-arent? Есть ли способ заставить дескриптор gralloc/GraphicsBuffer привязать фрейм к EGL/GLES2?

Поскольку для медиакадры есть много форматов пикселей, без дополнительной документации по их макете памяти, трудно использовать NdkMediaCodec.

Спасибо за любые подсказки!

ответ

2

Для Java в общем MediaCodec, создать SurfaceTexture для текстуры GL ES вы хотите, чтобы данные в, а затем создать Surface из этого SurfaceTexture, и использовать это в качестве мишени для MediaCodec декодера. См. Пример http://bigflake.com/mediacodec/ (например, EncodeDecodeTest) для примера.

Классы SurfaceTexture и Surface недоступны непосредственно в NDK прямо сейчас (насколько мне известно), поэтому вам нужно будет их вызвать через JNI. Затем вы можете создать ANativeWindow с Surface, используя ANativeWindow_fromSurface.

Вы правы, что выходные буферы являются буферами gralloc, но поскольку для этого существуют общедоступные API, безопаснее полагаться на них, чем пытаться использовать ярлыки.

+0

Ndk Api просто берет один ANativeWindow в режиме конфигурации. Мне нужен способ декодировать каждый новый кадр в другой (ну текстуры N в кольцевой буфере). Идеальное решение - даже если это означает использование private apis - было бы способом получить дескриптор gralloc для ptr, возвращаемый с помощью выходного буфера. – youaresoomean

+1

Вам явно нужно иметь доступ к более чем одному из декодированных кадров одновременно или достаточно, чтобы иметь точный контроль над тем, какой из фреймов вы используете? При использовании 'SurfaceTexture' вы получаете обратный вызов, когда доступен новый фрейм, тогда вы можете по своему усмотрению вызвать' updateTexImage() ', чтобы поменять этот новый кадр на текстуру (и вызвать' getTimestamp() ', чтобы узнать, какой кадр это). Таким образом, вы можете иметь точный контроль над тем, какие кадры используются когда и где, но вы можете использовать только по одному и только последовательно. – mstorsjo

+0

Да, мне нужно больше одного кадра. HW-декодирование на других наших поддерживаемых платформах (iOS, Intel MFX) работает таким образом. Насколько я понял, текстура не сразу доступна GLES2 при вызове updateTexImage, не так ли? Планировщик видео вычисляет текущую задержку рендеринга для потокового видео и определяет временную метку отображения. Для этого важно, чтобы рамка была доступна в то время. Можно ли выделить хранилище для N кадров в одной SurfaceTexture и изменить привязку GL tex obj после хранения фрейма? – youaresoomean