עבור Android 11 ומעלה, אתה יכול להשתמש במסגרת Android Tuner כדי לספק תוכן A/V. המסגרת משתמשת בצינור החומרה של ספקים, מה שהופך אותה למתאימה ל-SoC ברמה נמוכה וגם ל-high-end. המסגרת מספקת דרך מאובטחת לספק תוכן A/V מוגן על ידי סביבת ביצוע מהימנה (TEE) ונתיב מדיה מאובטח (SMP), המאפשרת להשתמש בו בסביבת הגנה על תוכן מוגבלת ביותר.
הממשק הסטנדרטי בין Tuner ו-Android CAS מביא לאינטגרציה מהירה יותר בין ספקי Tuner וספקי CAS. ממשק הטיונר עובד עם MediaCodec
ו- AudioTrack
כדי לבנות פתרון של עולם אחד עבור Android TV. ממשק הטיונר תומך הן בטלוויזיה דיגיטלית והן בטלוויזיה אנלוגית המבוססת על תקני שידור עיקריים.
רכיבים
עבור אנדרואיד 11, שלושה רכיבים תוכננו במיוחד עבור פלטפורמת הטלוויזיה.
- Tuner HAL: ממשק בין המסגרת לספקים
- Tuner SDK API: ממשק בין המסגרת לאפליקציות
- מנהל משאבי טיונר (TRM): מתאם משאבי טיונר HW
עבור אנדרואיד 11, הרכיבים הבאים שופרו.
- CAS V2
-
TvInputService
או שירות קלט טלוויזיה (TIS) -
TvInputManagerService
או TV Input Manager Service (TIMS) -
MediaCodec
או MediaCodec -
AudioTrack
או רצועת אודיו -
MediaResourceManager
או מנהל משאבי מדיה (MRM)
איור 1. אינטראקציות בין רכיבי Android TV
מאפיינים
Frontend תומך בתקני DTV להלן.
- ATSC
- ATSC3
- DVB C/S/T
- ISDB S/S3/T
- אנלוגי
הקצה הקדמי באנדרואיד 12 עם Tuner HAL 1.1 ומעלה תומך בתקן DTV למטה.
- DTMB
Demux תומך בפרוטוקולי הזרם שלהלן.
- זרם תחבורה (TS)
- פרוטוקול העברת מדיה MPEG (MMTP)
- פרוטוקול אינטרנט (IP)
- ערך אורך סוג (TLV)
- פרוטוקול שכבת קישור ATSC (ALP)
Descrambler תומך בהגנות התוכן שלהלן.
- נתיב מדיה מאובטח
- נקה נתיב מדיה
- תיעוד מקומי מאובטח
- השמעה מקומית מאובטחת
ממשקי API של Tuner תומכים במקרי השימוש שלהלן.
- לִסְרוֹק
- לחיות
- השמעה
- תקליט
טיונר, MediaCodec
ו- AudioTrack
תומכים במצבי זרימת הנתונים שלהלן.
- מטען ES עם מאגר זיכרון נקי
- מטען ES עם ידית זיכרון מאובטחת
- עובר דרך
עיצוב כולל
ה-Tuner HAL מוגדר בין מסגרת האנדרואיד לבין החומרה של הספק.
- מתאר מה המסגרת מצפה מהספק וכיצד הספק עשוי לעשות זאת.
- מייצא את הפונקציונליות של Frontend, Demux ו-Descrambler למסגרת באמצעות ממשקי
IFrontend
,IDemux
,IDescrambler
,IFilter
,IDvr
ו-ILnb
. - כולל את הפונקציות לשילוב ה-Tuner HAL עם רכיבי מסגרת אחרים, כגון
MediaCodec
ו-AudioTrack
.
נוצרות מחלקה של Tuner Java ומחלקה מקורית.
- ה-API של Tuner Java מאפשר לאפליקציות לגשת ל-Tuner HAL דרך ממשקי API ציבוריים.
- מחלקה מקורית מאפשרת בקרת הרשאות וטיפול בכמויות גדולות של נתוני הקלטה או השמעה באמצעות Tuner HAL.
- מודול טיונר מקורי הוא גשר בין מחלקת הטיונר Java לבין הטיונר HAL.
נוצר כיתת TRM.
- מנהל משאבי טיונר מוגבלים, כגון הפעלות Frontend, LNB, CAS והתקן קלט טלוויזיה מכניסת הטלוויזיה HAL.
- מחיל כללים כדי להחזיר משאבים לא מספיקים מאפליקציות. כלל ברירת המחדל הוא הניצחון בחזית.
Media CAS ו-CAS HAL משופרים עם התכונות שלהלן.
- פותח הפעלות CAS עבור שימושים ואלגוריתמים שונים.
- תומך במערכות CAS דינמיות, כגון הסרה והכנסת CICAM.
- משתלב עם Tuner HAL על ידי מתן אסימוני מפתח.
MediaCodec
ו- AudioTrack
משופרים עם התכונות שלהלן.
- לוקח זיכרון A/V מאובטח כקלט תוכן.
- מוגדר לבצע סינכרון A/V של החומרה בהשמעה במנהור.
- תמיכה מוגדרת עבור
ES_payload
ומצב מעבר.
איור 2. תרשים של הרכיבים בתוך הטיונר HAL
זרימת עבודה כוללת
התרשימים להלן ממחישים רצפי שיחות להשמעת שידור חי.
להכין
איור 3. רצף הגדרה של השמעת שידור חי
טיפול ב-A/V
איור 4. טיפול ב-A/V עבור השמעת שידור חי
טיפול בתוכן מקושקש
איור 5. טיפול בתוכן מקושקש עבור השמעת שידור חי
עיבוד נתוני A/V
איור 6. עיבוד A/V עבור השמעת שידור חי
טיונר SDK API
ה-API של Tuner SDK מטפל באינטראקציות עם Tuner JNI, Tuner HAL ו- TunerResourceManager
. אפליקציית TIS משתמשת בממשק ה-API של Tuner SDK כדי לגשת למשאבי טיונר ולרכיבי משנה כגון המסנן וה-Descrambler. Frontend ו-demux הם רכיבים פנימיים.
איור 7. אינטראקציות עם ה-API של Tuner SDK
גרסאות
מאנדרואיד 12, ה-API של Tuner SDK תומך בתכונה חדשה ב-Tuner HAL 1.1, שהוא שדרוג גרסה תואמת לאחור של Tuner 1.0.
השתמש ב-API הבא כדי לבדוק את גרסת ה-HAL הפועלת.
-
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. חבילות API של Tuner SDK
Android.media.tv.tuner
חבילת הטיונר היא נקודת כניסה לשימוש במסגרת הטיונר. אפליקציית TIS משתמשת בחבילה כדי לאתחל ולרכוש מופעי משאבים על ידי ציון ההגדרה הראשונית והתקשרות חוזרת.
-
tuner()
: מאתחל מופע של Tuner על ידי ציון הפרמטריםuseCase
ו-sessionId
. -
tune()
: רוכש משאב קצה ומכוון על ידי ציון הפרמטרFrontendSetting
. -
openFilter()
: רוכש מופע מסנן על ידי ציון סוג המסנן. -
openDvrRecorder()
: רוכש מופע הקלטה על ידי ציון גודל המאגר. -
openDvrPlayback()
: רוכש מופע השמעה על ידי ציון גודל המאגר. -
openDescrambler()
: רוכש מופע Descrambler. -
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
מאנדרואיד 12 עם Tuner HAL 1.1 ומעלה, תקן ה-DTV הבא נתמך.
-
DtmbFrontendSettings
FrontendCapabilities
נגזרת עבור תקני DTV שונים לפי המעמדות שלהלן.
-
AnalogFrontendCapabilities
-
Atsc3FrontendCapabilities
-
AtscFrontendCapabilities
-
DvbcFrontendCapabilities
-
DvbsFrontendCapabilities
-
DvbtFrontendCapabilities
-
Isdbs3FrontendCapabilities
-
IsdbsFrontendCapabilities
-
IsdbtFrontendCapabilities
מאנדרואיד 12 עם Tuner HAL 1.1 ומעלה, תקן ה-DTV הבא נתמך.
-
DtmbFrontendCapabilities
FrontendInfo
מאחזר את המידע של ה-frontend. FrontendStatus
מאחזר את המצב הנוכחי של ה-frontend. 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 של הספק יכול לחפש את התדירות של ה-frontend שצוין על-ידי המשתמש כדי לקבל את המשאב ה-frontend, אז 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
אנדרואיד.media.tv.tuner.filter
חבילת הסינון היא אוסף של פעולות סינון יחד עם תצורה, הגדרות, התקשרויות חוזרות ואירועים. החבילה כוללת את הפעולות שלהלן. עיין בקוד המקור של אנדרואיד לקבלת רשימה מלאה של פעולות.
-
configure()
-
start()
-
stop()
-
flush()
-
read()
עיין בקוד המקור של אנדרואיד לרשימה המלאה.
FilterConfiguration
נגזר מהשיעורים שלהלן. התצורות מיועדות לסוג המסנן הראשי והן מציינות באיזה פרוטוקול המסנן משתמש כדי לחלץ נתונים.
-
AlpFilterConfiguration
-
IpFilterConfiguration
-
MmtpFilterConfiguration
-
TlvFilterConfiguration
-
TsFilterConfiguration
ההגדרות נגזרות מהשיעורים שלהלן. ההגדרות מיועדות לתת-סוג המסנן והן מציינות אילו סוגי נתונים המסנן יכול לא לכלול.
-
SectionSettings
-
AvSettings
-
PesSettings
-
RecordSettings
-
DownloadSettings
FilterEvent
נגזר מהשיעורים למטה כדי לדווח על אירועים עבור סוגים שונים של נתונים.
-
SectionEvent
-
MediaEvent
-
PesEvent
-
TsRecordEvent
-
MmtpRecordEvent
-
TemiEvent
-
DownloadEvent
-
IpPayloadEvent
מאנדרואיד 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) פעם אחת או יותר.הנתונים מועתקים מה-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) פעם אחת או יותר.הנתונים מועתקים מה-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) פעם אחת או יותר.הנתונים מועתקים מה-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) פעם אחת או יותר.הנתונים מועתקים מה-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 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++ | לא |
MMTP.MMTP | לא | חובה:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW מוּמלָץ: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | בהתאם לאירוע וללוח הזמנים הפנימי, רוץFilter.read(buffer, offset, adjustedSize) פעם אחת או יותר.הנתונים מועתקים מה-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 עם מעבר, לזרם המוקלט יש כותרת 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) פעם אחת או יותר.הנתונים מועתקים מה-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();
Process
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
ה-Tuner 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 |
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
קישור סינון
ה-Tuner HAL תומך בקישור מסננים כך שניתן לקשר מסננים למסננים אחרים עבור מספר שכבות. המסננים פועלים לפי הכללים הבאים.
- מסננים מקושרים כעץ, נתיב סגור אסור.
- צומת השורש הוא דמוקס.
- מסננים פועלים באופן עצמאי.
- כל המסננים מתחילים לקבל נתונים.
- הצמדת המסנן שוטפת את המסנן האחרון.
בלוק הקוד למטה ואיור 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), המעבר בין שתי אפליקציות הצריך את אותה חומרת הטיונר. TV Input Framework (TIF) השתמשה במנגנון "ראשון לרכישה", כלומר כל אפליקציה שמקבלת את המשאב תחילה שומרת על המשאב. עם זאת, מנגנון זה עשוי שלא להיות אידיאלי עבור מקרי שימוש מסובכים.
TRM פועל כשירות מערכת לניהול משאבי החומרה של Tuner, TVInput
ו-CAS עבור אפליקציות. TRM משתמש במנגנון "ניצחון בחזית", אשר מחשב את עדיפות האפליקציה על סמך מצב החזית או הרקע של האפליקציה וסוג מקרה השימוש. TRM מעניק או מבטל את המשאב על סמך העדיפות. TRM מרכזת את ניהול משאבי הטרקטורונים עבור שידור, 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
מציין את מקרה השימוש של ההפעלה. מקרי השימוש המוגדרים מראש מפורטים להלן.
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
.
ערך עדיפות שרירותי וערך נחמד
TRM מספקת updateClientPriority
ללקוח כדי לעדכן את ערך העדיפות השרירותי ואת הערך הנחמד. ערך העדיפות השרירותי מחליף את ערך העדיפות המחושב לפי סוג מקרה השימוש ומזהה ההפעלה.
הערך הנחמד מציין עד כמה התנהגות הלקוח מקלה כאשר היא מסוכסכת עם לקוח אחר. הערך הנחמד מוריד את ערך העדיפות של הלקוח לפני שערך העדיפות שלו מושווה ללקוח המאתגר.
מנגנון תביעה חוזר
התרשים שלהלן מראה כיצד משאבים חוזרים ומוקצים כאשר מתרחשת התנגשות משאבים.
איור 15. תרשים של מנגנון החזרה להתנגשות בין משאבי הטיונר