@@ -125,6 +125,7 @@ public final class TextRenderer extends BaseRenderer implements Callback {
125125 private long outputStreamOffsetUs ;
126126 private long lastRendererPositionUs ;
127127 private long finalStreamEndPositionUs ;
128+ private boolean legacyDecodingEnabled ;
128129
129130 /**
130131 * @param output The output.
@@ -163,6 +164,7 @@ public TextRenderer(
163164 finalStreamEndPositionUs = C .TIME_UNSET ;
164165 outputStreamOffsetUs = C .TIME_UNSET ;
165166 lastRendererPositionUs = C .TIME_UNSET ;
167+ legacyDecodingEnabled = true ;
166168 }
167169
168170 @ Override
@@ -172,6 +174,10 @@ public String getName() {
172174
173175 @ Override
174176 public @ Capabilities int supportsFormat (Format format ) {
177+ // TODO: b/289983417 - Return UNSUPPORTED for non-media3-queues once we stop supporting them
178+ // completely. In the meantime, we return SUPPORTED here and then throw later if
179+ // legacyDecodingEnabled is false (when receiving the first Format or sample). This ensures
180+ // apps are aware (via the playback failure) they're using a legacy/deprecated code path.
175181 if (isCuesWithTiming (format ) || subtitleDecoderFactory .supportsFormat (format )) {
176182 return RendererCapabilities .create (
177183 format .cryptoType == C .CRYPTO_TYPE_NONE ? C .FORMAT_HANDLED : C .FORMAT_UNSUPPORTED_DRM );
@@ -206,6 +212,7 @@ protected void onStreamChanged(
206212 outputStreamOffsetUs = offsetUs ;
207213 streamFormat = formats [0 ];
208214 if (!isCuesWithTiming (streamFormat )) {
215+ assertLegacyDecodingEnabledIfRequired ();
209216 if (subtitleDecoder != null ) {
210217 decoderReplacementState = REPLACEMENT_STATE_SIGNAL_END_OF_STREAM ;
211218 } else {
@@ -258,10 +265,30 @@ public void render(long positionUs, long elapsedRealtimeUs) {
258265 checkNotNull (cuesResolver );
259266 renderFromCuesWithTiming (positionUs );
260267 } else {
268+ assertLegacyDecodingEnabledIfRequired ();
261269 renderFromSubtitles (positionUs );
262270 }
263271 }
264272
273+ /**
274+ * Sets whether to decode subtitle data during rendering.
275+ *
276+ * <p>If this is enabled, then the {@link SubtitleDecoderFactory} passed to the constructor is
277+ * used to decode subtitle data during rendering.
278+ *
279+ * <p>If this is disabled this text renderer can only handle tracks with MIME type {@link
280+ * MimeTypes#APPLICATION_MEDIA3_CUES} (which have been parsed from their original format during
281+ * extraction), and will throw an exception if passed data of a different type.
282+ *
283+ * <p>This is enabled by default.
284+ *
285+ * <p>This method is experimental. It may change behavior, be renamed, or removed in a future
286+ * release.
287+ */
288+ public void experimentalSetLegacyDecodingEnabled (boolean legacyDecodingEnabled ) {
289+ this .legacyDecodingEnabled = legacyDecodingEnabled ;
290+ }
291+
265292 @ RequiresNonNull ("this.cuesResolver" )
266293 private void renderFromCuesWithTiming (long positionUs ) {
267294 boolean outputNeedsUpdating = readAndDecodeCuesWithTiming (positionUs );
@@ -558,7 +585,22 @@ private long getPresentationTimeUs(long positionUs) {
558585 return positionUs - outputStreamOffsetUs ;
559586 }
560587
588+ @ RequiresNonNull ("streamFormat" )
589+ private void assertLegacyDecodingEnabledIfRequired () {
590+ checkState (
591+ legacyDecodingEnabled
592+ || Objects .equals (streamFormat .sampleMimeType , MimeTypes .APPLICATION_CEA608 )
593+ || Objects .equals (streamFormat .sampleMimeType , MimeTypes .APPLICATION_MP4CEA608 )
594+ || Objects .equals (streamFormat .sampleMimeType , MimeTypes .APPLICATION_CEA708 ),
595+ "Legacy decoding is disabled, can't handle "
596+ + streamFormat .sampleMimeType
597+ + " samples (expected "
598+ + MimeTypes .APPLICATION_MEDIA3_CUES
599+ + ")." );
600+ }
601+
561602 /** Returns whether {@link Format#sampleMimeType} is {@link MimeTypes#APPLICATION_MEDIA3_CUES}. */
603+ @ SideEffectFree
562604 private static boolean isCuesWithTiming (Format format ) {
563605 return Objects .equals (format .sampleMimeType , MimeTypes .APPLICATION_MEDIA3_CUES );
564606 }
0 commit comments