Framework de Tuner

En el caso de Android 11 o versiones posteriores, puedes usar la Framework de Tuner para publicar contenido A/V. El framework usa el hardware de los proveedores, lo que la hace adecuada para SoC de gama baja y alta. El framework proporciona una forma segura de entregar contenido A/V protegido por una entorno de ejecución confiable (TEE) y una ruta de medios segura (SMP), lo que le permite para usarse en un entorno de protección de contenido altamente restringido.

La interfaz estandarizada entre Tuner y Android CAS da como resultado una integración entre proveedores de Tuner y de CAS. Cómo funciona la interfaz de Tuner con MediaCodec y AudioTrack para crear una solución única para Android TV. La interfaz del sintonizador admite tanto TV digital como analógica según las de transmisión.

Componentes

Para Android 11, tres componentes son específicamente diseñada para la plataforma de TV.

  • HAL del sintonizador: Es una interfaz entre el framework y los proveedores.
  • API del SDK de Tuner: Es una interfaz entre el framework y las apps.
  • Tuner Resource Manager (TRM): Coordina los recursos de Tuner HW.

Para Android 11, se implementaron los siguientes componentes y mejorarlo.

  • CAS V2
  • TvInputService o servicio de entrada de TV (TIS)
  • TvInputManagerService o servicio de administrador de entrada de TV (TIMS)
  • MediaCodec o códec multimedia
  • AudioTrack o pista de audio
  • MediaResourceManager o administrador de recursos de medios (MRM)

Diagrama de flujo de los componentes del framework de Tuner.

Figura 1: Interacciones entre los componentes de Android TV

Funciones

Frontend admite los estándares de DTV que se indican a continuación.

  • ATSC
  • ATSC3
  • DVB C/S/T
  • ISDB S/S3/T
  • Analógico

El frontend de Android 12 con Tuner HAL 1.1 o versiones posteriores es compatible con el estándar de DTV que se indica a continuación.

  • DTMB

Demux es compatible con los protocolos de transmisión que se indican a continuación.

  • Flujo de transporte (TS)
  • Protocolo de transporte de medios MPEG (MMTP)
  • Protocolo de Internet (IP)
  • Valor de longitud de tipo (TLV)
  • Protocolo de capa de vínculo (ALP) de ATSC

Descrambler admite las protecciones de contenido que se indican a continuación.

  • Ruta de acceso a medios seguros
  • Borrar ruta de acceso al contenido multimedia
  • Registro local seguro
  • Reproducción local segura

Las APIs de Tuner admiten los casos de uso que se indican a continuación.

  • Escanear
  • En vivo
  • Reproducción
  • Grabar

Tuner, MediaCodec y AudioTrack admiten los modos de flujo de datos que se indican a continuación.

  • Carga útil de ES con búfer de memoria libre
  • Carga útil de ES con controlador de memoria seguro
  • Modo de cámara externa

Diseño general

La HAL del sintonizador se define entre el framework de Android y la configuración hardware.

  • Describe lo que el marco de trabajo espera del proveedor y cómo este último hazlo.
  • Exporta las funcionalidades de frontend, demux y descrambler al a través de IFrontend, IDemux, IDescrambler, IFilter, IDvr, y ILnb.
  • Incluye las funciones para integrar la HAL de Tuner con otro framework. componentes, como MediaCodec y AudioTrack.

Se crean una clase nativa y una clase de Java de Tuner.

  • La API de Tuner para Java permite que las apps accedan a la HAL de Tuner a través de APIs públicas.
  • La clase nativa permite controlar los permisos y administrar grandes cantidades de grabación o reproducción de datos con la HAL del sintonizador.
  • El módulo Native Tuner es un puente entre la clase Tuner Java y Tuner. HAL.

Se crea una clase TRM.

  • Administra recursos limitados de Tuner, como frontend, LNB, sesiones de CAS y un dispositivo de entrada de TV de la HAL de entrada de TV.
  • Aplica reglas para reclamar recursos insuficientes de de Google Chat. La regla predeterminada es la victoria en primer plano.

Los medios CAS y la HAL de CAS se mejoraron con las siguientes funciones.

  • Abre sesiones de CAS para diferentes usos y algoritmos.
  • Admite sistemas CAS dinámicos, como la inserción y eliminación de CICAM.
  • Se integra con la HAL de Tuner proporcionando tokens de clave.

