เฟรมเวิร์กตัวรับสัญญาณ

สำหรับ Android 11 ขึ้นไป คุณสามารถใช้เฟรมเวิร์ก Android TUNER เพื่อส่งเนื้อหา A/V เฟรมเวิร์กนี้ใช้ไปป์ไลน์ฮาร์ดแวร์จากผู้ให้บริการ จึงเหมาะสำหรับทั้ง SoC ระดับล่างและระดับสูง เฟรมเวิร์กนี้มอบวิธีส่งเนื้อหา A/V ที่ปลอดภัยซึ่งได้รับการปกป้องโดยสภาพแวดล้อมการประมวลผลที่เชื่อถือได้ (TEE) และเส้นทางสื่อที่ปลอดภัย (SMP) จึงนำไปใช้ในสภาพแวดล้อมที่มีการปกป้องเนื้อหาอย่างเข้มงวดได้

อินเทอร์เฟซมาตรฐานระหว่างตัวรับสัญญาณกับ Android CAS ช่วยให้ผสานรวมระหว่างผู้ให้บริการตัวรับสัญญาณกับผู้ให้บริการ CAS ได้เร็วขึ้น อินเทอร์เฟซของโปรแกรมจูนใช้ร่วมกับ MediaCodec และ AudioTrack เพื่อสร้างโซลูชันแบบครบวงจรสำหรับ Android TV อินเทอร์เฟซของจูนเนอร์รองรับทั้งทีวีดิจิทัลและทีวีอนาล็อกตามมาตรฐานการออกอากาศหลักๆ

คอมโพเนนต์

สำหรับ Android 11 คอมโพเนนต์ 3 รายการได้รับการออกแบบมาเพื่อแพลตฟอร์มทีวีโดยเฉพาะ

  • Tuner HAL: อินเทอร์เฟซระหว่างเฟรมเวิร์กกับผู้ให้บริการ
  • Tuner SDK API: อินเทอร์เฟซระหว่างเฟรมเวิร์กกับแอป
  • เครื่องมือจัดการทรัพยากรของจูนเนอร์ (TRM): ประสานทรัพยากรฮาร์ดแวร์ของจูนเนอร์

สำหรับ Android 11 เราได้ปรับปรุงคอมโพเนนต์ต่อไปนี้

  • CAS V2
  • TvInputService หรือบริการอินพุตทีวี (TIS)
  • TvInputManagerService หรือบริการ TV Input Manager (TIMS)
  • MediaCodec หรือตัวแปลงรหัสสื่อ
  • AudioTrack หรือแทร็กเสียง
  • MediaResourceManager หรือเครื่องมือจัดการทรัพยากรสื่อ (MRM)

แผนภาพลำดับขั้นตอนของคอมโพเนนต์เฟรมเวิร์ก Tuner

รูปที่ 1 การโต้ตอบระหว่างคอมโพเนนต์ Android TV

ฟีเจอร์

ฟรอนต์เอนด์รองรับมาตรฐาน DTV ด้านล่าง

  • ATSC
  • ATSC3
  • DVB C/S/T
  • ISDB S/S3/T
  • แอนะล็อก

อินเทอร์เฟซส่วนหน้าใน Android 12 ที่มี Tuner HAL 1.1 ขึ้นไปรองรับมาตรฐาน DTV ด้านล่าง

  • DTMB

การแยกข้อมูลรองรับโปรโตคอลสตรีมด้านล่าง

  • สตรีมการนำส่ง (TS)
  • โปรโตคอลการนำส่งสื่อ MPEG (MMTP)
  • โปรโตคอลอินเทอร์เน็ต (IP)
  • ค่าความยาวประเภท (TLV)
  • โปรโตคอลเลเยอร์ลิงก์ ATSC (ALP)

โปรแกรมถอดรหัสรองรับการป้องกันเนื้อหาต่อไปนี้

  • เส้นทางสื่อที่ปลอดภัย
  • ล้างเส้นทางสื่อ
  • บันทึกในเครื่องที่ปลอดภัย
  • การเล่นในเครื่องที่ปลอดภัย

