Фреймворк тюнера

Для Android 11 и выше можно использовать фреймворк Android Tuner для доставки аудио- и видеоконтента. Фреймворк использует аппаратный конвейер от производителей, что делает его подходящим как для недорогих, так и для высокопроизводительных SoC. Фреймворк обеспечивает безопасный способ доставки аудио- и видеоконтента, защищенный доверенной средой выполнения (TEE) и защищенным медиа-путем (SMP), что позволяет использовать его в условиях строгой защиты контента.

Стандартизированный интерфейс между тюнером и Android CAS обеспечивает более быструю интеграцию между производителями тюнеров и CAS. Интерфейс тюнера работает с MediaCodec и AudioTrack , создавая универсальное решение для Android TV. Интерфейс тюнера поддерживает как цифровое, так и аналоговое телевидение на основе основных стандартов вещания.

Компоненты

В Android 11 три компонента разработаны специально для телевизионной платформы.

  • Tuner HAL: интерфейс между фреймворком и поставщиками.
  • API Tuner SDK: интерфейс между фреймворком и приложениями.
  • Менеджер ресурсов тюнера (TRM): координирует аппаратные ресурсы тюнера.

В Android 11 были улучшены следующие компоненты.

  • CAS V2
  • TvInputService или TV Input Service (TIS)
  • TvInputManagerService или служба управления входами телевизора (TIMS)
  • MediaCodec или медиакодек
  • AudioTrack или аудиотрек
  • MediaResourceManager или менеджер медиаресурсов (MRM)

Блок-схема компонентов фреймворка Tuner.

Рисунок 1. Взаимодействие компонентов Android TV.

Функции

Фронтенд поддерживает указанные ниже стандарты DTV.

  • ATSC
  • ATSC3
  • DVB C/S/T
  • ISDB S/S3/T
  • Аналоговый

В Android 12 с Tuner HAL 1.1 или выше интерфейс пользователя поддерживает указанный ниже стандарт цифрового телевидения.

  • ДТМБ

Демультиплексор поддерживает указанные ниже потоковые протоколы.

  • Транспортный поток (ТС)
  • Протокол передачи мультимедиа MPEG (MMTP)
  • Интернет-протокол (IP)
  • Тип значения длины (TLV)
  • Протокол канального уровня ATSC (ALP)

Descrambler поддерживает следующие средства защиты контента.

  • Защищенный путь передачи медиафайлов
  • Очистка пути к медиафайлу
  • Надежная локальная запись
  • Безопасное локальное воспроизведение

API тюнера поддерживают следующие варианты использования.

  • Сканировать
  • Жить
  • Воспроизведение
  • Записывать

Tuner, MediaCodec и AudioTrack поддерживают указанные ниже режимы передачи данных.

  • Полезная нагрузка ES с очищенным буфером памяти
  • Полезная нагрузка ES с защищенным дескриптором памяти
  • Сквозной проход

Общий дизайн

Tuner HAL — это интерфейс, определяющий взаимодействие между фреймворком Android и оборудованием производителя.

  • Описывает, чего ожидает платформа от поставщика и как поставщик может это обеспечить.
  • Экспортирует функциональные возможности интерфейса, демультиплексора и дескремблера во фреймворк через интерфейсы IFrontend , IDemux , IDescrambler , IFilter , IDvr и ILnb .
  • Включает в себя функции для интеграции Tuner HAL с другими компонентами фреймворка, такими как MediaCodec и AudioTrack .

Создаются Java-класс Tuner и нативный класс.

  • Java API Tuner позволяет приложениям получать доступ к HAL Tuner через общедоступные API.
  • Встроенный класс позволяет контролировать права доступа и обрабатывать большие объемы данных для записи или воспроизведения с помощью Tuner HAL.
  • Нативный модуль Tuner представляет собой связующее звено между Java-классом Tuner и HAL-интерфейсом Tuner.

Создан класс TRM.

  • Управляет ограниченными ресурсами тюнера, такими как интерфейсная часть, LNB, сессии CAS и входное устройство телевизора, через HAL-интерфейс телевизионного входа.
  • Применяет правила для высвобождения недостаточных ресурсов у приложений. Правило по умолчанию — приоритет для приложений переднего плана.

