2014-02-11 3 views
2

фон:Расширенной собственность клиента выходных кодировщика буферов MediaCodec для RTMP потокового

Я подключил MediaCodec Android, чтобы FFmpeg для мультиплексирования различных форматов не поддерживается MediaMuxer, в том числе rtmp:// выхода через .flv контейнера. Такие потоковые мультиплексоры требуют более длительного, непредсказуемого владения выходными буферами MediaCodec, поскольку они могут выполнять сетевой ввод-вывод на любом этапе обработки пакетов. Для моего видеопотока я использую MediaCodec, настроенный для ввода поверхности. Чтобы отделить мультиплексор от кодирования, я помещаю выходные буферы MediaCodec ByteBuffer в мой мультиплекс через обработчик.

Все работает отлично, если я использую вывод .flv в файл, а не в конечную точку rtmp.

Проблема:

При сжатии в rtmp://... конечной точке я заметил мое потоковое приложение начинает блокировать на звонки в eglSwapBuffers(mEGLDisplay, mEncodingEGLSurface) на dequeueOutputBuffer() раз я сохранить даже несколько MediaCodec выходных буферов в моей очереди, как MediaCodec мультиплексирования, кажется, быть заблокировано только для 4 выходных буферов.

Любые трюки, чтобы избежать копирования всего выходного сигнала энкодера, возвращаемого MediaCodec#dequeueOutputBuffers и сразу же вызывающего releaseOutputBuffer(...)?

Полный источник моего проекта доступен по телефону Github. В частности, см:

  • AndroidEncoder.java: класс Аннотация кодировщик с общим поведением между аудио и видео кодеров: в основном drainEncoder(). Записывает данные в экземпляр Muxer.
  • FFmpegMuxer.java: Режущие инструменты Muxer
  • CameraEncoder.java. Отправляет кадры камеры в подкласс AndroidEncoder, настроенный для кодирования видео.

Systrace

Systrace output

Вот некоторые Systrace выход потокового 720p @ 2 Mbps видео в Zencoder.

решаемых

Копирования затем рилизинг выходного кодера ByteBuffers MediaCodec как только они доступны решает эту проблему без существенного влияния на производительность. Я перерабатываю копии ByteBuffer в ArrayDeque<ByteBuffer> для каждого трека мультиплеера, что ограничивает количество распределений.

ответ

3

К сожалению, этот вариант использования не поддерживается большинством телефонов Android. MediaCodec - это просто абстракция API OMX IL, используемого поставщиками кодеков на устройствах. Для кодеков поставщиков требуется определенное количество входных и выходных буферов для данной конфигурации.

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

Нет управления приложениями по количеству буферов ввода-вывода, выделенных для экземпляра MediaCodec - Android пытается выделить минимальное количество необходимых буферов для сохранения памяти. Поэтому единственным вариантом является копирование выходных буферов. Хотя это не идеально, кодированные буферы, как правило, достаточно малы.

+0

Спасибо за подробный ответ! – dbro