Se mejoraron MediaCodec y AudioTrack con las siguientes funciones.

  • Toma memoria A/V segura como entrada de contenido.
  • Se configuró para realizar la sincronización de A/V de hardware en la reproducción en túnel.
  • Se configuró la compatibilidad con ES_payload y el modo de transferencia.

Diseño general de la HAL de Tuner.

Figura 2: Diagrama de los componentes dentro de la HAL del sintonizador

Flujo de trabajo general

En los diagramas que aparecen a continuación, se ilustran las secuencias de llamadas para la reproducción de transmisiones en vivo.

Configuración

Diagrama de la secuencia de configuración del diagrama de reproducción de una transmisión en vivo.

Figura 3: Secuencia de configuración para la reproducción de transmisiones en vivo

Cómo manejar el contenido audiovisual y de audio

Diagrama de manejo de audio y video para la reproducción de transmisiones en vivo.

Figura 4: Cómo manejar el audio y video para la reproducción de transmisiones en vivo

Cómo controlar contenido codificado

Diagrama de manejo de contenido codificado para la reproducción de una transmisión en vivo.

Figura 5: Cómo manejar contenido codificado para la reproducción de transmisiones en vivo

Procesamiento de datos A/V

Diagrama de procesamiento de datos de audio y video para la reproducción de transmisiones en vivo.

Figura 6: Procesamiento de audio y video para la reproducción de transmisiones en vivo

API del SDK de Tuner

La API del SDK de Tuner controla las interacciones con la JNI de Tuner, la HAL de Tuner, y TunerResourceManager. La app de TIS usa la API del SDK de Tuner para acceder a Tuner. recursos y subcomponentes como el filtro y el decodificador. Interfaz de usuario demux son componentes internos.

Diagrama de flujo de la API del SDK de Tuner.

Figura 7: Interacciones con la API del SDK de Tuner

Versiones

A partir de Android 12, la API del SDK de Tuner admite una función nueva en Tuner HAL 1.1, que es una actualización retrocompatible de Tuner 1.0.

Usa la siguiente API para verificar la versión de HAL en ejecución.

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

Puedes encontrar la versión mínima requerida de la HAL en la documentación de las nuevas APIs de Android 12.

Paquetes

La API del SDK de Tuner proporciona los cuatro paquetes que se indican a continuación.

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

Diagrama de flujo de los paquetes de la API del SDK de Tuner.

Figura 8: Paquetes de la API del SDK de Tuner

Android.media.tv.tuner.

El paquete Tuner es un punto de entrada para usar el framework de Tuner. La app de TIS usa el paquete para inicializar y adquirir instancias de recursos especificando la configuración inicial y la devolución de llamada.

  • tuner(): inicializa una instancia de Tuner mediante la especificación de useCase y Parámetros sessionId.
  • tune(): Adquiere un recurso de frontend y se ajusta mediante la especificación de Parámetro FrontendSetting.
  • openFilter(): Adquiere una instancia de filtro mediante la especificación del tipo de filtro.
  • openDvrRecorder(): Adquiere una instancia de grabación mediante la especificación del búfer. de tamaño del ensamble.
  • openDvrPlayback(): Adquiere una instancia de reproducción mediante la especificación del búfer. de tamaño del ensamble.
  • openDescrambler(): Adquiere una instancia de decodificador.
  • openLnb(): Adquiere una instancia de LNB interna.
  • openLnbByName(): Adquiere una instancia de LNB externa.
  • openTimeFilter(): Adquiere una instancia de filtro de tiempo.

El paquete Tuner proporciona funcionalidades que no se incluyen en el filtro, el DVR y los paquetes de frontend. Las funciones se enumeran a continuación.

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

Android.media.tv.tuner.frontend.

El paquete de frontend incluye colecciones de configuraciones relacionadas con el frontend, información, estados, eventos y capacidades.

Clases

Las clases que se indican a continuación derivan de FrontendSettings para diferentes estándares de DTV.

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

A partir de Android 12 con Tuner HAL 1.1 o versiones posteriores, se admite el siguiente estándar de DTV.

  • DtmbFrontendSettings

FrontendCapabilities se deriva para diferentes estándares de DTV según las clases. a continuación.

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

