|
21 | 21 | import static androidx.media3.common.util.Assertions.checkState;
|
22 | 22 | import static androidx.media3.common.util.Assertions.checkStateNotNull;
|
23 | 23 | import static androidx.media3.common.util.Util.usToMs;
|
24 |
| -import static androidx.media3.transformer.CompositionUtil.shouldRePreparePlayerForSequence; |
25 | 24 | import static com.google.common.util.concurrent.Futures.immediateFuture;
|
26 | 25 | import static java.lang.Math.max;
|
27 | 26 | import static java.lang.Math.min;
|
|
84 | 83 | import androidx.media3.exoplayer.video.VideoFrameMetadataListener;
|
85 | 84 | import androidx.media3.exoplayer.video.VideoFrameReleaseControl;
|
86 | 85 | import com.google.common.collect.ImmutableList;
|
| 86 | +import com.google.common.collect.Iterables; |
87 | 87 | import com.google.common.util.concurrent.Futures;
|
88 | 88 | import com.google.common.util.concurrent.ListenableFuture;
|
89 | 89 | import com.google.errorprone.annotations.CanIgnoreReturnValue;
|
@@ -1483,6 +1483,75 @@ private static boolean shouldRePreparePlayerForComposition(
|
1483 | 1483 | return false;
|
1484 | 1484 | }
|
1485 | 1485 |
|
| 1486 | + /** |
| 1487 | + * Returns whether the player should be re-prepared after switching {@link |
| 1488 | + * EditedMediaItemSequence} to the new one. |
| 1489 | + * |
| 1490 | + * <p>It returns {@code true} if the {@code oldSequence} is {@code null}. |
| 1491 | + * |
| 1492 | + * <p>Currently this method returns {@code false} when |
| 1493 | + * |
| 1494 | + * <ul> |
| 1495 | + * <li>All the {@link MediaItem mediaItems} in the {@code oldSequence} match with those in the |
| 1496 | + * {@code newSequence}. |
| 1497 | + * <li>Changes in {@link EditedMediaItem}: |
| 1498 | + * <ul> |
| 1499 | + * <li>{@linkplain EditedMediaItem#effects Video effects} changed. Except when there are |
| 1500 | + * speed adjustments ({@link InactiveTimestampAdjustment}). |
| 1501 | + * </ul> |
| 1502 | + * </ul> |
| 1503 | + */ |
| 1504 | + @VisibleForTesting |
| 1505 | + /* package */ static boolean shouldRePreparePlayerForSequence( |
| 1506 | + @Nullable EditedMediaItemSequence oldSequence, EditedMediaItemSequence newSequence) { |
| 1507 | + if (oldSequence == null) { |
| 1508 | + return true; |
| 1509 | + } |
| 1510 | + |
| 1511 | + if (oldSequence.editedMediaItems.size() != newSequence.editedMediaItems.size()) { |
| 1512 | + return true; |
| 1513 | + } |
| 1514 | + |
| 1515 | + for (int i = 0; i < oldSequence.editedMediaItems.size(); i++) { |
| 1516 | + EditedMediaItem oldEditedMediaItem = oldSequence.editedMediaItems.get(i); |
| 1517 | + EditedMediaItem newEditedMediaItem = newSequence.editedMediaItems.get(i); |
| 1518 | + if (!oldEditedMediaItem.mediaItem.equals(newEditedMediaItem.mediaItem)) { |
| 1519 | + // All MediaItems must match - this checks the URI and the clipping. |
| 1520 | + return true; |
| 1521 | + } |
| 1522 | + |
| 1523 | + if (oldEditedMediaItem.flattenForSlowMotion != newEditedMediaItem.flattenForSlowMotion) { |
| 1524 | + return true; |
| 1525 | + } |
| 1526 | + |
| 1527 | + if (oldEditedMediaItem.removeVideo != newEditedMediaItem.removeVideo) { |
| 1528 | + return true; |
| 1529 | + } |
| 1530 | + |
| 1531 | + if (oldEditedMediaItem.removeAudio != newEditedMediaItem.removeAudio) { |
| 1532 | + return true; |
| 1533 | + } |
| 1534 | + |
| 1535 | + if (!oldEditedMediaItem.effects.audioProcessors.equals( |
| 1536 | + newEditedMediaItem.effects.audioProcessors)) { |
| 1537 | + return true; |
| 1538 | + } |
| 1539 | + |
| 1540 | + // TimestampAdjustment change needs to be handled separately. Player needs to be re-prepared |
| 1541 | + // if the timestamp adjustments change. |
| 1542 | + if (!Iterables.elementsEqual( |
| 1543 | + // Old timestamp adjustments |
| 1544 | + Iterables.filter( |
| 1545 | + oldEditedMediaItem.effects.videoEffects, InactiveTimestampAdjustment.class), |
| 1546 | + // New timestamp adjustments |
| 1547 | + Iterables.filter( |
| 1548 | + newEditedMediaItem.effects.videoEffects, InactiveTimestampAdjustment.class))) { |
| 1549 | + return true; |
| 1550 | + } |
| 1551 | + } |
| 1552 | + return false; |
| 1553 | + } |
| 1554 | + |
1486 | 1555 | private static final class GapHandlingDecoderFactory implements ImageDecoder.Factory {
|
1487 | 1556 | private static final String BLANK_FRAMES_MEDIA_SOURCE_TYPE = "composition_player_blank_frames";
|
1488 | 1557 | private static final int BLANK_IMAGE_BITMAP_WIDTH = 1;
|
|
0 commit comments