mirror of
https://github.com/androidx/media.git
synced 2025-05-16 20:19:57 +08:00
Add NonNull annotations to metadata packages
Also remove MetadataRenderer and SpliceInfoDecoder from the nullness blacklist PiperOrigin-RevId: 283744417
This commit is contained in:
parent
b7666df2b3
commit
3930a539e0
@ -22,7 +22,6 @@ import com.google.android.exoplayer2.Format;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.checkerframework.checker.nullness.compatqual.NullableType;
|
||||
|
||||
/**
|
||||
* A collection of metadata entries.
|
||||
@ -57,19 +56,15 @@ public final class Metadata implements Parcelable {
|
||||
* @param entries The metadata entries.
|
||||
*/
|
||||
public Metadata(Entry... entries) {
|
||||
this.entries = entries == null ? new Entry[0] : entries;
|
||||
this.entries = entries;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param entries The metadata entries.
|
||||
*/
|
||||
public Metadata(List<? extends Entry> entries) {
|
||||
if (entries != null) {
|
||||
this.entries = new Entry[entries.size()];
|
||||
entries.toArray(this.entries);
|
||||
} else {
|
||||
this.entries = new Entry[0];
|
||||
}
|
||||
this.entries = new Entry[entries.size()];
|
||||
entries.toArray(this.entries);
|
||||
}
|
||||
|
||||
/* package */ Metadata(Parcel in) {
|
||||
@ -118,9 +113,10 @@ public final class Metadata implements Parcelable {
|
||||
* @return The metadata instance with the appended entries.
|
||||
*/
|
||||
public Metadata copyWithAppendedEntries(Entry... entriesToAppend) {
|
||||
@NullableType Entry[] merged = Arrays.copyOf(entries, entries.length + entriesToAppend.length);
|
||||
System.arraycopy(entriesToAppend, 0, merged, entries.length, entriesToAppend.length);
|
||||
return new Metadata(Util.castNonNullTypeArray(merged));
|
||||
if (entriesToAppend.length == 0) {
|
||||
return this;
|
||||
}
|
||||
return new Metadata(Util.nullSafeArrayConcatenation(entries, entriesToAppend));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.google.android.exoplayer2.metadata;
|
||||
|
||||
import static com.google.android.exoplayer2.util.Util.castNonNull;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.os.Handler.Callback;
|
||||
import android.os.Looper;
|
||||
@ -22,7 +24,6 @@ import android.os.Message;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.BaseRenderer;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.ExoPlaybackException;
|
||||
import com.google.android.exoplayer2.Format;
|
||||
import com.google.android.exoplayer2.FormatHolder;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
@ -30,6 +31,7 @@ import com.google.android.exoplayer2.util.Util;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.checkerframework.checker.nullness.compatqual.NullableType;
|
||||
|
||||
/**
|
||||
* A renderer for metadata.
|
||||
@ -46,12 +48,12 @@ public final class MetadataRenderer extends BaseRenderer implements Callback {
|
||||
private final MetadataOutput output;
|
||||
@Nullable private final Handler outputHandler;
|
||||
private final MetadataInputBuffer buffer;
|
||||
private final Metadata[] pendingMetadata;
|
||||
private final @NullableType Metadata[] pendingMetadata;
|
||||
private final long[] pendingMetadataTimestamps;
|
||||
|
||||
private int pendingMetadataIndex;
|
||||
private int pendingMetadataCount;
|
||||
private MetadataDecoder decoder;
|
||||
@Nullable private MetadataDecoder decoder;
|
||||
private boolean inputStreamEnded;
|
||||
private long subsampleOffsetUs;
|
||||
|
||||
@ -98,7 +100,7 @@ public final class MetadataRenderer extends BaseRenderer implements Callback {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStreamChanged(Format[] formats, long offsetUs) throws ExoPlaybackException {
|
||||
protected void onStreamChanged(Format[] formats, long offsetUs) {
|
||||
decoder = decoderFactory.createDecoder(formats[0]);
|
||||
}
|
||||
|
||||
@ -109,7 +111,7 @@ public final class MetadataRenderer extends BaseRenderer implements Callback {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(long positionUs, long elapsedRealtimeUs) throws ExoPlaybackException {
|
||||
public void render(long positionUs, long elapsedRealtimeUs) {
|
||||
if (!inputStreamEnded && pendingMetadataCount < MAX_PENDING_METADATA_COUNT) {
|
||||
buffer.clear();
|
||||
FormatHolder formatHolder = getFormatHolder();
|
||||
@ -124,7 +126,7 @@ public final class MetadataRenderer extends BaseRenderer implements Callback {
|
||||
} else {
|
||||
buffer.subsampleOffsetUs = subsampleOffsetUs;
|
||||
buffer.flip();
|
||||
Metadata metadata = decoder.decode(buffer);
|
||||
@Nullable Metadata metadata = castNonNull(decoder).decode(buffer);
|
||||
if (metadata != null) {
|
||||
List<Metadata.Entry> entries = new ArrayList<>(metadata.length());
|
||||
decodeWrappedMetadata(metadata, entries);
|
||||
@ -139,12 +141,13 @@ public final class MetadataRenderer extends BaseRenderer implements Callback {
|
||||
}
|
||||
}
|
||||
} else if (result == C.RESULT_FORMAT_READ) {
|
||||
subsampleOffsetUs = formatHolder.format.subsampleOffsetUs;
|
||||
subsampleOffsetUs = Assertions.checkNotNull(formatHolder.format).subsampleOffsetUs;
|
||||
}
|
||||
}
|
||||
|
||||
if (pendingMetadataCount > 0 && pendingMetadataTimestamps[pendingMetadataIndex] <= positionUs) {
|
||||
invokeRenderer(pendingMetadata[pendingMetadataIndex]);
|
||||
Metadata metadata = castNonNull(pendingMetadata[pendingMetadataIndex]);
|
||||
invokeRenderer(metadata);
|
||||
pendingMetadata[pendingMetadataIndex] = null;
|
||||
pendingMetadataIndex = (pendingMetadataIndex + 1) % MAX_PENDING_METADATA_COUNT;
|
||||
pendingMetadataCount--;
|
||||
@ -158,7 +161,7 @@ public final class MetadataRenderer extends BaseRenderer implements Callback {
|
||||
*/
|
||||
private void decodeWrappedMetadata(Metadata metadata, List<Metadata.Entry> decodedEntries) {
|
||||
for (int i = 0; i < metadata.length(); i++) {
|
||||
Format wrappedMetadataFormat = metadata.get(i).getWrappedMetadataFormat();
|
||||
@Nullable Format wrappedMetadataFormat = metadata.get(i).getWrappedMetadataFormat();
|
||||
if (wrappedMetadataFormat != null && decoderFactory.supportsFormat(wrappedMetadataFormat)) {
|
||||
MetadataDecoder wrappedMetadataDecoder =
|
||||
decoderFactory.createDecoder(wrappedMetadataFormat);
|
||||
@ -167,7 +170,7 @@ public final class MetadataRenderer extends BaseRenderer implements Callback {
|
||||
Assertions.checkNotNull(metadata.get(i).getWrappedMetadataBytes());
|
||||
buffer.clear();
|
||||
buffer.ensureSpaceForWrite(wrappedMetadataBytes.length);
|
||||
buffer.data.put(wrappedMetadataBytes);
|
||||
castNonNull(buffer.data).put(wrappedMetadataBytes);
|
||||
buffer.flip();
|
||||
@Nullable Metadata innerMetadata = wrappedMetadataDecoder.decode(buffer);
|
||||
if (innerMetadata != null) {
|
||||
|
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2019 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.
|
||||
*/
|
||||
@NonNullApi
|
||||
package com.google.android.exoplayer2.metadata.emsg;
|
||||
|
||||
import com.google.android.exoplayer2.util.NonNullApi;
|
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2019 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.
|
||||
*/
|
||||
@NonNullApi
|
||||
package com.google.android.exoplayer2.metadata.flac;
|
||||
|
||||
import com.google.android.exoplayer2.util.NonNullApi;
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.google.android.exoplayer2.metadata.icy;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import com.google.android.exoplayer2.metadata.Metadata;
|
||||
import com.google.android.exoplayer2.metadata.MetadataDecoder;
|
||||
@ -28,8 +29,6 @@ import java.util.regex.Pattern;
|
||||
/** Decodes ICY stream information. */
|
||||
public final class IcyDecoder implements MetadataDecoder {
|
||||
|
||||
private static final String TAG = "IcyDecoder";
|
||||
|
||||
private static final Pattern METADATA_ELEMENT = Pattern.compile("(.+?)='(.*?)';", Pattern.DOTALL);
|
||||
private static final String STREAM_KEY_NAME = "streamtitle";
|
||||
private static final String STREAM_KEY_URL = "streamurl";
|
||||
@ -45,8 +44,8 @@ public final class IcyDecoder implements MetadataDecoder {
|
||||
|
||||
@VisibleForTesting
|
||||
/* package */ Metadata decode(String metadata) {
|
||||
String name = null;
|
||||
String url = null;
|
||||
@Nullable String name = null;
|
||||
@Nullable String url = null;
|
||||
int index = 0;
|
||||
Matcher matcher = METADATA_ELEMENT.matcher(metadata);
|
||||
while (matcher.find(index)) {
|
||||
|
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2019 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.
|
||||
*/
|
||||
@NonNullApi
|
||||
package com.google.android.exoplayer2.metadata.icy;
|
||||
|
||||
import com.google.android.exoplayer2.util.NonNullApi;
|
@ -47,7 +47,7 @@ public final class ApicFrame extends Id3Frame {
|
||||
/* package */ ApicFrame(Parcel in) {
|
||||
super(ID);
|
||||
mimeType = castNonNull(in.readString());
|
||||
description = castNonNull(in.readString());
|
||||
description = in.readString();
|
||||
pictureType = in.readInt();
|
||||
pictureData = castNonNull(in.createByteArray());
|
||||
}
|
||||
|
@ -155,7 +155,8 @@ public final class Id3Decoder implements MetadataDecoder {
|
||||
* @param data A {@link ParsableByteArray} from which the header should be read.
|
||||
* @return The parsed header, or null if the ID3 tag is unsupported.
|
||||
*/
|
||||
private static @Nullable Id3Header decodeHeader(ParsableByteArray data) {
|
||||
@Nullable
|
||||
private static Id3Header decodeHeader(ParsableByteArray data) {
|
||||
if (data.bytesLeft() < ID3_HEADER_LENGTH) {
|
||||
Log.w(TAG, "Data too short to be an ID3 tag");
|
||||
return null;
|
||||
@ -269,7 +270,8 @@ public final class Id3Decoder implements MetadataDecoder {
|
||||
}
|
||||
}
|
||||
|
||||
private static @Nullable Id3Frame decodeFrame(
|
||||
@Nullable
|
||||
private static Id3Frame decodeFrame(
|
||||
int majorVersion,
|
||||
ParsableByteArray id3Data,
|
||||
boolean unsignedIntFrameSizeHack,
|
||||
@ -404,8 +406,9 @@ public final class Id3Decoder implements MetadataDecoder {
|
||||
}
|
||||
}
|
||||
|
||||
private static @Nullable TextInformationFrame decodeTxxxFrame(
|
||||
ParsableByteArray id3Data, int frameSize) throws UnsupportedEncodingException {
|
||||
@Nullable
|
||||
private static TextInformationFrame decodeTxxxFrame(ParsableByteArray id3Data, int frameSize)
|
||||
throws UnsupportedEncodingException {
|
||||
if (frameSize < 1) {
|
||||
// Frame is malformed.
|
||||
return null;
|
||||
@ -427,7 +430,8 @@ public final class Id3Decoder implements MetadataDecoder {
|
||||
return new TextInformationFrame("TXXX", description, value);
|
||||
}
|
||||
|
||||
private static @Nullable TextInformationFrame decodeTextInformationFrame(
|
||||
@Nullable
|
||||
private static TextInformationFrame decodeTextInformationFrame(
|
||||
ParsableByteArray id3Data, int frameSize, String id) throws UnsupportedEncodingException {
|
||||
if (frameSize < 1) {
|
||||
// Frame is malformed.
|
||||
@ -446,7 +450,8 @@ public final class Id3Decoder implements MetadataDecoder {
|
||||
return new TextInformationFrame(id, null, value);
|
||||
}
|
||||
|
||||
private static @Nullable UrlLinkFrame decodeWxxxFrame(ParsableByteArray id3Data, int frameSize)
|
||||
@Nullable
|
||||
private static UrlLinkFrame decodeWxxxFrame(ParsableByteArray id3Data, int frameSize)
|
||||
throws UnsupportedEncodingException {
|
||||
if (frameSize < 1) {
|
||||
// Frame is malformed.
|
||||
@ -557,7 +562,8 @@ public final class Id3Decoder implements MetadataDecoder {
|
||||
return new ApicFrame(mimeType, description, pictureType, pictureData);
|
||||
}
|
||||
|
||||
private static @Nullable CommentFrame decodeCommentFrame(ParsableByteArray id3Data, int frameSize)
|
||||
@Nullable
|
||||
private static CommentFrame decodeCommentFrame(ParsableByteArray id3Data, int frameSize)
|
||||
throws UnsupportedEncodingException {
|
||||
if (frameSize < 4) {
|
||||
// Frame is malformed.
|
||||
|
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2019 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.
|
||||
*/
|
||||
@NonNullApi
|
||||
package com.google.android.exoplayer2.metadata.id3;
|
||||
|
||||
import com.google.android.exoplayer2.util.NonNullApi;
|
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2019 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.
|
||||
*/
|
||||
@NonNullApi
|
||||
package com.google.android.exoplayer2.metadata;
|
||||
|
||||
import com.google.android.exoplayer2.util.NonNullApi;
|
@ -15,13 +15,16 @@
|
||||
*/
|
||||
package com.google.android.exoplayer2.metadata.scte35;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.metadata.Metadata;
|
||||
import com.google.android.exoplayer2.metadata.MetadataDecoder;
|
||||
import com.google.android.exoplayer2.metadata.MetadataInputBuffer;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.ParsableBitArray;
|
||||
import com.google.android.exoplayer2.util.ParsableByteArray;
|
||||
import com.google.android.exoplayer2.util.TimestampAdjuster;
|
||||
import java.nio.ByteBuffer;
|
||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
|
||||
/**
|
||||
* Decodes splice info sections and produces splice commands.
|
||||
@ -37,7 +40,7 @@ public final class SpliceInfoDecoder implements MetadataDecoder {
|
||||
private final ParsableByteArray sectionData;
|
||||
private final ParsableBitArray sectionHeader;
|
||||
|
||||
private TimestampAdjuster timestampAdjuster;
|
||||
@MonotonicNonNull private TimestampAdjuster timestampAdjuster;
|
||||
|
||||
public SpliceInfoDecoder() {
|
||||
sectionData = new ParsableByteArray();
|
||||
@ -47,6 +50,8 @@ public final class SpliceInfoDecoder implements MetadataDecoder {
|
||||
@SuppressWarnings("ByteBufferBackingArray")
|
||||
@Override
|
||||
public Metadata decode(MetadataInputBuffer inputBuffer) {
|
||||
ByteBuffer buffer = Assertions.checkNotNull(inputBuffer.data);
|
||||
|
||||
// Internal timestamps adjustment.
|
||||
if (timestampAdjuster == null
|
||||
|| inputBuffer.subsampleOffsetUs != timestampAdjuster.getTimestampOffsetUs()) {
|
||||
@ -54,7 +59,6 @@ public final class SpliceInfoDecoder implements MetadataDecoder {
|
||||
timestampAdjuster.adjustSampleTimestamp(inputBuffer.timeUs - inputBuffer.subsampleOffsetUs);
|
||||
}
|
||||
|
||||
ByteBuffer buffer = inputBuffer.data;
|
||||
byte[] data = buffer.array();
|
||||
int size = buffer.limit();
|
||||
sectionData.reset(data, size);
|
||||
@ -68,7 +72,7 @@ public final class SpliceInfoDecoder implements MetadataDecoder {
|
||||
sectionHeader.skipBits(20);
|
||||
int spliceCommandLength = sectionHeader.readBits(12);
|
||||
int spliceCommandType = sectionHeader.readBits(8);
|
||||
SpliceCommand command = null;
|
||||
@Nullable SpliceCommand command = null;
|
||||
// Go to the start of the command by skipping all fields up to command_type.
|
||||
sectionData.skipBytes(14);
|
||||
switch (spliceCommandType) {
|
||||
|
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2019 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.
|
||||
*/
|
||||
@NonNullApi
|
||||
package com.google.android.exoplayer2.metadata.scte35;
|
||||
|
||||
import com.google.android.exoplayer2.util.NonNullApi;
|
Loading…
x
Reference in New Issue
Block a user