A partir de Android 12 con Tuner HAL 1.1 o versiones posteriores, se admite el siguiente estándar de DTV.

  • DtmbFrontendCapabilities

FrontendInfo recupera la información del frontend. FrontendStatus recupera el estado actual del frontend. OnTuneEventListener escucha los eventos en el frontend. La app de TIS usa ScanCallback para procesar los mensajes de análisis desde el frontend.

Búsqueda de canales

Para configurar una TV, la app escanea las frecuencias posibles y crea un canal de contenido para que accedan los usuarios. TIS podría usar Tuner.tune, Tuner.scan(BLIND_SCAN) o Tuner.scan(AUTO_SCAN) para completar el canal en tus servicios.

Si TIS tiene información de entrega precisa para el indicador, como la frecuencia, estándar (por ejemplo, T/T2, S/S2) y la información adicional necesaria (por ejemplo, ID de PLD) y, luego, Se recomienda Tuner.tune como la opción más rápida.

Cuando el usuario llama a Tuner.tune, se producen las siguientes acciones:

  • TIS propaga FrontendSettings con la información requerida mediante Tuner.tune.
  • La HAL ajusta los mensajes de LOCKED si la señal está bloqueada.
  • TIS utiliza Frontend.getStatus para recopilar la información necesaria.
  • TIS pasa a la siguiente frecuencia disponible en su lista de frecuencias.

TIS vuelve a llamar a Tuner.tune hasta que se agoten todas las frecuencias.

Durante el ajuste, puedes llamar a stopTune() o close() para pausar o finalizar la Llamada de Tuner.tune.

Tuner.scan(AUTO_SCAN)

Si TIS no tiene suficiente información para usar Tuner.tune, pero tiene una frecuencia el tipo de lista y el estándar (por ejemplo, DVB T/C/S); entonces se recomienda Tuner.scan(AUTO_SCAN).

Cuando el usuario llama a Tuner.scan(AUTO_SCAN), se producen las siguientes acciones:

  • TIS usa Tuner.scan(AUTO_SCAN) con FrontendSettings completados con frecuencia.

  • El informe de la HAL escanea los mensajes de LOCKED si la señal está bloqueada. Es posible que la HAL también informar otros mensajes de análisis para brindar información adicional sobre la señal.

  • TIS utiliza Frontend.getStatus para recopilar la información necesaria.

  • TIS llama a Tuner.scan para que la HAL continúe con la siguiente configuración del mismo frecuencia. Si la estructura FrontendSettings está vacía, la HAL usa el siguiente los parámetros de configuración disponibles. De lo contrario, la HAL usa FrontendSettings durante un período análisis y envía END para indicar que finalizó la operación de análisis.

  • TIS repite las acciones anteriores hasta que todos los parámetros de configuración de la frecuencia agotarse.

  • La HAL envía END para indicar que finalizó la operación de búsqueda.

  • TIS pasa a la siguiente frecuencia disponible en su lista de frecuencias.

TIS vuelve a llamar a Tuner.scan(AUTO_SCAN) hasta que se agoten todas las frecuencias.

Durante la búsqueda, puedes llamar a stopScan() o close() para pausar o finalizar la analizarlo.

Tuner.scan(BLIND_SCAN)

Si TIS no tiene una lista de frecuencias, y la HAL del proveedor puede buscar la frecuencia del frontend especificado por el usuario para obtener el recurso de frontend y, luego, Horario recomendado: Tuner.scan(BLIND_SCAN)

  • TIS utiliza Tuner.scan(BLIND_SCAN). Una frecuencia puede especificarse en FrontendSettings para la frecuencia de inicio, pero TIS ignora otros parámetros de configuración. en FrontendSettings.
  • La HAL informa un mensaje de escaneo LOCKED si la señal está bloqueada.
  • TIS utiliza Frontend.getStatus para recopilar la información necesaria.
  • TIS vuelve a llamar a Tuner.scan para continuar con el escaneo. (FrontendSettings es ignoradas).
  • TIS repite las acciones anteriores hasta que todos los parámetros de configuración de la frecuencia agotarse. La HAL aumenta la frecuencia sin que TIS deba realizar ninguna acción. La HAL informa PROGRESS.