Функции Media CAS и CAS HAL расширены за счет перечисленных ниже возможностей.

  • Открывает сессии CAS для различных целей и алгоритмов.
  • Поддерживает динамические системы CAS, такие как удаление и установка CICAM.
  • Интегрируется с Tuner HAL, предоставляя ключевые токены.

MediaCodec и AudioTrack расширены за счет перечисленных ниже возможностей.

  • Принимает в качестве входного контента защищённую аудио- и видеопамять.
  • Настроено для аппаратной синхронизации аудио и видео в режиме туннельного воспроизведения.
  • Настроена поддержка режима ES_payload и режима сквозной передачи.

Общий дизайн Tuner HAL.

Рисунок 2. Схема компонентов внутри Tuner HAL.

Общий рабочий процесс

Приведенные ниже диаграммы иллюстрируют последовательность вызовов для воспроизведения прямой трансляции.

Настраивать

Схема последовательности настройки воспроизведения прямой трансляции.

Рисунок 3. Последовательность настройки для воспроизведения прямой трансляции.

Обработка аудио- и видеоматериалов

Схема обработки аудио- и видеосигнала для воспроизведения в прямом эфире.

Рисунок 4. Обработка аудио- и видеосигнала для воспроизведения прямой трансляции.

Обработка зашифрованного контента

Диаграмма обработки зашифрованного контента для воспроизведения прямой трансляции.

Рисунок 5. Обработка зашифрованного контента для воспроизведения прямой трансляции.

Обработка аудио-видео данных

Схема обработки аудио- и видеоданных для воспроизведения в прямом эфире.

Рисунок 6. Обработка аудио/видео для воспроизведения прямой трансляции.

API SDK тюнера

API Tuner SDK обрабатывает взаимодействие с Tuner JNI, Tuner HAL и TunerResourceManager . Приложение TIS использует API Tuner SDK для доступа к ресурсам Tuner и его подкомпонентам, таким как фильтр и дескремблер. Фронтенд и демультиплексор являются внутренними компонентами.

Блок-схема API Tuner SDK.

Рисунок 7. Взаимодействие с API Tuner SDK.

Версии

Начиная с Android 12, API Tuner SDK поддерживает новую функцию в Tuner HAL 1.1, которая является обратно совместимым обновлением версии Tuner 1.0.

Для проверки версии HAL используйте следующий API.

  • android.media.tv.tuner.TunerVersionChecker.getTunerVersion()

Минимально необходимая версия HAL указана в документации к новым API Android 12.

Пакеты

API Tuner SDK предоставляет четыре пакета, перечисленных ниже.

  • android.media.tv.tuner
  • android.media.tv.tuner.frontend
  • android.media.tv.tuner.filter
  • android.media.tv.tuner.dvr

Блок-схема пакетов API Tuner SDK.

Рисунок 8. Пакеты API Tuner SDK

Android.media.tv.tuner

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

  • tuner() : Инициализирует экземпляр Tuner, указывая параметры useCase и sessionId .
  • tune() : Получает ресурс интерфейса и выполняет настройку, указывая параметр FrontendSetting .
  • openFilter() : Получает экземпляр фильтра, указывая его тип.
  • openDvrRecorder() : Получает экземпляр записи, указывая размер буфера.
  • openDvrPlayback() : Получает экземпляр воспроизведения, указывая размер буфера.
  • openDescrambler() : Получает экземпляр дескремблера.
  • openLnb() : Получает внутренний экземпляр LNB.
  • openLnbByName() : Получает внешний экземпляр LNB.
  • openTimeFilter() : Получает экземпляр фильтра времени.

Пакет Tuner предоставляет функциональные возможности, которые не входят в пакеты Filter, DVR и Frontend. Эти функциональные возможности перечислены ниже.

  • cancelTuning
  • scan / cancelScanning
  • getAvSyncHwId
  • getAvSyncTime
  • connectCiCam1 / disconnectCiCam
  • shareFrontendFromTuner
  • updateResourcePriority
  • setOnTuneEventListener
  • setResourceLostListener

Android.media.tv.tuner.frontend

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

Классы

FrontendSettings для различных стандартов цифрового телевидения создается на основе классов, перечисленных ниже.

  • AnalogFrontendSettings
  • Atsc3FrontendSettings
  • AtscFrontendSettings
  • DvbcFrontendSettings
  • DvbsFrontendSettings
  • DvbtFrontendSettings
  • Isdbs3FrontendSettings
  • IsdbsFrontendSettings
  • IsdbtFrontendSettings

