ב-Android מגרסה 11 ואילך, אפשר להשתמש במסגרת Android Tuner כדי להציג תוכן אודיו/וידאו. המסגרת משתמשת בצינור הנתונים של החומרה מהספקים, ולכן היא מתאימה ל-SoC ברמה נמוכה וברמה גבוהה. המסגרת מספקת דרך מאובטחת להעברת תוכן אודיו/וידאו שמוגן על ידי סביבת ביצוע מהימנה (TEE) ונתיב מדיה מאובטח (SMP), ולכן אפשר להשתמש בה בסביבה מוגבלת מאוד להגנה על תוכן.
הממשק המתוקנן בין Tuner לבין Android CAS מאפשר שילוב מהיר יותר בין ספקי Tuner לבין ספקי CAS. ממשק הכוונון פועל עם MediaCodec
ועם AudioTrack
כדי ליצור פתרון עולמי ל-Android TV.
ממשק הכוונון תומך בטלוויזיה דיגיטלית ובטלוויזיה אנלוגית על סמך תקני שידור עיקריים.
רכיבים
ב-Android 11, יש שלושה רכיבים שתוכננו במיוחד לפלטפורמת הטלוויזיה.
- Tuner HAL: ממשק בין המסגרת לספקים
- Tuner SDK API: ממשק בין המסגרת לבין האפליקציות
- Tuner Resource Manager (TRM): מתאם משאבי חומרה של מקלט
ב-Android 11, הרכיבים הבאים שופרו:
- CAS V2
-
TvInputService
או שירות קלט לטלוויזיה (TIS) -
TvInputManagerService
או TV Input Manager Service (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 תומך בפרוטוקולים הבאים של סטרימינג.
- Transport stream (TS)
- פרוטוקול להעברת מדיה MPEG (MMTP)
- פרוטוקול אינטרנט (IP)
- ערך אורך הסוג (TLV)
- פרוטוקול שכבת הקישור (ALP) של ATSC
מפענח התוכן תומך באמצעי ההגנה על התוכן שמופיעים בהמשך.
- נתיב מאובטח של מדיה
- ניקוי נתיב המדיה
- הקלטה מאובטחת של שיחות מקומיות
- הפעלה מאובטחת של קבצים מקומיים
ממשקי Tuner API תומכים בתרחישי השימוש הבאים.
- סריקה
- בשידור חי
- הפעלה
- הקלטה
הכלים Tuner, MediaCodec
ו-AudioTrack
תומכים במצבי זרימת הנתונים שמופיעים בהמשך.
- מטען ייעודי (payload) של ES עם מאגר נתונים זמני ברור בזיכרון
- מטען ייעודי (payload) של ES עם טיפול בזיכרון מאובטח
- שקופה
עיצוב כללי
ה-HAL של הכלי Tuner מוגדר בין מסגרת Android לבין החומרה של הספק.
- מתאר מה נדרש מהספק במסגרת התקנים ואיך הספק יכול לעשות זאת.
- מייצא את הפונקציות של חזית האתר, מפענח ה-demux ומפענח ה-descrambler אל המסגרת באמצעות הממשקים
IFrontend
,IDemux
,IDescrambler
,IFilter
,IDvr
ו-ILnb
. - כולל את הפונקציות לשילוב של Tuner HAL עם רכיבים אחרים של המסגרת, כמו
MediaCodec
ו-AudioTrack
.
נוצרות מחלקת Java ומחלקה מקורית של Tuner.
- ממשק Tuner Java API מאפשר לאפליקציות לגשת ל-Tuner HAL דרך ממשקי API ציבוריים.
- המחלקות המקוריות מאפשרות שליטה בהרשאות וטיפול בכמויות גדולות של נתוני הקלטה או הפעלה באמצעות Tuner HAL.
- מודול Native Tuner הוא גשר בין מחלקת Tuner Java לבין Tuner HAL.
נוצרת כיתת TRM.
- מנהל משאבי כוונון מוגבלים, כמו Frontend, LNB, סשנים של CAS ומכשיר קלט לטלוויזיה מ-HAL של קלט לטלוויזיה.
- החלת כללים להחזרת משאבים לא מספיקים מאפליקציות. כלל ברירת המחדל הוא שהצבע הקדמי מנצח.
התכונות הבאות משפרות את Media CAS ואת CAS HAL.
- פתיחת סשנים של CAS לשימושים ולאלגוריתמים שונים.
- תמיכה במערכות CAS דינמיות, כמו הסרה והוספה של CICAM.
- הוא משתלב עם Tuner HAL על ידי אספקת אסימוני מפתח.
MediaCodec
ו-AudioTrack
משופרים באמצעות התכונות הבאות.
- מקבל זיכרון מאובטח של אודיו ווידאו כקלט תוכן.
- מוגדר לבצע סנכרון של אודיו ווידאו בחומרה בהפעלה במנהור.
- הגדרת תמיכה ב-
ES_payload
ובמצב מעבר.
איור 2. תרשים של הרכיבים ב-Tuner HAL
תהליך העבודה הכולל
בתרשימים הבאים אפשר לראות את רצפי הקריאות להפעלה של שידור חי.
הגדרה
איור 3. הגדרת רצף להפעלת שידור חי
טיפול באודיו/בווידאו
איור 4. טיפול באודיו ובווידאו בהפעלת שידור חי
טיפול בתוכן מבולבל
איור 5. טיפול בתוכן מקושקש להפעלה בשידור חי
עיבוד נתוני אודיו ווידאו
איור 6. עיבוד של אודיו ווידאו להפעלת שידור חי
Tuner SDK API
ממשק ה-API של Tuner SDK מטפל באינטראקציות עם Tuner JNI, Tuner HAL ו-TunerResourceManager
. אפליקציית TIS משתמשת ב-Tuner SDK API כדי לגשת למשאבי Tuner ולרכיבי משנה כמו המסנן וה-descrambler. ה-Frontend וה-demux הם רכיבים פנימיים.
איור 7. אינטראקציות עם Tuner SDK API
גרסאות
מ-Android 12, ה-API של Tuner SDK תומך בתכונה חדשה ב-Tuner HAL 1.1, שהיא שדרוג של Tuner 1.0 עם תאימות לאחור.
כדי לבדוק את גרסת ה-HAL שפועלת, משתמשים ב-API הבא.
android.media.tv.tuner.TunerVersionChecker.getTunerVersion()
אפשר למצוא את גרסת ה-HAL המינימלית הנדרשת במסמכים של ממשקי ה-API החדשים של Android 12.
חבילות
ממשק ה-API של Tuner SDK מספק את ארבעת החבילות הבאות.
android.media.tv.tuner
android.media.tv.tuner.frontend
android.media.tv.tuner.filter
android.media.tv.tuner.dvr
איור 8. חבילות Tuner SDK API
Android.media.tv.tuner
חבילת Tuner היא נקודת כניסה לשימוש ב-Tuner framework. אפליקציית TIS משתמשת בחבילה כדי לאתחל ולקבל מופעי משאבים על ידי ציון ההגדרה הראשונית והקריאה החוזרת.
-
tuner()
: מאתחל מופע של Tuner על ידי ציון הפרמטריםuseCase
ו-sessionId
. -
tune()
: מקבלים משאב ומכוונים אותו על ידי ציון הפרמטרFrontendSetting
. -
openFilter()
: מקבל מופע של מסנן על ידי ציון סוג המסנן. -
openDvrRecorder()
: מקבלים מופע הקלטה על ידי ציון גודל המאגר. -
openDvrPlayback()
: מקבל מופע הפעלה על ידי ציון גודל המאגר. -
openDescrambler()
: קבלת מופע של מפענח. -
openLnb()
: קבלת מופע פנימי של מאזן עומסים. -
openLnbByName()
: קבלת מופע LNB חיצוני. -
openTimeFilter()
: מקבל מופע של מסנן זמן.
חבילת Tuner מספקת פונקציות שלא נכללות בחבילות filter, DVR ו-frontend. הפונקציות מפורטות בהמשך.
cancelTuning
-
scan
מתוךcancelScanning
getAvSyncHwId
getAvSyncTime
-
connectCiCam1
מתוךdisconnectCiCam
shareFrontendFromTuner
updateResourcePriority
setOnTuneEventListener
setResourceLostListener
Android.media.tv.tuner.frontend
חבילת ה-frontend כוללת אוספים של הגדרות, מידע, סטטוסים, אירועים ויכולות שקשורים ל-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 קורא 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 קורא Tuner.scan(AUTO_SCAN)
שוב עד שכל התדרים מוצו.
במהלך הסריקה, אפשר להתקשר אל stopScan()
או אל close()
כדי להשהות או לסיים את הסריקה.
Tuner.scan(BLIND_SCAN)
אם ל-TIS אין רשימת תדרים ו-Vendor HAL יכול לחפש את התדר של הקצה הקדמי שצוין על ידי המשתמש כדי לקבל את משאב הקצה הקדמי, מומלץ להשתמש ב-Tuner.scan(BLIND_SCAN)
.
- ב-TIS נעשה שימוש ב-
Tuner.scan(BLIND_SCAN)
. אפשר לציין תדירות ב-FrontendSettings
לתדירות התחלה, אבל TIS מתעלם מהגדרות אחרות ב-FrontendSettings
. - אם האות נעול, ה-HAL מדווח על הודעת סריקה
LOCKED
. - TIS משתמשת ב-
Frontend.getStatus
כדי לאסוף את המידע הנדרש. - TIS מתקשר
Tuner.scan
שוב כדי להמשיך בסריקה. (המערכת מתעלמת מFrontendSettings
). - הכלי TIS חוזר על הפעולות שלמעלה עד שכל ההגדרות בתדירות מסוימת מושלמות. ה-HAL מגדיל את התדירות בלי שתידרש פעולה מצד TIS.
דוחות HAL
PROGRESS
.
ה-TIS קורא Tuner.scan(AUTO_SCAN)
שוב עד שכל התדרים מוצו.
ה-HAL מדווח על END
כדי לציין שפעולת הסריקה הסתיימה.
במהלך הסריקה, אפשר להתקשר אל stopScan()
או אל close()
כדי להשהות או לסיים את הסריקה.
איור 9. תרשים זרימה של סריקת TIS
Android.media.tv.tuner.filter
חבילת המסננים היא אוסף של פעולות סינון, יחד עם הגדרות, קריאות חוזרות ואירועים. החבילה כוללת את הפעולות הבאות. רשימה מלאה של הפעולות זמינה בקוד המקור של Android.
configure()
start()
stop()
flush()
read()
הרשימה המלאה מופיעה בקוד המקור של Android.
הציון FilterConfiguration
מחושב על סמך הציונים בכיתות שלמטה. ההגדרות הן לסוג המסנן הראשי, והן מציינות באיזה פרוטוקול המסנן משתמש כדי לחלץ נתונים.
AlpFilterConfiguration
IpFilterConfiguration
MmtpFilterConfiguration
TlvFilterConfiguration
TsFilterConfiguration
ההגדרות נגזרות מהכיתות שמופיעות בהמשך. ההגדרות מתייחסות לסוג המשנה של המסנן ומציינות אילו סוגי נתונים המסנן יכול להחריג.
SectionSettings
AvSettings
PesSettings
RecordSettings
DownloadSettings
FilterEvent
נגזר מהמחלקות שבהמשך כדי לדווח על אירועים עבור סוגים שונים של נתונים.
SectionEvent
MediaEvent
PesEvent
TsRecordEvent
MmtpRecordEvent
TemiEvent
DownloadEvent
IpPayloadEvent
מגרסה 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) פעם אחת או יותר.הנתונים מועתקים מ-HAL MQ למאגר הלקוח. |
חבילת סשן אחת שהורכבה מתמלאת ב-FMQ על ידי חבילת סשן אחרת. |
isRaw: |
מאפיינים חובה:DemuxFilterEvent::DemuxFilterSectionEvent[n] DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW מאפיינים אופציונליים: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
for i=0; i<n; i++ הנתונים מועתקים מ-HAL MQ למאגר הלקוח. |
||
TS.PES |
isRaw: |
חובה:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW מומלץ: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
בהתאם לאירוע וללוח הזמנים הפנימי, מריצים אתFilter.read(buffer, offset, adjustedSize) פעם אחת או יותר.הנתונים מועתקים מ-HAL's MQ למאגר הלקוח. |
חבילת PES אחת מורכבת מלאה ב-FMQ על ידי חבילת PES אחרת. |
isRaw: |
מאפיינים חובה:DemuxFilterEvent::DemuxFilterPesEvent[n] DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW מאפיינים אופציונליים: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
for i=0; i<n; i++ הנתונים מועתקים מ-HAL's MQ למאגר הלקוח. |
||
MMTP.PES |
isRaw: |
חובה:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW מומלץ: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
בהתאם לאירוע וללוח הזמנים הפנימי, מריצים אתFilter.read(buffer, offset, adjustedSize) פעם אחת או יותר.הנתונים מועתקים מ-HAL MQ למאגר הלקוח. |
חבילת MFU אחת מלאה ב-FMQ על ידי חבילת MFU אחרת. |
isRaw: |
מאפיינים חובה:DemuxFilterEvent::DemuxFilterPesEvent[n] DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW מאפיינים אופציונליים: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
for i=0; i<n; i++ הנתונים מועתקים מ-HAL's MQ למאגר הלקוח. |
||
TS.TS |
לא רלוונטי | חובה:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW מומלץ: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
בהתאם לאירוע וללוח הזמנים הפנימי, מריצים אתFilter.read(buffer, offset, adjustedSize) פעם אחת או יותר.הנתונים מועתקים מ-HAL MQ למאגר הלקוח. |
הסינון בוצע ts עם ts כותרתמלאה ב-FMQ. |
TS.Audio TS.Video MMTP.Audio MMTP.Video |
isPassthrough: |
אופציונלי:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW |
הלקוח יכול להתחיל 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::* ולתזמון הפנימי, מבצעים
אחת מהפעולות הבאות:
|
לגבי נתוני אינדקס: נכללים במטען הייעודי (payload) של האירוע. לתוכן מוקלט: זרם Muxed TS שמולא ב-FMQ. |
TS.TEMI |
לא רלוונטי | חובה:DemuxFilterEvent::DemuxFilterTemiEvent[n] אופציונלי: DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
for i=0; i<n; i++ |
לא רלוונטי |
MMTP.MMTP |
לא רלוונטי | חובה:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW מומלץ: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
בהתאם לאירוע וללוח הזמנים הפנימי, מריצים אתFilter.read(buffer, offset, adjustedSize) פעם אחת או יותר.הנתונים מועתקים מ-HAL MQ למאגר הלקוח. |
הסינון בוצע mmtp עם mmtp כותרתמלאה ב-FMQ. |
MMTP.RECORD |
לא רלוונטי | חובה:DemuxFilterEvent::DemuxFilterMmtpRecordEvent[n] RecordStatus::DATA_READY RecordStatus::DATA_OVERFLOW RecordStatus::LOW_WATER RecordStatus::HIGH_WATER אופציונלי: DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
לנתוני אינדקס: for i=0; i<n; i++ לתוכן מוקלט, בהתאם ל RecordStatus::* ולתזמון הפנימי, מבצעים אחת מהפעולות הבאות:
|
לגבי נתוני אינדקס: נכללים במטען הייעודי (payload) של האירוע. לתוכן מוקלט: סטרימינג מוקלט עם אודיו וסרטון משולבים, מלא ב-FMQ. FMQ. אם מקור הסינון להקלטה הוא TLV.TLV עד IP.IP עם העברה, לזרם המוקלט יש TLV וכותרת IP. |
MMTP.DOWNLOAD |
לא רלוונטי | מאפיינים חובה:DemuxFilterEvent::DemuxFilterDownloadEvent[n] DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW מאפיינים אופציונליים: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
for i=0; i<n; i++
Filter.read(buffer, offset, DemuxFilterDownloadEvent[i].size) הנתונים מועתקים מ-HAL's MQ למאגר הלקוח. |
חבילת ההורדה מתמלאת ב-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) הנתונים מועתקים מ-HAL's MQ למאגר הלקוח. |
חבילת מטען ייעודי (payload) של IP מתמלאת ב-FMQ על ידי חבילת מטען ייעודי (payload) אחרת של IP. |
IP.IP TLV.TLV ALP.ALP |
isPassthrough: |
אופציונלי:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW |
הפידים של זרמי המשנה של הפרוטוקול שסוננו מוזנים למסנן הבא בשרשרת המסננים filter. | לא רלוונטי |
isPassthrough: |
חובה:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW מומלץ: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
בהתאם לאירוע וללוח הזמנים הפנימי, מריצים אתFilter.read(buffer, offset, adjustedSize) פעם אחת או יותר.הנתונים מועתקים מ-HAL MQ למאגר הלקוח. |
הסינון של נתוני המשנה של הפרוטוקול עם כותרת הפרוטוקול הושלם FMQ. | |
IP.PAYLOAD_THROUGH TLV.PAYLOAD_THROUGH ALP.PAYLOAD_THROUGH |
לא רלוונטי | אופציונלי:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW |
הפידים של מטען הייעודי (payload) של הפרוטוקול שסוננו מוזנים למסנן הבא בשרשרת המסננים. | לא רלוונטי |
תרשים זרימה לדוגמה לשימוש במסנן כדי ליצור 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. Flow to use MediaEvent from filter
- פותחים את המסננים של האודיו והווידאו, מגדירים אותם ומתחילים להשתמש בהם.
- עיבוד
MediaEvent
. - קבלת
MediaEvent
. - הוספת הבלוק הליניארי לתור של
codec
. - משחררים את ה-handle של האודיו והווידאו אחרי שהנתונים נצרכים.
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); } } };
Tuner HAL
ה-HAL של הכרטיס הדיגיטלי לשידור (Tuner) פועל לפי 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 |
איור 13. תרשים של האינטראקציות בין מודולי Tuner HAL
קישור סינון
ה-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. תרשים זרימה של קישור מסנן למספר שכבות
Tuner Resource Manager
לפני Tuner Resource Manager (TRM), כדי לעבור בין שתי אפליקציות היה צריך להשתמש באותו חומרה של מקלט. ב-TV Input Framework (TIF) נעשה שימוש במנגנון 'הראשון זוכה', כלומר האפליקציה שמקבלת את המשאב ראשונה שומרת אותו. עם זאת, יכול להיות שהמנגנון הזה לא יתאים לתרחישי שימוש מורכבים.
ה-TRM פועל כשירות מערכת לניהול המשאבים של הכרטיס לשידורי טלוויזיה, TVInput
וחומרת ה-CAS באפליקציות. הכלי לניהול תנועה משתמש במנגנון 'ניצחון במצב פעיל', שמחשב את העדיפות של האפליקציה על סמך הסטטוס שלה (פעילה או ברקע) וסוג תרחיש השימוש. מערכת TRM מעניקה או מבטלת את הגישה למשאב על סמך העדיפות. TRM מרכז את ניהול המשאבים של ATV לשידור, ל-OTT ול-DVR.
ממשק TRM
TRM חושף ממשקי AIDL ב-ITunerResourceManager.aidl
עבור Tuner Framework, 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
מציין את תרחיש השימוש בסשן. תרחישי השימוש המוגדרים מראש מפורטים בהמשך.
TvInputService.PriorityHintUseCaseType {
PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK
PRIORITY_HINT_USE_CASE_TYPE_LIVE
PRIORITY_HINT_USE_CASE_TYPE_RECORD,
PRIORITY_HINT_USE_CASE_TYPE_SCAN,
PRIORITY_HINT_USE_CASE_TYPE_BACKGROUND
}
קובץ תצורה
קובץ תצורה שמוגדר כברירת מחדל
קובץ ההגדרות שמוגדר כברירת מחדל שמופיע בהמשך מספק ערכי עדיפות לתרחישי שימוש מוגדרים מראש. המשתמשים יכולים לשנות את הערכים באמצעות קובץ תצורה בהתאמה אישית.
תרחיש לדוגמה | חזית | רקע |
---|---|---|
LIVE |
490 | 400 |
PLAYBACK |
480 | 300 |
RECORD |
600 | 500 |
SCAN |
450 | 200 |
BACKGROUND |
180 | 100 |
קובץ הגדרות בהתאמה אישית
ספקים יכולים להתאים אישית את קובץ ההגדרות /vendor/etc/tunerResourceManagerUseCaseConfig.xml
. הקובץ הזה משמש להוספה, להסרה או לעדכון של סוגי תרחישי השימוש וערכי העדיפות של תרחישי השימוש.
אפשר להשתמש בקובץ המותאם אישית בתור תבנית ב-platform/hardware/interfaces/tv/tuner/1.0/config/tunerResourceManagerUseCaseConfigSample.xml
.
לדוגמה, תרחיש שימוש של ספק חדש הוא VENDOR_USE_CASE__[A-Z0-9]+, [0 - 1000]
.
הפורמט צריך להיות platform/hardware/interfaces/tv/tuner/1.0/config/tunerResourceManagerUseCaseConfig.xsd
.
ערך עדיפות שרירותי וערך nice
ה-TRM מספק updateClientPriority
ללקוח כדי לעדכן את ערך העדיפות השרירותי ואת ערך ה-nice.
ערך העדיפות השרירותי מחליף את ערך העדיפות שחושב לפי סוג תרחיש השימוש ומזהה הסשן.
הערך nice מציין עד כמה ההתנהגות של הלקוח סלחנית כשהיא מתנגשת עם התנהגות של לקוח אחר. ערך ה-nice מקטין את ערך העדיפות של הלקוח לפני שערך העדיפות שלו מושווה לערך העדיפות של הלקוח המאתגר.
מנגנון ההחזרה
בתרשים הבא מוצג איך המערכת משחררת משאבים ומקצה אותם מחדש כשמתרחש קונפליקט משאבים.
איור 15. דיאגרמה של מנגנון ההחזרה של משאבי Tuner במקרה של קונפליקט