Tuner API รองรับกรณีการใช้งานด้านล่าง

  • สแกน
  • สด
  • การเล่น
  • บันทึก

Tuner, MediaCodec และ AudioTrack รองรับโหมดการไหลของข้อมูลด้านล่าง

  • เพย์โหลด ES ที่มีบัฟเฟอร์หน่วยความจําที่ล้างแล้ว
  • เพย์โหลด ES ที่มีแฮนเดิลหน่วยความจำที่ปลอดภัย
  • การแสดงภาพ

การออกแบบโดยรวม

HAL ของ Tuner จะกำหนดระหว่างเฟรมเวิร์ก Android กับฮาร์ดแวร์ของผู้ให้บริการ

  • อธิบายสิ่งที่เฟรมเวิร์กคาดหวังจากผู้ให้บริการและวิธีที่ผู้ให้บริการอาจดำเนินการ
  • ส่งออกฟังก์ชันการทำงานของส่วนหน้า โปรแกรมแยกข้อมูล และโปรแกรมถอดรหัสไปยังเฟรมเวิร์กผ่านอินเทอร์เฟซ IFrontend, IDemux, IDescrambler, IFilter, IDvr และ ILnb
  • มีฟังก์ชันในการผสานรวม HAL ของ Tuner กับคอมโพเนนต์เฟรมเวิร์กอื่นๆ เช่น MediaCodec และ AudioTrack

ระบบจะสร้างคลาส Java และคลาสเนทีฟของ Tuner

  • Tuner Java API อนุญาตให้แอปเข้าถึง Tuner HAL ผ่าน API สาธารณะ
  • คลาสเนทีฟช่วยให้ควบคุมสิทธิ์และจัดการข้อมูลการบันทึกหรือการเล่นจำนวนมากด้วย Tuner HAL ได้
  • โมดูล Tuner เดิมเป็นบริดจ์ระหว่างคลาส Java ของ Tuner กับ Tuner HAL

ระบบจะสร้างคลาส TRM

  • จัดการทรัพยากรจูนเนอร์ที่จำกัด เช่น ฟรอนเทนเอนด์, LNB, เซสชัน CAS และอุปกรณ์อินพุตทีวีจาก HAL อินพุตทีวี
  • ใช้กฎเพื่อเรียกคืนทรัพยากรที่ไม่เพียงพอจากแอป กฎเริ่มต้นคือโฟกัสอยู่เบื้องหน้าจะชนะ

Media CAS และ CAS HAL ได้รับการปรับปรุงด้วยฟีเจอร์ด้านล่าง

  • เปิดเซสชัน CAS สําหรับการใช้งานและอัลกอริทึมที่แตกต่างกัน
  • รองรับระบบ CAS แบบไดนามิก เช่น การนำ CICAM ออกและแทรก CICAM
  • ผสานรวมกับ Tuner HAL ด้วยการระบุโทเค็นคีย์

MediaCodec และ AudioTrack ได้รับการปรับปรุงด้วยฟีเจอร์ด้านล่าง

  • ใช้หน่วยความจำ A/V ที่ปลอดภัยเป็นอินพุตเนื้อหา
  • กำหนดค่าให้ทำการซิงค์ A/V ของฮาร์ดแวร์ในการเล่นแบบใช้อุโมงค์
  • กำหนดค่าการรองรับ ES_payload และโหมดการส่งผ่านแล้ว

การออกแบบโดยรวมของ HAL ตัวรับสัญญาณ

รูปที่ 2 แผนภาพส่วนประกอบภายใน HAL ของจูนเนอร์

เวิร์กโฟลว์โดยรวม

แผนภาพด้านล่างแสดงลําดับการเรียกใช้สําหรับการเล่นการถ่ายทอดสด

ตั้งค่า

ลำดับการตั้งค่าแผนภาพการเล่นสตรีมแบบสด

รูปที่ 3 ลำดับการตั้งค่าสำหรับการเล่นสตรีมแบบสด

การจัดการ A/V

แผนภาพการจัดการ A/V สำหรับการถ่ายทอดสด

รูปที่ 4 การจัดการ A/V สำหรับการถ่ายทอดสด

