From aee7e6087c31c3650895495d77695b9d8220c1a1 Mon Sep 17 00:00:00 2001 From: tonihei Date: Tue, 27 Oct 2020 10:16:52 +0000 Subject: [PATCH] Parse min/max live offset from ServiceDescription. Issue: #4904 PiperOrigin-RevId: 339215091 --- .../dash/manifest/DashManifestParser.java | 7 +++++- .../manifest/ServiceDescriptionElement.java | 16 ++++++++++++- .../dash/manifest/DashManifestParserTest.java | 23 ++++++++++++------- .../dash/manifest/DashManifestTest.java | 6 ++++- ...sample_mpd_service_description_low_latency | 2 +- ...scription_low_latency_only_playback_rates} | 0 ...scription_low_latency_only_target_latency} | 0 7 files changed, 42 insertions(+), 12 deletions(-) rename testdata/src/test/assets/media/mpd/{sample_mpd_service_description_low_latency_no_target_latency => sample_mpd_service_description_low_latency_only_playback_rates} (100%) rename testdata/src/test/assets/media/mpd/{sample_mpd_service_description_low_latency_no_playback_rates => sample_mpd_service_description_low_latency_only_target_latency} (100%) diff --git a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/DashManifestParser.java b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/DashManifestParser.java index 6f4fbf8123..9b5efd4953 100644 --- a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/DashManifestParser.java +++ b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/DashManifestParser.java @@ -250,18 +250,23 @@ public class DashManifestParser extends DefaultHandler protected ServiceDescriptionElement parseServiceDescription(XmlPullParser xpp) throws XmlPullParserException, IOException { long targetOffsetMs = C.TIME_UNSET; + long minOffsetMs = C.TIME_UNSET; + long maxOffsetMs = C.TIME_UNSET; float minPlaybackSpeed = C.RATE_UNSET; float maxPlaybackSpeed = C.RATE_UNSET; do { xpp.next(); if (XmlPullParserUtil.isStartTag(xpp, "Latency")) { targetOffsetMs = parseLong(xpp, "target", C.TIME_UNSET); + minOffsetMs = parseLong(xpp, "min", C.TIME_UNSET); + maxOffsetMs = parseLong(xpp, "max", C.TIME_UNSET); } else if (XmlPullParserUtil.isStartTag(xpp, "PlaybackRate")) { minPlaybackSpeed = parseFloat(xpp, "min", C.RATE_UNSET); maxPlaybackSpeed = parseFloat(xpp, "max", C.RATE_UNSET); } } while (!XmlPullParserUtil.isEndTag(xpp, "ServiceDescription")); - return new ServiceDescriptionElement(targetOffsetMs, minPlaybackSpeed, maxPlaybackSpeed); + return new ServiceDescriptionElement( + targetOffsetMs, minOffsetMs, maxOffsetMs, minPlaybackSpeed, maxPlaybackSpeed); } protected Pair parsePeriod( diff --git a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/ServiceDescriptionElement.java b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/ServiceDescriptionElement.java index f54f3aa2ad..51bd365e3c 100644 --- a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/ServiceDescriptionElement.java +++ b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/ServiceDescriptionElement.java @@ -22,6 +22,10 @@ public final class ServiceDescriptionElement { /** The target live offset in milliseconds, or {@link C#TIME_UNSET} if undefined. */ public final long targetOffsetMs; + /** The minimum live offset in milliseconds, or {@link C#TIME_UNSET} if undefined. */ + public final long minOffsetMs; + /** The maximum live offset in milliseconds, or {@link C#TIME_UNSET} if undefined. */ + public final long maxOffsetMs; /** The minimum playback speed for live speed adjustment, or {@link C#RATE_UNSET} if undefined. */ public final float minPlaybackSpeed; /** The maximum playback speed for live speed adjustment, or {@link C#RATE_UNSET} if undefined. */ @@ -32,14 +36,24 @@ public final class ServiceDescriptionElement { * * @param targetOffsetMs The target live offset in milliseconds, or {@link C#TIME_UNSET} if * undefined. + * @param minOffsetMs The minimum live offset in milliseconds, or {@link C#TIME_UNSET} if + * undefined. + * @param maxOffsetMs The maximum live offset in milliseconds, or {@link C#TIME_UNSET} if + * undefined. * @param minPlaybackSpeed The minimum playback speed for live speed adjustment, or {@link * C#RATE_UNSET} if undefined. * @param maxPlaybackSpeed The maximum playback speed for live speed adjustment, or {@link * C#RATE_UNSET} if undefined. */ public ServiceDescriptionElement( - long targetOffsetMs, float minPlaybackSpeed, float maxPlaybackSpeed) { + long targetOffsetMs, + long minOffsetMs, + long maxOffsetMs, + float minPlaybackSpeed, + float maxPlaybackSpeed) { this.targetOffsetMs = targetOffsetMs; + this.minOffsetMs = minOffsetMs; + this.maxOffsetMs = maxOffsetMs; this.minPlaybackSpeed = minPlaybackSpeed; this.maxPlaybackSpeed = maxPlaybackSpeed; } diff --git a/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/manifest/DashManifestParserTest.java b/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/manifest/DashManifestParserTest.java index 4eb2d37bab..1265e3d40a 100644 --- a/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/manifest/DashManifestParserTest.java +++ b/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/manifest/DashManifestParserTest.java @@ -59,10 +59,10 @@ public class DashManifestParserTest { "media/mpd/sample_mpd_availabilityTimeOffset_segmentList"; private static final String SAMPLE_MPD_SERVICE_DESCRIPTION_LOW_LATENCY = "media/mpd/sample_mpd_service_description_low_latency"; - private static final String SAMPLE_MPD_SERVICE_DESCRIPTION_LOW_LATENCY_NO_TARGET_LATENCY = - "media/mpd/sample_mpd_service_description_low_latency_no_target_latency"; - private static final String SAMPLE_MPD_SERVICE_DESCRIPTION_LOW_LATENCY_NO_PLAYBACK_RATES = - "media/mpd/sample_mpd_service_description_low_latency_no_playback_rates"; + private static final String SAMPLE_MPD_SERVICE_DESCRIPTION_LOW_LATENCY_ONLY_PLAYBACK_RATES = + "media/mpd/sample_mpd_service_description_low_latency_only_playback_rates"; + private static final String SAMPLE_MPD_SERVICE_DESCRIPTION_LOW_LATENCY_ONLY_TARGET_LATENCY = + "media/mpd/sample_mpd_service_description_low_latency_only_target_latency"; private static final String NEXT_TAG_NAME = "Next"; private static final String NEXT_TAG = "<" + NEXT_TAG_NAME + "/>"; @@ -579,12 +579,14 @@ public class DashManifestParserTest { assertThat(manifest.serviceDescription).isNotNull(); assertThat(manifest.serviceDescription.targetOffsetMs).isEqualTo(20_000); + assertThat(manifest.serviceDescription.minOffsetMs).isEqualTo(1_000); + assertThat(manifest.serviceDescription.maxOffsetMs).isEqualTo(30_000); assertThat(manifest.serviceDescription.minPlaybackSpeed).isEqualTo(0.1f); assertThat(manifest.serviceDescription.maxPlaybackSpeed).isEqualTo(99f); } @Test - public void serviceDescriptionElement_noLatency_isUnset() throws IOException { + public void serviceDescriptionElement_onlyPlaybackRates_latencyValuesUnset() throws IOException { DashManifestParser parser = new DashManifestParser(); DashManifest manifest = @@ -592,16 +594,19 @@ public class DashManifestParserTest { Uri.parse("https://example.com/test.mpd"), TestUtil.getInputStream( ApplicationProvider.getApplicationContext(), - SAMPLE_MPD_SERVICE_DESCRIPTION_LOW_LATENCY_NO_TARGET_LATENCY)); + SAMPLE_MPD_SERVICE_DESCRIPTION_LOW_LATENCY_ONLY_PLAYBACK_RATES)); assertThat(manifest.serviceDescription).isNotNull(); assertThat(manifest.serviceDescription.targetOffsetMs).isEqualTo(C.TIME_UNSET); + assertThat(manifest.serviceDescription.minOffsetMs).isEqualTo(C.TIME_UNSET); + assertThat(manifest.serviceDescription.maxOffsetMs).isEqualTo(C.TIME_UNSET); assertThat(manifest.serviceDescription.minPlaybackSpeed).isEqualTo(0.1f); assertThat(manifest.serviceDescription.maxPlaybackSpeed).isEqualTo(99f); } @Test - public void serviceDescriptionElement_noPlaybackRates_isUnset() throws IOException { + public void serviceDescriptionElement_onlyTargetLatency_playbackRatesAndMinMaxLatencyUnset() + throws IOException { DashManifestParser parser = new DashManifestParser(); DashManifest manifest = @@ -609,10 +614,12 @@ public class DashManifestParserTest { Uri.parse("https://example.com/test.mpd"), TestUtil.getInputStream( ApplicationProvider.getApplicationContext(), - SAMPLE_MPD_SERVICE_DESCRIPTION_LOW_LATENCY_NO_PLAYBACK_RATES)); + SAMPLE_MPD_SERVICE_DESCRIPTION_LOW_LATENCY_ONLY_TARGET_LATENCY)); assertThat(manifest.serviceDescription).isNotNull(); assertThat(manifest.serviceDescription.targetOffsetMs).isEqualTo(20_000); + assertThat(manifest.serviceDescription.minOffsetMs).isEqualTo(C.TIME_UNSET); + assertThat(manifest.serviceDescription.maxOffsetMs).isEqualTo(C.TIME_UNSET); assertThat(manifest.serviceDescription.minPlaybackSpeed).isEqualTo(C.RATE_UNSET); assertThat(manifest.serviceDescription.maxPlaybackSpeed).isEqualTo(C.RATE_UNSET); } diff --git a/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/manifest/DashManifestTest.java b/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/manifest/DashManifestTest.java index c6c5b56e7d..7b3b3cab51 100644 --- a/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/manifest/DashManifestTest.java +++ b/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/manifest/DashManifestTest.java @@ -43,7 +43,11 @@ public class DashManifestTest { Representation[][][] representations = newRepresentations(3, 2, 3); ServiceDescriptionElement serviceDescriptionElement = new ServiceDescriptionElement( - /* targetOffsetMs= */ 20, /* minPlaybackSpeed= */ 0.9f, /* maxPlaybackSpeed= */ 1.1f); + /* targetOffsetMs= */ 20, + /* minOffsetMs= */ 10, + /* maxOffsetMs= */ 40, + /* minPlaybackSpeed= */ 0.9f, + /* maxPlaybackSpeed= */ 1.1f); DashManifest sourceManifest = newDashManifest( 10, diff --git a/testdata/src/test/assets/media/mpd/sample_mpd_service_description_low_latency b/testdata/src/test/assets/media/mpd/sample_mpd_service_description_low_latency index 57b8d59ff1..33d398bc7f 100644 --- a/testdata/src/test/assets/media/mpd/sample_mpd_service_description_low_latency +++ b/testdata/src/test/assets/media/mpd/sample_mpd_service_description_low_latency @@ -1,7 +1,7 @@ - + diff --git a/testdata/src/test/assets/media/mpd/sample_mpd_service_description_low_latency_no_target_latency b/testdata/src/test/assets/media/mpd/sample_mpd_service_description_low_latency_only_playback_rates similarity index 100% rename from testdata/src/test/assets/media/mpd/sample_mpd_service_description_low_latency_no_target_latency rename to testdata/src/test/assets/media/mpd/sample_mpd_service_description_low_latency_only_playback_rates diff --git a/testdata/src/test/assets/media/mpd/sample_mpd_service_description_low_latency_no_playback_rates b/testdata/src/test/assets/media/mpd/sample_mpd_service_description_low_latency_only_target_latency similarity index 100% rename from testdata/src/test/assets/media/mpd/sample_mpd_service_description_low_latency_no_playback_rates rename to testdata/src/test/assets/media/mpd/sample_mpd_service_description_low_latency_only_target_latency