Modify EventMessageDecoder to return null if decoding fails (currently throws exceptions)

This matches the documentation on MetadataDecoder.decode:
"@return The decoded metadata object, or null if the metadata could not be decoded."

PiperOrigin-RevId: 263767144
This commit is contained in:
ibaker 2019-08-16 15:31:05 +01:00 committed by Toni
parent 89dd105034
commit 01f484cbe9
3 changed files with 37 additions and 15 deletions

View File

@ -15,6 +15,7 @@
*/
package com.google.android.exoplayer2.metadata.emsg;
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;
@ -28,21 +29,31 @@ public final class EventMessageDecoder implements MetadataDecoder {
@SuppressWarnings("ByteBufferBackingArray")
@Override
@Nullable
public Metadata decode(MetadataInputBuffer inputBuffer) {
ByteBuffer buffer = Assertions.checkNotNull(inputBuffer.data);
byte[] data = buffer.array();
int size = buffer.limit();
return new Metadata(decode(new ParsableByteArray(data, size)));
EventMessage decodedEventMessage = decode(new ParsableByteArray(data, size));
if (decodedEventMessage == null) {
return null;
} else {
return new Metadata(decodedEventMessage);
}
}
@Nullable
public EventMessage decode(ParsableByteArray emsgData) {
String schemeIdUri = Assertions.checkNotNull(emsgData.readNullTerminatedString());
String value = Assertions.checkNotNull(emsgData.readNullTerminatedString());
long durationMs = emsgData.readUnsignedInt();
long id = emsgData.readUnsignedInt();
byte[] messageData =
Arrays.copyOfRange(emsgData.data, emsgData.getPosition(), emsgData.limit());
return new EventMessage(schemeIdUri, value, durationMs, id, messageData);
try {
String schemeIdUri = Assertions.checkNotNull(emsgData.readNullTerminatedString());
String value = Assertions.checkNotNull(emsgData.readNullTerminatedString());
long durationMs = emsgData.readUnsignedInt();
long id = emsgData.readUnsignedInt();
byte[] messageData =
Arrays.copyOfRange(emsgData.data, emsgData.getPosition(), emsgData.limit());
return new EventMessage(schemeIdUri, value, durationMs, id, messageData);
} catch (RuntimeException e) {
return null;
}
}
}

View File

@ -55,13 +55,20 @@ public class MetadataRendererTest {
/* id= */ 0,
"Test data".getBytes(UTF_8));
List<Metadata> metadata = runRenderer(eventMessageEncoder.encode(emsg));
List<Metadata> metadata = runRenderer(EMSG_FORMAT, eventMessageEncoder.encode(emsg));
assertThat(metadata).hasSize(1);
assertThat(metadata.get(0).length()).isEqualTo(1);
assertThat(metadata.get(0).get(0)).isEqualTo(emsg);
}
@Test
public void decodeMetadata_skipsMalformed() throws Exception {
List<Metadata> metadata = runRenderer(EMSG_FORMAT, "not valid emsg bytes".getBytes(UTF_8));
assertThat(metadata).isEmpty();
}
@Test
public void decodeMetadata_handlesWrappedMetadata() throws Exception {
EventMessage emsg =
@ -72,7 +79,7 @@ public class MetadataRendererTest {
/* id= */ 0,
encodeTxxxId3Frame("Test description", "Test value"));
List<Metadata> metadata = runRenderer(eventMessageEncoder.encode(emsg));
List<Metadata> metadata = runRenderer(EMSG_FORMAT, eventMessageEncoder.encode(emsg));
assertThat(metadata).hasSize(1);
assertThat(metadata.get(0).length()).isEqualTo(1);
@ -91,17 +98,18 @@ public class MetadataRendererTest {
/* id= */ 0,
"Not a real ID3 tag".getBytes(ISO_8859_1));
List<Metadata> metadata = runRenderer(eventMessageEncoder.encode(emsg));
List<Metadata> metadata = runRenderer(EMSG_FORMAT, eventMessageEncoder.encode(emsg));
assertThat(metadata).isEmpty();
}
private static List<Metadata> runRenderer(byte[] input) throws ExoPlaybackException {
private static List<Metadata> runRenderer(Format format, byte[] input)
throws ExoPlaybackException {
List<Metadata> metadata = new ArrayList<>();
MetadataRenderer renderer = new MetadataRenderer(metadata::add, /* outputLooper= */ null);
renderer.replaceStream(
new Format[] {EMSG_FORMAT},
new FakeSampleStream(EMSG_FORMAT, /* eventDispatcher= */ null, input),
new Format[] {format},
new FakeSampleStream(format, /* eventDispatcher= */ null, input),
/* offsetUs= */ 0L);
renderer.render(/* positionUs= */ 0, /* elapsedRealtimeUs= */ 0); // Read the format
renderer.render(/* positionUs= */ 0, /* elapsedRealtimeUs= */ 0); // Read the data

View File

@ -360,6 +360,9 @@ public final class PlayerEmsgHandler implements Handler.Callback {
}
long eventTimeUs = inputBuffer.timeUs;
Metadata metadata = decoder.decode(inputBuffer);
if (metadata == null) {
continue;
}
EventMessage eventMessage = (EventMessage) metadata.get(0);
if (isPlayerEmsgEvent(eventMessage.schemeIdUri, eventMessage.value)) {
parsePlayerEmsgEvent(eventTimeUs, eventMessage);