TIS vuelve a llamar a Tuner.scan(AUTO_SCAN) hasta que se agoten todas las frecuencias. La HAL informa END para indicar que finalizó la operación de búsqueda.

Durante la búsqueda, puedes llamar a stopScan() o close() para detenerla o finalizarla.

Diagrama de flujo del proceso de análisis de TIS.

Figura 9: Diagrama de flujo de un análisis de TIS

Android.media.tv.tuner.filter.

El paquete de filtro es una colección de operaciones de filtro junto con la configuración, parámetros de configuración, devoluciones de llamada y eventos. El paquete incluye las operaciones que se indican a continuación. Consulta el código fuente de Android para ver la lista completa de operaciones.

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

Consulta el código fuente de Android para ver la lista completa.

FilterConfiguration se deriva de las siguientes clases. Los parámetros de configuración para el tipo de filtro principal y especifican qué protocolo usa el filtro extraer datos.

  • AlpFilterConfiguration
  • IpFilterConfiguration
  • MmtpFilterConfiguration
  • TlvFilterConfiguration
  • TsFilterConfiguration

La configuración se deriva de las siguientes clases. La configuración es para el filtro y especifican qué tipos de datos puede excluir el filtro.

  • SectionSettings
  • AvSettings
  • PesSettings
  • RecordSettings
  • DownloadSettings

FilterEvent se deriva de las siguientes clases para informar eventos de diferentes tipos de datos.

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

A partir de Android 12 con Tuner HAL 1.1 o versiones posteriores, se admiten los siguientes eventos.

  • IpCidChangeEvent
  • RestartEvent
  • ScramblingStatusEvent
Eventos y formato de datos del filtro
Tipo de filtro Marcas Eventos Operación de datos Formato de los datos
TS.SECTION
MMTP.SECTION
IP.SECTION
TLV.SECTION
ALP.SECTION
isRaw:
true
Obligatorio:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Recomendado:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
Según el programa interno y el evento, ejecuta
Filter.read(buffer, offset, adjustedSize) uno o más veces.

Los datos se copian del MQ de HAL al búfer del cliente.
Otro paquete de sesión ensamblada se completa en FMQ de sesión del usuario.
isRaw:
false
Obligatorio:
DemuxFilterEvent::DemuxFilterSectionEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Opcional:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
for i=0; i<n; i++
Filter.read(buffer, offset, DemuxFilterSectionEven[i].size)
de

Los datos se copian del MQ de HAL al búfer del cliente.
TS.PES isRaw:
true
Obligatorio:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Recomendado:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
Según el programa interno y el evento, ejecuta
Filter.read(buffer, offset, adjustedSize) uno o más veces.

Los datos se copian del MQ de la HAL al búfer del cliente.
Otro paquete de PES ensamblado se completa en FMQ paquete de PES.
isRaw:
false
Obligatorio:
DemuxFilterEvent::DemuxFilterPesEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Opcional:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
for i=0; i<n; i++
Filter.read(buffer, offset, DemuxFilterPesEven[i].size)
de

Los datos se copian del MQ de HAL al búfer del cliente.
MMTP.PES isRaw:
true
Obligatorio:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Recomendado:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
Según el programa interno y el evento, ejecuta
Filter.read(buffer, offset, adjustedSize) uno o más veces.

Los datos se copian del MQ de la HAL al búfer del cliente.
Otro paquete de MFU ensamblado se completa en FMQ paquete de MFU.
isRaw:
false
Obligatorio:
DemuxFilterEvent::DemuxFilterPesEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Opcional:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
for i=0; i<n; i++
Filter.read(buffer, offset, DemuxFilterPesEven[i].size)
de

Los datos se copian del MQ de la HAL al búfer del cliente.
TS.TS
N/A Obligatorio:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Recomendado:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
Según el programa interno y el evento, ejecuta
Filter.read(buffer, offset, adjustedSize) uno o más veces.

