Skip to content

Commit

Permalink
Merge pull request #8634 from google/dev-v2-r2.13.2
Browse files Browse the repository at this point in the history
r2.13.2
  • Loading branch information
marcbaechinger authored Feb 25, 2021
2 parents 4b1e0fa + c96f695 commit ce48a28
Show file tree
Hide file tree
Showing 35 changed files with 310 additions and 156 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ bazel-testlogs
.DS_Store
cmake-build-debug
dist
jacoco.exec
tmp

# External native builds
Expand Down
33 changes: 33 additions & 0 deletions RELEASENOTES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,38 @@
# Release notes

### 2.13.2 (2021-02-25)

* Extractors:
* Add support for MP4 and QuickTime meta atoms that are not full atoms.
* UI:
* Make conditions to enable UI actions consistent in
`DefaultControlDispatcher`, `PlayerControlView`,
`StyledPlayerControlView`, `PlayerNotificationManager` and
`TimelineQueueNavigator`.
* Fix conditions to enable seeking to next/previous media item to handle
the case where a live stream has ended.
* Audio:
* Fix `SimpleExoPlayer` reporting audio session ID as 0 in some cases
([#8585](https://github.com/google/ExoPlayer/issues/8585)).
* IMA extension:
* Fix a bug where playback could get stuck when seeking into a playlist
item with ads, if the preroll ad had preloaded but the window position
of the seek should instead trigger playback of a midroll.
* Fix a bug with playback of ads in playlists, where the incorrect period
index was used when deciding whether to trigger playback of an ad after
a seek.
* Text:
* Parse SSA/ASS font size in `Style:` lines
([#8435](https://github.com/google/ExoPlayer/issues/8435)).
* VP9 extension: Update to use NDK r21
([#8581](https://github.com/google/ExoPlayer/issues/8581)).
* FLAC extension: Update to use NDK r21
([#8581](https://github.com/google/ExoPlayer/issues/8581)).
* Opus extension: Update to use NDK r21
([#8581](https://github.com/google/ExoPlayer/issues/8581)).
* FFmpeg extension: Update to use NDK r21
([#8581](https://github.com/google/ExoPlayer/issues/8581)).

### 2.13.1 (2021-02-12)

* Live streaming:
Expand Down
4 changes: 2 additions & 2 deletions constants.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
// limitations under the License.
project.ext {
// ExoPlayer version and version code.
releaseVersion = '2.13.1'
releaseVersionCode = 2013001
releaseVersion = '2.13.2'
releaseVersionCode = 2013002
minSdkVersion = 16
appTargetSdkVersion = 29
targetSdkVersion = 28 // TODO: Bump once b/143232359 is resolved. Also fix TODOs in UtilTest.
Expand Down
2 changes: 1 addition & 1 deletion extensions/ffmpeg/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ FFMPEG_EXT_PATH="${EXOPLAYER_ROOT}/extensions/ffmpeg/src/main"
```

* Download the [Android NDK][] and set its location in a shell variable.
This build configuration has been tested on NDK r20.
This build configuration has been tested on NDK r21.

```
NDK_PATH="<path to Android NDK>"
Expand Down
2 changes: 1 addition & 1 deletion extensions/flac/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ FLAC_EXT_PATH="${EXOPLAYER_ROOT}/extensions/flac/src/main"
```

* Download the [Android NDK][] and set its location in an environment variable.
This build configuration has been tested on NDK r20.
This build configuration has been tested on NDK r21.

```
NDK_PATH="<path to Android NDK>"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -341,11 +341,25 @@ public void activate(Player player) {

boolean playWhenReady = player.getPlayWhenReady();
onTimelineChanged(player.getCurrentTimeline(), Player.TIMELINE_CHANGE_REASON_SOURCE_UPDATE);
if (!AdPlaybackState.NONE.equals(adPlaybackState)
&& adsManager != null
&& imaPausedContent
&& playWhenReady) {
adsManager.resume();
@Nullable AdsManager adsManager = this.adsManager;
if (!AdPlaybackState.NONE.equals(adPlaybackState) && adsManager != null && imaPausedContent) {
// Check whether the current ad break matches the expected ad break based on the current
// position. If not, discard the current ad break so that the correct ad break can load.
long contentPositionMs = getContentPeriodPositionMs(player, timeline, period);
int adGroupForPositionIndex =
adPlaybackState.getAdGroupIndexForPositionUs(
C.msToUs(contentPositionMs), C.msToUs(contentDurationMs));
if (adGroupForPositionIndex != C.INDEX_UNSET
&& imaAdInfo != null
&& imaAdInfo.adGroupIndex != adGroupForPositionIndex) {
if (configuration.debugModeEnabled) {
Log.d(TAG, "Discarding preloaded ad " + imaAdInfo);
}
adsManager.discardAdBreak();
}
if (playWhenReady) {
adsManager.resume();
}
}
}

Expand Down Expand Up @@ -826,7 +840,7 @@ private void handleTimelineOrPositionChanged() {
ensureSentContentCompleteIfAtEndOfStream();
if (!sentContentComplete && !timeline.isEmpty()) {
long positionMs = getContentPeriodPositionMs(player, timeline, period);
timeline.getPeriod(/* periodIndex= */ 0, period);
timeline.getPeriod(player.getCurrentPeriodIndex(), period);
int newAdGroupIndex = period.getAdGroupIndexForPositionUs(C.msToUs(positionMs));
if (newAdGroupIndex != C.INDEX_UNSET) {
sentPendingContentPositionMs = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@ public long getSupportedQueueNavigatorActions(Player player) {
if (!timeline.isEmpty() && !player.isPlayingAd()) {
timeline.getWindow(player.getCurrentWindowIndex(), window);
enableSkipTo = timeline.getWindowCount() > 1;
enablePrevious = window.isSeekable || !window.isDynamic || player.hasPrevious();
enableNext = window.isDynamic || player.hasNext();
enablePrevious = window.isSeekable || !window.isLive() || player.hasPrevious();
enableNext = (window.isLive() && window.isDynamic) || player.hasNext();
}

long actions = 0;
Expand Down
2 changes: 1 addition & 1 deletion extensions/opus/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ OPUS_EXT_PATH="${EXOPLAYER_ROOT}/extensions/opus/src/main"
```

* Download the [Android NDK][] and set its location in an environment variable.
This build configuration has been tested on NDK r20.
This build configuration has been tested on NDK r21.

```
NDK_PATH="<path to Android NDK>"
Expand Down
2 changes: 1 addition & 1 deletion extensions/vp9/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ VP9_EXT_PATH="${EXOPLAYER_ROOT}/extensions/vp9/src/main"
```

* Download the [Android NDK][] and set its location in an environment variable.
This build configuration has been tested on NDK r20.
This build configuration has been tested on NDK r21.

```
NDK_PATH="<path to Android NDK>"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@ public final class ExoPlayerLibraryInfo {

/** The version of the library expressed as a string, for example "1.2.3". */
// Intentionally hardcoded. Do not derive from other constants (e.g. VERSION_INT) or vice versa.
public static final String VERSION = "2.13.1";
public static final String VERSION = "2.13.2";

/** The version of the library expressed as {@code "ExoPlayerLib/" + VERSION}. */
// Intentionally hardcoded. Do not derive from other constants (e.g. VERSION) or vice versa.
public static final String VERSION_SLASHY = "ExoPlayerLib/2.13.1";
public static final String VERSION_SLASHY = "ExoPlayerLib/2.13.2";

/**
* The version of the library expressed as an integer, for example 1002003.
Expand All @@ -44,7 +44,7 @@ public final class ExoPlayerLibraryInfo {
* integer version 123045006 (123-045-006).
*/
// Intentionally hardcoded. Do not derive from other constants (e.g. VERSION) or vice versa.
public static final int VERSION_INT = 2013001;
public static final int VERSION_INT = 2013002;

/**
* The default user agent for requests made by the library.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,12 @@ public boolean dispatchPrevious(Player player) {
int windowIndex = player.getCurrentWindowIndex();
timeline.getWindow(windowIndex, window);
int previousWindowIndex = player.getPreviousWindowIndex();
boolean isUnseekableLiveStream = window.isLive() && !window.isSeekable;
if (previousWindowIndex != C.INDEX_UNSET
&& (player.getCurrentPosition() <= MAX_POSITION_FOR_SEEK_TO_PREVIOUS
|| (window.isDynamic && !window.isSeekable))) {
|| isUnseekableLiveStream)) {
player.seekTo(previousWindowIndex, C.TIME_UNSET);
} else {
} else if (!isUnseekableLiveStream) {
player.seekTo(windowIndex, /* positionMs= */ 0);
}
return true;
Expand All @@ -96,10 +97,11 @@ public boolean dispatchNext(Player player) {
return true;
}
int windowIndex = player.getCurrentWindowIndex();
timeline.getWindow(windowIndex, window);
int nextWindowIndex = player.getNextWindowIndex();
if (nextWindowIndex != C.INDEX_UNSET) {
player.seekTo(nextWindowIndex, C.TIME_UNSET);
} else if (timeline.getWindow(windowIndex, window).isLive()) {
} else if (window.isLive() && window.isDynamic) {
player.seekTo(windowIndex, C.TIME_UNSET);
}
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2140,7 +2140,6 @@ public void onAudioDisabled(DecoderCounters counters) {
analyticsCollector.onAudioDisabled(counters);
audioFormat = null;
audioDecoderCounters = null;
audioSessionId = C.AUDIO_SESSION_ID_UNSET;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -305,11 +305,15 @@ public int readData(
return C.RESULT_BUFFER_READ;
}

buffer.timeUs = getAudioPositionUs(positionBytes);
buffer.addFlag(C.BUFFER_FLAG_KEY_FRAME);
if (buffer.isFlagsOnly()) {
return C.RESULT_BUFFER_READ;
}

int bytesToWrite = (int) min(SILENCE_SAMPLE.length, bytesRemaining);
buffer.ensureSpaceForWrite(bytesToWrite);
buffer.data.put(SILENCE_SAMPLE, /* offset= */ 0, bytesToWrite);
buffer.timeUs = getAudioPositionUs(positionBytes);
buffer.addFlag(C.BUFFER_FLAG_KEY_FRAME);
positionBytes += bytesToWrite;
return C.RESULT_BUFFER_READ;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;

/**
* A {@link MediaSource} that inserts ads linearly with a provided content media source. This source
* cannot be used as a child source in a composition. It must be the top-level source used to
* prepare the player.
* A {@link MediaSource} that inserts ads linearly into a provided content media source.
*
* <p>The wrapped content media source must contain a single {@link Timeline.Period}.
*/
public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,10 @@ private static Cue createCue(
/* end= */ spannableText.length(),
SpannableString.SPAN_EXCLUSIVE_EXCLUSIVE);
}
if (style.fontSize != Cue.DIMEN_UNSET && screenHeight != Cue.DIMEN_UNSET) {
cue.setTextSize(
style.fontSize / screenHeight, Cue.TEXT_SIZE_TYPE_FRACTIONAL_IGNORE_PADDING);
}
}

@SsaStyle.SsaAlignment int alignment;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import androidx.annotation.IntDef;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.text.Cue;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.Log;
import com.google.android.exoplayer2.util.Util;
Expand Down Expand Up @@ -90,12 +91,17 @@
public final String name;
@SsaAlignment public final int alignment;
@Nullable @ColorInt public final Integer primaryColor;
public final float fontSize;

private SsaStyle(
String name, @SsaAlignment int alignment, @Nullable @ColorInt Integer primaryColor) {
String name,
@SsaAlignment int alignment,
@Nullable @ColorInt Integer primaryColor,
float fontSize) {
this.name = name;
this.alignment = alignment;
this.primaryColor = primaryColor;
this.fontSize = fontSize;
}

@Nullable
Expand All @@ -114,7 +120,8 @@ public static SsaStyle fromStyleLine(String styleLine, Format format) {
return new SsaStyle(
styleValues[format.nameIndex].trim(),
parseAlignment(styleValues[format.alignmentIndex].trim()),
parseColor(styleValues[format.primaryColorIndex].trim()));
parseColor(styleValues[format.primaryColorIndex].trim()),
parseFontSize(styleValues[format.fontSizeIndex].trim()));
} catch (RuntimeException e) {
Log.w(TAG, "Skipping malformed 'Style:' line: '" + styleLine + "'", e);
return null;
Expand Down Expand Up @@ -191,6 +198,15 @@ public static Integer parseColor(String ssaColorExpression) {
return Color.argb(a, r, g, b);
}

private static float parseFontSize(String fontSize) {
try {
return Float.parseFloat(fontSize);
} catch (NumberFormatException e) {
Log.w(TAG, "Failed to parse font size: '" + fontSize + "'", e);
return Cue.DIMEN_UNSET;
}
}

/**
* Represents a {@code Format:} line from the {@code [V4+ Styles]} section
*
Expand All @@ -202,12 +218,15 @@ public static Integer parseColor(String ssaColorExpression) {
public final int nameIndex;
public final int alignmentIndex;
public final int primaryColorIndex;
public final int fontSizeIndex;
public final int length;

private Format(int nameIndex, int alignmentIndex, int primaryColorIndex, int length) {
private Format(
int nameIndex, int alignmentIndex, int primaryColorIndex, int fontSizeIndex, int length) {
this.nameIndex = nameIndex;
this.alignmentIndex = alignmentIndex;
this.primaryColorIndex = primaryColorIndex;
this.fontSizeIndex = fontSizeIndex;
this.length = length;
}

Expand All @@ -221,6 +240,7 @@ public static Format fromFormatLine(String styleFormatLine) {
int nameIndex = C.INDEX_UNSET;
int alignmentIndex = C.INDEX_UNSET;
int primaryColorIndex = C.INDEX_UNSET;
int fontSizeIndex = C.INDEX_UNSET;
String[] keys =
TextUtils.split(styleFormatLine.substring(SsaDecoder.FORMAT_LINE_PREFIX.length()), ",");
for (int i = 0; i < keys.length; i++) {
Expand All @@ -234,10 +254,13 @@ public static Format fromFormatLine(String styleFormatLine) {
case "primarycolour":
primaryColorIndex = i;
break;
case "fontsize":
fontSizeIndex = i;
break;
}
}
return nameIndex != C.INDEX_UNSET
? new Format(nameIndex, alignmentIndex, primaryColorIndex, keys.length)
? new Format(nameIndex, alignmentIndex, primaryColorIndex, fontSizeIndex, keys.length)
: null;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ public final class SsaDecoderTest {
private static final String INVALID_TIMECODES = "media/ssa/invalid_timecodes";
private static final String INVALID_POSITIONS = "media/ssa/invalid_positioning";
private static final String POSITIONS_WITHOUT_PLAYRES = "media/ssa/positioning_without_playres";
private static final String COLORS = "media/ssa/colors";
private static final String STYLE_COLORS = "media/ssa/style_colors";
private static final String STYLE_FONT_SIZE = "media/ssa/style_font_size";

@Test
public void decodeEmpty() throws IOException {
Expand Down Expand Up @@ -274,7 +275,7 @@ public void decodeInvalidTimecodes() throws IOException {
@Test
public void decodeColors() throws IOException {
SsaDecoder decoder = new SsaDecoder();
byte[] bytes = TestUtil.getByteArray(ApplicationProvider.getApplicationContext(), COLORS);
byte[] bytes = TestUtil.getByteArray(ApplicationProvider.getApplicationContext(), STYLE_COLORS);
Subtitle subtitle = decoder.decode(bytes, bytes.length, false);
assertThat(subtitle.getEventTimeCount()).isEqualTo(14);
// &H000000FF (AABBGGRR) -> #FFFF0000 (AARRGGBB)
Expand Down Expand Up @@ -319,6 +320,22 @@ public void decodeColors() throws IOException {
.hasNoForegroundColorSpanBetween(0, seventhCueText.length());
}

@Test
public void decodeFontSize() throws IOException {
SsaDecoder decoder = new SsaDecoder();
byte[] bytes =
TestUtil.getByteArray(ApplicationProvider.getApplicationContext(), STYLE_FONT_SIZE);
Subtitle subtitle = decoder.decode(bytes, bytes.length, false);
assertThat(subtitle.getEventTimeCount()).isEqualTo(4);

Cue firstCue = Iterables.getOnlyElement(subtitle.getCues(subtitle.getEventTime(0)));
assertThat(firstCue.textSize).isWithin(1.0e-8f).of(30f / 720f);
assertThat(firstCue.textSizeType).isEqualTo(Cue.TEXT_SIZE_TYPE_FRACTIONAL_IGNORE_PADDING);
Cue secondCue = Iterables.getOnlyElement(subtitle.getCues(subtitle.getEventTime(2)));
assertThat(secondCue.textSize).isWithin(1.0e-8f).of(72.2f / 720f);
assertThat(secondCue.textSizeType).isEqualTo(Cue.TEXT_SIZE_TYPE_FRACTIONAL_IGNORE_PADDING);
}

private static void assertTypicalCue1(Subtitle subtitle, int eventIndex) {
assertThat(subtitle.getEventTime(eventIndex)).isEqualTo(0);
assertThat(subtitle.getCues(subtitle.getEventTime(eventIndex)).get(0).text.toString())
Expand Down
Loading

0 comments on commit ce48a28

Please sign in to comment.