การจัดการเนื้อหาที่มีการสับเปลี่ยน

แผนภาพการจัดการเนื้อหาที่มีการสับเปลี่ยนสำหรับการเล่นสตรีมแบบสด

รูปที่ 5 การจัดการเนื้อหาที่มีการสับเปลี่ยนสำหรับการเล่นการถ่ายทอดสด

การประมวลผลข้อมูล A/V

ประมวลผลข้อมูล A/V สำหรับแผนภาพการเล่นการออกอากาศสด

รูปที่ 6 กำลังประมวลผล A/V สำหรับการถ่ายทอดสด

Tuner SDK API

Tuner SDK API จะจัดการการโต้ตอบกับ Tuner JNI, Tuner HAL และ TunerResourceManager แอป TIS ใช้ Tuner SDK API เพื่อเข้าถึงทรัพยากรและคอมโพเนนต์ย่อยของ Tuner เช่น ตัวกรองและโปรแกรมถอดรหัส ส่วนหน้าและตัวแยกสัญญาณเป็นคอมโพเนนต์ภายใน

แผนภาพโฟลว์ของ Tuner SDK API

รูปที่ 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

แผนภาพเวิร์กโฟลว์ของแพ็กเกจ Tuner SDK API

รูปที่ 8 แพ็กเกจ Tuner SDK API

Android.media.tv.tuner

แพ็กเกจ Tuner คือจุดแรกเข้าเพื่อใช้เฟรมเวิร์ก Tuner แอป TIS ใช้แพ็กเกจเพื่อเริ่มต้นและรับอินสแตนซ์ทรัพยากรโดยระบุการตั้งค่าเริ่มต้นและการเรียกกลับ

  • tuner(): เริ่มต้นอินสแตนซ์ Tuner โดยระบุพารามิเตอร์ useCase และ sessionId
  • tune(): รับทรัพยากรส่วนหน้าและปรับแต่งโดยระบุพารามิเตอร์ FrontendSetting
  • openFilter(): รับอินสแตนซ์ตัวกรองโดยระบุประเภทตัวกรอง
  • openDvrRecorder(): รับอินสแตนซ์การบันทึกโดยระบุขนาดบัฟเฟอร์
  • openDvrPlayback(): รับอินสแตนซ์การเล่นโดยระบุขนาดบัฟเฟอร์
  • openDescrambler(): รับอินสแตนซ์โปรแกรมถอดรหัส
  • openLnb(): รับอินสแตนซ์ LNB ภายใน
  • openLnbByName(): รับอินสแตนซ์ LNB ภายนอก
  • openTimeFilter(): รับอินสแตนซ์ตัวกรองเวลา

แพ็กเกจ Tuner มีฟังก์ชันการทำงานที่ไม่ครอบคลุมในแพ็กเกจตัวกรอง, 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() เพื่อหยุดการสแกนชั่วคราวหรือสิ้นสุดการสแกนได้

โฟลว์ชาร์ตของกระบวนการสแกน TIS

รูปที่ 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

ตั้งแต่ Android 12 ที่มี Tuner HAL 1.1 ขึ้นไป ระบบจะรองรับเหตุการณ์ต่อไปนี้

  • IpCidChangeEvent
  • RestartEvent
  • ScramblingStatusEvent
เหตุการณ์และรูปแบบข้อมูลจากตัวกรอง
ประเภทตัวกรอง ธง กิจกรรม การดำเนินการกับข้อมูล รูปแบบข้อมูล
TS.SECTION
MMTP.SECTION
IP.SECTION
TLV.SECTION
ALP.SECTION
isRaw:
true
ต้องระบุ:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

แนะนำ:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
เรียกใช้
Filter.read(buffer, offset, adjustedSize)อย่างน้อย 1 ครั้งตามเหตุการณ์และกำหนดเวลาภายใน

ระบบจะคัดลอกข้อมูลจาก MQ ของ HAL ไปยังบัฟเฟอร์ไคลเอ็นต์
แพ็กเกจเซสชันที่ประกอบขึ้น 1 รายการจะได้รับการบรรจุใน FMQ โดยแพ็กเกจเซสชันอื่น
isRaw:
false
ต้องระบุ:
DemuxFilterEvent::DemuxFilterSectionEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