Los datos se copian del MQ de la HAL al búfer del cliente.
Se filtró ts con el encabezado
de ts se completa en FMQ.
TS.Audio
TS.Video
MMTP.Audio
MMTP.Video
isPassthrough:
true
Opcional:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
El cliente puede iniciar MediaCodec después de recibir DemuxFilterStatus::DATA_READY.
El cliente puede llamar a Filter.flush después de recibir DemuxFilterStatus::DATA_OVERFLOW.
N/A
isPassthrough:
false
Obligatorio:
DemuxFilterEvent::DemuxFilterMediaEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Opcional:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
Para usar MediaCodec, haz lo siguiente:
for i=0; i<n; i++
linearblock = MediaEvent[i].getLinearBlock();
codec.startQueueLinearBlock(linearblock)
linearblock.recycle()


Para usar audio directo de AudioTrack, haz lo siguiente:
for i=0; i<n; i++
audioHandle = MediaEvent[i].getAudioHandle();
audiotrack.write(encapsulated(audiohandle))
Datos ES o parciales ES en la memoria ION.
TS.PCR
IP.NTP
ALP.PTP
N/A Obligatorio: N/A
Opcional: N/A
N/A N/A
TS.RECORD N/A Obligatorio:
DemuxFilterEvent::DemuxFilterTsRecordEvent[n]
RecordStatus::DATA_READY
RecordStatus::DATA_OVERFLOW
RecordStatus::LOW_WATER
RecordStatus::HIGH_WATER

Opcional:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

de DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER
Para los datos de índice:
for i=0; i<n; i++
DemuxFilterTsRecordEvent[i];


Para el contenido grabado, de acuerdo con RecordStatus::* y un cronograma interno, una de las siguientes opciones:
  • Ejecutar DvrRecord.write(adustedSize) una o más veces a almacenamiento.
    Los datos se transfieren del MQ de la HAL al almacenamiento.
  • Ejecutar DvrRecord.write(buffer, adustedSize) una o más veces para almacenar en búfer.
    Los datos se copian del MQ de la HAL al búfer del cliente.
Para datos de índice: Se transporta en la carga útil del evento.

Para contenido grabado: Transmisión de TS multiplexada completada con FMQ.
TS.TEMI N/A Obligatorio:
DemuxFilterEvent::DemuxFilterTemiEvent[n]

Opcional:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
for i=0; i<n; i++
DemuxFilterTemiEvent[i];
N/A
MMTP.MMTP N/A Obligatorio:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Recomendado:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
Según el programa interno y el evento, ejecuta
Filter.read(buffer, offset, adjustedSize) uno o más veces.

Los datos se copian del MQ de la HAL al búfer del cliente.
Se filtró mmtp con el encabezado
de mmtp se completa en FMQ.
MMTP.RECORD N/A Obligatorio:
DemuxFilterEvent::DemuxFilterMmtpRecordEvent[n]
RecordStatus::DATA_READY
RecordStatus::DATA_OVERFLOW
RecordStatus::LOW_WATER
RecordStatus::HIGH_WATER

Opcional:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

de DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER
Para los datos de índice: for i=0; i<n; i++
DemuxFilterMmtpRecordEvent[i];


Para el contenido grabado, de acuerdo con RecordStatus::* y un cronograma interno, realiza una de las siguiente:
  • Ejecutar DvrRecord.write(adjustedSize) una o más veces en el almacenamiento.
    Los datos se transfieren del MQ de la HAL al almacenamiento.
  • Ejecuta DvrRecord.write(buffer, adjustedSize)una o más tiempos para almacenar en búfer.
    Los datos se copian del MQ de la HAL al búfer del cliente.
Para datos de índice: Se transporta en la carga útil del evento.

Para el contenido grabado: Se completó la transmisión grabada y silenciada. FMQ.

Si la fuente del filtro para la grabación es de TLV.TLV a IP.IP con transferencia, la transmisión grabada tiene un Encabezado IP y TLV.
MMTP.DOWNLOAD N/A Obligatorio:
DemuxFilterEvent::DemuxFilterDownloadEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Opcional:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
for i=0; i<n; i++ Filter.read(buffer, offset, DemuxFilterDownloadEvent[i].size) de

Los datos se copian del MQ de HAL al búfer del cliente.
El paquete de descarga se completa en FMQ con otro paquete de descarga de IP.
IP.IP_PAYLOAD N/A Obligatorio:
DemuxFilterEvent::DemuxFilterIpPayloadEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Opcional:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
for i=0; i<n; i++ Filter.read(buffer, offset, DemuxFilterIpPayloadEvent[i].size) de

