Платформа тюнера

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

Стандартизированный интерфейс между Tuner и Android CAS обеспечивает более быструю интеграцию между поставщиками Tuner и поставщиками CAS. Интерфейс Tuner работает с 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

Функции

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

  • АТСК
  • ATSC3
  • ДВБ К/С/Т
  • ИСДБ С/С3/Т
  • Аналоговый

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

  • ДТМБ

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

  • Транспортный поток (TS)
  • Протокол передачи мультимедиа 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 .

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

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

Создается класс TRM.

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

Медиа CAS и CAS HAL дополнены перечисленными ниже функциями.

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

MediaCodec и AudioTrack дополнены перечисленными ниже функциями.

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

Общий дизайн тюнера HAL.

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

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

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

Настраивать

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

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

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

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

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

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

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

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

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

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

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

API SDK для тюнера

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

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

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

Версии

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

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

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

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

Пакеты

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

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

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

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

Android.media.tv.tuner

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

  • Tuner 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 сканируют сообщения 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() , чтобы приостановить или завершить сканирование.

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

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

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

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

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