ไม่บังคับ:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
for i=0; i<n; i++
Filter.read(buffer, offset, DemuxFilterSectionEven[i].size)


ระบบจะคัดลอกข้อมูลจาก MQ ของ HAL ไปยังบัฟเฟอร์ไคลเอ็นต์
TS.PES isRaw:
true
ต้องระบุ:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

แนะนำ:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
เรียกใช้
Filter.read(buffer, offset, adjustedSize)อย่างน้อย 1 ครั้งตามเหตุการณ์และกำหนดเวลาภายใน

ระบบจะคัดลอกข้อมูลจาก MQ ของ HAL ไปยังบัฟเฟอร์ไคลเอ็นต์
แพ็กเกจ PES ที่ประกอบแล้ว 1 รายการจะกรอกข้อมูลใน FMQ โดยแพ็กเกจ PES อื่น
isRaw:
false
ต้องระบุ:
DemuxFilterEvent::DemuxFilterPesEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

ไม่บังคับ:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
for i=0; i<n; i++
Filter.read(buffer, offset, DemuxFilterPesEven[i].size)


ระบบจะคัดลอกข้อมูลจาก MQ ของ HAL ไปยังบัฟเฟอร์ไคลเอ็นต์
MMTP.PES isRaw:
true
ต้องระบุ:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

แนะนำ:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
เรียกใช้
Filter.read(buffer, offset, adjustedSize)อย่างน้อย 1 ครั้งตามเหตุการณ์และกำหนดการภายใน

ระบบจะคัดลอกข้อมูลจาก MQ ของ HAL ไปยังบัฟเฟอร์ไคลเอ็นต์
แพ็กเกจ MFU ที่ประกอบแล้ว 1 รายการจะบรรจุใน FMQ โดยแพ็กเกจ MFU อื่น
isRaw:
false
ต้องระบุ:
DemuxFilterEvent::DemuxFilterPesEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

ไม่บังคับ:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
for i=0; i<n; i++
Filter.read(buffer, offset, DemuxFilterPesEven[i].size)


ระบบจะคัดลอกข้อมูลจาก 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:
true
ไม่บังคับ:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
ลูกค้าจะเริ่ม MediaCodec ได้หลังจากได้รับ DemuxFilterStatus::DATA_READY
ไคลเอ็นต์จะโทรหา Filter.flush ได้หลังจากได้รับ DemuxFilterStatus::DATA_OVERFLOW
ไม่มี
isPassthrough:
false
ต้องระบุ:
DemuxFilterEvent::DemuxFilterMediaEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

ไม่บังคับ:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
วิธีใช้ MediaCodec
for i=0; i<n; i++
linearblock = MediaEvent[i].getLinearBlock();
codec.startQueueLinearBlock(linearblock)
linearblock.recycle()


วิธีใช้เสียงโดยตรงของ AudioTrack
for i=0; i<n; i++
audioHandle = MediaEvent[i].getAudioHandle();
audiotrack.write(encapsulated(audiohandle))
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++
DemuxFilterTsRecordEvent[i];


สำหรับเนื้อหาที่บันทึกไว้ ให้ทำอย่างใดอย่างหนึ่งต่อไปนี้ตาม RecordStatus::* และกำหนดการภายใน
  • เรียกใช้ DvrRecord.write(adustedSize) อย่างน้อย 1 ครั้งไปยังพื้นที่เก็บข้อมูล
    ระบบจะโอนข้อมูลจาก MQ ของ HAL ไปยังพื้นที่เก็บข้อมูล
  • เรียกใช้ DvrRecord.write(buffer, adustedSize) อย่างน้อย 1 ครั้งเพื่อบัฟเฟอร์
    ระบบจะคัดลอกข้อมูลจาก MQ ของ HAL ไปยังบัฟเฟอร์ไคลเอ็นต์
สําหรับข้อมูลดัชนี: ระบุไว้ในเพย์โหลดของเหตุการณ์

