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

สำหรับ 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: อินเทอร์เฟซระหว่างเฟรมเวิร์กกับแอป
  • Tuner Resource Manager (TRM): ทรัพยากร HW ของตัวรับสัญญาณสำหรับพิกัด

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

  • CAS V2
  • TvInputService หรือบริการอินพุตทีวี (TIS)
  • TvInputManagerService หรือบริการโปรแกรมจัดการอินพุตทีวี (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 ที่มีแฮนเดิลหน่วยความจำที่ปลอดภัย
  • การแสดงภาพ

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

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

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

จะมีการสร้างคลาส Java ตัวรับสัญญาณและคลาสเนทีฟ

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

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

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

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

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

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

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

การออกแบบโดยรวมของ Tuner HAL

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

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

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

ตั้งค่า

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

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

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

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

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

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

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

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

กำลังประมวลผลข้อมูล A/V

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

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

API ของตัวรับสัญญาณ SDK

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

แผนภาพลำดับการทำงานของ 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 ใช้แพ็กเกจเพื่อเริ่มต้นและรับอินสแตนซ์ทรัพยากรด้วยการระบุการตั้งค่าเริ่มต้นและ Callback

  • tuner(): เริ่มต้นอินสแตนซ์ 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 ในการสแกน 1 ครั้ง และส่ง 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 ไปยังบัฟเฟอร์ไคลเอ็นต์
แพ็กเกจเซสชันที่ประกอบแล้วหนึ่งแพ็กเกจจะมีการเติม 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 แบบ Muxed ที่ได้รับการตอบสนองเป็น 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
กรองฟีดเพย์โหลดโปรโตคอลออกซึ่งตัวกรองถัดไปในสายตัวกรอง ไม่มี
ตัวอย่างขั้นตอนการใช้ตัวกรองเพื่อสร้าง 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

โมดูล

ตัวรับสัญญาณ 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

แผนภาพโฟลว์ของการโต้ตอบระหว่างโมดูลของตัวรับสัญญาณ HAL

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

การเชื่อมโยงตัวกรอง

Tuner 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 แอปจะต้องใช้ฮาร์ดแวร์ตัวรับสัญญาณเดียวกัน 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
}

ไฟล์การกำหนดค่า

ไฟล์การกําหนดค่าเริ่มต้น

ไฟล์การกําหนดค่าเริ่มต้นด้านล่างแสดงค่าลําดับความสําคัญสําหรับ Use Case ที่กําหนดไว้ล่วงหน้า ผู้ใช้จะเปลี่ยนค่าได้โดยใช้ไฟล์การกำหนดค่าที่กำหนดเอง

กรณีการใช้งาน เบื้องหน้า ฉากหลัง
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 เป็นเทมเพลตได้

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

ให้คุณค่าลำดับความสำคัญได้เองและคุ้มราคา

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

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

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

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

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

รูปที่ 15 แผนภาพของกลไกการอ้างสิทธิ์ซ้ำสำหรับความขัดแย้งระหว่างทรัพยากรของตัวรับสัญญาณ