Начиная с Android 12 и Tuner HAL 1.1 или выше, поддерживаются следующие стандарты цифрового телевидения.

  • DtmbFrontendSettings

FrontendCapabilities представленный ниже, наследуется от других классов для различных стандартов цифрового телевидения.

  • AnalogFrontendCapabilities
  • Atsc3FrontendCapabilities
  • AtscFrontendCapabilities
  • DvbcFrontendCapabilities
  • DvbsFrontendCapabilities
  • DvbtFrontendCapabilities
  • Isdbs3FrontendCapabilities
  • IsdbsFrontendCapabilities
  • IsdbtFrontendCapabilities

Начиная с Android 12 и Tuner HAL 1.1 или выше, поддерживаются следующие стандарты цифрового телевидения.

  • DtmbFrontendCapabilities

FrontendInfo получает информацию о внешнем интерфейсе. FrontendStatus получает текущий статус внешнего интерфейса. OnTuneEventListener прослушивает события на внешнем интерфейсе. Приложение TIS использует ScanCallback для обработки сообщений сканирования с внешнего интерфейса.

сканирование каналов

Для настройки телевизора приложение сканирует возможные частоты и формирует список каналов, к которым пользователи могут получить доступ. TIS может использовать Tuner.tune , Tuner.scan(BLIND_SCAN) или Tuner.scan(AUTO_SCAN) для завершения сканирования каналов.

Если TIS располагает точной информацией о передаче сигнала, такой как частота, стандарт (например, T/T2, S/S2) и дополнительная необходимая информация (например, идентификатор PLD), то Tuner.tune рекомендуется как более быстрый вариант.

Когда пользователь вызывает Tuner.tune , происходят следующие действия:

  • TIS заполняет FrontendSettings необходимой информацией с помощью Tuner.tune .
  • Если сигнал заблокирован, HAL выдает сообщение "tune LOCKED .
  • TIS использует Frontend.getStatus для сбора необходимой информации.
  • TIS переключается на следующую доступную частоту в своем частотном списке.

TIS снова вызывает Tuner.tune до тех пор, пока не будут исчерпаны все частоты.

Во время настройки вы можете вызвать stopTune() или close() чтобы приостановить или завершить вызов Tuner.tune .

Tuner.scan(AUTO_SCAN)

Если у TIS недостаточно информации для использования Tuner.tune , но есть список частот и тип стандарта (например, DVB T/C/S), то рекомендуется использовать Tuner.scan(AUTO_SCAN) .

