如果是 Android 11 以上版本,您可以使用 Android 裝置 用於提供 A/V 內容的調諧器架構。架構會使用 管道,因此適用於低階和高階 SoC。 這個架構能讓使用者以安全的方式,提供受試者保護的 A/V 內容 信任的執行環境 (TEE) 和安全媒體路徑 (SMP),以允許 用於嚴格限制的內容保護環境
Tuner 與 Android CAS 之間的標準化介面可加快
協調工具供應商與 CAS 供應商之間的整合調諧器介面可正常運作
與 MediaCodec
和 AudioTrack
攜手打造全方位的 Android TV 解決方案。
The Tuner 介面可同時支援數位電視和類比電視,
廣播標準
元件
針對 Android 11,三個元件會特別 專為電視平台設計的應用程式
- Tuner HAL:架構和廠商之間的介面
- Tuner SDK API:架構與應用程式之間的介面
- Tuner Resource Manager (TRM):協調 Tuner HW 資源
對於 Android 11,下列元件 強化。
- CAS V2
TvInputService
或電視輸入服務 (TIS)- 「
TvInputManagerService
」或電視輸入管理員服務 (TIMS) MediaCodec
或媒體轉碼器AudioTrack
或音軌MediaResourceManager
或媒體資源管理工具 (MRM)
圖 1. Android TV 元件之間的互動
功能
前端支援下列 DTV 標準。
- ATSC 架構
- ATSC3
- DVB C/S/T
- ISDB S/S3/T
- 類比
在搭載 Tuner HAL 1.1 以上版本的 Android 12 前端,即可支援下方的 DTV 標準。
- 資料移轉
Demux 支援下列串流通訊協定。
- 傳輸串流 (TS)
- MPEG 媒體傳輸通訊協定 (MMTP)
- 網際網路通訊協定 (IP)
- 類型長度值 (TLV)
- ATSC 連結層通訊協定 (ALP)
Descrambler 支援下列內容保護功能。
- 安全的媒體路徑
- 清除媒體路徑
- 保護本機記錄
- 安全本機播放
Tuner API 支援下列用途。
- 掃描
- 直播
- 播放
- 錄製
協調器、MediaCodec
和 AudioTrack
支援下列的資料流程模式。
- 具有清除記憶體緩衝區的 ES 酬載
- 具有安全記憶體控點的 ES 酬載
- 透視
整體設計
調諧器 HAL 的定義應介於 Android 架構與供應商的 硬體
- 說明供應商對架構的預期,以及供應商可能的接受方式 親自體驗
- 將前端、demux 和 descrambler 的功能匯出到
整合了
IFrontend
、IDemux
、IDescrambler
、IFilter
、IDvr
和 和ILnb
介面。 - 包含將 Tuner HAL 與其他架構整合的功能
例如
MediaCodec
和AudioTrack
系統會建立 Tuner Java 類別和原生類別。
- Tuner Java API 可讓應用程式透過公用 API 存取 Tuner HAL。
- 原生類別允許權限控制及處理大量 透過調諧器 HAL 建立記錄或播放資料
- Native Tuner 模組是 Tuner Java 類別與 Tuner 之間的橋樑 HAL。
系統隨即建立 TRM 類別。
- 可管理有限的 Tuner 資源,例如 Frontend、LNB 以及來自電視輸入 HAL 的電視輸入裝置。
- 套用規則來收回不足的資源 應用程式。預設規則為前景勝出。
媒體 CAS 和 CAS HAL 使用以下功能來增強效果。
- 開啟不同用法和演算法的 CAS 工作階段。
- 支援動態 CAS 系統,例如 CICAM 移除和插入。
- 提供金鑰權杖,與調諧器 HAL 整合。
使用下列功能強化 MediaCodec
和 AudioTrack
。
- 使用安全的 A/V 記憶體做為內容輸入來源。
- 已設為在通道播放時進行硬體 A/V 同步處理。
- 設定對
ES_payload
和直通模式的支援。
圖 2. 調諧器 HAL 內的元件圖表
整體工作流程
下圖是即時播送播放的呼叫序列。
設定
圖 3. 現場直播播放的設定順序
處理 A/V
圖 4. 處理現場直播播放的 A/V
處理打散的內容
圖 5. 處理打散播放的直播影片
正在處理影音設備資料
圖 6. 處理 A/V 進行即時播送
調諧器 SDK API
Tuner SDK API 會處理與 Tuner JNI、 Tuner HAL 的互動
和TunerResourceManager
。TIS 應用程式使用 Tuner SDK API 存取 Tuner
和子元件,例如篩選器和解碼器元件前端和
demux 是內部元件。
圖 7. 與 Tuner SDK API 的互動
版本
自 Android 12 起, Tuner SDK API 支援 Tuner HAL 1.1 的新功能 是 Tuner 1.0 的回溯相容版本升級版本。
使用以下 API 檢查執行中的 HAL 版本。
android.media.tv.tuner.TunerVersionChecker.getTunerVersion()
您可以參閱新版 Android 12 API 的說明文件,瞭解需要的最低 HAL 版本。
套件
Tuner SDK API 提供以下四個套件。
android.media.tv.tuner
android.media.tv.tuner.frontend
android.media.tv.tuner.filter
android.media.tv.tuner.dvr
圖 8. Tuner SDK API 套件
Android.media.tv.tuner
Tuner 套件是使用 Tuner 架構的進入點。TIS 應用程式 使用此套件初始化及取得資源執行個體,方法是指定 初始設定和回呼
tuner()
:透過指定useCase
和sessionId
參數。tune()
:取得前端資源,並透過指定FrontendSetting
參數。openFilter()
:指定篩選器類型,以取得篩選器執行個體。openDvrRecorder()
:指定緩衝區,以取得錄製執行個體 大小openDvrPlayback()
:指定緩衝區,藉此取得播放執行個體 大小openDescrambler()
:取得 descrambler 執行個體。openLnb()
:取得內部 LNB 執行個體。openLnbByName()
:取得外部 LNB 執行個體。openTimeFilter()
:取得時間篩選器執行個體。
調諧器套件提供其中不包含的功能 篩選器、DVR 和前端套件這些功能已列於下方。
cancelTuning
scan
/cancelScanning
getAvSyncHwId
getAvSyncTime
connectCiCam1
/disconnectCiCam
shareFrontendFromTuner
updateResourcePriority
setOnTuneEventListener
setResourceLostListener
Android.media.tv.tuner.Frontend
前端套件包含一組前端相關設定, 資訊、狀態、事件和功能
類別
下列類別依不同的 DTV 標準衍生 FrontendSettings
。
AnalogFrontendSettings
Atsc3FrontendSettings
AtscFrontendSettings
DvbcFrontendSettings
DvbsFrontendSettings
DvbtFrontendSettings
Isdbs3FrontendSettings
IsdbsFrontendSettings
IsdbtFrontendSettings
從搭載 Tuner HAL 1.1 以上版本的 Android 12 起,支援下列 DTV 標準。
DtmbFrontendSettings
系統會依類別針對不同的 DTV 標準衍生 FrontendCapabilities
。
AnalogFrontendCapabilities
Atsc3FrontendCapabilities
AtscFrontendCapabilities
DvbcFrontendCapabilities
DvbsFrontendCapabilities
DvbtFrontendCapabilities
Isdbs3FrontendCapabilities
IsdbsFrontendCapabilities
IsdbtFrontendCapabilities
從搭載 Tuner HAL 1.1 以上版本的 Android 12 起,支援下列 DTV 標準。
DtmbFrontendCapabilities
FrontendInfo
會擷取前端資訊。
FrontendStatus
會擷取前端的目前狀態。
OnTuneEventListener
會監聽前端的事件。
TIS 應用程式會使用 ScanCallback
掃描前端的訊息。
頻道掃描
設定電視時,應用程式會掃描可能的頻率,並建立頻道
供使用者存取TIS 可能會使用 Tuner.tune
。
Tuner.scan(BLIND_SCAN)
,或 Tuner.scan(AUTO_SCAN)
以完成頻道
或是掃描內容
如果目標曝光比重 (TIS) 提供的信號放送資訊 (例如頻率)
標準 (例如 T/T2、S/S2) 和其他必要資訊
(例如 PLD ID)
建議設為 Tuner.tune
,這是更快速的選項。
使用者呼叫 Tuner.tune
時,會發生以下動作:
- TIS 會使用
Tuner.tune
將必要資訊填入FrontendSettings
。 - HAL 會在訊號鎖定時調整
LOCKED
訊息。 - TIS 會使用
Frontend.getStatus
收集必要資訊。 - TIS 會移至頻率清單中的下一個可用頻率。
TIS 會再次呼叫 Tuner.tune
,直到所有頻率都用盡為止。
在調整期間,您可以呼叫 stopTune()
或 close()
來暫停或結束
Tuner.tune
呼叫。
Tuner.scan(AUTO_SCAN)
如果 TIS 的資訊不足,無法使用 Tuner.tune
,但設有頻率
和標準類型 (例如 DVB T/C/S)
則建議採用 Tuner.scan(AUTO_SCAN)
。
使用者呼叫 Tuner.scan(AUTO_SCAN)
時,會發生以下動作:
TIS 使用的
Tuner.scan(AUTO_SCAN)
已填入頻率:FrontendSettings
。HAL 報表會在訊號鎖定時掃描
LOCKED
封郵件。HAL 可能會 該工具也會回報其他掃描郵件,以提供 信號TIS 會使用
Frontend.getStatus
收集必要資訊。TIS 對 HAL 呼叫
Tuner.scan
,以便繼續在同一環境下進行下一個設定 頻率。 如果FrontendSettings
結構空白,HAL 會使用下一個 可用的設定。否則,HAL 會使用FrontendSettings
一次使用一次 掃描並傳送END
,表示掃描作業已完成。TIS 會重複上述動作,直到頻率的所有設定都達到 。
HAL 會傳送
END
,表示掃描作業已完成。TIS 會移至頻率清單中的下一個可用頻率。
TIS 會再次呼叫 Tuner.scan(AUTO_SCAN)
,直到所有頻率都用盡為止。
掃描時,您可以呼叫 stopScan()
或 close()
來暫停或結束
或是掃描內容
Tuner.scan(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()
來暫停或結束掃描作業。
圖 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
從搭載 Tuner HAL 1.1 以上版本的 Android 12 版本開始,系統會支援下列事件。
IpCidChangeEvent
RestartEvent
ScramblingStatusEvent
篩選器中的事件和資料格式
篩選器類型 | 旗幟 | 事件 | 資料作業 | 資料格式 |
---|---|---|---|---|
TS.SECTION MMTP.SECTION IP.SECTION TLV.SECTION ALP.SECTION |
isRaw: |
必要程序:DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
建議: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
根據活動和內部排程,執行Filter.read(buffer, offset, adjustedSize) 一或多個
次。資料會從 HAL 的 MQ 複製到用戶端緩衝區。 |
一個組裝的工作階段套件由另一個 FMQ 填入 工作階段套件 |
isRaw: |
必要程序:DemuxFilterEvent::DemuxFilterSectionEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW 選用: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
for i=0; i<n; i++ 資料會從 HAL 的 MQ 複製到用戶端緩衝區。 |
||
TS.PES |
isRaw: |
必要程序:DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
建議: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
根據活動和內部排程,執行Filter.read(buffer, offset, adjustedSize) 一或多個
次。資料會從 HAL 的 MQ 複製到用戶端緩衝區。 |
一個 PES 套件組裝後又由另一個 FMQ 填補 PES 套件。 |
isRaw: |
必要程序:DemuxFilterEvent::DemuxFilterPesEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW 選用: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
for i=0; i<n; i++ 資料會從 HAL 的 MQ 複製到用戶端緩衝區。 |
||
MMTP.PES |
isRaw: |
必要程序:DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
建議: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
根據活動和內部排程,執行Filter.read(buffer, offset, adjustedSize) 一或多個
次。資料會從 HAL 的 MQ 複製到用戶端緩衝區。 |
一個組裝的 MFU 套件由另一個 FMQ 填補 MFU 套件。 |
isRaw: |
必要程序:DemuxFilterEvent::DemuxFilterPesEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW 選用: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
for i=0; i<n; i++ 資料會從 HAL 的 MQ 複製到用戶端緩衝區。 |
||
TS.TS |
無 | 必要程序:DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
建議: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
根據活動和內部排程,執行Filter.read(buffer, offset, adjustedSize) 一或多個
次。資料會從 HAL 的 MQ 複製到用戶端緩衝區。 |
已篩除含有ts 標題的「 ts 」
就需要填寫 FMQ 編號 |
TS.Audio TS.Video MMTP.Audio MMTP.Video |
isPassthrough: |
選用:DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
|
用戶端可在收到 DemuxFilterStatus::DATA_READY 後啟動 MediaCodec 。用戶端可在收到 DemuxFilterStatus::DATA_OVERFLOW 後呼叫 Filter.flush 。 |
無 |
isPassthrough: |
必要程序:DemuxFilterEvent::DemuxFilterMediaEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW 選用: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
如何使用「MediaCodec 」:for i=0; i<n; i++ 如何使用 AudioTrack 的直接音訊功能:for i=0; i<n; i++ |
ION 記憶體中的 ES 或部分 ES 資料。 | |
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++
如果是錄製的內容, 依據 RecordStatus::* 和內部時間表,進行下列操作:
下列其中一項:
|
索引資料:包含在事件酬載中。 錄製的內容:混合型 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++ |
無 |
MMTP.MMTP |
無 | 必要程序:DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
建議: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
根據活動和內部排程,執行Filter.read(buffer, offset, adjustedSize) 一或多個
次。資料會從 HAL 的 MQ 複製到用戶端緩衝區。 |
已篩除含有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++ 錄製的內容,根據 RecordStatus::* 和內部排程,
追蹤:
|
索引資料:包含在事件酬載中。 錄製內容:混合的錄製內容串流,並填入資料 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) 資料會從 HAL 的 MQ 複製到用戶端緩衝區。 |
下載套件已由其他 IP 下載套件填入 FMQ。 |
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) 資料會從 HAL 的 MQ 複製到用戶端緩衝區。 |
IP 酬載套件會由另一個 IP 酬載套件填入 FMQ。 |
IP.IP TLV.TLV ALP.ALP |
isPassthrough: |
選用:DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
|
已篩除通訊協定子串流動態饋給,這個篩選器中的下一個篩選器 鏈結。 | 無 |
isPassthrough: |
必要程序:DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
建議: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
根據活動和內部排程,執行Filter.read(buffer, offset, adjustedSize) 一或多個
次。資料會從 HAL 的 MQ 複製到用戶端緩衝區。 |
已篩除含有通訊協定標頭的通訊協定子串流 FMQ | |
IP.PAYLOAD_THROUGH TLV.PAYLOAD_THROUGH ALP.PAYLOAD_THROUGH |
無 | 選用:DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
|
篩除的通訊協定酬載動態饋給下一個篩選器 鏈結。 | 無 |
使用篩選器建構 PSI/SI 的流程範例
圖 10. 建構 PSI/SI 的流程
開啟所需篩選器。
Filter filter = tuner.openFilter( Filter.TYPE_TS, Filter.SUBTYPE_SECTION, /* bufferSize */1000, executor, filterCallback );
設定並啟動篩選器。
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();
第
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 流程範例
圖 11. 透過篩選器使用 MediaEvent 的流程
- 開啟、設定及啟動影音濾鏡。
- 第
MediaEvent
個程序。 - 即將收到
MediaEvent
。 - 將線性區塊排入
codec
佇列。 - 在已經使用資料後,釋放 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. 開始記錄的流程
開啟、設定並啟動
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();
接收
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. } } } };
初始化
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
調諧器 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 、
setLnb 和 stopScan |
IFrontend.hal IFrontendCallback.hal |
IDemux |
close |
setFrontendDataSource 、openFilter 、openDvr 、getAvSyncHwId 、
getAvSyncTime 、connect / disconnectCiCam |
IDemux.hal |
IDvr |
close 、start 、stop 、configure |
attach/detachFilters 、flush 、getQueueDesc |
IDvr.hal IDvrCallback.hal |
IFilter |
close 、start 、stop 、configure 、getId |
flush 、getQueueDesc 、releaseAvHandle 、setDataSource |
IFilter.hal IFilterCallback.hal |
ILnb |
close 、setCallback |
setVoltage 、setTone 、setSatellitePosition 、sendDiseqcMessage |
ILnb.hal ILnbCallback.hal |
IDescrambler |
close |
setDemuxSource 、setKeyToken 、
addPid removePid |
IDescrambler.hal |
調諧器 HAL 1.1 (衍生自調諧器 HAL 1.0)
模組 | 基本控制選項 | 模組專屬控制項 | HAL 檔案 |
---|---|---|---|
ITuner |
無 | getFrontendDtmbCapabilities |
@1.1::ITuner.hal |
IFrontend |
tune_1_1 、scan_1_1 、getStatusExt1_1 |
link/unlinkCiCam |
@1.1::IFrontend.hal @1.1::IFrontendCallback.hal |
IFilter |
getStatusExt1_1 |
configureIpCid 、configureAvStreamType 、getAvSharedHandle 、configureMonitorEvent |
@1.1::IFilter.hal @1.1::IFilterCallback.hal |
圖 13. 調諧器 HAL 模組之間的互動圖表
篩選器連結
調諧器 HAL 支援篩選器連結,讓篩選器可與其他 多個圖層的篩選器篩選器會採用下列規則。
- 篩選器以樹狀結構連結,無法使用關閉路徑。
- 根節點為 demux。
- 篩選器會獨立運作,
- 所有篩選器都會開始取得資料。
- 最後一個篩選器的連結內容會清除。
下方程式碼區塊和圖 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) 之前,您必須在兩個應用程式之間切換: 相同的調諧器硬體電視輸入架構 (TIF) 使用「第一至獲勝」 機制,也就是任何先取得資源的應用程式都能保留資源。 不過,這個機制對於一些複雜的用途而言可能不是理想的選擇。
TRM 會以系統服務的形式運作,以管理 Tuner、TVInput
和 CAS 硬體
管理應用程式的所有資源TRM 使用「前景勝出」是針對
根據應用程式的前景或背景計算應用程式的優先順序
狀態和用途類型TRM 會根據以下項目授予或撤銷資源:
TRM 為廣播、OTT、
以及 DVR 功能
TRM 介面
TRM 會在 ITunerResourceManager.aidl
中為調諧器公開 AIDL 介面
架構、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
擷取程序 ID,判斷應用程式是否
則是前景或背景應用程式如要建立「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
,讓用戶端更新任意
預測的價值
任意優先順序值會覆寫先前計算的優先值
從用途類型和工作階段 ID 擷取
理想的值代表用戶端行為的寬鬆程度 與其他用戶端相衝突良好的值會降低客戶優先順序 比較困難的客戶進行比較。
回收機制
下圖顯示系統如何在 會發生資源衝突的情況
圖 15.調諧器之間衝突的回收機制圖表 資源