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

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

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

Компоненты

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

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

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

  • КАС V2
  • TvInputService или Служба ТВ-входа (TIS)
  • TvInputManagerService или служба диспетчера входов ТВ (TIMS)
  • MediaCodec или медиакодек
  • AudioTrack или звуковая дорожка
  • MediaResourceManager или менеджер медиаресурсов (MRM)

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

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

Функции

Интерфейс поддерживает следующие стандарты DTV.

  • АТСК
  • ATSC3
  • DVB-C/S/T
  • ISDB S/S3/T
  • Аналоговый

Интерфейс в Android 12 с Tuner HAL 1.1 или выше поддерживает стандарт DTV, указанный ниже.

  • ДТМБ

Demux поддерживает перечисленные ниже потоковые протоколы.

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

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

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

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

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

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

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

Общий дизайн

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

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

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

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

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

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

Media CAS и CAS HAL улучшены за счет следующих функций.

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

MediaCodec и AudioTrack улучшены с помощью следующих функций.

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

Общая конструкция тюнера HAL.

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

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

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

Настраивать

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

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

Обработка аудио/видео

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

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

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

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

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

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

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

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

API-интерфейс SDK тюнера

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

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

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

Версии

Начиная с Android 12, Tuner SDK API поддерживает новую функцию в 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 выводится для различных стандартов DTV с помощью классов, указанных ниже.

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

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

  • DtmbFrontendSettings

FrontendCapabilities выводится для различных стандартов DTV с помощью классов, указанных ниже.

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

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

  • 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 выдает сообщения LOCKED .
  • TIS использует Frontend.getStatus для сбора необходимой информации.
  • TIS переходит на следующую доступную частоту в своем списке частот.

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

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

Тюнер.сканирование(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 также может сообщать о других сообщениях scan, чтобы предоставить дополнительную информацию о сигнале.

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

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

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

  • HAL отправляет END , чтобы указать, что операция сканирования завершена.

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

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

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

Тюнер.сканирование(BLIND_SCAN)

Если у TIS нет списка частот и 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

Пакет фильтра представляет собой набор операций фильтра вместе с конфигурацией, настройками, обратными вызовами и событиями. Пакет включает операции ниже. Полный список операций см. в исходном коде 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. Процесс 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. Откройте, настройте и запустите фильтры A/V.
  2. Процесс MediaEvent .
  3. Получаем MediaEvent .
  4. Поставьте линейный блок в очередь codec .
  5. Отпустите кнопку A/V после того, как данные будут обработаны.

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

Тюнер HAL 1.1 (производный от тюнера 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

Блок-схема взаимодействия модулей тюнера 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) переключение между двумя приложениями требовало одного и того же оборудования Tuner. TV Input Framework (TIF) использовал механизм «первый получил победу», что означает, что приложение, которое первым получило ресурс, сохраняет его. Однако этот механизм может быть неидеальным для некоторых сложных случаев использования.

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

Интерфейс ТРМ

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. Произвольное значение приоритета перезаписывает значение приоритета, вычисленное на основе типа варианта использования и идентификатора сеанса.

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

Механизм возврата

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

Схема процесса работы механизма возврата.

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