Когда пользователь вызывает Tuner.scan(AUTO_SCAN) , происходят следующие действия:

  • TIS использует Tuner.scan(AUTO_SCAN) , в котором FrontendSettings заполнены частотой.

  • HAL сообщает о блокировке сигнала (Scan LOCKED , если сигнал заблокирован. HAL также может сообщать о других сообщениях сканирования, предоставляя дополнительную информацию о сигнале.

  • TIS использует Frontend.getStatus для сбора необходимой информации.

  • TIS вызывает Tuner.scan , чтобы HAL перешел к следующей настройке на той же частоте. Если структура FrontendSettings пуста, HAL использует следующую доступную настройку. В противном случае HAL использует FrontendSettings для однократного сканирования и отправляет END , указывая на завершение операции сканирования.

  • Система TIS повторяет описанные выше действия до тех пор, пока не будут исчерпаны все настройки частоты.

  • HAL отправляет END , указывающий на завершение операции сканирования.

  • TIS переключается на следующую доступную частоту в своем частотном списке.

TIS вызывает Tuner.scan(AUTO_SCAN) снова и снова, пока не будут исчерпаны все частоты.

Во время сканирования вы можете вызвать stopScan() или close() , чтобы приостановить или завершить сканирование.

Tuner.scan(BLIND_SCAN)

Если в TIS отсутствует список частот, а Vendor HAL может выполнить поиск частоты указанного пользователем интерфейса для получения ресурса интерфейса, то рекомендуется использовать Tuner.scan(BLIND_SCAN) .

  • TIS использует Tuner.scan(BLIND_SCAN) . В FrontendSettings можно указать начальную частоту, но TIS игнорирует другие настройки в FrontendSettings .
  • Если сигнал заблокирован, HAL выдает сообщение "сканирование LOCKED .
  • TIS использует Frontend.getStatus для сбора необходимой информации.
  • TIS снова вызывает Tuner.scan для продолжения сканирования. ( FrontendSettings игнорируются.)
  • TIS повторяет описанные выше действия до тех пор, пока не будут исчерпаны все настройки частоты. HAL увеличивает частоту без каких-либо действий со стороны TIS. HAL сообщает PROGRESS .

TIS снова вызывает Tuner.scan(AUTO_SCAN) до тех пор, пока не будут исчерпаны все частоты. HAL сообщает END , указывая на завершение операции сканирования.

Во время сканирования вы можете вызвать stopScan() или close() , чтобы приостановить или завершить сканирование.

Блок-схема процесса сканирования TIS.

Рисунок 9. Блок-схема сканирования TIS.

Android.media.tv.tuner.filter

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

  • configure()
  • start()
  • stop()
  • flush()
  • read()

Полный список см. в исходном коде Android.

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

  • AlpFilterConfiguration
  • IpFilterConfiguration
  • MmtpFilterConfiguration
  • TlvFilterConfiguration
  • TsFilterConfiguration

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

  • SectionSettings
  • AvSettings
  • PesSettings
  • RecordSettings
  • DownloadSettings

FilterEvent является производным от описанных ниже классов и предназначен для регистрации событий, связанных с различными типами данных.

  • SectionEvent
  • MediaEvent
  • PesEvent
  • TsRecordEvent
  • MmtpRecordEvent
  • TemiEvent
  • DownloadEvent
  • IpPayloadEvent

Начиная с Android 12 и версии Tuner HAL 1.1 или выше, поддерживаются следующие события.

  • IpCidChangeEvent
  • RestartEvent
  • ScramblingStatusEvent
События и формат данных из фильтра
Тип фильтра Флаги События Операция с данными Формат данных
TS.SECTION
MMTP.SECTION
IP.SECTION
TLV.SECTION
ALP.SECTION
isRaw:
true
Обязательный:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Рекомендуется:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
В соответствии с расписанием мероприятия и внутренним графиком, запуск
Filter.read(buffer, offset, adjustedSize) один или несколько раз.

Данные копируются из MQ HAL в буфер клиента.
Один собранный пакет материалов для сессии заполняется в FMQ другим пакетом материалов для сессии.
isRaw:
false
Обязательный:
DemuxFilterEvent::DemuxFilterSectionEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Необязательный:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
for i=0; i<n; i++
Filter.read(buffer, offset, DemuxFilterSectionEven[i].size)


Данные копируются из MQ HAL в буфер клиента.
TS.PES isRaw:
true
Обязательный:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Рекомендуется:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
В соответствии с расписанием мероприятия и внутренним графиком, запуск
Filter.read(buffer, offset, adjustedSize) один или несколько раз.

Данные копируются из буфера MQ HAL в буфер клиента.
Один собранный пакет из полиэфирсульфона (PES) заполняется методом FMQ другим пакетом из полиэфирсульфона (PES).
isRaw:
false
Обязательный:
DemuxFilterEvent::DemuxFilterPesEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Необязательный:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
for i=0; i<n; i++
Filter.read(buffer, offset, DemuxFilterPesEven[i].size)


Данные копируются из MQ HAL в буфер клиента.
MMTP.PES isRaw:
true
Обязательный:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Рекомендуется:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
В соответствии с расписанием мероприятия и внутренним графиком, запуск
Filter.read(buffer, offset, adjustedSize) один или несколько раз.

Данные копируются из буфера MQ HAL в буфер клиента.
Один собранный пакет MFU заполняется методом FMQ другим пакетом MFU.
isRaw:
false
Обязательный:
DemuxFilterEvent::DemuxFilterPesEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Необязательный:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
for i=0; i<n; i++
Filter.read(buffer, offset, DemuxFilterPesEven[i].size)


Данные копируются из буфера MQ HAL в буфер клиента.
TS.TS
Н/Д Обязательный:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Рекомендуется:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
В соответствии с расписанием мероприятия и внутренним графиком, запуск
Filter.read(buffer, offset, adjustedSize) один или несколько раз.

Данные копируются из буфера MQ HAL в буфер клиента.
Отфильтрованы ts с заголовком ts
Заполняется в формате FMQ.
TS.Audio
TS.Video
MMTP.Audio
MMTP.Video
isPassthrough:
true
Необязательный:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
Клиент может запустить MediaCodec после получения значения DemuxFilterStatus::DATA_READY .
Клиент может вызвать Filter.flush после получения значения DemuxFilterStatus::DATA_OVERFLOW .
Н/Д
isPassthrough:
false
Обязательный:
DemuxFilterEvent::DemuxFilterMediaEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Необязательный:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
Для использования MediaCodec :
for i=0; i<n; i++
linearblock = MediaEvent[i].getLinearBlock();
codec.startQueueLinearBlock(linearblock)
linearblock.recycle()


Для использования функции Direct Audio в AudioTrack :
for i=0; i<n; i++
audioHandle = MediaEvent[i].getAudioHandle();
audiotrack.write(encapsulated(audiohandle))
Данные ES или частичные данные ES в памяти ION.
TS.PCR
IP.NTP
ALP.PTP
Н/Д Обязательно: Нет данных
Необязательно: Нет
Н/Д Н/Д
TS.RECORD Н/Д Обязательный:
DemuxFilterEvent::DemuxFilterTsRecordEvent[n]
RecordStatus::DATA_READY
RecordStatus::DATA_OVERFLOW
RecordStatus::LOW_WATER
RecordStatus::HIGH_WATER

Необязательный:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
Для индексных данных:
for i=0; i<n; i++
DemuxFilterTsRecordEvent[i];


Для записанного контента , в соответствии с RecordStatus::* и внутренним расписанием, выполните одно из следующих действий:
  • Выполните команду DvrRecord.write(adustedSize) один или несколько раз в хранилище.
    Данные передаются из MQ HAL в хранилище.
  • Для создания буфера выполните команду DvrRecord.write(buffer, adustedSize) один или несколько раз.
    Данные копируются из MQ HAL в буфер клиента.
Для индексных данных: передаются в составе полезной нагрузки события.

Для записанного контента: смешанный поток TS, заполненный в формате FMQ.
TS.TEMI Н/Д Обязательный:
DemuxFilterEvent::DemuxFilterTemiEvent[n]

Необязательный:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
for i=0; i<n; i++
DemuxFilterTemiEvent[i];
Н/Д
MMTP.MMTP Н/Д Обязательный:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Рекомендуется:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
В соответствии с расписанием мероприятия и внутренним графиком, запуск
Filter.read(buffer, offset, adjustedSize) один или несколько раз.

Данные копируются из буфера MQ HAL в буфер клиента.
Отфильтрованы протоколы mmtp с заголовком mmtp
Заполняется в формате FMQ.
MMTP.RECORD Н/Д Обязательный:
DemuxFilterEvent::DemuxFilterMmtpRecordEvent[n]
RecordStatus::DATA_READY
RecordStatus::DATA_OVERFLOW
RecordStatus::LOW_WATER
RecordStatus::HIGH_WATER

Необязательный:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
Для индексных данных: for i=0; i<n; i++
DemuxFilterMmtpRecordEvent[i];


Для записанного контента , в соответствии с RecordStatus::* и внутренним расписанием, выполните одно из следующих действий:
  • Выполните команду DvrRecord.write(adjustedSize) один или несколько раз в хранилище.
    Данные передаются из MQ HAL в хранилище.
  • Для создания буфера выполните команду DvrRecord.write(buffer, adjustedSize) один или несколько раз.
    Данные копируются из MQ HAL в буфер клиента.
Для индексных данных: передаются в составе полезной нагрузки события.

Для записанного контента: в поле FMQ заполнен смешанный записанный поток.

Если источником фильтра для записи является TLV.TLV в IP.IP с сквозной передачей, то записанный поток будет иметь заголовок TLV и IP.
MMTP.DOWNLOAD Н/Д Обязательный:
DemuxFilterEvent::DemuxFilterDownloadEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Необязательный:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
for i=0; i<n; i++ Filter.read(buffer, offset, DemuxFilterDownloadEvent[i].size)

Данные копируются из MQ HAL в буфер клиента.
Пакет для загрузки заполняется в FMQ другим пакетом для загрузки с IP-адреса.
IP.IP_PAYLOAD Н/Д Обязательный:
DemuxFilterEvent::DemuxFilterIpPayloadEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Необязательный:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
for i=0; i<n; i++ Filter.read(buffer, offset, DemuxFilterIpPayloadEvent[i].size)

Данные копируются из MQ HAL в буфер клиента.
Пакет полезной нагрузки IP-протокола заполняется в FMQ другим пакетом полезной нагрузки IP-протокола.
IP.IP
TLV.TLV
ALP.ALP
isPassthrough:
true
Необязательный:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
Отфильтрованный протокольный подпоток поступает на следующий фильтр в цепочке фильтров. Н/Д
isPassthrough:
false
Обязательный:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Рекомендуется:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
В соответствии с расписанием мероприятия и внутренним графиком, запуск
Filter.read(buffer, offset, adjustedSize) один или несколько раз.

Данные копируются из буфера MQ HAL в буфер клиента.
Отфильтрованный подпоток протокола с заголовком протокола заполняется в FMQ.
IP.PAYLOAD_THROUGH
TLV.PAYLOAD_THROUGH
ALP.PAYLOAD_THROUGH
Н/Д Необязательный:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
Отфильтрованная полезная нагрузка протокола поступает в следующий фильтр в цепочке фильтров. Н/Д
Пример алгоритма использования фильтра для построения PSI/SI.

Пример алгоритма использования фильтра для построения PSI/SI.

Рисунок 10. Поток для построения PSI/SI

  1. Откройте фильтр.

    Filter filter = tuner.openFilter(
      Filter.TYPE_TS,
      Filter.SUBTYPE_SECTION,
      /* bufferSize */1000,
      executor,
      filterCallback
    );
    
  2. Настройте и запустите фильтр.

    Settings settings = SectionSettingsWithTableInfo
        .builder(Filter.TYPE_TS)
        .setTableId(2)
        .setVersion(1)
        .setCrcEnabled(true)
        .setRaw(false)
        .setRepeat(false)
        .build();
      FilterConfiguration config = TsFilterConfiguration
        .builder()
        .setTpid(10)
        .setSettings(settings)
        .build();
      filter.configure(config);
      filter.start();
    
  3. Process SectionEvent .

    FilterCallback filterCallback = new FilterCallback() {
      @Override
      public void onFilterEvent(Filter filter, FilterEvent[] events) {
        for (FilterEvent event : events) {
          if (event instanceof SectionEvent) {
            SectionEvent sectionEvent = (SectionEvent) event;
            int tableId = sectionEvent.getTableId();
            int version = sectionEvent.getVersion();
            int dataLength = sectionEvent.getDataLength();
            int sectionNumber = sectionEvent.getSectionNumber();
            filter.read(buffer, 0, dataLength); }
          }
        }
    };
    
Пример схемы использования MediaEvent из фильтра.

Пример схемы использования MediaEvent из фильтра.

Рисунок 11. Схема использования MediaEvent из фильтра.

  1. Откройте, настройте и запустите аудио- и видеофильтры.
  2. Обработка MediaEvent .
  3. Получить MediaEvent .
  4. Поставьте линейный блок в очередь на codec .
  5. Отпустите дескриптор аудио/видео, когда данные будут израсходованы.

Android.media.tv.tuner.dvr

DvrRecorder предоставляет следующие методы для записи.

  • configure
  • attachFilter
  • detachFilter
  • start
  • flush
  • stop
  • setFileDescriptor
  • write

DvrPlayback предоставляет следующие методы для воспроизведения.

  • configure
  • start
  • flush
  • stop
  • setFileDescriptor
  • read

DvrSettings используется для настройки DvrRecorder и DvrPlayback . OnPlaybackStatusChangedListener и OnRecordStatusChangedListener используются для сообщения о состоянии экземпляра DVR.

Пример последовательности действий для начала записи.

Пример последовательности действий для начала записи.

Рисунок 12. Схема начала записи.

  1. Откройте, настройте и запустите DvrRecorder .

    DvrRecorder recorder = openDvrRecorder(/* bufferSize */ 1000, executor, listener);
    DvrSettings dvrSettings = DvrSettings
    .builder()
    .setDataFormat(DvrSettings.DATA_FORMAT_TS)
    .setLowThreshold(100)
    .setHighThreshold(900)
    .setPacketSize(188)
    .build();
    recorder.configure(dvrSettings);
    recorder.attachFilter(filter);
    recorder.setFileDescriptor(fd);
    recorder.start();
    
  2. Получите RecordEvent и извлеките информацию об индексе.

    FilterCallback filterCallback = new FilterCallback() {
      @Override
      public void onFilterEvent(Filter filter, FilterEvent[] events) {
        for (FilterEvent event : events) {
          if (event instanceof TsRecordEvent) {
            TsRecordEvent recordEvent = (TsRecordEvent) event;
            int tsMask = recordEvent.getTsIndexMask();
            int scMask = recordEvent.getScIndexMask();
            int packetId = recordEvent.getPacketId();
            long dataLength = recordEvent.getDataLength();
            // handle the masks etc. }
          }
        }
    };
    
  3. Инициализируйте обработчик OnRecordStatusChangedListener и сохраните данные записи.

      OnRecordStatusChangedListener listener = new OnRecordStatusChangedListener() {
        @Override
        public void onRecordStatusChanged(int status) {
          // a customized way to consume data efficiently by using status as a hint.
          if (status == Filter.STATUS_DATA_READY) {
            recorder.write(size);
          }
        }
      };
    

Тюнер HAL

Tuner HAL следует протоколу HIDL и определяет интерфейс между фреймворком и оборудованием поставщика. Поставщики используют этот интерфейс для реализации Tuner HAL, а фреймворк использует его для связи с реализацией Tuner HAL.

Модули

Тюнер HAL 1.0

Модули Основные элементы управления Элементы управления, специфичные для модуля Файлы HAL
ITuner Н/Д frontend(open, getIds, getInfo) , openDemux , openDescrambler , openLnb , getDemuxCaps ITuner.hal
IFrontend setCallback , getStatus , close tune , stopTune , scan , stopScan , setLnb IFrontend.hal
IFrontendCallback.hal
IDemux close setFrontendDataSource , openFilter , openDvr , getAvSyncHwId , getAvSyncTime , connect / disconnectCiCam IDemux.hal
IDvr close , start , stop , configure attach/detachFilters , flush , getQueueDesc IDvr.hal
IDvrCallback.hal
IFilter close , start , stop , configure , getId flush , getQueueDesc , releaseAvHandle , setDataSource IFilter.hal
IFilterCallback.hal
ILnb close , setCallback setVoltage , setTone , setSatellitePosition , sendDiseqcMessage ILnb.hal
ILnbCallback.hal
IDescrambler close setDemuxSource , setKeyToken , addPid , removePid IDescrambler.hal

Tuner HAL 1.1 (на основе Tuner HAL 1.0)

Модули Основные элементы управления Элементы управления, специфичные для модуля Файлы HAL
ITuner Н/Д getFrontendDtmbCapabilities @1.1::ITuner.hal
IFrontend tune_1_1 , scan_1_1 , getStatusExt1_1 link/unlinkCiCam @1.1::IFrontend.hal
@1.1::IFrontendCallback.hal
IFilter getStatusExt1_1 configureIpCid , configureAvStreamType , getAvSharedHandle , configureMonitorEvent @1.1::IFilter.hal
@1.1::IFilterCallback.hal

Блок-схема взаимодействия между модулями Tuner HAL.

Рисунок 13. Схема взаимодействия между модулями Tuner HAL.

Фильтр связи

Tuner HAL поддерживает связь фильтров, что позволяет связывать фильтры с другими фильтрами для нескольких слоев. Фильтры подчиняются приведенным ниже правилам.

  • Фильтры связаны между собой в виде дерева, замыкание путей не допускается.
  • Корневой узел — это демультиплексор.
  • Фильтры работают независимо друг от друга.
  • Все фильтры начинают получать данные.
  • Механизм промывки фильтра срабатывает при использовании последнего фильтра.

Приведённый ниже фрагмент кода и рисунок 14 иллюстрируют пример фильтрации нескольких слоёв.

demuxCaps = ITuner.getDemuxCap;
If (demuxCaps[IP][MMTP] == true) {
        ipFilter = ITuner.openFilter(<IP, ..>)
        mmtpFilter1 = ITuner.openFilter(<MMTP ..>)
        mmtpFilter2 = ITuner.openFilter(<MMTP ..>)
        mmtpFilter1.setDataSource(<ipFilter>)
        mmtpFilter2.setDataSource(<ipFilter>)
}

Схема примера соединения фильтров.

Рисунок 14. Блок-схема механизма фильтрации для нескольких слоев.

Менеджер ресурсов тюнера

До появления Tuner Resource Manager (TRM) для переключения между двумя приложениями требовалось одно и то же аппаратное обеспечение тюнера. TV Input Framework (TIF) использовал механизм «кто первый получит ресурс, тот и сохранит его». Однако этот механизм может быть не идеальным для некоторых сложных сценариев использования.

TRM работает как системная служба и управляет аппаратными ресурсами тюнера, TVInput и CAS для приложений. TRM использует механизм «победы в фоновом режиме», который вычисляет приоритет приложения на основе его состояния (в фоновом или переднем плане) и типа использования. TRM предоставляет или отзывает ресурс в зависимости от приоритета. TRM централизует управление ресурсами ATV для вещания, OTT и DVR.

интерфейс TRM

TRM предоставляет интерфейсы AIDL в файле ITunerResourceManager.aidl для фреймворка Tuner, MediaCas и TvInputHardwareManager для регистрации, запроса или освобождения ресурсов.

Ниже перечислены интерфейсы для управления клиентами.

  • registerClientProfile(in ResourceClientProfile profile, IResourcesReclaimListener listener, out int[] clientId)
  • unregisterClientProfile(in int clientId)

Ниже перечислены интерфейсы для запроса и выделения ресурсов.

  • requestFrontend(TunerFrontendRequest request, int[] frontendHandle) / releaseFrontend
  • requestDemux(TunerDemuxRequest request, int[] demuxHandle) / releaseDemux
  • requestDescrambler(TunerDescramblerRequest request, int[] descramblerHandle) / releaseDescrambler
  • requestCasSession(CasSessionRequest request, int[] casSessionHandle) / releaseCasSession
  • requestLnb(TunerLnbRequest request, int[] lnbHandle) / releaseLnb

Ниже перечислены классы клиента и запроса.

  • ResourceClientProfile
  • ResourcesReclaimListener
  • TunerFrontendRequest
  • TunerDemuxRequest
  • TunerDescramblerRequest
  • CasSessionRequest
  • TunerLnbRequest

Приоритет клиента

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

Параметры в профиле клиента

TRM получает идентификатор процесса из mTvInputSessionId , чтобы определить, является ли приложение активным или фоновым. Для создания mTvInputSessionId TvInputService.onCreateSession или TvInputService.onCreateRecordingSession , которые инициализируют сессию TIS.

mUseCase указывает сценарий использования сессии. Предопределенные сценарии использования перечислены ниже.

TvInputService.PriorityHintUseCaseType  {
  PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK
  PRIORITY_HINT_USE_CASE_TYPE_LIVE
  PRIORITY_HINT_USE_CASE_TYPE_RECORD,
  PRIORITY_HINT_USE_CASE_TYPE_SCAN,
  PRIORITY_HINT_USE_CASE_TYPE_BACKGROUND
}

Файл конфигурации

Файл конфигурации по умолчанию

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

Вариант использования Передний план Фон
LIVE 490 400
PLAYBACK 480 300
RECORD 600 500
SCAN 450 200
BACKGROUND 180 100
Пользовательский файл конфигурации

Производители могут настраивать конфигурационный файл /vendor/etc/tunerResourceManagerUseCaseConfig.xml . Этот файл используется для добавления, удаления или обновления типов вариантов использования и значений приоритета вариантов использования. В качестве шаблона для настраиваемого файла можно использовать platform/hardware/interfaces/tv/tuner/1.0/config/tunerResourceManagerUseCaseConfigSample.xml .

Например, новый вариант использования поставщика обозначается как VENDOR_USE_CASE__[A-Z0-9]+, [0 - 1000] . Формат должен соответствовать файлу platform/hardware/interfaces/tv/tuner/1.0/config/tunerResourceManagerUseCaseConfig.xsd .

Произвольное значение приоритета и хорошее значение

TRM предоставляет updateClientPriority позволяющий клиенту обновлять произвольное значение приоритета и значение nice. Произвольное значение приоритета перезаписывает значение приоритета, вычисленное на основе типа варианта использования и идентификатора сессии.

Значение показателя «доброжелательность» указывает на то, насколько снисходительно клиент ведет себя в конфликтных ситуациях с другим клиентом. Значение «доброжелательность» снижает приоритет клиента перед сравнением его приоритета с приоритетом клиента, создающего конфликт.

Механизм восстановления

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

Схема процесса механизма регенерации.

Рисунок 15. Схема механизма восстановления при конфликте между ресурсами тюнера.