สำหรับ Android 11 ขึ้นไป คุณสามารถใช้ เฟรมเวิร์กตัวรับสัญญาณสำหรับนำเสนอเนื้อหาภาพและเสียง เฟรมเวิร์กจะใช้ฮาร์ดแวร์ จากผู้ขาย ทำให้เหมาะกับ SoC ระดับต่ำและระดับไฮเอนด์ เฟรมเวิร์กนี้มอบวิธีที่ปลอดภัยในการแสดงเนื้อหาภาพและเสียงที่ได้รับการป้องกันโดย สภาพแวดล้อมการดำเนินการที่เชื่อถือได้ (TEE) และเส้นทางสื่อที่ปลอดภัย (SMP) ซึ่งทำให้ ใช้งานในสภาพแวดล้อมที่มีการจำกัดระดับสูงและได้รับการปกป้องด้วยเนื้อหา
อินเทอร์เฟซที่เป็นมาตรฐานระหว่าง Tuner และ Android CAS จะช่วยให้ทำงานได้เร็วขึ้น
การผสานรวมระหว่างผู้ให้บริการตัวรับสัญญาณและผู้ให้บริการ CAS อินเทอร์เฟซตัวรับสัญญาณทำงานได้
ร่วมกับ MediaCodec
และ AudioTrack
เพื่อสร้างโซลูชันระดับโลกหนึ่งเดียวสำหรับ Android TV
อินเทอร์เฟซตัวรับสัญญาณรองรับทั้งทีวีดิจิทัลและทีวีแอนะล็อกโดยอิงตาม
มาตรฐานการออกอากาศ
คอมโพเนนต์
สำหรับ Android 11 จะมีคอมโพเนนต์ 3 รายการต่อไปนี้ ที่ออกแบบมาสำหรับแพลตฟอร์มทีวี
- Tuner HAL: อินเทอร์เฟซระหว่างเฟรมเวิร์กและผู้ให้บริการ
- Tuner SDK API: อินเทอร์เฟซระหว่างเฟรมเวิร์กกับแอป
- Tuner Resource Manager (TRM): ทรัพยากร HW ของตัวรับสัญญาณสำหรับพิกัด
สําหรับ Android 11 คอมโพเนนต์ต่อไปนี้ ที่ได้รับการปรับปรุงแล้ว
- แคลิฟอร์เนีย V2
TvInputService
หรือบริการอินพุตทีวี (TIS)TvInputManagerService
หรือบริการโปรแกรมจัดการอินพุตทีวี (TIMS)MediaCodec
หรือตัวแปลงรหัสสื่อAudioTrack
หรือแทร็กเสียงMediaResourceManager
หรือผู้จัดการทรัพยากรสื่อ (MRM)
รูปที่ 1 การโต้ตอบระหว่างคอมโพเนนต์ของ Android TV
ฟีเจอร์
ฟรอนท์เอนด์รองรับมาตรฐาน DTV ด้านล่าง
- ATSC
- ATSC3
- DVB C/S/T
- ISDB S/S3/T
- แอนะล็อก
ฟรอนท์เอนด์ใน Android 12 ที่มี Tuner HAL 1.1 ขึ้นไปรองรับมาตรฐาน DTV ด้านล่าง
- DTMB
Demux รองรับโปรโตคอลสตรีมด้านล่าง
- สตรีมการนำส่ง (TS)
- โปรโตคอลการส่งสื่อ MPEG (MMTP)
- โปรโตคอลอินเทอร์เน็ต (IP)
- ค่าความยาวของประเภท (TLV)
- โปรโตคอลเลเยอร์ลิงก์ ATSC (ALP)
เครื่องมือถอดรหัสรองรับการป้องกันเนื้อหาด้านล่าง
- เส้นทางสื่อที่ปลอดภัย
- ล้างเส้นทางสื่อ
- ระเบียนในเครื่องที่ปลอดภัย
- เล่นในเครื่องที่ปลอดภัย
Tuner API รองรับกรณีการใช้งานด้านล่าง
- สแกน
- สด
- การเล่น
- บันทึก
ตัวรับสัญญาณ MediaCodec
และ AudioTrack
รองรับโหมดโฟลว์ข้อมูลด้านล่าง
- เพย์โหลด ES ที่มีบัฟเฟอร์หน่วยความจำที่ชัดเจน
- เพย์โหลด ES ที่มีแฮนเดิลหน่วยความจำที่ปลอดภัย
- โปร่ง
การออกแบบโดยรวม
HAL ตัวรับสัญญาณมีการกำหนดระหว่างเฟรมเวิร์กของ Android และผู้ให้บริการ ฮาร์ดแวร์
- อธิบายว่าผู้ให้บริการคาดหวังอะไรจากเฟรมเวิร์กและผู้ให้บริการรายนี้ สิ่งที่ควรทำ
- ส่งออกฟังก์ชันของฟรอนท์เอนด์, Demux และ Deskrambler ไปยัง
ผ่าน
IFrontend
,IDemux
,IDescrambler
,IFilter
,IDvr
และILnb
อินเทอร์เฟซ - มีฟังก์ชันในการผสานรวม Tuner HAL กับเฟรมเวิร์กอื่นๆ
เช่น
MediaCodec
และAudioTrack
จะมีการสร้างคลาส Java ตัวรับสัญญาณและคลาสเนทีฟ
- Tuner Java API อนุญาตให้แอปเข้าถึง Tuner HAL ผ่าน API สาธารณะ
- คลาสดั้งเดิมทำให้ควบคุมสิทธิ์และจัดการ การบันทึกหรือเล่นข้อมูลด้วยตัวรับสัญญาณ HAL ของตัวรับสัญญาณ
- โมดูล Native Tuner เป็นสะพานเชื่อมระหว่างคลาส Tuner Java กับตัวรับสัญญาณ HAL
ระบบสร้างคลาส TRM แล้ว
- จัดการทรัพยากรตัวรับสัญญาณแบบจำกัด เช่น ฟรอนท์เอนด์, LNB, เซสชัน CAS และอุปกรณ์อินพุตทีวีจาก HAL อินพุตทีวี
- ใช้กฎเพื่ออ้างสิทธิ์ทรัพยากรที่ไม่เพียงพออีกครั้งจาก แอป กฎเริ่มต้นคือผู้ชนะในเบื้องหน้า
Media CAS และ CAS HAL ได้รับการเพิ่มประสิทธิภาพด้วยฟีเจอร์ด้านล่างนี้
- เปิดเซสชัน CAS สำหรับการใช้งานและอัลกอริทึมต่างๆ
- รองรับระบบ CAS แบบไดนามิก เช่น การลบและการแทรก CICAM
- ผสานรวมกับ HAL ตัวรับสัญญาณโดยการระบุโทเค็นคีย์
MediaCodec
และ AudioTrack
ได้รับการเพิ่มประสิทธิภาพด้วยฟีเจอร์ด้านล่างนี้
- ใช้หน่วยความจำ A/V ที่ปลอดภัยเป็นอินพุตเนื้อหา
- กำหนดค่าให้ซิงค์ A/V ของฮาร์ดแวร์ในการเล่น Tunnel
- กำหนดค่าการรองรับ
ES_payload
และโหมดส่งผ่านแล้ว
รูปที่ 2 แผนภาพองค์ประกอบภายใน Tuner HAL
เวิร์กโฟลว์โดยรวม
แผนภาพด้านล่างแสดงลำดับการโทรของการเล่นการถ่ายทอดสด
ตั้งค่า
รูปที่ 3 ตั้งค่าลำดับการเล่นการถ่ายทอดสด
การจัดการ A/V
รูปที่ 4 การจัดการ A/V สำหรับการเล่นการถ่ายทอดสด
การจัดการเนื้อหาที่อ่านไม่ได้
รูปที่ 5 การจัดการเนื้อหาที่อ่านไม่ได้สำหรับการเล่นการถ่ายทอดสด
กำลังประมวลผลข้อมูล A/V
รูปที่ 6 กำลังประมวลผล A/V สำหรับการเล่นการถ่ายทอดสด
API ของตัวรับสัญญาณ SDK
Tuner SDK API จัดการการโต้ตอบกับ Tuner JNI หรือ Tuner HAL
และ TunerResourceManager
แอป TIS ใช้ Tuner SDK API เพื่อเข้าถึงตัวรับสัญญาณ
ทรัพยากรและองค์ประกอบย่อย เช่น ตัวกรองและดีสแครมเบลอ ฟรอนท์เอนด์และ
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()
ดูเวอร์ชัน HAL ขั้นต่ำที่จำเป็นได้ในเอกสารประกอบของ Android 12 API ใหม่
แพ็กเกจ
Tuner SDK API มีแพ็กเกจ 4 รายการด้านล่าง
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
แพ็กเกจตัวรับสัญญาณคือจุดแรกเข้าในการใช้เฟรมเวิร์กตัวรับสัญญาณ แอป TIS ใช้แพ็กเกจเพื่อเริ่มต้นและรับอินสแตนซ์ทรัพยากรโดยระบุ การตั้งค่าเริ่มต้นและการติดต่อกลับ
tuner()
: เริ่มต้นอินสแตนซ์ตัวรับสัญญาณด้วยการระบุuseCase
และsessionId
พารามิเตอร์tune()
: รับทรัพยากรฟรอนท์เอนด์และปรับแต่งด้วยการระบุ พารามิเตอร์FrontendSetting
openFilter()
: รับอินสแตนซ์ตัวกรองโดยการระบุประเภทตัวกรองopenDvrRecorder()
: รับอินสแตนซ์การบันทึกโดยการระบุบัฟเฟอร์ ขนาดopenDvrPlayback()
: รับอินสแตนซ์การเล่นโดยการระบุบัฟเฟอร์ ขนาดopenDescrambler()
: รับอินสแตนซ์เครื่องมือถอดรหัสopenLnb()
: รับอินสแตนซ์ LNB ภายในopenLnbByName()
: รับอินสแตนซ์ LNB ภายนอกopenTimeFilter()
: รับอินสแตนซ์ตัวกรองเวลา
แพ็กเกจตัวรับสัญญาณมีฟังก์ชันการทำงานที่ไม่ครอบคลุม ตัวกรอง, DVR และแพ็กเกจฟรอนท์เอนด์ ฟังก์ชันการทำงานมีดังนี้
cancelTuning
scan
/cancelScanning
getAvSyncHwId
getAvSyncTime
connectCiCam1
/disconnectCiCam
shareFrontendFromTuner
updateResourcePriority
setOnTuneEventListener
setResourceLostListener
Android.media.tv.tuner.frontend
แพ็กเกจฟรอนท์เอนด์ประกอบด้วยคอลเล็กชันการตั้งค่าที่เกี่ยวข้องกับฟรอนท์เอนด์ ข้อมูล สถานะ เหตุการณ์ และความสามารถต่างๆ
ชั้นเรียน
FrontendSettings
มาจากมาตรฐาน DTV ที่แตกต่างกันโดยชั้นเรียนด้านล่าง
AnalogFrontendSettings
Atsc3FrontendSettings
AtscFrontendSettings
DvbcFrontendSettings
DvbsFrontendSettings
DvbtFrontendSettings
Isdbs3FrontendSettings
IsdbsFrontendSettings
IsdbtFrontendSettings
จาก Android 12 ที่มี Tuner HAL 1.1 ขึ้นไป ระบบรองรับมาตรฐาน DTV ต่อไปนี้
DtmbFrontendSettings
FrontendCapabilities
ได้มาจากมาตรฐาน DTV ที่แตกต่างกันโดยชั้นเรียน
ที่ด้านล่าง
AnalogFrontendCapabilities
Atsc3FrontendCapabilities
AtscFrontendCapabilities
DvbcFrontendCapabilities
DvbsFrontendCapabilities
DvbtFrontendCapabilities
Isdbs3FrontendCapabilities
IsdbsFrontendCapabilities
IsdbtFrontendCapabilities
จาก Android 12 ที่มี Tuner HAL 1.1 ขึ้นไป ระบบรองรับมาตรฐาน DTV ต่อไปนี้
DtmbFrontendCapabilities
FrontendInfo
จะเรียกข้อมูลของฟรอนท์เอนด์
FrontendStatus
จะดึงข้อมูลสถานะปัจจุบันของฟรอนท์เอนด์
OnTuneEventListener
จะฟังเหตุการณ์ในส่วนฟรอนท์เอนด์
แอป TIS ใช้ ScanCallback
ในการประมวลผลการสแกนข้อความจากฟรอนท์เอนด์
สแกนช่อง
ในการตั้งค่าทีวี แอปจะสแกนความถี่ที่เป็นไปได้และสร้างช่อง
รายการช่องที่ผู้ใช้เข้าถึงได้ TIS อาจใช้ Tuner.tune
Tuner.scan(BLIND_SCAN)
หรือTuner.scan(AUTO_SCAN)
เพื่อทำให้ช่องเสร็จสมบูรณ์
สแกน
หาก TIS มีข้อมูลการนำส่งที่ถูกต้องสำหรับสัญญาณ เช่น ความถี่
มาตรฐาน (เช่น T/T2, S/S2) และข้อมูลเพิ่มเติมที่จําเป็น
(เช่น รหัส PLD) จากนั้น
ขอแนะนำให้ใช้ Tuner.tune
เป็นตัวเลือกที่เร็วกว่า
เมื่อผู้ใช้โทรหา Tuner.tune
ระบบจะดำเนินการต่อไปนี้
- TIS จะป้อนข้อมูลที่จำเป็นให้กับ
FrontendSettings
โดยใช้Tuner.tune
- รายงาน HAL จะปรับแต่งข้อความ
LOCKED
หากสัญญาณล็อกอยู่ - TIS ใช้
Frontend.getStatus
เพื่อรวบรวมข้อมูลที่จำเป็น - TIS ย้ายไปยังความถี่ถัดไปที่ใช้ได้ในรายการความถี่
TIS จะโทรหา Tuner.tune
อีกครั้งจนกว่าความถี่ทั้งหมดจะหมด
ระหว่างการปรับแต่ง คุณสามารถโทรหา stopTune()
หรือ close()
เพื่อหยุดชั่วคราวหรือสิ้นสุดการโทร
Tuner.tune
สาย
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 เรียก
Tuner.scan
สำหรับ HAL เพื่อไปยังการตั้งค่าถัดไปที่เดียวกัน ความถี่ หากโครงสร้าง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
แพ็กเกจตัวกรองคือคอลเล็กชันของการดำเนินการของตัวกรอง พร้อมกับการกำหนดค่า การตั้งค่า, Callback และเหตุการณ์ แพ็กเกจมีการดำเนินการด้านล่างนี้ โปรดดูรายการการดำเนินการทั้งหมดได้ในซอร์สโค้ดของ Android
configure()
start()
stop()
flush()
read()
โปรดดูรายการทั้งหมดในซอร์สโค้ดของ Android
FilterConfiguration
มาจากชั้นเรียนด้านล่าง การกำหนดค่ามีดังนี้
สำหรับประเภทตัวกรองหลัก และระบุโปรโตคอลที่ตัวกรองใช้
แตกข้อมูล
AlpFilterConfiguration
IpFilterConfiguration
MmtpFilterConfiguration
TlvFilterConfiguration
TsFilterConfiguration
การตั้งค่ามาจากชั้นเรียนด้านล่าง การตั้งค่านี้มีไว้สำหรับตัวกรอง ประเภทย่อย และระบุประเภทของข้อมูลที่ตัวกรองสามารถยกเว้นได้
SectionSettings
AvSettings
PesSettings
RecordSettings
DownloadSettings
FilterEvent
ได้มาจากชั้นเรียนด้านล่างเพื่อรายงานเหตุการณ์สำหรับ
ประเภทต่างๆ
SectionEvent
MediaEvent
PesEvent
TsRecordEvent
MmtpRecordEvent
TemiEvent
DownloadEvent
IpPayloadEvent
จาก Android 12 ที่มี Tuner HAL 1.1 ขึ้นไป ระบบจะรองรับเหตุการณ์ต่อไปนี้
IpCidChangeEvent
RestartEvent
ScramblingStatusEvent
เหตุการณ์และรูปแบบข้อมูลจากตัวกรอง
ประเภทตัวกรอง | ธง | กิจกรรม | การดำเนินการกับข้อมูล | รูปแบบข้อมูล |
---|---|---|---|---|
TS.SECTION MMTP.SECTION IP.SECTION TLV.SECTION ALP.SECTION |
isRaw: |
บังคับ:DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW แนะนำ: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
ตามกิจกรรมและกำหนดการภายใน ให้เรียกใช้Filter.read(buffer, offset, adjustedSize) อย่างน้อย 1 รายการ
ครั้งระบบจะคัดลอกข้อมูลจาก MQ ของ HAL ไปยังบัฟเฟอร์ของไคลเอ็นต์ |
แพ็กเกจเซสชันที่ประกอบแล้วรายการหนึ่งมี FMQ อยู่แล้ว แพ็กเกจเซสชัน |
isRaw: |
บังคับ:DemuxFilterEvent::DemuxFilterSectionEvent[n]
DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW ไม่บังคับ: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
for i=0; i<n; i++ วันที่ ระบบจะคัดลอกข้อมูลจาก MQ ของ HAL ไปยังบัฟเฟอร์ของไคลเอ็นต์ |
||
TS.PES |
isRaw: |
บังคับ:DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW แนะนำ: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
ตามกิจกรรมและกำหนดการภายใน ให้เรียกใช้Filter.read(buffer, offset, adjustedSize) อย่างน้อย 1 รายการ
ครั้งระบบจะคัดลอกข้อมูลจาก MQ ของ HAL ไปยังบัฟเฟอร์ของไคลเอ็นต์ |
แพ็กเกจ 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++ วันที่ ระบบจะคัดลอกข้อมูลจาก MQ ของ HAL ไปยังบัฟเฟอร์ของไคลเอ็นต์ |
||
MMTP.PES |
isRaw: |
บังคับ:DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW แนะนำ: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
ตามกิจกรรมและกำหนดการภายใน ให้เรียกใช้Filter.read(buffer, offset, adjustedSize) อย่างน้อย 1 รายการ
ครั้งระบบจะคัดลอกข้อมูลจาก MQ ของ HAL ไปยังบัฟเฟอร์ของไคลเอ็นต์ |
แพ็กเกจ 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++ วันที่ ระบบจะคัดลอกข้อมูลจาก MQ ของ HAL ไปยังบัฟเฟอร์ของไคลเอ็นต์ |
||
TS.TS |
ไม่มี | บังคับ:DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW แนะนำ: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
ตามกิจกรรมและกำหนดการภายใน ให้เรียกใช้Filter.read(buffer, offset, adjustedSize) อย่างน้อย 1 รายการ
ครั้งระบบจะคัดลอกข้อมูลจาก MQ ของ HAL ไปยังบัฟเฟอร์ของไคลเอ็นต์ |
กรองts ที่มีส่วนหัวts ออกแล้ว จะอยู่ในรูปแบบ FMQ |
TS.Audio TS.Video MMTP.Audio MMTP.Video |
isPassthrough: |
ไม่บังคับ:DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW |
ลูกค้าเริ่มต้นได้ MediaCodec หลังจากได้รับ DemuxFilterStatus::DATA_READY ลูกค้าสามารถโทรหา Filter.flush หลังจากได้รับ DemuxFilterStatus::DATA_OVERFLOW |
ไม่มี |
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++ |
ES หรือข้อมูล ES บางส่วนในหน่วยความจำ ION | |
TS.PCR IP.NTP ALP.PTP |
ไม่มี | บังคับ: ไม่มี
ไม่บังคับ: ไม่มี |
ไม่มี | ไม่มีข้อมูล |
TS.RECORD |
ไม่มี | บังคับ: DemuxFilterEvent::DemuxFilterTsRecordEvent[n]
RecordStatus::DATA_READY RecordStatus::DATA_OVERFLOW RecordStatus::LOW_WATER RecordStatus::HIGH_WATER ไม่บังคับ: DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
สำหรับข้อมูลดัชนี:for i=0; i<n; i++
สำหรับเนื้อหาที่บันทึกไว้ ตาม 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) อย่างน้อย 1 รายการ
ครั้งระบบจะคัดลอกข้อมูลจาก MQ ของ HAL ไปยังบัฟเฟอร์ของไคลเอ็นต์ |
กรองmmtp ที่มีส่วนหัวmmtp ออกแล้ว จะอยู่ในรูปแบบ FMQ |
MMTP.RECORD |
ไม่มี | บังคับ:DemuxFilterEvent::DemuxFilterMmtpRecordEvent[n]
RecordStatus::DATA_READY RecordStatus::DATA_OVERFLOW RecordStatus::LOW_WATER RecordStatus::HIGH_WATER ไม่บังคับ: DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
สำหรับข้อมูลดัชนี: for i=0; i<n; i++ สำหรับเนื้อหาที่บันทึกไว้ ตาม RecordStatus::* และกำหนดการภายใน ให้ทำอย่างใดอย่างหนึ่ง
ต่อไปนี้:
|
สำหรับข้อมูลดัชนี: ข้อมูลที่นำส่งในเพย์โหลดเหตุการณ์ สำหรับเนื้อหาที่บันทึกไว้: สตรีมที่บันทึกแบบผสม FMQ หากแหล่งที่มาของตัวกรองสำหรับการบันทึกคือ TLV.TLV ถึง
IP.IP ที่มี Passthrough สตรีมที่บันทึกไว้จะมี
ส่วนหัว TLV และ IP |
MMTP.DOWNLOAD |
ไม่มี | บังคับ:DemuxFilterEvent::DemuxFilterDownloadEvent[n]
DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW ไม่บังคับ: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
for i=0; i<n; i++
Filter.read(buffer, offset, DemuxFilterDownloadEvent[i].size) วันที่ ระบบจะคัดลอกข้อมูลจาก MQ ของ HAL ไปยังบัฟเฟอร์ของไคลเอ็นต์ |
แพ็กเกจการดาวน์โหลดมีการเติม FMQ โดยแพ็กเกจการดาวน์โหลด IP อื่น |
IP.IP_PAYLOAD |
ไม่มี | บังคับ:DemuxFilterEvent::DemuxFilterIpPayloadEvent[n]
DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW ไม่บังคับ: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
for i=0; i<n; i++
Filter.read(buffer, offset, DemuxFilterIpPayloadEvent[i].size) วันที่ ระบบจะคัดลอกข้อมูลจาก MQ ของ HAL ไปยังบัฟเฟอร์ของไคลเอ็นต์ |
แพ็กเกจเพย์โหลด IP ได้รับการเติมเป็น FMQ โดยแพ็กเกจเพย์โหลด IP อื่น |
IP.IP TLV.TLV ALP.ALP |
isPassthrough: |
ไม่บังคับ:DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW |
กรองฟีดสตรีมย่อยของโปรโตคอลออกจากตัวกรองถัดไปในตัวกรองแล้ว เครือ | ไม่มี |
isPassthrough: |
บังคับ:DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW แนะนำ: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
ตามกิจกรรมและกำหนดการภายใน ให้เรียกใช้Filter.read(buffer, offset, adjustedSize) อย่างน้อย 1 รายการ
ครั้งระบบจะคัดลอกข้อมูลจาก MQ ของ HAL ไปยังบัฟเฟอร์ของไคลเอ็นต์ |
ระบบกรอกข้อมูลสตรีมย่อยของโปรโตคอลที่มีส่วนหัวของโปรโตคอลที่กรองแล้ว 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 จากตัวกรอง
- เปิด กำหนดค่า และเริ่มใช้ฟิลเตอร์ A/V
- ประมวลผล
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 และ จะใช้กระบวนการนี้ในการสื่อสารกับการปรับใช้ตัวรับสัญญาณ HAL
โมดูล
HAL ตัวรับสัญญาณ 1.0
โมดูล | การควบคุมพื้นฐาน | การควบคุมเฉพาะโมดูล | ไฟล์ HAL |
---|---|---|---|
ITuner |
ไม่มี | frontend(open, getIds, getInfo) openDemux
openDescrambler openLnb
getDemuxCaps |
ITuner.hal |
IFrontend |
setCallback , getStatus , close
| tune stopTune scan
stopScan setLnb |
IFrontend.hal IFrontendCallback.hal |
IDemux |
close |
setFrontendDataSource openFilter openDvr getAvSyncHwId
getAvSyncTime connect / disconnectCiCam |
IDemux.hal |
IDvr |
close , start , stop , configure |
attach/detachFilters , flush , getQueueDesc |
IDvr.hal IDvrCallback.hal |
IFilter |
close , start , stop , configure , getId |
flush , getQueueDesc , releaseAvHandle , setDataSource |
IFilter.hal IFilterCallback.hal |
ILnb |
close , setCallback |
setVoltage , setTone , setSatellitePosition , sendDiseqcMessage |
ILnb.hal ILnbCallback.hal |
IDescrambler |
close |
setDemuxSource setKeyToken
addPid removePid |
IDescrambler.hal |
ตัวรับสัญญาณ HAL 1.1 (มาจากตัวรับสัญญาณ 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) การสลับระหว่าง 2 แอปจำเป็นต้องมี ฮาร์ดแวร์ตัวรับสัญญาณเดียวกัน เฟรมเวิร์กอินพุตทีวี (TIF) ใช้ "การได้รับชัยชนะครั้งแรก" ซึ่งหมายความว่าแอปใดก็ตามที่ได้รับทรัพยากรก่อนจะเก็บทรัพยากรนั้นไว้ อย่างไรก็ตาม กลไกนี้อาจไม่เหมาะสำหรับกรณีการใช้งานที่ซับซ้อน
TRM ทำงานเป็นบริการของระบบเพื่อจัดการตัวรับสัญญาณ, TVInput
และฮาร์ดแวร์ CAS
ทรัพยากรต่างๆ สำหรับแอป TRM ใช้ "ชัยชนะเบื้องหน้า" ที่
คำนวณลำดับความสำคัญของแอปตามพื้นหน้าหรือพื้นหลังของแอป
สถานะและประเภทกรณีการใช้งาน TRM จะให้สิทธิ์หรือเพิกถอนทรัพยากรโดยอิงตาม
ลำดับความสำคัญ TRM รวมศูนย์การจัดการทรัพยากร ATV สำหรับการออกอากาศ, OTT,
และ DVR
อินเทอร์เฟซ TRM
TRM แสดงอินเทอร์เฟซ AIDL ใน ITunerResourceManager.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
เพื่อตัดสินว่าแอป
เป็นแอปที่ทำงานอยู่เบื้องหน้าหรือเบื้องหลัง วิธีสร้างmTvInputSessionId
TvInputService.onCreateSession
หรือ TvInputService.onCreateRecordingSession
เริ่มต้นเซสชัน TIS
mUseCase
ระบุ Use Case ของเซสชัน Use Case ที่กำหนดไว้ล่วงหน้า
ที่ระบุไว้ด้านล่าง
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
มีการใช้ไฟล์นี้
เพื่อเพิ่ม นําออก หรืออัปเดตประเภท Use Case และค่าลําดับความสําคัญของ Use Case
ไฟล์ที่กำหนดเองสามารถใช้
platform/hardware/interfaces/tv/tuner/1.0/config/tunerResourceManagerUseCaseConfigSample.xml
เป็นเทมเพลต
ตัวอย่างเช่น Use Case ของผู้ให้บริการรายใหม่คือ VENDOR_USE_CASE__[A-Z0-9]+, [0 - 1000]
รูปแบบควรเป็นไปตามนี้
platform/hardware/interfaces/tv/tuner/1.0/config/tunerResourceManagerUseCaseConfig.xsd
ให้คุณค่าลำดับความสำคัญได้เองและคุ้มราคา
TRM ให้ updateClientPriority
แก่ลูกค้าในการอัปเดต
ลำดับความสำคัญ และคุณค่าที่เหมาะสม
ค่าลำดับความสำคัญที่กำหนดเองจะเขียนทับค่าลำดับความสำคัญที่คำนวณไว้
จากประเภทกรณีการใช้งานและรหัสเซสชัน
ค่าที่ดีจะบ่งชี้ว่าพฤติกรรมของลูกค้ามีการผ่อนปรนเพียงใดเมื่อ ขัดแย้งกับไคลเอ็นต์อื่น มูลค่าที่ดีจะทำให้ลำดับความสำคัญของลูกค้าลดลง ก่อนค่าลำดับความสำคัญจะถูกนำไปเปรียบเทียบกับลูกค้าที่ท้าทาย
กลไกการอ้างสิทธิ์อีกครั้ง
แผนภาพด้านล่างแสดงวิธีการเรียกคืนและมอบหมายทรัพยากร เกิดความขัดแย้งของทรัพยากร
รูปที่ 15 แผนภาพของกลไกการอ้างสิทธิ์ซ้ำสำหรับความขัดแย้งระหว่างตัวรับสัญญาณ ทรัพยากร