สำหรับเนื้อหาที่บันทึกไว้: สตรีม 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++
DemuxFilterTemiEvent[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++
DemuxFilterMmtpRecordEvent[i];


สำหรับเนื้อหาที่บันทึกไว้ ให้ทำอย่างใดอย่างหนึ่งต่อไปนี้
    RecordStatus::*
  • เรียกใช้ DvrRecord.write(adjustedSize) อย่างน้อย 1 ครั้งเพื่อไปยังพื้นที่เก็บข้อมูล
    ระบบจะโอนข้อมูลจาก MQ ของ HAL ไปยังพื้นที่เก็บข้อมูล
  • เรียกใช้ DvrRecord.write(buffer, adjustedSize) อย่างน้อย 1 ครั้งเพื่อบัฟเฟอร์
    ระบบจะคัดลอกข้อมูลจาก MQ ของ HAL ไปยังบัฟเฟอร์ไคลเอ็นต์
สําหรับข้อมูลดัชนี: ระบุไว้ในเพย์โหลดของเหตุการณ์

สำหรับเนื้อหาที่บันทึกไว้: สตรีมที่บันทึกไว้ซึ่งมีการรวมข้อมูลใน 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)

ระบบจะคัดลอกข้อมูลจาก 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:
true
ไม่บังคับ:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
สตรีมย่อยของโปรโตคอลที่กรองออกจะส่งไปยังตัวกรองถัดไปในเชนตัวกรอง ไม่มี
isPassthrough:
false
ต้องระบุ:
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
Payload ของโปรโตคอลที่กรองออกจะส่งไปยังตัวกรองถัดไปในเชนตัวกรอง ไม่มี
ตัวอย่างขั้นตอนการใช้ตัวกรองเพื่อสร้าง PSI/SI

ตัวอย่างขั้นตอนการใช้ตัวกรองเพื่อสร้าง PSI/SI

รูปที่ 10 ขั้นตอนการสร้าง PSI/SI

  1. เปิดตัวกรอง

    Filter filter = tuner.openFilter(
      Filter.TYPE_TS,
      Filter.SUBTYPE_SECTION,
      /* bufferSize */1000,
      executor,
      filterCallback
    );
    
  2. กำหนดค่าและเริ่มตัวกรอง

    Settings settings = SectionSettingsWithTableInfo
        .builder(Filter.TYPE_TS)
        .setTableId(2)
        .setVersion(1)
        .setCrcEnabled(true)
        .setRaw(false)
        .setRepeat(false)
        .build();
      FilterConfiguration config = TsFilterConfiguration
        .builder()
        .setTpid(10)
        .setSettings(settings)
        .build();
      filter.configure(config);
      filter.start();
    
  3. กระบวนการ 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 จากตัวกรอง

ตัวอย่างขั้นตอนในการใช้ MediaEvent จากตัวกรอง

รูปที่ 11 ขั้นตอนในการใช้ MediaEvent จากตัวกรอง

  1. เปิด กำหนดค่า และเริ่มตัวกรอง A/V
  2. กระบวนการ MediaEvent
  3. รับ MediaEvent
  4. จัดคิวบล็อกเชิงเส้นไปยัง codec
  5. ปล่อยตัวแฮนเดิล 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 ขั้นตอนในการเริ่มบันทึก

  1. เปิด กำหนดค่า และเริ่ม DvrRecorder

    DvrRecorder recorder = openDvrRecorder(/* bufferSize */ 1000, executor, listener);
    DvrSettings dvrSettings = DvrSettings
    .builder()
    .setDataFormat(DvrSettings.DATA_FORMAT_TS)
    .setLowThreshold(100)
    .setHighThreshold(900)
    .setPacketSize(188)
    .build();
    recorder.configure(dvrSettings);
    recorder.attachFilter(filter);
    recorder.setFileDescriptor(fd);
    recorder.start();
    
  2. รับ 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. }
          }
        }
    };
    
  3. เริ่มต้น 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

โมดูล

Tuner 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

