Đối với Android 11 trở lên, bạn có thể sử dụng khung Android Tuner để phân phối nội dung A/V. Khung này sử dụng hệ thống phần cứng từ các nhà cung cấp, làm cho nó phù hợp với cả SoC cấp thấp và cao cấp. Khung này cung cấp một cách an toàn để phân phối nội dung A/V được bảo vệ bởi môi trường thực thi đáng tin cậy (TEE) và đường dẫn phương tiện an toàn (SMP), cho phép sử dụng nó trong môi trường bảo vệ nội dung, bị hạn chế cao.
Giao diện được tiêu chuẩn hóa giữa Tuner và Android CAS mang lại sự tích hợp nhanh hơn giữa nhà cung cấp Tuner và nhà cung cấp CAS. Giao diện Tuner hoạt động với MediaCodec
và AudioTrack
để xây dựng giải pháp toàn cầu cho Android TV. Giao diện Tuner hỗ trợ cả TV kỹ thuật số và TV analog dựa trên các tiêu chuẩn phát sóng chính.
Các thành phần
Đối với Android 11, ba thành phần được thiết kế riêng cho nền tảng TV.
- Tuner HAL: Giao diện giữa khung và nhà cung cấp
- API Tuner SDK: Giao diện giữa khung và ứng dụng
- Trình quản lý tài nguyên bộ điều chỉnh (TRM): Tọa độ các tài nguyên CTNH của bộ điều chỉnh
Đối với Android 11, các thành phần sau đã được cải tiến.
- CAS V2
-
TvInputService
hoặc Dịch vụ đầu vào TV (TIS) -
TvInputManagerService
hoặc Dịch vụ quản lý đầu vào TV (TIMS) -
MediaCodec
hoặc codec phương tiện -
AudioTrack
hoặc bản âm thanh -
MediaResourceManager
hoặc trình quản lý tài nguyên phương tiện (MRM)
Hình 1. Tương tác giữa các thành phần Android TV
Đặc trưng
Frontend hỗ trợ các tiêu chuẩn DTV bên dưới.
- ATSC
- ATSC3
- DVB C/S/T
- ISDB S/S3/T
- Tương tự
Giao diện người dùng trong Android 12 có Tuner HAL 1.1 trở lên hỗ trợ chuẩn DTV bên dưới.
- DTMB
Demux hỗ trợ các giao thức truyền phát bên dưới.
- Luồng vận chuyển (TS)
- Giao thức truyền tải phương tiện MPEG (MMTP)
- Giao thức Internet (IP)
- Giá trị độ dài loại (TLV)
- Giao thức lớp liên kết ATSC (ALP)
Descrambler hỗ trợ các biện pháp bảo vệ nội dung bên dưới.
- Đường dẫn phương tiện an toàn
- Xóa đường dẫn phương tiện
- Bảo mật hồ sơ địa phương
- Phát lại cục bộ an toàn
API bộ điều chỉnh hỗ trợ các trường hợp sử dụng bên dưới.
- Quét
- Sống
- Phát lại
- Ghi
Tuner, MediaCodec
và AudioTrack
hỗ trợ các chế độ luồng dữ liệu bên dưới.
- Tải trọng ES với bộ nhớ đệm rõ ràng
- Tải trọng ES có bộ nhớ an toàn
- Truyền qua
Thiết kế tổng thể
Tuner HAL được xác định giữa khung Android và phần cứng của nhà cung cấp.
- Mô tả những gì framework mong đợi từ nhà cung cấp và cách nhà cung cấp có thể thực hiện điều đó.
- Xuất các chức năng của giao diện người dùng, demux và descrambler sang khung thông qua các giao diện
IFrontend
,IDemux
,IDescrambler
,IFilter
,IDvr
vàILnb
. - Bao gồm các chức năng để tích hợp Tuner HAL với các thành phần khung khác, chẳng hạn như
MediaCodec
vàAudioTrack
.
Một lớp Java Tuner và lớp gốc được tạo.
- API Tuner Java cho phép các ứng dụng truy cập Tuner HAL thông qua các API công khai.
- Lớp gốc cho phép kiểm soát quyền và xử lý lượng lớn dữ liệu ghi hoặc phát lại bằng Tuner HAL.
- Mô-đun Tuner gốc là cầu nối giữa lớp Tuner Java và Tuner HAL.
Một lớp TRM được tạo.
- Quản lý các tài nguyên Bộ điều chỉnh có giới hạn, chẳng hạn như các phiên Frontend, LNB, CAS và thiết bị đầu vào TV từ HAL đầu vào TV.
- Áp dụng các quy tắc để lấy lại tài nguyên không đủ từ ứng dụng. Quy tắc mặc định là chiến thắng ở tiền cảnh.
Media CAS và CAS HAL được cải tiến với các tính năng bên dưới.
- Mở các phiên CAS cho các cách sử dụng và thuật toán khác nhau.
- Hỗ trợ các hệ thống CAS động, chẳng hạn như loại bỏ và chèn CICAM.
- Tích hợp với Tuner HAL bằng cách cung cấp mã thông báo chính.
MediaCodec
và AudioTrack
được cải tiến với các tính năng bên dưới.
- Lấy bộ nhớ A/V an toàn làm đầu vào nội dung.
- Được định cấu hình để thực hiện đồng bộ hóa A/V phần cứng khi phát lại theo đường hầm.
- Hỗ trợ được định cấu hình cho
ES_payload
và chế độ chuyển tiếp.
Hình 2. Sơ đồ các thành phần trong Tuner HAL
Quy trình làm việc tổng thể
Các sơ đồ bên dưới minh họa trình tự cuộc gọi để phát lại chương trình phát sóng trực tiếp.
Cài đặt
Hình 3. Trình tự thiết lập để phát lại chương trình phát sóng trực tiếp
Xử lý A/V
Hình 4. Xử lý A/V để phát lại chương trình phát sóng trực tiếp
Xử lý nội dung bị xáo trộn
Hình 5. Xử lý nội dung bị xáo trộn để phát lại chương trình phát sóng trực tiếp
Xử lý dữ liệu A/V
Hình 6. Xử lý A/V để phát lại chương trình phát sóng trực tiếp
API SDK điều chỉnh
API Tuner SDK xử lý các tương tác với Tuner JNI, Tuner HAL và TunerResourceManager
. Ứng dụng TIS sử dụng API Tuner SDK để truy cập các tài nguyên và thành phần phụ của Tuner như bộ lọc và bộ giải mã. Frontend và demux là các thành phần bên trong.
Hình 7. Tương tác với API Tuner SDK
Phiên bản
Từ Android 12, API Tuner SDK hỗ trợ tính năng mới trong Tuner HAL 1.1, đây là phiên bản nâng cấp tương thích ngược của Tuner 1.0.
Sử dụng API sau để kiểm tra phiên bản HAL đang chạy.
-
android.media.tv.tuner.TunerVersionChecker.getTunerVersion()
Bạn có thể tìm thấy phiên bản HAL yêu cầu tối thiểu trong tài liệu về API Android 12 mới.
Gói
API Tuner SDK cung cấp bốn gói bên dưới.
-
android.media.tv.tuner
-
android.media.tv.tuner.frontend
-
android.media.tv.tuner.filter
-
android.media.tv.tuner.dvr
Hình 8. Các gói API Tuner SDK
Android.media.tv.tuner
Gói Tuner là điểm bắt đầu để sử dụng khung Tuner. Ứng dụng TIS sử dụng gói để khởi tạo và thu thập các phiên bản tài nguyên bằng cách chỉ định cài đặt ban đầu và gọi lại.
-
tuner()
: Khởi tạo một phiên bản Tuner bằng cách chỉ định các tham sốuseCase
vàsessionId
. -
tune()
: Thu thập tài nguyên giao diện người dùng và điều chỉnh bằng cách chỉ định tham sốFrontendSetting
. -
openFilter()
: Lấy một phiên bản bộ lọc bằng cách chỉ định loại bộ lọc. -
openDvrRecorder()
: Lấy phiên bản ghi bằng cách chỉ định kích thước bộ đệm. -
openDvrPlayback()
: Lấy phiên bản phát lại bằng cách chỉ định kích thước bộ đệm. -
openDescrambler()
: Thu thập một phiên bản descrambler. -
openLnb()
: Thu thập một phiên bản LNB nội bộ. -
openLnbByName()
: Thu thập một phiên bản LNB bên ngoài. -
openTimeFilter()
: Lấy phiên bản bộ lọc thời gian.
Gói Tuner cung cấp các chức năng không có trong các gói bộ lọc, DVR và giao diện người dùng. Các chức năng được liệt kê dưới đây.
-
cancelTuning
-
scan
/cancelScanning
-
getAvSyncHwId
-
getAvSyncTime
-
connectCiCam1
/disconnectCiCam
-
shareFrontendFromTuner
-
updateResourcePriority
-
setOnTuneEventListener
-
setResourceLostListener
Android.media.tv.tuner.frontend
Gói giao diện người dùng bao gồm các bộ sưu tập cài đặt, thông tin, trạng thái, sự kiện và khả năng liên quan đến giao diện người dùng.
Các lớp học
FrontendSettings
được lấy từ các tiêu chuẩn DTV khác nhau theo các lớp bên dưới.
-
AnalogFrontendSettings
-
Atsc3FrontendSettings
-
AtscFrontendSettings
-
DvbcFrontendSettings
-
DvbsFrontendSettings
-
DvbtFrontendSettings
-
Isdbs3FrontendSettings
-
IsdbsFrontendSettings
-
IsdbtFrontendSettings
Từ Android 12 với Tuner HAL 1.1 trở lên, chuẩn DTV sau được hỗ trợ.
-
DtmbFrontendSettings
FrontendCapabilities
được bắt nguồn từ các tiêu chuẩn DTV khác nhau theo các lớp bên dưới.
-
AnalogFrontendCapabilities
-
Atsc3FrontendCapabilities
-
AtscFrontendCapabilities
-
DvbcFrontendCapabilities
-
DvbsFrontendCapabilities
-
DvbtFrontendCapabilities
-
Isdbs3FrontendCapabilities
-
IsdbsFrontendCapabilities
-
IsdbtFrontendCapabilities
Từ Android 12 với Tuner HAL 1.1 trở lên, chuẩn DTV sau được hỗ trợ.
-
DtmbFrontendCapabilities
FrontendInfo
lấy thông tin của giao diện người dùng. FrontendStatus
truy xuất trạng thái hiện tại của giao diện người dùng. OnTuneEventListener
lắng nghe các sự kiện ở giao diện người dùng. Ứng dụng TIS sử dụng ScanCallback
để xử lý tin nhắn quét từ giao diện người dùng.
Quét kênh
Để thiết lập TV, ứng dụng sẽ quét các tần số có thể có và xây dựng danh sách kênh để người dùng truy cập. TIS có thể sử dụng Tuner.tune
, Tuner.scan(BLIND_SCAN)
hoặc Tuner.scan(AUTO_SCAN)
để hoàn tất quá trình quét kênh.
Nếu TIS có thông tin phân phối chính xác cho tín hiệu, chẳng hạn như tần số, tiêu chuẩn (ví dụ: T/T2, S/S2) và thông tin cần thiết bổ sung (ví dụ: ID PLD), thì Tuner.tune
được khuyến nghị là tùy chọn nhanh hơn .
Khi người dùng gọi Tuner.tune
, các hành động sau sẽ xảy ra:
- TIS điền thông tin bắt buộc vào
FrontendSettings
bằng cách sử dụngTuner.tune
. - Báo cáo HAL điều chỉnh các tin nhắn
LOCKED
nếu tín hiệu bị khóa. - TIS sử dụng
Frontend.getStatus
để thu thập thông tin cần thiết. - TIS chuyển sang tần số khả dụng tiếp theo trong danh sách tần số của nó.
TIS gọi lại Tuner.tune
cho đến khi hết tần số.
Trong khi điều chỉnh, bạn có thể gọi stopTune()
hoặc close()
để tạm dừng hoặc kết thúc cuộc gọi Tuner.tune
.
Tuner.scan(AUTO_SCAN)
Nếu TIS không có đủ thông tin để sử dụng Tuner.tune
nhưng có danh sách tần số và loại tiêu chuẩn (ví dụ: DVB T/C/S), thì nên sử dụng Tuner.scan(AUTO_SCAN)
.
Khi người dùng gọi Tuner.scan(AUTO_SCAN)
, các hành động sau sẽ xảy ra:
TIS sử dụng
Tuner.scan(AUTO_SCAN)
vớiFrontendSettings
chứa đầy tần số.Báo cáo HAL quét các tin nhắn
LOCKED
nếu tín hiệu bị khóa. HAL cũng có thể báo cáo các thông báo quét khác để cung cấp thêm thông tin về tín hiệu.TIS sử dụng
Frontend.getStatus
để thu thập thông tin cần thiết.TIS gọi
Tuner.scan
để HAL tiếp tục cài đặt tiếp theo trên cùng tần số. Nếu cấu trúcFrontendSettings
trống, HAL sẽ sử dụng cài đặt có sẵn tiếp theo. Mặt khác, HAL sử dụngFrontendSettings
để quét một lần và gửiEND
để cho biết rằng thao tác quét đã kết thúc.TIS lặp lại các hành động trên cho đến khi hết tất cả cài đặt về tần số.
HAL gửi
END
để cho biết quá trình quét đã kết thúc.TIS chuyển sang tần số khả dụng tiếp theo trong danh sách tần số của nó.
TIS gọi lại Tuner.scan(AUTO_SCAN)
cho đến khi hết tần số.
Trong quá trình quét, bạn có thể gọi stopScan()
hoặc close()
để tạm dừng hoặc kết thúc quá trình quét.
Tuner.scan(BLIND_SCAN)
Nếu TIS không có danh sách tần số và HAL của nhà cung cấp có thể tìm kiếm tần số của giao diện người dùng do người dùng chỉ định để lấy tài nguyên giao diện người dùng, thì nên sử dụng Tuner.scan(BLIND_SCAN)
.
- TIS sử dụng
Tuner.scan(BLIND_SCAN)
. Một tần số có thể được chỉ định trongFrontendSettings
cho tần số bắt đầu, nhưng TIS bỏ qua các cài đặt khác trongFrontendSettings
. - HAL báo cáo thông báo KHÓA
LOCKED
nếu tín hiệu bị khóa. - TIS sử dụng
Frontend.getStatus
để thu thập thông tin cần thiết. - TIS gọi lại
Tuner.scan
để tiếp tục quét. (FrontendSettings
bị bỏ qua.) - TIS lặp lại các hành động trên cho đến khi hết tất cả cài đặt về tần số. Tần số tăng HAL mà không cần thực hiện hành động nào từ TIS. HAL báo cáo
PROGRESS
.
TIS gọi lại Tuner.scan(AUTO_SCAN)
cho đến khi hết tần số. HAL báo cáo END
để cho biết rằng thao tác quét đã kết thúc.
Trong quá trình quét, bạn có thể gọi stopScan()
hoặc close()
để tạm dừng hoặc kết thúc quá trình quét.
Hình 9. Sơ đồ quy trình quét TIS
Android.media.tv.tuner.filter
Gói bộ lọc là tập hợp các hoạt động lọc cùng với cấu hình, cài đặt, lệnh gọi lại và sự kiện. Gói này bao gồm các hoạt động dưới đây. Tham khảo mã nguồn Android để biết danh sách đầy đủ các hoạt động.
-
configure()
-
start()
-
stop()
-
flush()
-
read()
Tham khảo mã nguồn Android để biết danh sách đầy đủ.
FilterConfiguration
có nguồn gốc từ các lớp bên dưới. Các cấu hình dành cho loại bộ lọc chính và chúng chỉ định giao thức nào bộ lọc sử dụng để trích xuất dữ liệu.
-
AlpFilterConfiguration
-
IpFilterConfiguration
-
MmtpFilterConfiguration
-
TlvFilterConfiguration
-
TsFilterConfiguration
Các cài đặt được bắt nguồn từ các lớp bên dưới. Cài đặt dành cho loại bộ lọc phụ và chúng chỉ định loại dữ liệu mà bộ lọc có thể loại trừ.
-
SectionSettings
-
AvSettings
-
PesSettings
-
RecordSettings
-
DownloadSettings
FilterEvent
được lấy từ các lớp bên dưới để báo cáo các sự kiện cho các loại dữ liệu khác nhau.
-
SectionEvent
-
MediaEvent
-
PesEvent
-
TsRecordEvent
-
MmtpRecordEvent
-
TemiEvent
-
DownloadEvent
-
IpPayloadEvent
Từ Android 12 có Tuner HAL 1.1 trở lên, các sự kiện sau được hỗ trợ.
-
IpCidChangeEvent
-
RestartEvent
-
ScramblingStatusEvent
Sự kiện và định dạng dữ liệu từ bộ lọc
Tuýt lọc | Cờ | Sự kiện | Thao tác dữ liệu | Định dạng dữ liệu |
---|---|---|---|---|
TS.SECTION MMTP.SECTION IP.SECTION TLV.SECTION ALP.SECTION | isRaw: | Bắt buộc:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Khuyến khích: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Theo sự kiện và lịch trình nội bộ, chạyFilter.read(buffer, offset, adjustedSize) một hoặc nhiều lần.Dữ liệu được sao chép từ MQ của HAL vào bộ đệm máy khách. | Một gói phiên đã lắp ráp được điền vào FMQ bằng một gói phiên khác. |
isRaw: | Bắt buộc:DemuxFilterEvent::DemuxFilterSectionEvent[n] DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Không bắt buộc: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | for i=0; i<n; i++ Dữ liệu được sao chép từ MQ của HAL vào bộ đệm máy khách. | ||
TS.PES | isRaw: | Bắt buộc:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Khuyến khích: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Theo sự kiện và lịch trình nội bộ, chạyFilter.read(buffer, offset, adjustedSize) một hoặc nhiều lần.Dữ liệu được sao chép từ MQ của HAL vào bộ đệm máy khách. | Một gói PES đã lắp ráp sẽ được điền vào FMQ bằng một gói PES khác. |
isRaw: | Bắt buộc:DemuxFilterEvent::DemuxFilterPesEvent[n] DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Không bắt buộc: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | for i=0; i<n; i++ Dữ liệu được sao chép từ MQ của HAL vào bộ đệm máy khách. | ||
MMTP.PES | isRaw: | Bắt buộc:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Khuyến khích: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Theo sự kiện và lịch trình nội bộ, chạyFilter.read(buffer, offset, adjustedSize) một hoặc nhiều lần.Dữ liệu được sao chép từ MQ của HAL vào bộ đệm máy khách. | Một gói MFU đã lắp ráp được điền vào FMQ bằng một gói MFU khác. |
isRaw: | Bắt buộc:DemuxFilterEvent::DemuxFilterPesEvent[n] DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Không bắt buộc: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | for i=0; i<n; i++ Dữ liệu được sao chép từ MQ của HAL vào bộ đệm máy khách. | ||
TS.TS | không áp dụng | Bắt buộc:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Khuyến khích: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Theo sự kiện và lịch trình nội bộ, chạyFilter.read(buffer, offset, adjustedSize) một hoặc nhiều lần.Dữ liệu được sao chép từ MQ của HAL vào bộ đệm máy khách. | Đã lọc ts với tiêu đề ts được điền vào FMQ. |
TS.Audio TS.Video MMTP.Audio MMTP.Video | isPassthrough: | Không bắt buộc:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW | Máy khách có thể khởi động MediaCodec sau khi nhận được DemuxFilterStatus::DATA_READY .Máy khách có thể gọi Filter.flush sau khi nhận được DemuxFilterStatus::DATA_OVERFLOW . | không áp dụng |
isPassthrough: | Bắt buộc:DemuxFilterEvent::DemuxFilterMediaEvent[n] DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Không bắt buộc: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Để sử dụng MediaCodec :for i=0; i<n; i++ Để sử dụng Âm thanh trực tiếp của AudioTrack :for i=0; i<n; i++ | ES hoặc dữ liệu ES một phần trong bộ nhớ ION. | |
TS.PCR IP.NTP ALP.PTP | không áp dụng | Bắt buộc: Không áp dụng Tùy chọn: Không áp dụng | không áp dụng | không áp dụng |
TS.RECORD | không áp dụng | Bắt buộc:DemuxFilterEvent::DemuxFilterTsRecordEvent[n] RecordStatus::DATA_READY RecordStatus::DATA_OVERFLOW RecordStatus::LOW_WATER RecordStatus::HIGH_WATER Không bắt buộc: DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Đối với dữ liệu chỉ mục:for i=0; i<n; i++ Đối với nội dung đã ghi , theo RecordStatus::* và lịch trình nội bộ, hãy thực hiện một trong các thao tác sau:
| Đối với dữ liệu chỉ mục: Được mang trong tải trọng sự kiện. Đối với nội dung được ghi: Luồng TS trộn lẫn được điền vào FMQ. |
TS.TEMI | không áp dụng | Bắt buộc:DemuxFilterEvent::DemuxFilterTemiEvent[n] Không bắt buộc: DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | for i=0; i<n; i++ | không áp dụng |
MMTP.MMTP | không áp dụng | Bắt buộc:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Khuyến khích: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Theo sự kiện và lịch trình nội bộ, chạyFilter.read(buffer, offset, adjustedSize) một hoặc nhiều lần.Dữ liệu được sao chép từ MQ của HAL vào bộ đệm máy khách. | Đã lọc mmtp với tiêu đề mmtp được điền vào FMQ. |
MMTP.RECORD | không áp dụng | Bắt buộc:DemuxFilterEvent::DemuxFilterMmtpRecordEvent[n] RecordStatus::DATA_READY RecordStatus::DATA_OVERFLOW RecordStatus::LOW_WATER RecordStatus::HIGH_WATER Không bắt buộc: DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Đối với dữ liệu chỉ mục: for i=0; i<n; i++ Đối với nội dung đã ghi , theo RecordStatus::* và lịch trình nội bộ, hãy thực hiện một trong các thao tác sau:
| Đối với dữ liệu chỉ mục: Được mang trong tải trọng sự kiện. Đối với nội dung được ghi: Luồng ghi được trộn lẫn chứa FMQ. Nếu nguồn bộ lọc để ghi là TLV.TLV sang IP.IP có truyền qua thì luồng được ghi có tiêu đề TLV và IP. |
MMTP.DOWNLOAD | không áp dụng | Bắt buộc:DemuxFilterEvent::DemuxFilterDownloadEvent[n] DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Không bắt buộc: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | for i=0; i<n; i++ Filter.read(buffer, offset, DemuxFilterDownloadEvent[i].size) Dữ liệu được sao chép từ MQ của HAL vào bộ đệm máy khách. | Gói tải xuống được điền vào FMQ bằng gói tải xuống IP khác. |
IP.IP_PAYLOAD | không áp dụng | Bắt buộc:DemuxFilterEvent::DemuxFilterIpPayloadEvent[n] DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Không bắt buộc: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | for i=0; i<n; i++ Filter.read(buffer, offset, DemuxFilterIpPayloadEvent[i].size) Dữ liệu được sao chép từ MQ của HAL vào bộ đệm máy khách. | Gói tải trọng IP được điền vào FMQ bằng gói tải trọng IP khác. |
IP.IP TLV.TLV ALP.ALP | isPassthrough: | Không bắt buộc:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW | Luồng phụ giao thức được lọc ra sẽ cung cấp bộ lọc tiếp theo trong chuỗi bộ lọc. | không áp dụng |
isPassthrough: | Bắt buộc:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Khuyến khích: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Theo sự kiện và lịch trình nội bộ, chạyFilter.read(buffer, offset, adjustedSize) một hoặc nhiều lần.Dữ liệu được sao chép từ MQ của HAL vào bộ đệm máy khách. | Luồng phụ giao thức được lọc ra với tiêu đề giao thức được điền vào FMQ. | |
IP.PAYLOAD_THROUGH TLV.PAYLOAD_THROUGH ALP.PAYLOAD_THROUGH | không áp dụng | Không bắt buộc:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW | Tải trọng giao thức được lọc ra sẽ cung cấp bộ lọc tiếp theo trong chuỗi bộ lọc. | không áp dụng |
Luồng ví dụ sử dụng bộ lọc để xây dựng PSI/SI
Hình 10. Quy trình xây dựng PSI/SI
Mở một bộ lọc.
Filter filter = tuner.openFilter( Filter.TYPE_TS, Filter.SUBTYPE_SECTION, /* bufferSize */1000, executor, filterCallback );
Cấu hình và khởi động bộ lọc.
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();
Phần xử lý
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); } } } };
Luồng mẫu để sử dụng MediaEvent từ bộ lọc
Hình 11. Luồng sử dụng MediaEvent từ bộ lọc
- Mở, định cấu hình và khởi động bộ lọc A/V.
- Xử lý
MediaEvent
. - Nhận
MediaEvent
. - Xếp hàng khối tuyến tính vào
codec
. - Nhả tay cầm A/V khi dữ liệu đã được sử dụng.
Android.media.tv.tuner.dvr
DvrRecorder
cung cấp các phương pháp ghi này.
-
configure
-
attachFilter
-
detachFilter
-
start
-
flush
-
stop
-
setFileDescriptor
-
write
DvrPlayback
cung cấp các phương pháp này để phát lại.
-
configure
-
start
-
flush
-
stop
-
setFileDescriptor
-
read
DvrSettings
được sử dụng để cấu hình DvrRecorder
và DvrPlayback
. OnPlaybackStatusChangedListener
và OnRecordStatusChangedListener
được sử dụng để báo cáo trạng thái của phiên bản DVR.
Luồng ví dụ để bắt đầu một bản ghi
Hình 12. Quy trình bắt đầu một bản ghi
Mở, định cấu hình và khởi động
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();
Nhận
RecordEvent
và lấy thông tin chỉ mục.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. } } } };
Khởi tạo
OnRecordStatusChangedListener
và lưu trữ dữ liệu bản ghi.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); } } };
Bộ chỉnh HAL
Tuner HAL tuân theo HIDL và xác định giao diện giữa khung và phần cứng của nhà cung cấp. Các nhà cung cấp sử dụng giao diện để triển khai Tuner HAL và khung sử dụng nó để giao tiếp với việc triển khai Tuner HAL.
Mô-đun
Bộ chỉnh HAL 1.0
Mô-đun | Điều khiển cơ bản | Điều khiển dành riêng cho mô-đun | Tệp HAL |
---|---|---|---|
ITuner | không áp dụng | 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 |
Bộ điều chỉnh HAL 1.1 (bắt nguồn từ Bộ điều chỉnh HAL 1.0)
Mô-đun | Điều khiển cơ bản | Điều khiển dành riêng cho mô-đun | Tệp HAL |
---|---|---|---|
ITuner | không áp dụng | 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 |
Hình 13. Sơ đồ tương tác giữa các mô-đun Tuner HAL
Liên kết bộ lọc
Tuner HAL hỗ trợ liên kết bộ lọc sao cho các bộ lọc có thể được liên kết với các bộ lọc khác cho nhiều lớp. Các bộ lọc tuân theo các quy tắc dưới đây.
- Các bộ lọc được liên kết dưới dạng cây, không được phép đóng đường dẫn.
- Nút gốc là demux.
- Bộ lọc hoạt động độc lập.
- Tất cả các bộ lọc bắt đầu nhận dữ liệu.
- Liên kết bộ lọc xả vào bộ lọc cuối cùng.
Khối mã bên dưới và Hình 14 minh họa một ví dụ về lọc nhiều lớp.
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>)
}
Hình 14. Sơ đồ luồng liên kết bộ lọc cho nhiều lớp
Trình quản lý tài nguyên bộ điều chỉnh
Trước Trình quản lý tài nguyên Tuner (TRM), việc chuyển đổi giữa hai ứng dụng yêu cầu cùng một phần cứng Tuner. Khung đầu vào TV (TIF) đã sử dụng cơ chế "người đầu tiên giành được chiến thắng", nghĩa là ứng dụng nào nhận được tài nguyên trước sẽ giữ tài nguyên đó. Tuy nhiên, cơ chế này có thể không lý tưởng đối với một số trường hợp sử dụng phức tạp.
TRM hoạt động như một dịch vụ hệ thống để quản lý tài nguyên phần cứng Tuner, TVInput
và CAS cho ứng dụng. TRM sử dụng cơ chế "chiến thắng ở nền trước", tính toán mức độ ưu tiên của ứng dụng dựa trên trạng thái nền trước hoặc nền sau của ứng dụng và loại trường hợp sử dụng. TRM cấp hoặc thu hồi tài nguyên dựa trên mức độ ưu tiên. TRM tập trung quản lý tài nguyên ATV cho phát sóng, OTT và DVR.
Giao diện TRM
TRM hiển thị các giao diện AIDL trong ITunerResourceManager.aidl
cho khung Tuner, MediaCas
và TvInputHardwareManager
để đăng ký, yêu cầu hoặc giải phóng tài nguyên.
Các giao diện quản lý khách hàng được liệt kê dưới đây.
-
registerClientProfile(in ResourceClientProfile profile, IResourcesReclaimListener listener, out int[] clientId)
-
unregisterClientProfile(in int clientId)
Các giao diện để yêu cầu và giải phóng tài nguyên được liệt kê dưới đây.
-
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
Các lớp khách hàng và yêu cầu được liệt kê dưới đây.
-
ResourceClientProfile
-
ResourcesReclaimListener
-
TunerFrontendRequest
-
TunerDemuxRequest
-
TunerDescramblerRequest
-
CasSessionRequest
-
TunerLnbRequest
Ưu tiên khách hàng
TRM tính toán mức độ ưu tiên của máy khách bằng cách sử dụng các tham số từ hồ sơ của máy khách và giá trị mức độ ưu tiên từ tệp cấu hình. Mức độ ưu tiên cũng có thể được cập nhật theo giá trị ưu tiên tùy ý từ máy khách.
Các thông số trong hồ sơ của khách hàng
TRM truy xuất ID tiến trình từ mTvInputSessionId
để quyết định xem ứng dụng là ứng dụng nền trước hay ứng dụng nền. Để tạo mTvInputSessionId
, TvInputService.onCreateSession
hoặc TvInputService.onCreateRecordingSession
khởi tạo phiên TIS.
mUseCase
cho biết trường hợp sử dụng của phiên. Các trường hợp sử dụng được xác định trước được liệt kê dưới đây.
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
}
Tập tin cấu hình
Tệp cấu hình mặc định
Tệp cấu hình mặc định bên dưới cung cấp các giá trị ưu tiên cho các trường hợp sử dụng được xác định trước. Người dùng có thể thay đổi các giá trị bằng cách sử dụng tệp cấu hình tùy chỉnh .
Trường hợp sử dụng | Vấn đề xung quanh | Lý lịch |
---|---|---|
LIVE | 490 | 400 |
PLAYBACK | 480 | 300 |
RECORD | 600 | 500 |
SCAN | 450 | 200 |
BACKGROUND | 180 | 100 |
Tập tin cấu hình tùy chỉnh
Nhà cung cấp có thể tùy chỉnh tệp cấu hình /vendor/etc/tunerResourceManagerUseCaseConfig.xml
. Tệp này được sử dụng để thêm, xóa hoặc cập nhật các loại ca sử dụng và các giá trị ưu tiên của ca sử dụng. Tệp tùy chỉnh có thể sử dụng platform/hardware/interfaces/tv/tuner/1.0/config/tunerResourceManagerUseCaseConfigSample.xml
làm mẫu.
Ví dụ: trường hợp sử dụng của nhà cung cấp mới là VENDOR_USE_CASE__[A-Z0-9]+, [0 - 1000]
. Định dạng phải tuân theo platform/hardware/interfaces/tv/tuner/1.0/config/tunerResourceManagerUseCaseConfig.xsd
.
Giá trị ưu tiên tùy ý và giá trị đẹp
TRM cung cấp updateClientPriority
để khách hàng cập nhật giá trị ưu tiên tùy ý và giá trị Nice. Giá trị ưu tiên tùy ý ghi đè giá trị ưu tiên được tính từ loại trường hợp sử dụng và ID phiên.
Giá trị Nice biểu thị mức độ khoan dung của hành vi của khách hàng khi nó xung đột với khách hàng khác. Giá trị tốt làm giảm giá trị ưu tiên của khách hàng trước khi giá trị ưu tiên của nó được so sánh với khách hàng thách thức.
Cơ chế thu hồi
Sơ đồ bên dưới cho thấy cách thu hồi và phân bổ tài nguyên khi xảy ra xung đột tài nguyên.
Hình 15. Sơ đồ cơ chế thu hồi xung đột giữa các tài nguyên Tuner