diff options
author | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2020-02-06 23:50:44 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2020-02-06 23:50:44 +0000 |
commit | 01a12d7b0af5dd9a7ab2c45ca9eb66e5cda53fe2 (patch) | |
tree | fc22dff71a71eabe598f6507e98e64888a6bccfd | |
parent | a6b53117805483bf6a46eb24c75454bc9f74785f (diff) | |
parent | b58662836aa2feb0b8b387a843f820be50972bff (diff) | |
download | TV-01a12d7b0af5dd9a7ab2c45ca9eb66e5cda53fe2.tar.gz |
Merge "Add support for captions track in ExoV2" am: 3cb6f5ea67 am: b58662836a
Change-Id: I2e4e899f05a7fe18daf2e618f5529cb869f50bde
-rw-r--r-- | libs/Android.bp | 6 | ||||
-rwxr-xr-x | libs/exoplayer-ui-2.10.1.aar | bin | 0 -> 267537 bytes | |||
-rw-r--r-- | tuner/Android.bp | 1 | ||||
-rw-r--r-- | tuner/SampleDvbTuner/Android.bp | 1 | ||||
-rw-r--r-- | tuner/SampleDvbTuner/build.gradle | 1 | ||||
-rw-r--r-- | tuner/SampleNetworkTuner/Android.bp | 1 | ||||
-rw-r--r-- | tuner/SampleNetworkTuner/build.gradle | 1 | ||||
-rw-r--r-- | tuner/build.gradle | 1 | ||||
-rw-r--r-- | tuner/src/com/android/tv/tuner/cc/CaptionTrackRenderer.java | 24 | ||||
-rw-r--r-- | tuner/src/com/android/tv/tuner/cc/CaptionWindowLayout.java | 120 | ||||
-rw-r--r-- | tuner/src/com/android/tv/tuner/exoplayer2/MpegTsPlayerV2.java | 75 | ||||
-rw-r--r-- | tuner/tests/robotests/javatests/com/android/tv/tuner/tvinput/TunerSessionWorkerExoV2Test.java | 8 | ||||
-rw-r--r-- | tuner/tests/robotests/javatests/com/android/tv/tuner/tvinput/TunerSessionWorkerTest.java | 8 |
13 files changed, 216 insertions, 31 deletions
diff --git a/libs/Android.bp b/libs/Android.bp index 7c41f4ea..6c768fcb 100644 --- a/libs/Android.bp +++ b/libs/Android.bp @@ -115,6 +115,12 @@ android_library_import { sdk_version: "current", } +android_library_import { + name: "tv-lib-exoplayer-v2-ui", + aars: ["exoplayer-ui-2.10.1.aar"], + sdk_version: "current", +} + java_import_host { name: "tv-lib-dagger-compiler-import", jars: [ diff --git a/libs/exoplayer-ui-2.10.1.aar b/libs/exoplayer-ui-2.10.1.aar Binary files differnew file mode 100755 index 00000000..09b4a2b0 --- /dev/null +++ b/libs/exoplayer-ui-2.10.1.aar diff --git a/tuner/Android.bp b/tuner/Android.bp index 343c784c..bbafef2e 100644 --- a/tuner/Android.bp +++ b/tuner/Android.bp @@ -38,6 +38,7 @@ android_library { "tv-lib-dagger", "tv-lib-exoplayer", "tv-lib-exoplayer-v2-core", + "tv-lib-exoplayer-v2-ui", "tv-lib-dagger-android", ], plugins: [ diff --git a/tuner/SampleDvbTuner/Android.bp b/tuner/SampleDvbTuner/Android.bp index 21cfd67c..29a177fe 100644 --- a/tuner/SampleDvbTuner/Android.bp +++ b/tuner/SampleDvbTuner/Android.bp @@ -33,6 +33,7 @@ android_app { "tv-lib-dagger", "tv-lib-exoplayer", "tv-lib-exoplayer-v2-core", + "tv-lib-exoplayer-v2-ui", "tv-lib-dagger-android", "live-channels-partner-support", ], diff --git a/tuner/SampleDvbTuner/build.gradle b/tuner/SampleDvbTuner/build.gradle index 8efd2260..47534cfb 100644 --- a/tuner/SampleDvbTuner/build.gradle +++ b/tuner/SampleDvbTuner/build.gradle @@ -66,6 +66,7 @@ dependencies { implementation 'androidx.palette:palette:1.0.0' implementation 'androidx.tvprovider:tvprovider:1.0.0' + implementation 'com.google.android.exoplayer:exoplayer-ui:2.10.1' annotationProcessor 'com.google.auto.value:auto-value:1.5.3' implementation 'com.google.auto.value:auto-value:1.5.3' implementation 'com.google.dagger:dagger:2.23' diff --git a/tuner/SampleNetworkTuner/Android.bp b/tuner/SampleNetworkTuner/Android.bp index 5bb77d06..4c2b344e 100644 --- a/tuner/SampleNetworkTuner/Android.bp +++ b/tuner/SampleNetworkTuner/Android.bp @@ -33,6 +33,7 @@ android_app { "tv-lib-dagger", "tv-lib-exoplayer", "tv-lib-exoplayer-v2-core", + "tv-lib-exoplayer-v2-ui", "tv-lib-dagger-android", "live-channels-partner-support", ], diff --git a/tuner/SampleNetworkTuner/build.gradle b/tuner/SampleNetworkTuner/build.gradle index eabcd8f3..95322347 100644 --- a/tuner/SampleNetworkTuner/build.gradle +++ b/tuner/SampleNetworkTuner/build.gradle @@ -66,6 +66,7 @@ dependencies { implementation 'androidx.palette:palette:1.0.0' implementation 'androidx.tvprovider:tvprovider:1.0.0' + implementation 'com.google.android.exoplayer:exoplayer-ui:2.10.1' annotationProcessor 'com.google.auto.value:auto-value:1.5.3' implementation 'com.google.auto.value:auto-value:1.5.3' implementation 'com.google.dagger:dagger:2.23' diff --git a/tuner/build.gradle b/tuner/build.gradle index 36d55b0a..349176b2 100644 --- a/tuner/build.gradle +++ b/tuner/build.gradle @@ -74,6 +74,7 @@ dependencies { implementation 'com.google.android.exoplayer:exoplayer:r1.5.16' api 'com.google.android.exoplayer:exoplayer-core:2.10.1' + implementation 'com.google.android.exoplayer:exoplayer-ui:2.10.1' annotationProcessor 'com.google.auto.factory:auto-factory:1.0-beta7' implementation 'com.google.auto.factory:auto-factory:1.0-beta7' implementation 'com.google.dagger:dagger:2.23' diff --git a/tuner/src/com/android/tv/tuner/cc/CaptionTrackRenderer.java b/tuner/src/com/android/tv/tuner/cc/CaptionTrackRenderer.java index dc371212..a5d139ad 100644 --- a/tuner/src/com/android/tv/tuner/cc/CaptionTrackRenderer.java +++ b/tuner/src/com/android/tv/tuner/cc/CaptionTrackRenderer.java @@ -20,6 +20,8 @@ import android.os.Handler; import android.os.Message; import android.util.Log; import android.view.View; + +import com.android.tv.common.flags.TunerFlags; import com.android.tv.tuner.data.Cea708Data.CaptionEvent; import com.android.tv.tuner.data.Cea708Data.CaptionPenAttr; import com.android.tv.tuner.data.Cea708Data.CaptionPenColor; @@ -28,10 +30,12 @@ import com.android.tv.tuner.data.Cea708Data.CaptionWindow; import com.android.tv.tuner.data.Cea708Data.CaptionWindowAttr; import com.android.tv.tuner.data.Cea708Parser; import com.android.tv.tuner.data.Track.AtscCaptionTrack; +import com.google.android.exoplayer2.text.Cue; import com.google.auto.factory.AutoFactory; import com.google.auto.factory.Provided; import java.util.ArrayList; +import java.util.List; /** Decodes and renders CEA-708. */ public class CaptionTrackRenderer implements Handler.Callback { @@ -62,6 +66,7 @@ public class CaptionTrackRenderer implements Handler.Callback { private final CaptionLayout mCaptionLayout; private final CaptionWindowLayout.Factory mCaptionWindowLayoutFactory; + private final TunerFlags mTunerFlags; private boolean mIsDelayed = false; private CaptionWindowLayout mCurrentWindowLayout; private final CaptionWindowLayout[] mCaptionWindowLayouts = @@ -82,10 +87,12 @@ public class CaptionTrackRenderer implements Handler.Callback { @AutoFactory(implementing = Factory.class) public CaptionTrackRenderer( CaptionLayout captionLayout, - @Provided CaptionWindowLayout.Factory captionWindowLayoutFactory) { + @Provided CaptionWindowLayout.Factory captionWindowLayoutFactory, + @Provided TunerFlags tunerFlags) { mCaptionLayout = captionLayout; mHandler = new Handler(this); mCaptionWindowLayoutFactory = captionWindowLayoutFactory; + mTunerFlags = tunerFlags; } @Override @@ -129,7 +136,11 @@ public class CaptionTrackRenderer implements Handler.Callback { } switch (event.type) { case Cea708Parser.CAPTION_EMIT_TYPE_BUFFER: - sendBufferToCurrentWindow((String) event.obj); + if (mTunerFlags.useExoplayerV2()) { + sendCuesToCurrentWindow((List<Cue>) event.obj); + } else { + sendBufferToCurrentWindow((String) event.obj); + } break; case Cea708Parser.CAPTION_EMIT_TYPE_CONTROL: sendControlToCurrentWindow((char) event.obj); @@ -328,6 +339,15 @@ public class CaptionTrackRenderer implements Handler.Callback { } } + private void sendCuesToCurrentWindow(List<Cue> cues){ + if (mCurrentWindowLayout != null) { + mCurrentWindowLayout.setCues(cues); + mHandler.removeMessages(MSG_CAPTION_CLEAR); + mHandler.sendMessageDelayed( + mHandler.obtainMessage(MSG_CAPTION_CLEAR), CAPTION_CLEAR_INTERVAL_MS); + } + } + private void sendBufferToCurrentWindow(String buffer) { if (mCurrentWindowLayout != null) { mCurrentWindowLayout.sendBuffer(buffer); diff --git a/tuner/src/com/android/tv/tuner/cc/CaptionWindowLayout.java b/tuner/src/com/android/tv/tuner/cc/CaptionWindowLayout.java index 8a8916c7..4f3623f8 100644 --- a/tuner/src/com/android/tv/tuner/cc/CaptionWindowLayout.java +++ b/tuner/src/com/android/tv/tuner/cc/CaptionWindowLayout.java @@ -39,6 +39,8 @@ import android.view.accessibility.CaptioningManager; import android.view.accessibility.CaptioningManager.CaptionStyle; import android.view.accessibility.CaptioningManager.CaptioningChangeListener; import android.widget.RelativeLayout; + +import com.android.tv.common.flags.TunerFlags; import com.android.tv.tuner.data.Cea708Data.CaptionPenAttr; import com.android.tv.tuner.data.Cea708Data.CaptionPenColor; import com.android.tv.tuner.data.Cea708Data.CaptionWindow; @@ -46,12 +48,15 @@ import com.android.tv.tuner.data.Cea708Data.CaptionWindowAttr; import com.android.tv.tuner.exoplayer.text.SubtitleView; import com.android.tv.tuner.layout.ScaledLayout; import com.google.android.exoplayer.text.CaptionStyleCompat; +import com.google.android.exoplayer2.text.Cue; import com.google.auto.factory.AutoFactory; +import com.google.auto.factory.Provided; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; /** @@ -92,9 +97,11 @@ public class CaptionWindowLayout extends RelativeLayout implements View.OnLayout private CaptionLayout mCaptionLayout; private CaptionStyleCompat mCaptionStyleCompat; + private com.google.android.exoplayer2.text.CaptionStyleCompat mCaptionStyleCompatExoV2; // TODO: Replace SubtitleView to {@link com.google.android.exoplayer.text.SubtitleLayout}. private final SubtitleView mSubtitleView; + private final com.google.android.exoplayer2.ui.SubtitleView mSubtitleViewExoV2; private int mRowLimit = 0; private final SpannableStringBuilder mBuilder = new SpannableStringBuilder(); private final List<CharacterStyle> mCharacterStyles = new ArrayList<>(); @@ -107,12 +114,19 @@ public class CaptionWindowLayout extends RelativeLayout implements View.OnLayout private int mLastCaptionLayoutHeight; private int mWindowJustify; private int mPrintDirection; + private final TunerFlags mTunerFlags; private class SystemWideCaptioningChangeListener extends CaptioningChangeListener { @Override public void onUserStyleChanged(CaptionStyle userStyle) { - mCaptionStyleCompat = CaptionStyleCompat.createFromCaptionStyle(userStyle); - mSubtitleView.setStyle(mCaptionStyleCompat); + if (mTunerFlags.useExoplayerV2()) { + mCaptionStyleCompatExoV2 = com.google.android.exoplayer2.text.CaptionStyleCompat + .createFromCaptionStyle(userStyle); + mSubtitleViewExoV2.setStyle(mCaptionStyleCompatExoV2); + } else { + mCaptionStyleCompat = CaptionStyleCompat.createFromCaptionStyle(userStyle); + mSubtitleView.setStyle(mCaptionStyleCompat); + } updateWidestChar(); } @@ -134,32 +148,46 @@ public class CaptionWindowLayout extends RelativeLayout implements View.OnLayout } @AutoFactory(implementing = Factory.class) - public CaptionWindowLayout(Context context) { - this(context, null); + public CaptionWindowLayout(Context context, @Provided TunerFlags tunerFlags) { + this(context, null, tunerFlags); } - public CaptionWindowLayout(Context context, AttributeSet attrs) { - this(context, attrs, 0); + public CaptionWindowLayout(Context context, AttributeSet attrs, TunerFlags tunerFlags) { + this(context, attrs, 0, tunerFlags); } - public CaptionWindowLayout(Context context, AttributeSet attrs, int defStyleAttr) { + public CaptionWindowLayout( + Context context, + AttributeSet attrs, + int defStyleAttr, + TunerFlags tunerFlags) { super(context, attrs, defStyleAttr); - // Add a subtitle view to the layout. - mSubtitleView = new SubtitleView(context); + mTunerFlags = tunerFlags; LayoutParams params = new RelativeLayout.LayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); - addView(mSubtitleView, params); - // Set the system wide cc preferences to the subtitle view. CaptioningManager captioningManager = (CaptioningManager) context.getSystemService(Context.CAPTIONING_SERVICE); mFontScale = captioningManager.getFontScale(); - mCaptionStyleCompat = - CaptionStyleCompat.createFromCaptionStyle(captioningManager.getUserStyle()); - mSubtitleView.setStyle(mCaptionStyleCompat); - mSubtitleView.setText(""); + + // Add a subtitle view to the layout. + mSubtitleViewExoV2 = new com.google.android.exoplayer2.ui.SubtitleView(context); + mSubtitleView = new SubtitleView(context); + if (mTunerFlags.useExoplayerV2()) { + addView(mSubtitleViewExoV2, params); + mCaptionStyleCompatExoV2 = + com.google.android.exoplayer2.text.CaptionStyleCompat + .createFromCaptionStyle(captioningManager.getUserStyle()); + mSubtitleViewExoV2.setStyle(mCaptionStyleCompatExoV2); + } else { + addView(mSubtitleView, params); + mCaptionStyleCompat = + CaptionStyleCompat.createFromCaptionStyle(captioningManager.getUserStyle()); + mSubtitleView.setStyle(mCaptionStyleCompat); + mSubtitleView.setText(""); + } captioningManager.addCaptioningChangeListener(new SystemWideCaptioningChangeListener()); updateWidestChar(); } @@ -361,7 +389,7 @@ public class CaptionWindowLayout extends RelativeLayout implements View.OnLayout switch (horizontalMode) { case ANCHOR_HORIZONTAL_MODE_LEFT: gravity = Gravity.LEFT; - mSubtitleView.setTextAlignment(Alignment.ALIGN_NORMAL); + setCaptionsTextAlignment(Alignment.ALIGN_NORMAL); scaleStartCol = scaleCol; break; case ANCHOR_HORIZONTAL_MODE_CENTER: @@ -379,7 +407,9 @@ public class CaptionWindowLayout extends RelativeLayout implements View.OnLayout widestTextBuilder.append(mWidestChar); } Paint paint = new Paint(); - paint.setTypeface(mCaptionStyleCompat.typeface); + if (!mTunerFlags.useExoplayerV2()) { + paint.setTypeface(mCaptionStyleCompat.typeface); + } paint.setTextSize(mTextSize); float maxWindowWidth = paint.measureText(widestTextBuilder.toString()); float halfMaxWidthScale = @@ -391,7 +421,7 @@ public class CaptionWindowLayout extends RelativeLayout implements View.OnLayout // caption window multiplied by average alphabets char width, then align the // left side of the window with the left side of the expected max window. gravity = Gravity.LEFT; - mSubtitleView.setTextAlignment(Alignment.ALIGN_NORMAL); + setCaptionsTextAlignment(Alignment.ALIGN_NORMAL); scaleStartCol = scaleCol - halfMaxWidthScale; scaleEndCol = 1.0f; } else { @@ -402,14 +432,14 @@ public class CaptionWindowLayout extends RelativeLayout implements View.OnLayout // The anchor point is located at the horizontal center of the window in both // cases. gravity = Gravity.CENTER_HORIZONTAL; - mSubtitleView.setTextAlignment(Alignment.ALIGN_CENTER); + setCaptionsTextAlignment(Alignment.ALIGN_CENTER); scaleStartCol = scaleCol - gap; scaleEndCol = scaleCol + gap; } break; case ANCHOR_HORIZONTAL_MODE_RIGHT: gravity = Gravity.RIGHT; - mSubtitleView.setTextAlignment(Alignment.ALIGN_OPPOSITE); + setCaptionsTextAlignment(Alignment.ALIGN_OPPOSITE); scaleEndCol = scaleCol; break; } @@ -440,7 +470,7 @@ public class CaptionWindowLayout extends RelativeLayout implements View.OnLayout setGravity(gravity); setWindowStyle(captionWindow.windowStyle); if (mWindowJustify == CaptionWindowAttr.JUSTIFY_CENTER) { - mSubtitleView.setTextAlignment(Alignment.ALIGN_CENTER); + setCaptionsTextAlignment(Alignment.ALIGN_CENTER); } if (captionWindow.visible) { show(); @@ -487,7 +517,9 @@ public class CaptionWindowLayout extends RelativeLayout implements View.OnLayout mWidestChar = KOR_ALPHABET; } else { Paint paint = new Paint(); - paint.setTypeface(mCaptionStyleCompat.typeface); + if (!mTunerFlags.useExoplayerV2()) { + paint.setTypeface(mCaptionStyleCompat.typeface); + } Charset latin1 = Charset.forName("ISO-8859-1"); float widestCharWidth = 0f; for (int i = 0; i < 256; ++i) { @@ -502,6 +534,27 @@ public class CaptionWindowLayout extends RelativeLayout implements View.OnLayout updateTextSize(); } + private void setCaptionsTextAlignment(Alignment textAlignment){ + if (mTunerFlags.useExoplayerV2()){ + switch (textAlignment) { + case ALIGN_NORMAL: + mSubtitleViewExoV2.setTextAlignment(View.TEXT_ALIGNMENT_INHERIT); + break; + case ALIGN_OPPOSITE: + mSubtitleViewExoV2.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_END); + break; + case ALIGN_CENTER: + mSubtitleViewExoV2.setTextAlignment(View.TEXT_ALIGNMENT_CENTER); + break; + default: + mSubtitleViewExoV2.setTextAlignment(View.TEXT_ALIGNMENT_INHERIT); + break; + } + } else { + mSubtitleView.setTextAlignment(textAlignment); + } + } + private void updateTextSize() { if (mCaptionLayout == null) return; @@ -513,7 +566,9 @@ public class CaptionWindowLayout extends RelativeLayout implements View.OnLayout } String widestText = widestTextBuilder.toString(); Paint paint = new Paint(); - paint.setTypeface(mCaptionStyleCompat.typeface); + if (!mTunerFlags.useExoplayerV2()) { + paint.setTypeface(mCaptionStyleCompat.typeface); + } float startFontSize = 0f; float endFontSize = 255f; Rect boundRect = new Rect(); @@ -536,8 +591,13 @@ public class CaptionWindowLayout extends RelativeLayout implements View.OnLayout mTextSize = endFontSize * mFontScale; paint.setTextSize(mTextSize); float whiteSpaceWidth = paint.measureText(" "); - mSubtitleView.setWhiteSpaceWidth(whiteSpaceWidth); - mSubtitleView.setTextSize(mTextSize); + + if (mTunerFlags.useExoplayerV2()) { + mSubtitleViewExoV2.setFixedTextSize(0, mTextSize); + } else { + mSubtitleView.setWhiteSpaceWidth(whiteSpaceWidth); + mSubtitleView.setTextSize(mTextSize); + } } private int getScreenColumnCount() { @@ -577,7 +637,15 @@ public class CaptionWindowLayout extends RelativeLayout implements View.OnLayout public void clearText() { mBuilder.clear(); - mSubtitleView.setText(""); + if (mTunerFlags.useExoplayerV2()) { + mSubtitleViewExoV2.setCues(Collections.emptyList()); + } else { + mSubtitleView.setText(""); + } + } + + public void setCues(List<Cue> cues) { + mSubtitleViewExoV2.setCues(cues); } private void updateText(String text, boolean appended) { diff --git a/tuner/src/com/android/tv/tuner/exoplayer2/MpegTsPlayerV2.java b/tuner/src/com/android/tv/tuner/exoplayer2/MpegTsPlayerV2.java index 4af8c809..d27f4878 100644 --- a/tuner/src/com/android/tv/tuner/exoplayer2/MpegTsPlayerV2.java +++ b/tuner/src/com/android/tv/tuner/exoplayer2/MpegTsPlayerV2.java @@ -26,6 +26,7 @@ import android.view.Surface; import com.android.tv.common.SoftPreconditions; import com.android.tv.tuner.data.Cea708Data; import com.android.tv.tuner.data.Cea708Data.CaptionEvent; +import com.android.tv.tuner.data.Cea708Parser; import com.android.tv.tuner.data.TunerChannel; import com.android.tv.tuner.source.TsDataSource; import com.android.tv.tuner.source.TsDataSourceManager; @@ -44,6 +45,8 @@ import com.google.android.exoplayer2.source.MediaSource; import com.google.android.exoplayer2.source.ProgressiveMediaSource; import com.google.android.exoplayer2.source.TrackGroup; import com.google.android.exoplayer2.source.TrackGroupArray; +import com.google.android.exoplayer2.text.Cue; +import com.google.android.exoplayer2.text.TextOutput; import com.google.android.exoplayer2.trackselection.DefaultTrackSelector; import com.google.android.exoplayer2.trackselection.MappingTrackSelector.MappedTrackInfo; import com.google.android.exoplayer2.trackselection.TrackSelection; @@ -53,12 +56,14 @@ import com.google.android.exoplayer2.video.VideoRendererEventListener; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.util.List; /** MPEG-2 TS stream player implementation using ExoPlayer2. */ public class MpegTsPlayerV2 implements Player.EventListener, VideoListener, AudioListener, + TextOutput, VideoRendererEventListener { /** Interface definition for a callback to be notified of changes in player state. */ @@ -124,9 +129,9 @@ public class MpegTsPlayerV2 private final Context mContext; private final SimpleExoPlayer mPlayer; private final DefaultTrackSelector mTrackSelector; - private final DefaultTrackSelector.Parameters mTrackSelectorParameters; private final TsDataSourceManager mSourceManager; + private DefaultTrackSelector.Parameters mTrackSelectorParameters; private TrackGroupArray mLastSeenTrackGroupArray; private Callback mCallback; private TsDataSource mDataSource; @@ -150,6 +155,7 @@ public class MpegTsPlayerV2 mPlayer.addListener(this); mPlayer.addVideoListener(this); mPlayer.addAudioListener(this); + mPlayer.addTextOutput(this); mSourceManager = sourceManager; mCallback = callback; } @@ -170,6 +176,54 @@ public class MpegTsPlayerV2 */ public void setCaptionServiceNumber(int captionServiceNumber) { mCaptionServiceNumber = captionServiceNumber; + if (captionServiceNumber == Cea708Data.EMPTY_SERVICE_NUMBER) return; + MappedTrackInfo mappedTrackInfo = mTrackSelector.getCurrentMappedTrackInfo(); + if (mappedTrackInfo != null) { + int rendererCount = mappedTrackInfo.getRendererCount(); + for (int rendererIndex = 0; rendererIndex < rendererCount; rendererIndex++) { + if (mappedTrackInfo.getRendererType(rendererIndex) == C.TRACK_TYPE_TEXT) { + TrackGroupArray trackGroupArray = mappedTrackInfo.getTrackGroups(rendererIndex); + for (int i = 0; i < trackGroupArray.length; i++) { + int readServiceNumber = + trackGroupArray.get(i).getFormat(0).accessibilityChannel; + int serviceNumber = + readServiceNumber == Format.NO_VALUE ? 1 : readServiceNumber; + if (serviceNumber == captionServiceNumber) { + setSelectedTrack(TRACK_TYPE_TEXT, i); + } + } + } + } + } + } + + /** + * Invoked each time there is a change in the {@link Cue}s to be rendered + * + * @param cues The {@link Cue}s to be rendered, or an empty list if no cues are to be rendered. + */ + @Override + public void onCues(List<Cue> cues) { + mVideoEventListener.onEmitCaptionEvent( + new CaptionEvent( + Cea708Parser.CAPTION_EMIT_TYPE_COMMAND_DFX, + new Cea708Data.CaptionWindow( + /* id= */ 0, + /* visible= */ true, + /* rowlock= */ false, + /* columnLock= */ false, + /* priority= */ 3, + /* relativePositioning= */ true, + /* anchorVertical= */ 0, + /* anchorHorizontal= */ 0, + /* anchorId= */ 0, + /* rowCount= */ 0, + /* columnCount= */ 0, + /* penStyle= */ 0, + /* windowStyle= */ 2))); + mVideoEventListener.onEmitCaptionEvent( + new CaptionEvent(Cea708Parser.CAPTION_EMIT_TYPE_BUFFER, + cues)); } /** @@ -314,6 +368,24 @@ public class MpegTsPlayerV2 if (trackGroups != mLastSeenTrackGroupArray) { mLastSeenTrackGroupArray = trackGroups; } + if (mVideoEventListener != null) { + MappedTrackInfo mappedTrackInfo = mTrackSelector.getCurrentMappedTrackInfo(); + if (mappedTrackInfo != null) { + int rendererCount = mappedTrackInfo.getRendererCount(); + for (int rendererIndex = 0; rendererIndex < rendererCount; rendererIndex++) { + if (mappedTrackInfo.getRendererType(rendererIndex) == C.TRACK_TYPE_TEXT) { + TrackGroupArray trackGroupArray = + mappedTrackInfo.getTrackGroups(rendererIndex); + for (int i = 0; i < trackGroupArray.length; i++) { + int serviceNumber = + trackGroupArray.get(i).getFormat(0).accessibilityChannel; + mVideoEventListener.onDiscoverCaptionServiceNumber( + serviceNumber == Format.NO_VALUE ? 1 : serviceNumber); + } + } + } + } + } } /** @@ -362,6 +434,7 @@ public class MpegTsPlayerV2 return; } TrackGroupArray trackGroupArray = mappedTrackInfo.getTrackGroups(rendererIndex); + mTrackSelectorParameters = mTrackSelector.getParameters(); DefaultTrackSelector.SelectionOverride override = new DefaultTrackSelector.SelectionOverride(trackIndex, 0); DefaultTrackSelector.ParametersBuilder builder = diff --git a/tuner/tests/robotests/javatests/com/android/tv/tuner/tvinput/TunerSessionWorkerExoV2Test.java b/tuner/tests/robotests/javatests/com/android/tv/tuner/tvinput/TunerSessionWorkerExoV2Test.java index e43b726b..6ef09182 100644 --- a/tuner/tests/robotests/javatests/com/android/tv/tuner/tvinput/TunerSessionWorkerExoV2Test.java +++ b/tuner/tests/robotests/javatests/com/android/tv/tuner/tvinput/TunerSessionWorkerExoV2Test.java @@ -32,6 +32,7 @@ import com.android.tv.common.CommonPreferences; import com.android.tv.common.compat.TvInputConstantCompat; import com.android.tv.common.customization.CustomizationManager; import com.android.tv.common.flags.impl.DefaultLegacyFlags; +import com.android.tv.common.flags.impl.DefaultTunerFlags; import com.android.tv.testing.TestSingletonApp; import com.android.tv.testing.constants.ConfigConstants; import com.android.tv.tuner.cc.CaptionTrackRenderer; @@ -69,11 +70,13 @@ public class TunerSessionWorkerExoV2Test { private MpegTsPlayerV2 mPlayer = Mockito.mock(MpegTsPlayerV2.class); private Handler mHandler; private DefaultLegacyFlags mLegacyFlags; + private DefaultTunerFlags mTunerFlags; @Before public void setUp() throws NoSuchFieldException, IllegalAccessException { Application context = RuntimeEnvironment.application; mLegacyFlags = DefaultLegacyFlags.DEFAULT; + mTunerFlags = new DefaultTunerFlags(); CaptioningManager captioningManager = Mockito.mock(CaptioningManager.class); // TODO (b/65160115) @@ -101,7 +104,10 @@ public class TunerSessionWorkerExoV2Test { new TunerSessionOverlay( context1, captionLayout -> - new CaptionTrackRenderer(captionLayout, context2 -> null)); + new CaptionTrackRenderer( + captionLayout, + context2 -> null, + mTunerFlags)); new TunerSessionExoV2( context, diff --git a/tuner/tests/robotests/javatests/com/android/tv/tuner/tvinput/TunerSessionWorkerTest.java b/tuner/tests/robotests/javatests/com/android/tv/tuner/tvinput/TunerSessionWorkerTest.java index 938dae0b..b1a8fef1 100644 --- a/tuner/tests/robotests/javatests/com/android/tv/tuner/tvinput/TunerSessionWorkerTest.java +++ b/tuner/tests/robotests/javatests/com/android/tv/tuner/tvinput/TunerSessionWorkerTest.java @@ -32,6 +32,7 @@ import com.android.tv.common.CommonPreferences; import com.android.tv.common.compat.TvInputConstantCompat; import com.android.tv.common.customization.CustomizationManager; import com.android.tv.common.flags.impl.DefaultLegacyFlags; +import com.android.tv.common.flags.impl.DefaultTunerFlags; import com.android.tv.testing.TestSingletonApp; import com.android.tv.testing.constants.ConfigConstants; import com.android.tv.tuner.cc.CaptionTrackRenderer; @@ -69,12 +70,14 @@ public class TunerSessionWorkerTest { private MpegTsPlayer mPlayer = Mockito.mock(MpegTsPlayer.class); private Handler mHandler; private DefaultLegacyFlags mLegacyFlags; + private DefaultTunerFlags mTunerFlags; @Before public void setUp() throws NoSuchFieldException, IllegalAccessException { Application context = RuntimeEnvironment.application; CaptioningManager captioningManager = Mockito.mock(CaptioningManager.class); mLegacyFlags = DefaultLegacyFlags.DEFAULT; + mTunerFlags = new DefaultTunerFlags(); // TODO (b/65160115) Field field = CustomizationManager.class.getDeclaredField("sCustomizationPackage"); @@ -100,7 +103,10 @@ public class TunerSessionWorkerTest { new TunerSessionOverlay( context1, captionLayout -> - new CaptionTrackRenderer(captionLayout, context2 -> null)); + new CaptionTrackRenderer( + captionLayout, + context2 -> null, + mTunerFlags)); new TunerSession( context, |