2016-03-30 2 views
1

Я поддерживаю приложение с функциями видеочат. Я использую Camera2 для API>=21. Камера работает. Теперь мне нужно получить данные с камеры моего устройства и записать ее в байт [], а затем передать массив на нативный метод обработки и передачи изображений противнику. Функция передачи видео, написанная на C++. Моя задача - правильно записать видео в байт [] (потому что этот аргумент принимает собственный метод, который должен выполнять все следующие действия на видеоизображении).Сохранение выходного потока Camera2 в байте []

Если я начинаю что-то добавлять, камера перестает работать. Помогите мне правильно и легко как можно реализовать эту задачу. Я пытался использовать MediaRecorder, но он не записывает данные в байт []. Я смотрел стандартные Google-примеры, такие как Camera2Basic, Camera2Video. Я попытался реализовать MediaRecorder, как в этом уроке. Но это не работает. ImageReader как я понимаю, используется только для изображений. MediaCodec - это слишком сложно, я не мог понять. Какой лучший и самый простой способ реализовать для получения изображения с камеры моего устройства и для записи его в байт []. и, если возможно, дайте мне образец кода или ресурса, где я могу его увидеть. Thanks

+0

Вы посмотрели Распределение? http://developer.android.com/reference/android/renderscript/Allocation.html – rcsumner

+0

@Sumner - я попробовал это. он не работает https://android.googlesource.com/platform/cts/+/de096f7/tests/tests/hardware/src/android/hardware/camera2/cts/AllocationTest.java#493 – Jackky777

+0

также я не понимаю, что делать с TextureView. пример не использовать его – Jackky777

ответ

6

Вы хотите использовать ImageReader; это предполагаемая замена старых обратных вызовов предварительного просмотра API-камеры (а также для получения изображений JPEG или RAW, другое общее использование).

Используйте формат YUV_420_888.

Изображения ImageReader используют ByteBuffer вместо байта [], но вы можете передать ByteBuffer непосредственно через JNI и получить указатель void * на каждую плоскость изображения, используя standard JNI methods. Это намного эффективнее, чем копирование в байт [].


Edit: еще несколько деталей:

Это предполагает, что у вас есть собственное программное обеспечение кодирования видео/сетевой библиотеки передачи, и вы не хотите использовать аппаратные видеокодеры Android. (Если это так, вам нужно использовать класс MediaCodec).

  1. Настроить предварительный просмотр (SurfaceView или TextureView), установить его размер как желаемое разрешение предварительного просмотра.
  2. Создайте ImageReader с форматом YUV_420_888 и нужным разрешением записи. Подключите listener to it.
  3. Откройте устройство камеры (может быть сделано параллельно с предыдущими шагами)
  4. Получите поверхность от обоих View и ImageReader, и использовать их как для создания camera capture session
  5. После сеанса создается, create a capture request builder с TEMPLATE_RECORDING (для оптимизации настроек для случая использования записи) и add both the Surfaces as targets для запроса
  6. Постройте запрос и установите его как repeating request.
  7. Камера начнет толкать буферы как в предварительный просмотр, так и в ImageReader. Вы получите обратный вызов onImageAvailable всякий раз, когда новый фрейм готов. Приобретите latest Image from the ImageReader's queue, получите три байтовых буфера, которые составляют изображение YCbCr, и передают их через JNI в ваш собственный код.
  8. После обработки обработкой изображения обязательно укажите close it.Для эффективности в ImageReader есть фиксированное количество изображений, и если вы их не вернете, камера остановится, так как у нее не будет буферов для записи. Если вам нужно обработать несколько кадров параллельно, вам может потребоваться увеличить аргумент maxImages конструктора ImageReader.