Декодирование Raw H264 в андроиде?

У меня есть проект, в котором мне было предложено отображать видеоstream в android, stream является сырым H.264, и я подключаюсь к серверу и получаю stream байтов с сервера.

В основном мне интересно, есть ли способ отправить необработанные байты в декодер в Android и отобразить его на поверхности?

Мне удалось декодировать H264, завернутый в контейнер mp4, используя новый MediaCodec и MediaExtractor API в android 4.1, к сожалению, я не нашел способ декодировать необработанный файл H264 или stream, используя эти API.

Я понимаю, что одним из способов является компиляция и использование FFmpeg, но я бы предпочел использовать встроенный метод, который может использовать ускорение HW. Я также понимаю, что streamовая передача RTSP поддерживается в android, но это не вариант. Версия для Android не является проблемой.

Я не могу предоставить какой-либо код для этого, к сожалению, но я сделаю все возможное, чтобы объяснить это, основываясь на том, как я получил его на работу.

Итак, вот мой обзор того, как я получил исходное кодированное видео H.264 для работы с использованием classа MediaCodec ( http://developer.android.com/reference/android/media/MediaCodec.html ).

Используя приведенную выше ссылку, приведен пример получения установки декодера и способа ее использования, вам нужно будет настроить его для декодирования H264 AVC.

Формат H.264 состоит в том, что он состоит из блоков NAL, каждый из которых начинается с префикса запуска из трех байтов со значениями 0x00, 0x00, 0x01, и каждый блок имеет другой тип в зависимости от значения 4-го байта сразу после этого 3 стартовых байта. Один блок NAL НЕ является одним кадром в видео, каждый кадр состоит из нескольких блоков NAL.

В основном я написал метод, который находит каждое отдельное устройство и передает его в декодер (один блок NAL является стартовым префиксом и любыми байтами там после до следующего стартового префикса).

Теперь, если у вас есть декодер для декодирования H.264 AVC и у вас есть InputBuffer от декодера, тогда вы готовы к работе. Вам необходимо заполнить этот InputBuffer модулем NAL и передать его обратно в декодер и продолжить делать это для длины streamа. Но для выполнения этой работы мне пришлось сначала передать декодер SPS (набор параметров последовательности) NAL Unit. Этот блок имеет байтовое значение 0x67 после стартового префикса (4-й байт), на некоторых устройствах декодер будет сбой, если он не получит это устройство в первую очередь. В основном, пока вы не найдете это устройство, игнорируйте все другие блоки NAL и продолжайте parsing streamа до тех пор, пока не получите это устройство, тогда вы можете передать все остальные единицы в декодер.

Некоторым устройствам сначала не нужен SPS, а некоторые, но вам лучше передать их в первую очередь.

Теперь, если у вас есть поверхность, которую вы передали декодеру, когда вы ее настроили, то, получив достаточное количество блоков NAL для кадра, оно должно отображать его на поверхности.

Вы можете загрузить необработанный H.264 с сервера, а затем предложить его через локальный HTTP-сервер, работающий на телефоне, а затем позволить VLC для Android выполнять воспроизведение с этого HTTP-сервера. Вы должны использовать схему VLC http / h264: //, чтобы заставить демультиплекс к необработанному H.264 (если вы не заставляете демонстрационный VLC-приемник не может распознавать stream, даже если тип MIME, возвращаемый HTTP-сервером, правильно установлен). Видеть

https://github.com/rauljim/tgs-android/blob/integrate_record/src/com/tudelft/triblerdroid/first/VideoPlayerActivity.java#L211

для примера о том, как создать намерение, которое запустит VLC.

Примечание: сырой H.264, по-видимому, не имеет информации о времени, поэтому VLC будет играть как можно быстрее. Первое внедрение его в MPEGTS будет лучше. Не нашли Android-версию, которая пока еще будет работать.

Вот ресурсы, которые я нашел полезными в аналогичном проекте:

  1. Это видео было очень проницательным в понимании того, как MediaCodec обрабатывает сырые streamи h.264 на высоком уровне.
  2. Этот stream более подробно посвящен обработке SAL / PPS NALUs. Как уже упоминалось выше, вам нужно отделить отдельные блоки NAL с помощью префикса старта, а затем передать оставшиеся данные в MediaCodec.
  3. Это репо (libstreaming) – отличный пример декодирования streamа H264 в Android с использованием RTSP / RTP для передачи.
  • Исправлена ​​ошибка инициализации ffmpeg drawtext
  • Сжатие FFmpeg CRF медленнее на главной, чем в старой версии
  • Может ли FFmpeg конвертировать mp3-файлы в m4a в полном объеме, т. Е. С копированием как аудио-, так и видеопотоков (jpeg cover)?
  • Как объединить два файла MP4 с помощью FFmpeg?
  • FFMPEG: как добавить водяной знак к видео?
  • Использование FFMpeg для вырезания видео в 2-минутные клипы
  • Ffmpeg: гладкий зомпан без смеха
  • Последовательность изображений для качества видео
  • Каков наилучший способ уменьшить изображение mp4 при сохранении его как можно более резкого?
  • Как разместить границу вокруг видео для предотвращения отсечения контента
  • Получить длину MP3 в Linux / FreeBSD
  • Давайте будем гением компьютера.