Los datos se copian del MQ de HAL al búfer del cliente.
El paquete de carga útil de IP se completa en FMQ con otro paquete de carga útil de IP.
IP.IP
TLV.TLV
ALP.ALP
isPassthrough:
true
Opcional:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
La subtransmisión de protocolo filtrada alimenta el siguiente filtro del filtro de la cadena de suministro. N/A
isPassthrough:
false
Obligatorio:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Recomendado:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
Según el programa interno y el evento, ejecuta
Filter.read(buffer, offset, adjustedSize) uno o más veces.

Los datos se copian del MQ de la HAL al búfer del cliente.
Se completó la subtransmisión de protocolo filtrada con el encabezado de protocolo FMQ.
IP.PAYLOAD_THROUGH
TLV.PAYLOAD_THROUGH
ALP.PAYLOAD_THROUGH
N/A Opcional:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
La carga útil del protocolo filtrada envía el siguiente filtro del filtro de la cadena de suministro. N/A
Flujo de ejemplo para usar un filtro a fin de compilar PSI/SI

Ejemplo de flujo para usar un filtro a fin de compilar PSI/SI.

Figura 10: Flujo para compilar PSI/SI

  1. Abre un filtro.

    Filter filter = tuner.openFilter(
      Filter.TYPE_TS,
      Filter.SUBTYPE_SECTION,
      /* bufferSize */1000,
      executor,
      filterCallback
    );
    
  2. Configura y, luego, inicia el filtro.

    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. Procesa 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); }
          }
        }
    };
    
Ejemplo de flujo para usar MediaEvent desde el filtro

Ejemplo de flujo para usar MediaEvent desde el filtro.

Figura 11: Flujo para usar MediaEvent desde el filtro

  1. Abre, configura e inicia los filtros de A/V.
  2. Procesa MediaEvent.
  3. Recibe MediaEvent.
  4. Pon en cola el bloque lineal en codec.
  5. Libera el controlador de A/V cuando se hayan consumido los datos.

Android.media.tv.tuner.dvr.

DvrRecorder proporciona estos métodos para las grabaciones.

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

DvrPlayback proporciona estos métodos para la reproducción.

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

DvrSettings se usa para configurar DvrRecorder y DvrPlayback. Se usan OnPlaybackStatusChangedListener y OnRecordStatusChangedListener para informar el estado de una instancia de DVR.

Ejemplo de flujo para iniciar un registro

Ejemplo de flujo para iniciar un registro.

Figura 12: Flujo para iniciar un registro

  1. Abre, configura e inicia 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. Recibe RecordEvent y recupera la información del índice.

    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. Inicializa OnRecordStatusChangedListener y almacena los datos del registro.

      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 del sintonizador

La HAL del Tuner sigue el HIDL y define la interfaz entre el framework y el hardware del proveedor. Los proveedores usan la interfaz para implementar la HAL del sintonizador y la lo usa para comunicarse con la implementación de la HAL de Tuner.

Módulos

Sintonizador HAL 1.0

Módulos Controles básicos Controles específicos del módulo Archivos HAL
ITuner N/A frontend(open, getIds, getInfo), openDemux, openDescrambler, openLnb getDemuxCaps ITuner.hal
IFrontend setCallback, getStatus y close tune, stopTune y scan stopScan y setLnb IFrontend.hal
IFrontendCallback.hal
IDemux close setFrontendDataSource, openFilter, openDvr y getAvSyncHwId getAvSyncTime, connect / disconnectCiCam IDemux.hal
IDvr close, start, stop, configure attach/detachFilters, flush y 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 y removePid IDescrambler.hal

Tuner HAL 1.1 (derivado de Tuner HAL 1.0)

Módulos Controles básicos Controles específicos del módulo Archivos HAL
ITuner N/A getFrontendDtmbCapabilities @1.1::ITuner.hal
IFrontend tune_1_1, scan_1_1 y 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

Diagrama de flujo de las interacciones entre los módulos de la HAL de Tuner.

Figura 13: Diagrama de las interacciones entre los módulos de HAL de Tuner

Vinculación del filtro