Tuner HAL 1.1 (มาจาก Tuner 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

แผนภาพขั้นตอนการทำงานของการโต้ตอบระหว่างโมดูลของ Tuner HAL

รูปที่ 13 แผนภาพการโต้ตอบระหว่างโมดูล HAL ของ Tuner

การลิงก์ตัวกรอง

HAL ของ Tuner รองรับการลิงก์ตัวกรองเพื่อให้ลิงก์ตัวกรองกับตัวกรองอื่นๆ สำหรับเลเยอร์หลายเลเยอร์ได้ โดยตัวกรองจะเป็นไปตามกฎด้านล่าง

  • ตัวกรองจะลิงก์กันเป็นโครงสร้างต้นไม้ ไม่อนุญาตให้ใช้เส้นทางปิด
  • โหนดรากคือ 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 โฟลว์ชาร์ตของการเชื่อมโยงตัวกรองสำหรับเลเยอร์หลายรายการ

เครื่องมือจัดการทรัพยากรของตัวรับสัญญาณ

ก่อนที่จะมีเครื่องมือจัดการทรัพยากรของจูนเนอร์ (TRM) การสลับระหว่าง 2 แอปต้องใช้ฮาร์ดแวร์จูนเนอร์เดียวกัน TV Input Framework (TIF) ใช้กลไก "ผู้ชนะที่เข้าถึงก่อน" ซึ่งหมายความว่าแอปใดก็ตามที่เข้าถึงทรัพยากรก่อนก็จะได้ทรัพยากรนั้น อย่างไรก็ตาม กลไกนี้อาจไม่เหมาะกับ Use Case บางรายการที่ซับซ้อน

TRM จะทำงานเป็นบริการของระบบเพื่อจัดการทรัพยากรฮาร์ดแวร์ของจูนเนอร์, TVInput และ CAS สำหรับแอป TRM ใช้กลไก "การทำงานในเบื้องหน้าจะชนะ" ซึ่งจะคำนวณลำดับความสำคัญของแอปตามสถานะการทำงานในเบื้องหน้าหรือเบื้องหลังของแอปและประเภท Use Case TRM จะมอบหรือเพิกถอนทรัพยากรตามลําดับความสําคัญ TRM จะจัดการทรัพยากร ATV จากศูนย์กลางสําหรับการออกอากาศ OTT และ DVR

อินเทอร์เฟซ TRM

TRM จะแสดงอินเทอร์เฟซ AIDL ใน ITunerResourceManager.aidl สำหรับเฟรมเวิร์ก Tuner, 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 ที่กําหนดไว้ล่วงหน้าที่ระบุไว้ด้านล่าง

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 เป็นเทมเพลตได้

ตัวอย่างเช่น กรณีการใช้งานของผู้ให้บริการรายใหม่คือ VENDOR_USE_CASE__[A-Z0-9]+, [0 - 1000] รูปแบบควรเป็นไปตาม platform/hardware/interfaces/tv/tuner/1.0/config/tunerResourceManagerUseCaseConfig.xsd

ค่าลําดับความสําคัญที่กําหนดเองและค่าที่แสดง

TRM มี updateClientPriority เพื่อให้ไคลเอ็นต์อัปเดตค่าลําดับความสําคัญและค่าที่แสดง ค่าลําดับความสําคัญที่กําหนดเองจะเขียนทับค่าลําดับความสําคัญที่คํานวณจากประเภท Use Case และรหัสเซสชัน

ค่า nice บ่งบอกถึงความยืดหยุ่นของลักษณะการทํางานของไคลเอ็นต์เมื่อขัดแย้งกับไคลเอ็นต์อื่น ค่าที่เหมาะสมจะลดค่าลําดับความสําคัญของลูกค้าก่อนที่จะเปรียบเทียบค่าลําดับความสําคัญกับลูกค้าที่ท้าทาย

กลไกการเรียกคืน

แผนภาพด้านล่างแสดงวิธีเรียกคืนและกำหนดทรัพยากรเมื่อมีความขัดแย้งเกี่ยวกับทรัพยากร

แผนภาพกระบวนการของกลไกการอ้างสิทธิ์

รูปที่ 15 แผนภาพกลไกการเรียกคืนสำหรับความขัดแย้งระหว่างทรัพยากรของ Tuner