From 06f4983ffb0e64115026b59a686ab34f1c3ea8be Mon Sep 17 00:00:00 2001 From: olly Date: Wed, 12 Feb 2020 15:19:58 +0000 Subject: [PATCH] Split bitrate into average and peak in VariantInfo Issue: #2863 PiperOrigin-RevId: 294661214 --- .../source/hls/HlsTrackMetadataEntry.java | 32 ++++++++---- .../hls/playlist/HlsPlaylistParser.java | 15 ++++-- .../source/hls/HlsTrackMetadataEntryTest.java | 50 +++++++++++++++++++ .../playlist/HlsMasterPlaylistParserTest.java | 23 +++++---- 4 files changed, 95 insertions(+), 25 deletions(-) create mode 100644 library/hls/src/test/java/com/google/android/exoplayer2/source/hls/HlsTrackMetadataEntryTest.java diff --git a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsTrackMetadataEntry.java b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsTrackMetadataEntry.java index f26a9b8e9a..9a9566b63e 100644 --- a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsTrackMetadataEntry.java +++ b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsTrackMetadataEntry.java @@ -19,6 +19,7 @@ import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; import androidx.annotation.Nullable; +import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.metadata.Metadata; import java.util.ArrayList; import java.util.Collections; @@ -30,8 +31,14 @@ public final class HlsTrackMetadataEntry implements Metadata.Entry { /** Holds attributes defined in an EXT-X-STREAM-INF tag. */ public static final class VariantInfo implements Parcelable { - /** The bitrate as declared by the EXT-X-STREAM-INF tag. */ - public final long bitrate; + /** + * The average bitrate as declared by the AVERAGE-BANDWIDTH attribute of the EXT-X-STREAM-INF + * tag, or {@link Format#NO_VALUE} if the attribute is not declared. + */ + public final int averageBitrate; + + /** The peak bitrate as declared by the BANDWIDTH attribute of the EXT-X-STREAM-INF tag. */ + public final int peakBitrate; /** * The VIDEO value as defined in the EXT-X-STREAM-INF tag, or null if the VIDEO attribute is not @@ -60,19 +67,22 @@ public final class HlsTrackMetadataEntry implements Metadata.Entry { /** * Creates an instance. * - * @param bitrate See {@link #bitrate}. + * @param averageBitrate See {@link #averageBitrate}. + * @param peakBitrate See {@link #peakBitrate}. * @param videoGroupId See {@link #videoGroupId}. * @param audioGroupId See {@link #audioGroupId}. * @param subtitleGroupId See {@link #subtitleGroupId}. * @param captionGroupId See {@link #captionGroupId}. */ public VariantInfo( - long bitrate, + int averageBitrate, + int peakBitrate, @Nullable String videoGroupId, @Nullable String audioGroupId, @Nullable String subtitleGroupId, @Nullable String captionGroupId) { - this.bitrate = bitrate; + this.averageBitrate = averageBitrate; + this.peakBitrate = peakBitrate; this.videoGroupId = videoGroupId; this.audioGroupId = audioGroupId; this.subtitleGroupId = subtitleGroupId; @@ -80,7 +90,8 @@ public final class HlsTrackMetadataEntry implements Metadata.Entry { } /* package */ VariantInfo(Parcel in) { - bitrate = in.readLong(); + averageBitrate = in.readInt(); + peakBitrate = in.readInt(); videoGroupId = in.readString(); audioGroupId = in.readString(); subtitleGroupId = in.readString(); @@ -96,7 +107,8 @@ public final class HlsTrackMetadataEntry implements Metadata.Entry { return false; } VariantInfo that = (VariantInfo) other; - return bitrate == that.bitrate + return averageBitrate == that.averageBitrate + && peakBitrate == that.peakBitrate && TextUtils.equals(videoGroupId, that.videoGroupId) && TextUtils.equals(audioGroupId, that.audioGroupId) && TextUtils.equals(subtitleGroupId, that.subtitleGroupId) @@ -105,7 +117,8 @@ public final class HlsTrackMetadataEntry implements Metadata.Entry { @Override public int hashCode() { - int result = (int) (bitrate ^ (bitrate >>> 32)); + int result = averageBitrate; + result = 31 * result + peakBitrate; result = 31 * result + (videoGroupId != null ? videoGroupId.hashCode() : 0); result = 31 * result + (audioGroupId != null ? audioGroupId.hashCode() : 0); result = 31 * result + (subtitleGroupId != null ? subtitleGroupId.hashCode() : 0); @@ -122,7 +135,8 @@ public final class HlsTrackMetadataEntry implements Metadata.Entry { @Override public void writeToParcel(Parcel dest, int flags) { - dest.writeLong(bitrate); + dest.writeInt(averageBitrate); + dest.writeInt(peakBitrate); dest.writeString(videoGroupId); dest.writeString(audioGroupId); dest.writeString(subtitleGroupId); diff --git a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsPlaylistParser.java b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsPlaylistParser.java index 993ce8e5c1..edd04735f2 100644 --- a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsPlaylistParser.java +++ b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsPlaylistParser.java @@ -303,8 +303,7 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser variantInfosForUrl = urlToVariantInfos.get(uri); + @Nullable ArrayList variantInfosForUrl = urlToVariantInfos.get(uri); if (variantInfosForUrl == null) { variantInfosForUrl = new ArrayList<>(); urlToVariantInfos.put(uri, variantInfosForUrl); } variantInfosForUrl.add( new VariantInfo( - bitrate, videoGroupId, audioGroupId, subtitlesGroupId, closedCaptionsGroupId)); + averageBitrate, + peakBitrate, + videoGroupId, + audioGroupId, + subtitlesGroupId, + closedCaptionsGroupId)); } } diff --git a/library/hls/src/test/java/com/google/android/exoplayer2/source/hls/HlsTrackMetadataEntryTest.java b/library/hls/src/test/java/com/google/android/exoplayer2/source/hls/HlsTrackMetadataEntryTest.java new file mode 100644 index 0000000000..987c2bd1af --- /dev/null +++ b/library/hls/src/test/java/com/google/android/exoplayer2/source/hls/HlsTrackMetadataEntryTest.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.android.exoplayer2.source.hls; + +import static com.google.common.truth.Truth.assertThat; + +import android.os.Parcel; +import androidx.test.ext.junit.runners.AndroidJUnit4; +import com.google.android.exoplayer2.source.hls.HlsTrackMetadataEntry.VariantInfo; +import org.junit.Test; +import org.junit.runner.RunWith; + +/** Test for {@link HlsTrackMetadataEntry}. */ +@RunWith(AndroidJUnit4.class) +public class HlsTrackMetadataEntryTest { + + @Test + public void variantInfo_parcelRoundTrip_isEqual() { + VariantInfo variantInfoToParcel = + new VariantInfo( + /* averageBitrate= */ 1024, + /* peakBitrate= */ 2048, + "videoGroupId", + "audioGroupId", + "subtitleGroupId", + "captionGroupId"); + + Parcel parcel = Parcel.obtain(); + variantInfoToParcel.writeToParcel(parcel, 0); + parcel.setDataPosition(0); + + VariantInfo variantInfoFromParcel = VariantInfo.CREATOR.createFromParcel(parcel); + assertThat(variantInfoFromParcel).isEqualTo(variantInfoToParcel); + + parcel.recycle(); + } +} diff --git a/library/hls/src/test/java/com/google/android/exoplayer2/source/hls/playlist/HlsMasterPlaylistParserTest.java b/library/hls/src/test/java/com/google/android/exoplayer2/source/hls/playlist/HlsMasterPlaylistParserTest.java index 0aa78d9f02..78888d3630 100644 --- a/library/hls/src/test/java/com/google/android/exoplayer2/source/hls/playlist/HlsMasterPlaylistParserTest.java +++ b/library/hls/src/test/java/com/google/android/exoplayer2/source/hls/playlist/HlsMasterPlaylistParserTest.java @@ -352,24 +352,24 @@ public class HlsMasterPlaylistParserTest { assertThat(playlist.variants.get(0).format.metadata) .isEqualTo( createExtXStreamInfMetadata( - createVariantInfo(/* bitrate= */ 2227464, /* audioGroupId= */ "aud1"), - createVariantInfo(/* bitrate= */ 2448841, /* audioGroupId= */ "aud2"), - createVariantInfo(/* bitrate= */ 2256841, /* audioGroupId= */ "aud3"))); + createVariantInfo(/* peakBitrate= */ 2227464, /* audioGroupId= */ "aud1"), + createVariantInfo(/* peakBitrate= */ 2448841, /* audioGroupId= */ "aud2"), + createVariantInfo(/* peakBitrate= */ 2256841, /* audioGroupId= */ "aud3"))); assertThat(playlist.variants.get(1).format.metadata) .isEqualTo( createExtXStreamInfMetadata( - createVariantInfo(/* bitrate= */ 6453202, /* audioGroupId= */ "aud1"), - createVariantInfo(/* bitrate= */ 6482579, /* audioGroupId= */ "aud3"))); + createVariantInfo(/* peakBitrate= */ 6453202, /* audioGroupId= */ "aud1"), + createVariantInfo(/* peakBitrate= */ 6482579, /* audioGroupId= */ "aud3"))); assertThat(playlist.variants.get(2).format.metadata) .isEqualTo( createExtXStreamInfMetadata( - createVariantInfo(/* bitrate= */ 5054232, /* audioGroupId= */ "aud1"), - createVariantInfo(/* bitrate= */ 5275609, /* audioGroupId= */ "aud2"))); + createVariantInfo(/* peakBitrate= */ 5054232, /* audioGroupId= */ "aud1"), + createVariantInfo(/* peakBitrate= */ 5275609, /* audioGroupId= */ "aud2"))); assertThat(playlist.variants.get(3).format.metadata) .isEqualTo( createExtXStreamInfMetadata( - createVariantInfo(/* bitrate= */ 8399417, /* audioGroupId= */ "aud2"), - createVariantInfo(/* bitrate= */ 8207417, /* audioGroupId= */ "aud3"))); + createVariantInfo(/* peakBitrate= */ 8399417, /* audioGroupId= */ "aud2"), + createVariantInfo(/* peakBitrate= */ 8207417, /* audioGroupId= */ "aud3"))); assertThat(playlist.audios).hasSize(3); assertThat(playlist.audios.get(0).format.metadata) @@ -390,9 +390,10 @@ public class HlsMasterPlaylistParserTest { } private static HlsTrackMetadataEntry.VariantInfo createVariantInfo( - long bitrate, String audioGroupId) { + int peakBitrate, String audioGroupId) { return new HlsTrackMetadataEntry.VariantInfo( - bitrate, + /* averageBitrate= */ Format.NO_VALUE, + /* peakBitrate= */ peakBitrate, /* videoGroupId= */ null, audioGroupId, /* subtitleGroupId= */ "sub1",