-
Notifications
You must be signed in to change notification settings - Fork 6k
Description
This line tends to crash quite often for live content:
ExoPlayer/library/core/src/main/java/com/google/android/exoplayer2/text/cea/Cea608Decoder.java
Line 708 in 2b55c91
captionStringBuilder.setSpan(cueStyle.style, cueStyle.start, end, |
I had a pull request for handling the various styles in Cea608Decoders for ExoPlayer 1. For ExoPlayer 2, you have included many parts of that pull request, but you also re-designed the handling of the styles by adding the CueStyle class. So my understanding of the CueStyle might be different than yours.
This current code creates list of CueStyles, and adds them only when the captions are rendered. I could identify one case when this current solution crashes. Incoming caption bytes are:
MISC: RESUME_CAPTION_LOADING
MISC: ERASE_DISPLAYED_MEMORY
MISC: END_OF_CAPTION
MISC: RESUME_CAPTION_LOADING
PAC: Row:14; Col:1; Color:KEEP PREVIOUS COLOR; italic:true; underline:false
Incoming char: 'A'
Incoming char: 'l'
Incoming char: 'e'
Incoming char: 'v'
Incoming char: 'e'
Incoming char: ' '
Incoming char: 'P'
Incoming char: 'M'
Incoming char: ' '
Incoming char: 'f'
Incoming char: 'o'
Incoming char: 'r'
Incoming char: ' '
Incoming char: 'a'
Incoming char: ' '
Incoming char: 'B'
Incoming char: 'e'
Incoming char: 't'
Incoming char: 't'
Incoming char: 'e'
Incoming char: 'r'
Incoming char: ' '
Incoming char: 'A'
Incoming char: 'M'
Incoming char: '.'
MISC: RESUME_CAPTION_LOADING
MISC: ERASE_DISPLAYED_MEMORY
MISC: END_OF_CAPTION
MISC: ERASE_DISPLAYED_MEMORY
MISC: RESUME_DIRECT_CAPTIONING
PAC: Row:15; Col:1; Color:WHITE; italic:false; underline:false
MRC: ITALIC TURNED ON
Incoming char: ' '
MISC: BACKSPACE
The crash itself is:
05-26 08:49:36.592 E/ExoPlayerImplInternal(13783): Internal runtime error.
05-26 08:49:36.592 E/ExoPlayerImplInternal(13783): java.lang.IndexOutOfBoundsException: setSpan (1 ... 0) has end before start
05-26 08:49:36.592 E/ExoPlayerImplInternal(13783): at android.text.SpannableStringBuilder.checkRange(SpannableStringBuilder.java:1313)
05-26 08:49:36.592 E/ExoPlayerImplInternal(13783): at android.text.SpannableStringBuilder.setSpan(SpannableStringBuilder.java:683)
05-26 08:49:36.592 E/ExoPlayerImplInternal(13783): at android.text.SpannableStringBuilder.setSpan(SpannableStringBuilder.java:676)
05-26 08:49:36.592 E/ExoPlayerImplInternal(13783): at com.google.android.exoplayer2.text.cea.Cea608Decoder$CueBuilder.buildSpannableString(Cea608Decoder.java:1190)
(As the line numbers suggest, we have some modifications in Cea608Decoder that is not shared (yet), but the crash should be present irrespective of our changes.)
The issue seems to be the independent handling of the characters and the spans: backspace should be able to clear any characters and possibly create empty spans as well. This list of Spans applied right before rendering seems to be a fragile solution. In this specific case leading to the crash, turning on ITALIC adds two items to the span list:
ExoPlayer/library/core/src/main/java/com/google/android/exoplayer2/text/cea/Cea608Decoder.java
Lines 384 to 385 in 2b20780
currentCueBuilder.setMidrowStyle(new StyleSpan(Typeface.ITALIC), 2); | |
currentCueBuilder.setMidrowStyle(new ForegroundColorSpan(Color.WHITE), 1); |
Then comes a BackSpace command and our indices become invalid.
The crash can be avoided simply be checking the validity of the Span indices for the current content of the StringBuilder. Although it is hard to prove that the intention of the caption provider was matching the rendered result. I have a few question:
- Is the CueStyle.nextStyleIncrement member introduced only to handle the priorities of the CEA608 styles?
- Shouldn’t the preamble and mid-row styles handled in a single list as they both contain the same styling options?
- As I recall, my version of Span-handling added them whenever a span is closed. For example, when you set a color, all previous color spans should be closed instead of adding cascading color spans to the string. Isn't that a better approach?
- Currently, the Italic command adds a Span for Italic, and also a color White Span. Shouldn’t we replace the "adding the white span" with "closing any previous color spans" instead? Adding a white span means that this might rendered in white irrespective of the "default color" setting of the user. (Cea608 had implicit white as default color and was not prepared to have any user settings like the ones provided by CaptioningManager)