La HAL del sintonizador admite la vinculación de filtros de modo que estos puedan vincularse a otras filtros para varias capas. Los filtros siguen las reglas que se indican a continuación.

  • Los filtros se vinculan en forma de árbol; no se permite cerrar rutas.
  • El nodo raíz es demux.
  • Los filtros funcionan de forma independiente.
  • Todos los filtros comienzan a recibir datos.
  • La vinculación del filtro vaciando el último filtro.

El bloque de código que aparece a continuación y la Figura 14 ilustran un ejemplo de filtrado de varias capas.

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>)
}

Diagrama de ejemplo de vinculación de filtros.

Figura 14: Diagrama de flujo de una vinculación de filtro para varias capas

Tuner Resource Manager

Antes de Tuner Resource Manager (TRM), el cambio entre dos apps requería la mismo hardware de Tuner. El marco de trabajo de entrada de TV (TIF) utilizó una "primera adquisición" mecanismo de atención, lo que significa que la aplicación que obtenga primero el recurso lo conservará. Sin embargo, es posible que este mecanismo no sea ideal para algunos casos de uso complicados.

TRM se ejecuta como un servicio del sistema para administrar el hardware de Tuner, TVInput y CAS recursos para las apps. TRM usa la “victoria en primer plano” de atención, que calcula la prioridad de la app según el primer o segundo plano de esta estado y el tipo de caso de uso. TRM otorga o revoca el recurso según la prioridad. TRM centraliza la administración de recursos de ATV para transmisiones, OTT, y DVR.

Interfaz de TRM

TRM expone las interfaces del AIDL en ITunerResourceManager.aidl para el sintonizador framework, MediaCas y TvInputHardwareManager para registrar, solicitar o liberar recursos.

A continuación, se muestran las interfaces para la administración de clientes.

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

A continuación, se muestran las interfaces para solicitar y liberar recursos.

  • 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

A continuación, se indican las clases de solicitudes y clientes.

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

Prioridad del cliente

TRM calcula la prioridad del cliente usando parámetros de la y el valor de prioridad del archivo de configuración. La prioridad podría un valor de prioridad arbitrario del cliente.

Parámetros en el perfil del cliente

TRM recupera el ID de proceso de mTvInputSessionId para decidir si una app es una app en primer o segundo plano. Para crear mTvInputSessionId, sigue estos pasos: TvInputService.onCreateSession o TvInputService.onCreateRecordingSession inicializa una sesión de TIS.

mUseCase indica el caso de uso de la sesión. Los casos de uso predefinidos que se enumeran a continuación.

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
}

Archivo de configuración

Archivo de configuración predeterminado

El archivo de configuración predeterminado a continuación proporciona valores de prioridad para uso predefinido diferentes. Los usuarios pueden cambiar los valores con un archivo de configuración personalizado.

Caso de uso Primer plano Información general
LIVE 490 400
PLAYBACK 480 300
RECORD 600 500
SCAN 450 200
BACKGROUND 180 100
Archivo de configuración personalizado

Los proveedores pueden personalizar el archivo de configuración /vendor/etc/tunerResourceManagerUseCaseConfig.xml Este archivo se usa para agregar, quitar o actualizar sus tipos y sus valores de prioridad. El archivo personalizado puede usar platform/hardware/interfaces/tv/tuner/1.0/config/tunerResourceManagerUseCaseConfigSample.xml como plantilla.

Por ejemplo, un caso de uso de un proveedor nuevo es VENDOR_USE_CASE__[A-Z0-9]+, [0 - 1000]. El formato debe seguir platform/hardware/interfaces/tv/tuner/1.0/config/tunerResourceManagerUseCaseConfig.xsd

Valor de prioridad arbitrario y valor agradable

TRM proporciona updateClientPriority para que el cliente actualice el de prioridad y un buen valor. El valor de prioridad arbitrario reemplaza al valor de prioridad calculado a partir del tipo de caso de uso y el ID de sesión.

El valor agradable indica cuán tolerante es el comportamiento del cliente cuando se encuentra en un conflicto con otro cliente. El valor agradable disminuye la prioridad del cliente de valor antes de compararlo con el cliente desafiante.

Mecanismo de recuperación

En el siguiente diagrama, se muestra cómo se reclaman y asignan los recursos cuando se produce un conflicto de recursos.

Diagrama del proceso del mecanismo de recuperación.

Figura 15: Diagrama del mecanismo de recuperación para un conflicto entre Tuner recursos