aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2020-02-06 23:50:44 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2020-02-06 23:50:44 +0000
commit01a12d7b0af5dd9a7ab2c45ca9eb66e5cda53fe2 (patch)
treefc22dff71a71eabe598f6507e98e64888a6bccfd
parenta6b53117805483bf6a46eb24c75454bc9f74785f (diff)
parentb58662836aa2feb0b8b387a843f820be50972bff (diff)
downloadTV-01a12d7b0af5dd9a7ab2c45ca9eb66e5cda53fe2.tar.gz
Merge "Add support for captions track in ExoV2" am: 3cb6f5ea67 am: b58662836a
Change-Id: I2e4e899f05a7fe18daf2e618f5529cb869f50bde
-rw-r--r--libs/Android.bp6
-rwxr-xr-xlibs/exoplayer-ui-2.10.1.aarbin0 -> 267537 bytes
-rw-r--r--tuner/Android.bp1
-rw-r--r--tuner/SampleDvbTuner/Android.bp1
-rw-r--r--tuner/SampleDvbTuner/build.gradle1
-rw-r--r--tuner/SampleNetworkTuner/Android.bp1
-rw-r--r--tuner/SampleNetworkTuner/build.gradle1
-rw-r--r--tuner/build.gradle1
-rw-r--r--tuner/src/com/android/tv/tuner/cc/CaptionTrackRenderer.java24
-rw-r--r--tuner/src/com/android/tv/tuner/cc/CaptionWindowLayout.java120
-rw-r--r--tuner/src/com/android/tv/tuner/exoplayer2/MpegTsPlayerV2.java75
-rw-r--r--tuner/tests/robotests/javatests/com/android/tv/tuner/tvinput/TunerSessionWorkerExoV2Test.java8
-rw-r--r--tuner/tests/robotests/javatests/com/android/tv/tuner/tvinput/TunerSessionWorkerTest.java8
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
new file mode 100755
index 00000000..09b4a2b0
--- /dev/null
+++ b/libs/exoplayer-ui-2.10.1.aar
Binary files differ
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,