Внешние USB-камеры

<!-- Copyright 2018 The Android Open Source Project

Распространяется по лицензии Apache версии 2.0 (далее – Лицензия). Использовать этот файл можно только при соблюдении условий Лицензии. Чтобы получить текст Лицензии, перейдите по ссылке:

  http://www.apache.org/licenses/LICENSE-2.0

Если иное не предусмотрено применимым законодательством или письменным соглашением, Программное обеспечение, распространяемое в соответствии с Лицензией, предоставляется НА УСЛОВИЯХ "КАК ЕСТЬ", БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ ИЛИ УСЛОВИЙ, ЯВНЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ. Разрешения и ограничения в рамках Лицензии приводятся в Лицензии для каждого конкретного языка. -->

Платформа Android поддерживает использование USB-камер (веб-камер) с технологией Plug and Play через стандартный Android Camera2 API и интерфейс HAL. Веб-камеры обычно поддерживают драйверы USB Video Class (UVC), а в Linux для управления UVC-камерами используется стандартный драйвер Video4Linux (V4L).

Благодаря поддержке веб-камер устройства можно использовать для простых задач, например видеочатов и фотокиосков. Эта функция не заменяет стандартные внутренние HAL-компоненты камеры на телефонах Android и не предназначена для поддержки ресурсоемких и сложных задач, связанных с потоковой передачей видео высокого разрешения и высокой скорости, дополненной реальностью и ручным управлением ISP/сенсором/объективом.

Процесс HAL USB-камеры является частью поставщика внешней камеры, который отслеживает доступность USB-устройства и соответствующим образом перечисляет внешние камеры. У процесса есть разрешения и правила SE, аналогичные встроенному процессу HAL камеры. Сторонние приложения для веб-камер, которые напрямую взаимодействуют с USB-устройствами, требуют тех же разрешений на доступ к камере, что и обычные приложения для камеры.

Примеры и источники

Дополнительную информацию о том, как реализовать поддержку USB-камер, можно найти в справочной реализации поставщика внешних камер на странице ExternalCameraProvider. Реализации внешнего устройства камеры и сеанса включены в ExternalCameraDevice и ExternalCameraDeviceSession. Начиная с уровня API 28, клиентский API Java включает EXTERNAL – аппаратный уровень.

Реализация

Реализация должна поддерживать системную функцию android.hardware.usb.host.

Также должна быть включена поддержка устройств UVC в ядре. Чтобы включить эту функцию, добавьте в соответствующие файлы defconfig ядра указанные ниже строки.

+CONFIG_USB_VIDEO_CLASS=y
+CONFIG_MEDIA_USB_SUPPORT=y

Чтобы включить поставщика внешней камеры в сборке устройства, добавив необходимые разрешения SELinux, конфигурацию внешней камеры и зависимость поставщика внешней камеры, выполните следующие действия:

  • Добавьте файл конфигурации внешней камеры и библиотеку внешней камеры в папку device.mk.

    +PRODUCT_PACKAGES += android.hardware.camera.provider-V1-external-service
    
    +PRODUCT_COPY_FILES += \
    +device/manufacturerX/productY/external_camera_config.xml:$(TARGET_COPY_OUT_VENDOR)/etc/external_camera_config.xml
    
  • Добавьте название внешнего поставщика камеры в манифест HAL Treble устройства.

    <hal format="aidl">
        <name>android.hardware.camera.provider</name>
        <version>1</version>
        <interface>
            <name>ICameraProvider</name>
            <instance>internal/0</instance>
    +       <instance>external/0</instance>
        </interface>
    </hal>
    
  • Если устройство работает в режиме Treble passthrough, обновите sepolicy, чтобы у cameraserver был доступ к UVC-камере.

    +# for external camera
    +allow cameraserver device:dir r_dir_perms;
    +allow cameraserver video_device:dir r_dir_perms;
    +allow cameraserver video_device:chr_file rw_file_perms;
    

Вот пример разметки типа external_camera_config.xml (строки с информацией об авторских правах опущены).

<ExternalCamera>
    <Provider>
        <ignore> <!-- Internal video devices to be ignored by external camera HAL -->
            <id>0</id> <!-- No leading/trailing spaces -->
            <id>1</id>
        </ignore>
    </Provider>
    <!-- See ExternalCameraUtils.cpp for default values of Device configurations below -->
    <Device>
        <!-- Max JPEG buffer size in bytes-->
        <MaxJpegBufferSize bytes="3145728"/> <!-- 3MB (~= 1080p YUV420) -->
        <!-- Size of v4l2 buffer queue when streaming >= 30fps -->
        <!-- Larger value: more request can be cached pipeline (less janky)  -->
        <!-- Smaller value: use less memory -->
        <NumVideoBuffers count="4"/>
        <!-- Size of v4l2 buffer queue when streaming < 30fps -->
        <NumStillBuffers count="2"/>

        <!-- List of maximum fps for various output sizes -->
        <!-- Any image size smaller than the size listed in Limit row will report
            fps (as minimum frame duration) up to the fpsBound value. -->
        <FpsList>
            <!-- width/height must be increasing, fpsBound must be decreasing-->
            <Limit width="640" height="480" fpsBound="30.0"/>
            <Limit width="1280" height="720" fpsBound="15.0"/>
            <Limit width="1920" height="1080" fpsBound="10.0"/>
            <!-- image size larger than the last entry will not be supported-->
        </FpsList>
    </Device>
</ExternalCamera>

Настройка канала

Вы можете улучшить камеру Android с помощью общих параметров настройки или оптимизации для конкретного устройства.

Общие настройки

Вы можете настроить внешнего поставщика камер, изменив файл external_camera_config.xml. Клиенты могут настраивать следующие параметры:

  • Исключение видеоузлов внутренних камер
  • Поддерживаемый максимальный размер изображения и частота кадров
  • Количество буферов в полете (компромисс между задержкой и памятью)

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

Оптимизация для разных устройств

Вы также можете повысить эффективность, добавив оптимизацию для определенных устройств.

Копирование и масштабирование буфера, а также декодирование и кодирование JPEG.

В стандартных реализациях используется ЦП (libyuv/libjpeg), но вы можете заменить его оптимизациями для конкретных устройств.

Формат вывода HAL

В универсальных реализациях используются следующие форматы выходных данных:

  • YUV_420_888 для буферизации видео IMPLEMENTATION_DEFINED
  • YUV12 для всех остальных буферов IMPLEMENTATION_DEFINED

Чтобы повысить эффективность, вы можете заменить форматы вывода на эффективные форматы для конкретных устройств. Вы также можете добавить поддержку других форматов в собственную реализацию.

Проверка

Устройства с поддержкой внешних камер должны пройти тест CTS для камеры. Внешняя USB-камера должна быть подключена к устройству на протяжении всего тестирования, иначе некоторые проверки не будут пройдены.