From 18ab4b9112a8b0affac9ce1c4a376e08c7478ced Mon Sep 17 00:00:00 2001 From: olly Date: Thu, 12 Jul 2018 12:06:40 -0700 Subject: [PATCH] Fix / improve format merging 1. Prefer label and language values in the manifest to those in the media. This is particularly helpful if the sample format contains "und" as the language. 2. Copy label when deriving formats in HlsSampleStreamWrapper 3. When there's only one variant in HlsSampleStreamWrapper, use the regular copyWithManifestFormatInfo. This allows more information to be retained from the sample format. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=204340008 --- .../java/com/google/android/exoplayer2/Format.java | 13 ++++++++++--- .../source/hls/HlsSampleStreamWrapper.java | 12 +++++++++--- .../exoplayer2/ui/DefaultTrackNameProvider.java | 10 +++++++--- 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/library/core/src/main/java/com/google/android/exoplayer2/Format.java b/library/core/src/main/java/com/google/android/exoplayer2/Format.java index cf00173bbe..61cc50dfc5 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/Format.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/Format.java @@ -1041,6 +1041,7 @@ public final class Format implements Parcelable { public Format copyWithContainerInfo( @Nullable String id, + @Nullable String label, @Nullable String sampleMimeType, @Nullable String codecs, int bitrate, @@ -1084,15 +1085,21 @@ public final class Format implements Parcelable { // No need to copy from ourselves. return this; } + + // Use manifest value only. String id = manifestFormat.id; + // Prefer manifest values, but fill in from sample format if missing. + String label = manifestFormat.label != null ? manifestFormat.label : this.label; + String language = manifestFormat.language != null ? manifestFormat.language : this.language; + // Prefer sample format values, but fill in from manifest if missing. String codecs = this.codecs == null ? manifestFormat.codecs : this.codecs; int bitrate = this.bitrate == NO_VALUE ? manifestFormat.bitrate : this.bitrate; float frameRate = this.frameRate == NO_VALUE ? manifestFormat.frameRate : this.frameRate; - @C.SelectionFlags int selectionFlags = this.selectionFlags | manifestFormat.selectionFlags; - String language = this.language == null ? manifestFormat.language : this.language; - String label = this.label == null ? manifestFormat.label : this.label; + // Merge manifest and sample format values. + @C.SelectionFlags int selectionFlags = this.selectionFlags | manifestFormat.selectionFlags; DrmInitData drmInitData = DrmInitData.createSessionCreationData(manifestFormat.drmInitData, this.drmInitData); + return new Format( id, label, diff --git a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java index 01def14006..ff16d271f3 100644 --- a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java +++ b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java @@ -948,8 +948,12 @@ import java.util.List; Format sampleFormat = sampleQueues[i].getUpstreamFormat(); if (i == primaryExtractorTrackIndex) { Format[] formats = new Format[chunkSourceTrackCount]; - for (int j = 0; j < chunkSourceTrackCount; j++) { - formats[j] = deriveFormat(chunkSourceTrackGroup.getFormat(j), sampleFormat, true); + if (chunkSourceTrackCount == 1) { + formats[0] = sampleFormat.copyWithManifestFormatInfo(chunkSourceTrackGroup.getFormat(0)); + } else { + for (int j = 0; j < chunkSourceTrackCount; j++) { + formats[j] = deriveFormat(chunkSourceTrackGroup.getFormat(j), sampleFormat, true); + } } trackGroups[i] = new TrackGroup(formats); primaryTrackGroupIndex = i; @@ -997,7 +1001,8 @@ import java.util.List; } /** - * Derives a track format using master playlist and sample format information. + * Derives a track sample format from the corresponding format in the master playlist, and a + * sample format that may have been obtained from a chunk belonging to a different track. * * @param playlistFormat The format information obtained from the master playlist. * @param sampleFormat The format information obtained from the samples. @@ -1019,6 +1024,7 @@ import java.util.List; } return sampleFormat.copyWithContainerInfo( playlistFormat.id, + playlistFormat.label, mimeType, codecs, bitrate, diff --git a/library/ui/src/main/java/com/google/android/exoplayer2/ui/DefaultTrackNameProvider.java b/library/ui/src/main/java/com/google/android/exoplayer2/ui/DefaultTrackNameProvider.java index b36941e999..5d68387869 100644 --- a/library/ui/src/main/java/com/google/android/exoplayer2/ui/DefaultTrackNameProvider.java +++ b/library/ui/src/main/java/com/google/android/exoplayer2/ui/DefaultTrackNameProvider.java @@ -43,11 +43,11 @@ public class DefaultTrackNameProvider implements TrackNameProvider { } else if (trackType == C.TRACK_TYPE_AUDIO) { trackName = joinWithSeparator( - buildLanguageString(format), + buildLabelString(format), buildAudioChannelString(format), buildBitrateString(format)); } else { - trackName = buildLanguageString(format); + trackName = buildLabelString(format); } return trackName.length() == 0 ? resources.getString(R.string.exo_track_unknown) : trackName; } @@ -87,7 +87,11 @@ public class DefaultTrackNameProvider implements TrackNameProvider { } } - private String buildLanguageString(Format format) { + private String buildLabelString(Format format) { + if (!TextUtils.isEmpty(format.label)) { + return format.label; + } + // Fall back to using the language. String language = format.language; return TextUtils.isEmpty(language) || C.LANGUAGE_UNDETERMINED.equals(language) ? ""