W przypadku Androida 11 lub nowszego możesz użyć Platforma tunera do odtwarzania treści audiowizualnych. Platforma wykorzystuje sprzęt przez źródła sinusoidalne, dzięki czemu nadaje się zarówno dla niedrogich, jak i zaawansowanych układów SoC. Platforma ta zapewnia bezpieczny sposób dostarczania treści audiowizualnych chronionych zaufanego środowiska wykonawczego (TEE) i bezpiecznej ścieżki mediów (SMP), w bardzo ograniczonym środowisku ochrony treści.
Ustandaryzowany interfejs między Tunerem a urzędami certyfikacji na Androidzie zapewnia szybsze działanie
integracji między dostawcami tunerów a dostawcami CAS. Interfejs tunera działa
z MediaCodec
i AudioTrack
, aby stworzyć kompleksowe rozwiązanie na Androida TV.
Interfejs tunera obsługuje zarówno telewizję cyfrową, jak i analogową
standardów transmisji.
Komponenty
W przypadku Androida 11 3 komponenty stworzonych z myślą o platformie telewizyjnej.
- Tuner HAL: interfejs między platformą a dostawcami
- Tuner SDK API: interfejs między platformą a aplikacjami.
- Tuner Resource Manager (TRM): koordynuje zasoby HW Tuner.
W Androidzie 11 te komponenty ulepszone.
- CAS V2
TvInputService
lub usługa wejścia TV (TIS)TvInputManagerService
lub usługa menedżera wejścia TV (TIMS)MediaCodec
lub kodek multimediówAudioTrack
lub ścieżka audioMediaResourceManager
lub menedżer zasobów multimediów (MRM)
Rysunek 1. Interakcje między komponentami Androida TV
Funkcje
Frontend obsługuje wymienione poniżej standardy DTV.
- protokół ATSC
- protokół ATSC3
- DVB C/S/T,
- ISDB S/S3/T
- Analogowe
Interfejs Androida 12 z tunerem HAL 1.1 lub nowszym obsługuje standard DTV podany poniżej.
- DTMB
Demux obsługuje poniższe protokoły strumienia.
- Strumień transportu
- Protokół MPEG Media Transport Protocol (MMTP)
- Protokół internetowy (IP)
- Wpisz wartość długości (TLV)
- Protokół warstwy linków ATSC (ALP)
Dekoder obsługuje poniższe zabezpieczenia treści.
- Bezpieczna ścieżka multimediów
- Wyczyść ścieżkę multimediów
- Bezpieczny rekord lokalny
- Bezpieczne odtwarzanie lokalne
Interfejsy API dostrajania obsługują poniższe przypadki użycia.
- Skanuj
- Na żywo
- Odtwarzanie
- Nagraj
Tuner, MediaCodec
i AudioTrack
obsługują poniższe tryby przepływu danych.
- Ładunek ES z czystym buforem pamięci
- Ładunek ES z bezpiecznym uchwytem pamięci
- Widok otoczenia
Ogólny projekt
HAL dostrajania jest zdefiniowana między platformą Androida a zasobem dostawcy sprzęt.
- Opisuje, czego platforma oczekuje od dostawcy i w jaki sposób może to zrobić aby to zrobić.
- Eksportuje funkcje frontendu, demuksa i narzędzia do demusowania do
platformę
IFrontend
,IDemux
,IDescrambler
,IFilter
,IDvr
, iILnb
. - Obejmuje funkcje pozwalające zintegrować HAL Tuner z inną platformą
takie jak
MediaCodec
iAudioTrack
.
Zostanie utworzona klasa Java tunera i klasa natywna.
- Interfejs Tuner Java API umożliwia aplikacjom dostęp do interfejsu HAL Tuner przez publiczne interfejsy API.
- Klasa natywna umożliwia kontrolę uprawnień i obsługę dużych ilości do nagrywania i odtwarzania danych za pomocą oprogramowania Tuner HAL.
- Moduł natywnego dostrajania to połączenie między klasą Java Tuner i tunerem HAL.
Zostanie utworzona klasa TRM.
- Zarządza ograniczonymi zasobami usługi Tuner, takimi jak frontend, LNB, sesji CAS oraz przez wejście TV z wejścia HAL TV.
- Stosuje reguły, aby odzyskać niewystarczające zasoby z aplikacji. Domyślna reguła to wygrana na pierwszym planie.
Funkcje Media CAS i CAS HAL zostały uzupełnione o poniższe funkcje.
- Otwiera sesje CAS dla różnych zastosowań i algorytmów.
- Obsługuje dynamiczne systemy CAS, np. usuwanie i wstawianie CICAM.
- Integracja z HAL Tuner zapewnia tokeny kluczy.
Do MediaCodec
i AudioTrack
zostały dodane poniższe funkcje.
- Jako dane wejściowe pobiera bezpieczną pamięć AV.
- Skonfigurowane pod kątem sprzętowej synchronizacji dźwięku i obrazu w odtwarzaniu tunelowym.
- Skonfigurowano obsługę
ES_payload
i tryb przekazywania.
Rysunek 2. Schemat elementów składowych HAL tunera
Ogólny przepływ pracy
Na poniższych schematach przedstawiono sekwencje połączeń podczas odtwarzania transmisji na żywo.
Konfiguracja
Rysunek 3. Konfiguracja sekwencji odtwarzania transmisji na żywo
Obsługa sprzętu audiowizualnego
Rysunek 4. Obsługa dźwięku i obrazu podczas odtwarzania transmisji na żywo
Postępowanie w przypadku zaszyfrowanej treści
Rysunek 5. Odtwarzanie zakodowanych treści podczas transmisji na żywo
Przetwarzanie danych audiowizualnych
Rysunek 6. Przetwarzanie obrazu i dźwięku do odtwarzania transmisji na żywo
Interfejs API pakietu SDK Tuner
Interfejs API pakietu SDK Tuner obsługuje interakcje z JNI tunera, kodem HAL Tuner
i TunerResourceManager
. Aplikacja TIS używa interfejsu API Tuner SDK, aby uzyskać dostęp do Tuner
takich jak filtr i dekoder. Frontend
to komponenty wewnętrzne.
Rysunek 7. Interakcje z interfejsem API Tuner SDK
Wersje
Od Androida 12 interfejs Tuner SDK API obsługuje nową funkcję w Tuner HAL 1.1, to uaktualniona wstecznie wersja Tuner 1.0.
Użyj poniższego interfejsu API, aby sprawdzić uruchomioną wersję HAL.
android.media.tv.tuner.TunerVersionChecker.getTunerVersion()
Minimalną wymaganą wersję HAL znajdziesz w dokumentacji nowych interfejsów API Androida 12.
Pakiety
Interfejs API Tuner SDK udostępnia 4 poniższe pakiety.
android.media.tv.tuner
android.media.tv.tuner.frontend
android.media.tv.tuner.filter
android.media.tv.tuner.dvr
Rysunek 8. Pakiety interfejsu API Tuner SDK
Android.media.tv.tuner
Pakiet tunera to punkt wyjścia do korzystania z platformy Tuner. Aplikacja TIS używa pakietu do inicjowania i pozyskiwania instancji zasobów przez określenie ustawienia początkowego i wywołania zwrotnego.
tuner()
: inicjuje instancję tunera przez określenieuseCase
isessionId
parametry.tune()
: pozyskuje zasób frontendu i dostrajanie przez określenieFrontendSetting
.openFilter()
: pozyskuje instancję filtra, określając typ filtra.openDvrRecorder()
: pozyskuje instancję nagrywania przez określenie bufora rozmiaru.openDvrPlayback()
: uzyskuje wystąpienie odtwarzania przez określenie bufora rozmiaru.openDescrambler()
: pozyskuje instancję dekodera.openLnb()
: pozyskuje wewnętrzną instancję LNB.openLnbByName()
: pobiera zewnętrzną instancję LNB.openTimeFilter()
: pobiera wystąpienie filtra czasu.
Pakiet tunera zawiera funkcje, których nie obejmują za pomocą filtrów, nagrywarki cyfrowej i pakietów frontendu. Funkcje wymieniono poniżej.
cancelTuning
scan
/cancelScanning
getAvSyncHwId
getAvSyncTime
connectCiCam1
/disconnectCiCam
shareFrontendFromTuner
updateResourcePriority
setOnTuneEventListener
setResourceLostListener
Android.media.tv.tuner.frontend
Pakiet frontendu zawiera zbiory ustawień dotyczących frontendu, informacje, stany, zdarzenia i możliwości.
Zajęcia
FrontendSettings
jest określany dla różnych standardów DTV według poniższych klas.
AnalogFrontendSettings
Atsc3FrontendSettings
AtscFrontendSettings
DvbcFrontendSettings
DvbsFrontendSettings
DvbtFrontendSettings
Isdbs3FrontendSettings
IsdbsFrontendSettings
IsdbtFrontendSettings
Od Androida 12 z tunerem HAL 1.1 lub nowszym obsługiwany jest standard DTV.
DtmbFrontendSettings
FrontendCapabilities
jest określany dla różnych standardów DTV według klas
poniżej.
AnalogFrontendCapabilities
Atsc3FrontendCapabilities
AtscFrontendCapabilities
DvbcFrontendCapabilities
DvbsFrontendCapabilities
DvbtFrontendCapabilities
Isdbs3FrontendCapabilities
IsdbsFrontendCapabilities
IsdbtFrontendCapabilities
Od Androida 12 z tunerem HAL 1.1 lub nowszym obsługiwany jest standard DTV.
DtmbFrontendCapabilities
FrontendInfo
pobiera informacje o frontendzie.
FrontendStatus
pobiera bieżący stan frontendu.
OnTuneEventListener
nasłuchuje zdarzeń we frontendzie.
Aplikacja TIS używa ScanCallback
do przetwarzania komunikatów skanowania z frontendu.
Skanowanie kanałów
Aby skonfigurować telewizor, aplikacja skanuje możliwe częstotliwości i tworzy kanał
dostępnej dla użytkowników. TIS może używać wartości Tuner.tune
,
Tuner.scan(BLIND_SCAN)
lub Tuner.scan(AUTO_SCAN)
, aby zakończyć korzystanie z kanału
skanowanie.
Jeśli TIS ma dokładne informacje o dostarczaniu sygnału, takie jak częstotliwość,
(np. T/T2, S/S2) oraz dodatkowe niezbędne informacje.
(np. PLD ID), a następnie
Szybsza opcja to Tuner.tune
.
Gdy użytkownik wywoła metodę Tuner.tune
, wykonywane są te działania:
- TIS wypełnia pole
FrontendSettings
wymaganymi informacjami za pomocą polaTuner.tune
. - Raport HAL dostraja komunikaty
LOCKED
, jeśli sygnał jest zablokowany. - TIS używa
Frontend.getStatus
do zbierania niezbędnych informacji. - TIS przechodzi do następnej dostępnej częstotliwości na liście.
TIS wywołuje metodę Tuner.tune
ponownie, aż zostaną wyczerpane wszystkie częstotliwości.
Podczas dostrajania możesz zadzwonić pod numer stopTune()
lub close()
, aby wstrzymać lub zakończyć
Tuner.tune
połączenie.
Tuner.scan(AUTO_SCAN)
Jeśli system TIS nie ma wystarczającej ilości informacji, aby użyć funkcji Tuner.tune
, ale ma częstotliwość
typu list i standardowym (np. DVB T/C/S),
zalecamy Tuner.scan(AUTO_SCAN)
.
Gdy użytkownik wywoła metodę Tuner.scan(AUTO_SCAN)
, wykonywane są te działania:
TIS używa kolumny
Tuner.scan(AUTO_SCAN)
z polemFrontendSettings
wypełnionym częstotliwością.Jeśli sygnał jest zablokowany, raporty HAL skanują
LOCKED
wiadomości. HAL może zgłoś również inne wiadomości dotyczące skanowania, aby dostarczyć dodatkowe informacje o i wysyłanie sygnałów.TIS używa
Frontend.getStatus
do zbierania niezbędnych informacji.TIS wywołuje dla HAL parametr
Tuner.scan
, aby przejść do następnego ustawienia z poziomu tego samego i częstotliwości. Jeśli strukturaFrontendSettings
jest pusta, w HAL używa się następnego argumentu dostępne ustawienie. W przeciwnym razie HAL używa jednorazowego identyfikatoraFrontendSettings
skanuje i wysyłaEND
, aby wskazać, że operacja skanowania została zakończona.TIS powtarza powyższe czynności, aż wszystkie ustawienia częstotliwości zostaną wyczerpane.
HAL wysyła wiadomość
END
, aby wskazać, że operacja skanowania została zakończona.TIS przechodzi do następnej dostępnej częstotliwości na liście.
TIS wywołuje metodę Tuner.scan(AUTO_SCAN)
ponownie, aż zostaną wyczerpane wszystkie częstotliwości.
Podczas skanowania możesz zadzwonić pod numer stopScan()
lub close()
, aby wstrzymać lub zakończyć
skanować.
Tuner.scan(BLIND_SCAN)
Jeśli TIS nie ma listy częstotliwości, a HAL dostawcy może wyszukać
określona przez użytkownika częstotliwość pobierania zasobu frontendu, a następnie
Zalecamy Tuner.scan(BLIND_SCAN)
.
- TIS używa wartości
Tuner.scan(BLIND_SCAN)
. Częstotliwość można określić wFrontendSettings
w przypadku częstotliwości początkowej, ale TIS ignoruje inne ustawienia w usłudzeFrontendSettings
. - Jeśli sygnał jest zablokowany, HAL zgłasza komunikat skanowania
LOCKED
. - TIS używa
Frontend.getStatus
do zbierania niezbędnych informacji. - TIS ponownie wywołuje metodę
Tuner.scan
, aby kontynuować skanowanie. (FrontendSettings
to ignorowanych). - TIS powtarza powyższe czynności, aż wszystkie ustawienia częstotliwości zostaną
wyczerpane. HAL zwiększa częstotliwość. Z TIS nie trzeba nic robić.
HAL zgłasza
PROGRESS
.
TIS wywołuje metodę Tuner.scan(AUTO_SCAN)
ponownie, aż zostaną wyczerpane wszystkie częstotliwości.
HAL zgłasza END
, aby wskazać, że operacja skanowania została zakończona.
Podczas skanowania możesz wywołać stopScan()
lub close()
, aby wstrzymać lub zakończyć skanowanie.
Rysunek 9. Schemat procesu skanowania TIS
Android.media.tv.tuner.filter
Pakiet filtrów to zbiór operacji filtrowania wraz z konfiguracją, ustawienia, wywołania zwrotne i zdarzenia. Pakiet zawiera poniższe działania. Pełną listę operacji znajdziesz w kodzie źródłowym Androida.
configure()
start()
stop()
flush()
read()
Pełną listę znajdziesz w kodzie źródłowym Androida.
FilterConfiguration
pochodzi z poniższych klas. Konfiguracje są następujące
dla typu filtra głównego i określają, jakiego protokołu używa filtr
wyodrębniania danych.
AlpFilterConfiguration
IpFilterConfiguration
MmtpFilterConfiguration
TlvFilterConfiguration
TsFilterConfiguration
Ustawienia pochodzą z poniższych klas. Ustawienia dotyczą filtra i określają, jakie rodzaje danych może wykluczyć filtr.
SectionSettings
AvSettings
PesSettings
RecordSettings
DownloadSettings
Funkcja FilterEvent
pochodzi z klas poniżej w celu raportowania zdarzeń dla różnych
różne typy danych.
SectionEvent
MediaEvent
PesEvent
TsRecordEvent
MmtpRecordEvent
TemiEvent
DownloadEvent
IpPayloadEvent
Od Androida 12 z tunerem HAL 1.1 lub nowszym obsługiwane są te zdarzenia.
IpCidChangeEvent
RestartEvent
ScramblingStatusEvent
Zdarzenia i format danych z filtra
Typ filtra | Flagi | Wydarzenia | Operacja na danych | Format danych |
---|---|---|---|---|
TS.SECTION MMTP.SECTION IP.SECTION TLV.SECTION ALP.SECTION |
isRaw: |
Obowiązkowe:DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
Zalecane: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
Zgodnie z wydarzeniem i wewnętrznym harmonogramem uruchom Filter.read(buffer, offset, adjustedSize) jeden lub więcej
razy.Dane są kopiowane z MQ HAL do bufora klienta. |
Jeden z zebranych pakietów sesji jest wypełniany przez inny moduł FMQ pakietu sesji. |
isRaw: |
Obowiązkowe:DemuxFilterEvent::DemuxFilterSectionEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW Opcjonalnie: DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER |
for i=0; i<n; i++ , Dane są kopiowane z MQ HAL do bufora klienta. |
||
TS.PES |
isRaw: |
Obowiązkowe:DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
Zalecane: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
Zgodnie z wydarzeniem i wewnętrznym harmonogramem uruchom Filter.read(buffer, offset, adjustedSize) jeden lub więcej
razy.Dane są kopiowane z MQ HAL do bufora klienta. |
Jeden złożony pakiet PES jest wypełniany przez inny FMQ Pakiet PES. |
isRaw: |
Obowiązkowe:DemuxFilterEvent::DemuxFilterPesEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW Opcjonalnie: DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER |
for i=0; i<n; i++ , Dane są kopiowane z MQ HAL do bufora klienta. |
||
MMTP.PES |
isRaw: |
Obowiązkowe:DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
Zalecane: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
Zgodnie z wydarzeniem i wewnętrznym harmonogramem uruchom Filter.read(buffer, offset, adjustedSize) jeden lub więcej
razy.Dane są kopiowane z MQ HAL do bufora klienta. |
Jeden złożony pakiet MFU jest wypełniany przez inny pakiet FMQ pakietu MFU. |
isRaw: |
Obowiązkowe:DemuxFilterEvent::DemuxFilterPesEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW Opcjonalnie: DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER |
for i=0; i<n; i++ , Dane są kopiowane z MQ HAL do bufora klienta. |
||
TS.TS |
Nie dotyczy | Obowiązkowe:DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
Zalecane: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
Zgodnie z wydarzeniem i wewnętrznym harmonogramem uruchom Filter.read(buffer, offset, adjustedSize) jeden lub więcej
razy.Dane są kopiowane z MQ HAL do bufora klienta. |
Odfiltrowano ts z ts nagłówkiemjest wpisane FMQ. |
TS.Audio TS.Video MMTP.Audio MMTP.Video |
isPassthrough: |
Opcjonalnie:DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
|
Klient może uruchomić polecenie MediaCodec po otrzymaniu DemuxFilterStatus::DATA_READY .Klient może zadzwonić pod numer Filter.flush po otrzymaniu numeru DemuxFilterStatus::DATA_OVERFLOW . |
Nie dotyczy |
isPassthrough: |
Obowiązkowe:DemuxFilterEvent::DemuxFilterMediaEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW Opcjonalnie: DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER |
Aby użyć funkcji MediaCodec :for i=0; i<n; i++ Aby użyć bezpośredniego dźwięku w usłudze AudioTrack :for i=0; i<n; i++ |
ES lub częściowe dane ES w pamięci ION. | |
TS.PCR IP.NTP ALP.PTP |
Nie dotyczy | Obowiązkowe: nie dotyczy
Opcjonalnie: nie dotyczy |
Nie dotyczy | Nie dotyczy |
TS.RECORD |
Nie dotyczy | Obowiązkowe: DemuxFilterEvent::DemuxFilterTsRecordEvent[n]
RecordStatus::DATA_READY
RecordStatus::DATA_OVERFLOW RecordStatus::LOW_WATER
RecordStatus::HIGH_WATER Opcjonalnie: DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
W przypadku danych indeksu:for i=0; i<n; i++
W przypadku nagranych materiałów: zgodnie z RecordStatus::* i wewnętrznym harmonogramem
jedną z tych wartości:
|
W przypadku danych indeksu: przenoszone w ładunku zdarzenia. W przypadku nagranych treści: strumień z Muxed TS uzupełniony FMQ. |
TS.TEMI |
Nie dotyczy | Obowiązkowe:DemuxFilterEvent::DemuxFilterTemiEvent[n]
Opcjonalnie: DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER |
for i=0; i<n; i++ |
Nie dotyczy |
MMTP.MMTP |
Nie dotyczy | Obowiązkowe:DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
Zalecane: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
Zgodnie z wydarzeniem i wewnętrznym harmonogramem uruchom Filter.read(buffer, offset, adjustedSize) jeden lub więcej
razy.Dane są kopiowane z MQ HAL do bufora klienta. |
Odfiltrowano mmtp z mmtp nagłówkiemjest wpisane FMQ. |
MMTP.RECORD |
Nie dotyczy | Obowiązkowe:DemuxFilterEvent::DemuxFilterMmtpRecordEvent[n]
RecordStatus::DATA_READY
RecordStatus::DATA_OVERFLOW RecordStatus::LOW_WATER
RecordStatus::HIGH_WATER Opcjonalnie: DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
W przypadku danych indeksu: for i=0; i<n; i++ W przypadku nagranych treści: RecordStatus::* i harmonogram wewnętrzny, wykonaj jedną z tych czynności
obserwowanie:
|
W przypadku danych indeksu: przenoszone w ładunku zdarzenia. W przypadku nagranych treści: nagrana transmisja strumieniowa, wypełniona FMQ. Jeśli źródłem filtra rejestracji jest TLV.TLV do
IP.IP dzięki przekazującemu, nagrana transmisja ma
TLV i nagłówek IP. |
MMTP.DOWNLOAD |
Nie dotyczy | Obowiązkowe:DemuxFilterEvent::DemuxFilterDownloadEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW Opcjonalnie: DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER |
for i=0; i<n; i++
Filter.read(buffer, offset, DemuxFilterDownloadEvent[i].size) , Dane są kopiowane z MQ HAL do bufora klienta. |
Pole „Pobierz pakiet” jest wypełnione w FMQ przez inny pakiet do pobrania adresu IP. |
IP.IP_PAYLOAD |
Nie dotyczy | Obowiązkowe:DemuxFilterEvent::DemuxFilterIpPayloadEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW Opcjonalnie: DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER |
for i=0; i<n; i++
Filter.read(buffer, offset, DemuxFilterIpPayloadEvent[i].size) , Dane są kopiowane z MQ HAL do bufora klienta. |
Pakiet ładunku IP jest wypełniany FMQ przez inny pakiet ładunku IP. |
IP.IP TLV.TLV ALP.ALP |
isPassthrough: |
Opcjonalnie:DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
|
Odfiltrowano pliki danych ze strumieniem podrzędnym protokołu; następny filtr w filtrze łańcuch. | Nie dotyczy |
isPassthrough: |
Obowiązkowe:DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
Zalecane: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
Zgodnie z wydarzeniem i wewnętrznym harmonogramem uruchom Filter.read(buffer, offset, adjustedSize) jeden lub więcej
razy.Dane są kopiowane z MQ HAL do bufora klienta. |
Odfiltrowany strumień podrzędny protokołu z wypełnionym nagłówkiem protokołu FMQ. | |
IP.PAYLOAD_THROUGH TLV.PAYLOAD_THROUGH ALP.PAYLOAD_THROUGH |
Nie dotyczy | Opcjonalnie:DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
|
Odfiltrowano pliki danych z ładunkiem protokołów. Następny filtr w filtrze łańcuch. | Nie dotyczy |
Przykładowy proces z użyciem filtra do utworzenia wskaźnika PSI/SI
Rysunek 10. Procedura tworzenia PSI/SI
Otwórz filtr.
Filter filter = tuner.openFilter( Filter.TYPE_TS, Filter.SUBTYPE_SECTION, /* bufferSize */1000, executor, filterCallback );
Skonfiguruj i uruchom filtr.
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();
Przetwórz
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); } } } };
Przykładowy proces użycia obiektu MediaEvent z filtra
Rysunek 11. Procedura użycia obiektu MediaEvent z filtra
- Otwórz, skonfiguruj i uruchom filtry audio/wideo.
- Przetwórz
MediaEvent
. - Odbierz
MediaEvent
. - Umieść blok liniowy w kolejce do pozycji
codec
. - Po wykorzystaniu danych zwolnij uchwyt audio/wideo.
Android.media.tv.tuner.dvr
DvrRecorder
udostępnia te metody nagrywania.
configure
attachFilter
detachFilter
start
flush
stop
setFileDescriptor
write
DvrPlayback
udostępnia te metody odtwarzania.
configure
start
flush
stop
setFileDescriptor
read
Usługa DvrSettings
jest używana do konfigurowania usług DvrRecorder
i DvrPlayback
.
W użyciu OnPlaybackStatusChangedListener
i OnRecordStatusChangedListener
aby zgłosić stan nagrywarki cyfrowej.
Przykładowy proces rozpoczynania nagrywania
Rysunek 12. Proces rozpoczynania nagrywania
Otwórz, skonfiguruj i uruchom aplikację
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();
Odbierz
RecordEvent
i pobierz informacje o indeksie.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. } } } };
Zainicjuj
OnRecordStatusChangedListener
i zapisz dane rekordu.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 tunera
HAL tunera jest zgodny z HIDL i definiuje interfejs między platformą na swoim urządzeniu. Dostawcy korzystają z interfejsu do implementacji HAL Tuner oraz używa go do komunikacji z implementacją HAL Tuner.
Moduły
Tuner HAL 1.0
Moduły | Podstawowe funkcje sterowania | Elementy sterujące modułu | Pliki HAL |
---|---|---|---|
ITuner |
Nie dotyczy | frontend(open, getIds, getInfo) , openDemux ,
openDescrambler , openLnb ,
getDemuxCaps |
ITuner.hal |
IFrontend |
setCallback , getStatus , close
| tune , stopTune , scan
stopScan (setLnb ) |
IFrontend.hal IFrontendCallback.hal |
IDemux |
close |
setFrontendDataSource , openFilter , openDvr , getAvSyncHwId ,
getAvSyncTime , connect / disconnectCiCam |
IDemux.hal |
IDvr |
close , start , stop , configure |
attach/detachFilters , flush , getQueueDesc |
IDvr.hal IDvrCallback.hal |
IFilter |
close , start , stop , configure , getId |
flush , getQueueDesc , releaseAvHandle , setDataSource |
IFilter.hal IFilterCallback.hal |
ILnb |
close , setCallback |
setVoltage , setTone , setSatellitePosition , sendDiseqcMessage |
ILnb.hal ILnbCallback.hal |
IDescrambler |
close |
setDemuxSource , setKeyToken ,
addPid removePid |
IDescrambler.hal |
Tuner HAL 1.1 (pochodzący z tunera HAL 1.0)
Moduły | Podstawowe funkcje sterowania | Elementy sterujące modułu | Pliki HAL |
---|---|---|---|
ITuner |
Nie dotyczy | 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 |
Rysunek 13. Schemat interakcji między modułami HAL tunera
Połączenie filtrów
HAL tunera obsługuje połączenie filtrów, dzięki czemu filtry mogą być łączone z innymi, lub zastosowanie filtrów wielowarstwowych. Filtry są zgodne z poniższymi regułami.
- Filtry są połączone w postaci drzewa; ścieżka zamknięcia jest niedozwolona.
- Węzeł główny jest demuxem.
- Filtry działają niezależnie.
- Wszystkie filtry zaczynają pobierać dane.
- Połączenie filtra wyczyszczone jest przy ostatnim filtrze.
Blok kodu poniżej i na rys. 14 ilustrują przykład filtrowania wielu warstw.
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>)
}
Rysunek 14. Schemat blokowy połączenia filtrów dla wielu warstw
Menedżer zasobów tunera
Przed uruchomieniem usługi Tuner Resource Manager (TRM) przełączanie się między 2 aplikacjami wymagało tego samego tunera. Platforma danych wejściowych o telewizji (TIF) wykorzystała model „pierwszy do pozyskania” co oznacza, że zasób zostanie zachowany w przypadku aplikacji, która jako pierwsza uzyska zasób. Jednak ten mechanizm może nie być idealny w niektórych skomplikowanych przypadkach użycia.
TRM działa jako usługa systemowa do zarządzania sprzętem tunera, TVInput
i CAS
dla aplikacji. TRM stosuje „wygraną na pierwszym planie” który
oblicza priorytet aplikacji na podstawie jej pierwszego planu lub tła
stanu i typu przypadku użycia. TRM przyznaje lub anuluje zasób na podstawie
jego priorytet. TRM centralizuje zarządzanie zasobami ATV na potrzeby transmisji, OTT,
i nagrywarka cyfrowa.
Interfejs TRM
TRM ujawnia interfejsy AIDL w ITunerResourceManager.aidl
na potrzeby tunera
platformy, MediaCas
i TvInputHardwareManager
, aby zarejestrować się, poprosić lub
i uwolnij zasoby.
Poniżej znajdziesz interfejsy zarządzania klientami.
registerClientProfile(in ResourceClientProfile profile, IResourcesReclaimListener listener, out int[] clientId)
unregisterClientProfile(in int clientId)
Poniżej znajdziesz interfejsy żądania i zwalniania zasobów.
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
Poniżej znajdziesz klasy klientów i żądań.
ResourceClientProfile
ResourcesReclaimListener
TunerFrontendRequest
TunerDemuxRequest
TunerDescramblerRequest
CasSessionRequest
TunerLnbRequest
Priorytet klienta
TRM oblicza priorytet klienta, używając parametrów z profilu i wartości priorytetu z pliku konfiguracji. Priorytetem może być może być też aktualizowana dowolną wartością priorytetu określoną przez klienta.
Parametry w profilu klienta
TRM pobiera identyfikator procesu z mTvInputSessionId
, aby zdecydować, czy aplikacja
to aplikacja na pierwszym planie lub w tle. Aby utworzyć mTvInputSessionId
,
TvInputService.onCreateSession
lub TvInputService.onCreateRecordingSession
inicjuje sesję TIS.
mUseCase
wskazuje przypadek użycia sesji. Wstępnie zdefiniowane przypadki użycia to
wymienionych poniżej.
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
}
Plik konfiguracji
Domyślny plik konfiguracji
Domyślny plik konfiguracji poniżej zawiera wartości priorytetów do wstępnie zdefiniowanego użycia przypadków. Użytkownicy mogą zmienić te wartości za pomocą własny plik konfiguracji.
Przypadek użycia | Pierwszy plan | Tło |
---|---|---|
LIVE |
490 | 400 |
PLAYBACK |
480 | 300 |
RECORD |
600 | 500 |
SCAN |
450 | 200 |
BACKGROUND |
180 | 100 |
Plik konfiguracji niestandardowej
Dostawcy mogą dostosować plik konfiguracji
/vendor/etc/tunerResourceManagerUseCaseConfig.xml
Ten plik jest używany
aby dodawać, usuwać i aktualizować typy przypadków użycia oraz wartości priorytetów przypadków użycia.
Dostosowany plik może używać
platform/hardware/interfaces/tv/tuner/1.0/config/tunerResourceManagerUseCaseConfigSample.xml
jako szablon.
Na przykład nowy przypadek użycia dostawcy to VENDOR_USE_CASE__[A-Z0-9]+, [0 - 1000]
.
Powinno być zgodne
platform/hardware/interfaces/tv/tuner/1.0/config/tunerResourceManagerUseCaseConfig.xsd
Dowolna wartość priorytetu i wartość ładna
TRM udostępnia klientowi updateClientPriority
, aby zaktualizować dowolne
wartości priorytetu i wartości.
Dowolna wartość priorytetu zastępuje obliczoną wartość priorytetu
od typu przypadku użycia i identyfikatora sesji.
„Dobra wartość” wskazuje, na ile łagodne jest zachowanie klienta, gdy jest on konflikt z innym klientem. „Dobra wartość” zmniejsza priorytet klienta przed wartością priorytetu, która ma zostać porównana z klientem wymagającym.
Mechanizm odzyskiwania
Poniższy diagram pokazuje, jak zasoby są odzyskiwane i przypisywane podczas wystąpi konflikt zasobów.
Rysunek 15. Schemat mechanizmu odzyskiwania w przypadku konfliktu między tunerem zasoby