Commit 42d4afe7 by olly Committed by Oliver Woodman

Make Format.Builder, peakBitrate and averageBitrate public

- Deprecate old Format.createXXX methods
- Deprecate most Format.copyXXX methods
- Stop using deprecated Format.copyXXX methods in the library

Note: Replacing library usages of Format.createXXX method
will be done in follow up CLs. These changes aren't purely
mechanical because we need to decide which out of peakBitrate
and averageBitrate to set in each case where currently a
single bitrate is provided.

Issue: #2863
PiperOrigin-RevId: 296450935
parent 4c05201a
......@@ -32,6 +32,10 @@
* Add a sample count parameter to `MediaCodecRenderer.processOutputBuffer`
and `AudioSink.handleBuffer` to allow batching multiple encoded frames
in one buffer.
* Add a `Format.Builder` and deprecate all `Format.create*` methods and most
`Format.copyWith*` methods.
* Split `Format.bitrate` into `Format.averageBitrate` and `Format.peakBitrate`
([#2863](https://github.com/google/ExoPlayer/issues/2863)).
* Text:
* Parse `<ruby>` and `<rt>` tags in WebVTT subtitles (rendering is coming
later).
......
......@@ -32,7 +32,11 @@ import java.util.Map;
*/
public final class DataSpec {
/** Builds {@link DataSpec} instances. */
/**
* Builds {@link DataSpec} instances.
*
* <p>Use DataSpec#buildUpon() to obtain a builder representing an existing {@link DataSpec}.
*/
public static final class Builder {
@Nullable private Uri uri;
......
......@@ -699,7 +699,8 @@ public final class PlaybackStatsListener
*/
public void onVideoSizeChanged(EventTime eventTime, int width, int height) {
if (currentVideoFormat != null && currentVideoFormat.height == Format.NO_VALUE) {
Format formatWithHeight = currentVideoFormat.copyWithVideoSize(width, height);
Format formatWithHeight =
currentVideoFormat.buildUpon().setWidth(width).setHeight(height).build();
maybeUpdateVideoFormat(eventTime, formatWithHeight);
}
}
......
......@@ -317,7 +317,12 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb
// Clear gapless playback metadata if the start/end points don't match the media.
int encoderDelay = startUs != 0 ? 0 : format.encoderDelay;
int encoderPadding = endUs != C.TIME_END_OF_SOURCE ? 0 : format.encoderPadding;
formatHolder.format = format.copyWithGaplessInfo(encoderDelay, encoderPadding);
formatHolder.format =
format
.buildUpon()
.setEncoderDelay(encoderDelay)
.setEncoderPadding(encoderPadding)
.build();
}
return C.RESULT_FORMAT_READ;
}
......
......@@ -734,10 +734,13 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
? new Metadata(icyHeaders)
: metadata.copyWithAppendedEntries(icyHeaders));
}
// Update the track format with the bitrate from the ICY header only if it declares neither
// an average or peak bitrate of its own.
if (isAudio
&& trackFormat.bitrate == Format.NO_VALUE
&& trackFormat.averageBitrate == Format.NO_VALUE
&& trackFormat.peakBitrate == Format.NO_VALUE
&& icyHeaders.bitrate != Format.NO_VALUE) {
trackFormat = trackFormat.copyWithBitrate(icyHeaders.bitrate);
trackFormat = trackFormat.buildUpon().setAverageBitrate(icyHeaders.bitrate).build();
}
}
trackArray[i] = new TrackGroup(trackFormat);
......
......@@ -197,8 +197,8 @@ public final class ChunkExtractorWrapper implements ExtractorOutput {
@Override
public void format(Format format) {
sampleFormat = manifestFormat != null ? format.copyWithManifestFormatInfo(manifestFormat)
: format;
sampleFormat =
manifestFormat != null ? format.withManifestFormatInfo(manifestFormat) : format;
castNonNull(trackOutput).format(sampleFormat);
}
......
......@@ -98,7 +98,7 @@ public final class DashUtil {
Format sampleFormat = DashUtil.loadSampleFormat(dataSource, primaryTrackType, representation);
return sampleFormat == null
? manifestFormat.drmInitData
: sampleFormat.copyWithManifestFormatInfo(manifestFormat).drmInitData;
: sampleFormat.withManifestFormatInfo(manifestFormat).drmInitData;
}
/**
......
......@@ -284,25 +284,22 @@ import com.google.android.exoplayer2.util.ParsableByteArray;
private MetadataUtil() {}
/**
* Returns a {@link Format} that is the same as the input format but includes information from the
* specified sources of metadata.
*/
public static Format getFormatWithMetadata(
/** Updates a {@link Format.Builder} to include metadata from the provided sources. */
public static void setFormatMetadata(
int trackType,
Format format,
@Nullable Metadata udtaMetadata,
@Nullable Metadata mdtaMetadata,
GaplessInfoHolder gaplessInfoHolder) {
GaplessInfoHolder gaplessInfoHolder,
Format.Builder formatBuilder) {
if (trackType == C.TRACK_TYPE_AUDIO) {
if (gaplessInfoHolder.hasGaplessInfo()) {
format =
format.copyWithGaplessInfo(
gaplessInfoHolder.encoderDelay, gaplessInfoHolder.encoderPadding);
formatBuilder
.setEncoderDelay(gaplessInfoHolder.encoderDelay)
.setEncoderPadding(gaplessInfoHolder.encoderPadding);
}
// We assume all udta metadata is associated with the audio track.
if (udtaMetadata != null) {
format = format.copyWithMetadata(udtaMetadata);
formatBuilder.setMetadata(udtaMetadata);
}
} else if (trackType == C.TRACK_TYPE_VIDEO && mdtaMetadata != null) {
// Populate only metadata keys that are known to be specific to video.
......@@ -311,12 +308,11 @@ import com.google.android.exoplayer2.util.ParsableByteArray;
if (entry instanceof MdtaMetadataEntry) {
MdtaMetadataEntry mdtaMetadataEntry = (MdtaMetadataEntry) entry;
if (MDTA_KEY_ANDROID_CAPTURE_FPS.equals(mdtaMetadataEntry.key)) {
format = format.copyWithMetadata(new Metadata(mdtaMetadataEntry));
formatBuilder.setMetadata(new Metadata(mdtaMetadataEntry));
}
}
}
}
return format;
}
/**
......
......@@ -423,17 +423,17 @@ public final class Mp4Extractor implements Extractor, SeekMap {
// Each sample has up to three bytes of overhead for the start code that replaces its length.
// Allow ten source samples per output sample, like the platform extractor.
int maxInputSize = trackSampleTable.maximumSize + 3 * 10;
Format format = track.format.copyWithMaxInputSize(maxInputSize);
Format.Builder formatBuilder = track.format.buildUpon();
formatBuilder.setMaxInputSize(maxInputSize);
if (track.type == C.TRACK_TYPE_VIDEO
&& trackDurationUs > 0
&& trackSampleTable.sampleCount > 1) {
float frameRate = trackSampleTable.sampleCount / (trackDurationUs / 1000000f);
format = format.copyWithFrameRate(frameRate);
formatBuilder.setFrameRate(frameRate);
}
format =
MetadataUtil.getFormatWithMetadata(
track.type, format, udtaMetadata, mdtaMetadata, gaplessInfoHolder);
mp4Track.trackOutput.format(format);
MetadataUtil.setFormatMetadata(
track.type, udtaMetadata, mdtaMetadata, gaplessInfoHolder, formatBuilder);
mp4Track.trackOutput.format(formatBuilder.build());
if (track.type == C.TRACK_TYPE_VIDEO && firstVideoTrackIndex == C.INDEX_UNSET) {
firstVideoTrackIndex = tracks.size();
......
......@@ -568,7 +568,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
chunkIndex < mediaChunks.size()
? mediaChunks.get(chunkIndex).trackFormat
: Assertions.checkNotNull(upstreamTrackFormat);
format = format.copyWithManifestFormatInfo(trackFormat);
format = format.withManifestFormatInfo(trackFormat);
}
formatHolder.format = format;
}
......@@ -1160,7 +1160,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
if (i == primaryExtractorTrackIndex) {
Format[] formats = new Format[chunkSourceTrackCount];
if (chunkSourceTrackCount == 1) {
formats[0] = sampleFormat.copyWithManifestFormatInfo(chunkSourceTrackGroup.getFormat(0));
formats[0] = sampleFormat.withManifestFormatInfo(chunkSourceTrackGroup.getFormat(0));
} else {
for (int j = 0; j < chunkSourceTrackCount; j++) {
formats[j] = deriveFormat(chunkSourceTrackGroup.getFormat(j), sampleFormat, true);
......@@ -1346,6 +1346,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
invalidateUpstreamFormatAdjustment();
}
@SuppressWarnings("ReferenceEquality")
@Override
public Format getAdjustedUpstreamFormat(Format format) {
@Nullable
......@@ -1357,8 +1358,11 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
drmInitData = overridingDrmInitData;
}
}
return super.getAdjustedUpstreamFormat(
format.copyWithAdjustments(drmInitData, getAdjustedMetadata(format.metadata)));
@Nullable Metadata metadata = getAdjustedMetadata(format.metadata);
if (drmInitData != format.drmInitData || metadata != format.metadata) {
format = format.buildUpon().setDrmInitData(drmInitData).setMetadata(metadata).build();
}
return super.getAdjustedUpstreamFormat(format);
}
/**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment