Commit 16c43c6b by aquilescanta Committed by Oliver Woodman

Support undefined text track language when preferred is not available

Also slightly improve language normalization/documentation.

For this CL, it is assumed that null and "und" languages are different
entities. Once we fully tackle language tag normalization, we can decide
whether to normalize the "undefined" language.

Issue:#2867
Issue:#2980

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=177008509
parent ec2fbe5d
......@@ -18,8 +18,11 @@
use this with `FfmpegAudioRenderer`.
* Support extraction and decoding of Dolby Atmos
([#2465](https://github.com/google/ExoPlayer/issues/2465)).
* Added a reason to `EventListener.onTimelineChanged` to distinguish between
* Added a reason to `EventListener.onTimelineChanged` to distinguish between
initial preparation, reset and dynamic updates.
* DefaultTrackSelector: Support undefined language text track selection when the
preferred language is not available
([#2980](https://github.com/google/ExoPlayer/issues/2980)).
### 2.6.0 ###
......
......@@ -425,6 +425,11 @@ public final class C {
public static final int SELECTION_FLAG_AUTOSELECT = 4;
/**
* Represents an undetermined language as an ISO 639 alpha-3 language code.
*/
public static final String LANGUAGE_UNDETERMINED = "und";
/**
* Represents a streaming or other media type.
*/
@Retention(RetentionPolicy.SOURCE)
......
......@@ -50,6 +50,7 @@ import java.util.Formatter;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.TimeZone;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
......@@ -249,13 +250,18 @@ public final class Util {
}
/**
* Returns a normalized RFC 5646 language code.
* Returns a normalized RFC 639-2/T code for {@code language}.
*
* @param language A possibly non-normalized RFC 5646 language code.
* @return The normalized code, or null if the input was null.
* @param language A case-insensitive ISO 639 alpha-2 or alpha-3 language code.
* @return The all-lowercase normalized code, or null if the input was null, or
* {@code language.toLowerCase()} if the language could not be normalized.
*/
public static String normalizeLanguageCode(String language) {
return language == null ? null : new Locale(language).getLanguage();
try {
return language == null ? null : new Locale(language).getISO3Language();
} catch (MissingResourceException e) {
return language.toLowerCase();
}
}
/**
......
......@@ -36,6 +36,8 @@ public final class DefaultTrackSelectorTest {
private static final Parameters DEFAULT_PARAMETERS = new Parameters();
private static final RendererCapabilities ALL_AUDIO_FORMAT_SUPPORTED_RENDERER_CAPABILITIES =
new FakeRendererCapabilities(C.TRACK_TYPE_AUDIO);
private static final RendererCapabilities ALL_TEXT_FORMAT_SUPPORTED_RENDERER_CAPABILITIES =
new FakeRendererCapabilities(C.TRACK_TYPE_TEXT);
private static final RendererCapabilities ALL_AUDIO_FORMAT_EXCEEDED_RENDERER_CAPABILITIES =
new FakeRendererCapabilities(C.TRACK_TYPE_AUDIO, FORMAT_EXCEEDS_CAPABILITIES);
......@@ -535,6 +537,60 @@ public final class DefaultTrackSelectorTest {
}
/**
* Tests that the default track selector will select a text track with undetermined language if no
* text track with the preferred language is available but
* {@link Parameters#selectUndeterminedTextLanguage} is true.
*/
@Test
public void testSelectUndeterminedTextLanguageAsFallback() throws ExoPlaybackException{
Format spanish = Format.createTextContainerFormat("spanish", null,
MimeTypes.TEXT_VTT, null, Format.NO_VALUE, 0, "spa");
Format german = Format.createTextContainerFormat("german", null,
MimeTypes.TEXT_VTT, null, Format.NO_VALUE, 0, "de");
Format undeterminedUnd = Format.createTextContainerFormat("undeterminedUnd", null,
MimeTypes.TEXT_VTT, null, Format.NO_VALUE, 0, "und");
Format undeterminedNull = Format.createTextContainerFormat("undeterminedNull", null,
MimeTypes.TEXT_VTT, null, Format.NO_VALUE, 0, null);
RendererCapabilities[] textRendererCapabilites =
new RendererCapabilities[] {ALL_TEXT_FORMAT_SUPPORTED_RENDERER_CAPABILITIES};
TrackSelectorResult result;
result = trackSelector.selectTracks(textRendererCapabilites,
wrapFormats(spanish, german, undeterminedUnd, undeterminedNull));
assertThat(result.selections.get(0)).isNull();
trackSelector.setParameters(
DEFAULT_PARAMETERS.withSelectUndeterminedTextLanguageAsFallback(true));
result = trackSelector.selectTracks(textRendererCapabilites,
wrapFormats(spanish, german, undeterminedUnd, undeterminedNull));
assertThat(result.selections.get(0).getFormat(0)).isSameAs(undeterminedUnd);
trackSelector.setParameters(DEFAULT_PARAMETERS.withPreferredTextLanguage("spa"));
result = trackSelector.selectTracks(textRendererCapabilites,
wrapFormats(spanish, german, undeterminedUnd, undeterminedNull));
assertThat(result.selections.get(0).getFormat(0)).isSameAs(spanish);
result = trackSelector.selectTracks(textRendererCapabilites,
wrapFormats(german, undeterminedUnd, undeterminedNull));
assertThat(result.selections.get(0)).isNull();
trackSelector.setParameters(
trackSelector.getParameters().withSelectUndeterminedTextLanguageAsFallback(true));
result = trackSelector.selectTracks(textRendererCapabilites,
wrapFormats(german, undeterminedUnd, undeterminedNull));
assertThat(result.selections.get(0).getFormat(0)).isSameAs(undeterminedUnd);
result = trackSelector.selectTracks(textRendererCapabilites,
wrapFormats(german, undeterminedNull));
assertThat(result.selections.get(0).getFormat(0)).isSameAs(undeterminedNull);
result = trackSelector.selectTracks(textRendererCapabilites, wrapFormats(german));
assertThat(result.selections.get(0)).isNull();
}
/**
* Tests that track selector will select audio tracks with lower bitrate when {@link Parameters}
* indicate lowest bitrate preference, even when tracks are within capabilities.
*/
......@@ -562,6 +618,14 @@ public final class DefaultTrackSelectorTest {
return new TrackGroupArray(new TrackGroup(formats));
}
private static TrackGroupArray wrapFormats(Format... formats) {
TrackGroup[] trackGroups = new TrackGroup[formats.length];
for (int i = 0; i < trackGroups.length; i++) {
trackGroups[i] = new TrackGroup(formats[i]);
}
return new TrackGroupArray(trackGroups);
}
/**
* A {@link RendererCapabilities} that advertises support for all formats of a given type using
* a provided support value. For any format that does not have the given track type,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment