Remove data capturing logic from ShadowMediaCodecConfig
We're now using CapturingRenderersFactory everywhere PiperOrigin-RevId: 348018988
This commit is contained in:
parent
0d1dac93c4
commit
466826e673
@ -22,10 +22,8 @@ import com.google.android.exoplayer2.metadata.Metadata;
|
||||
import com.google.android.exoplayer2.testutil.CapturingRenderersFactory;
|
||||
import com.google.android.exoplayer2.testutil.Dumper;
|
||||
import com.google.android.exoplayer2.text.Cue;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@ -39,17 +37,13 @@ import java.util.List;
|
||||
*/
|
||||
public final class PlaybackOutput implements Dumper.Dumpable {
|
||||
|
||||
@Nullable private final ShadowMediaCodecConfig codecConfig;
|
||||
@Nullable private final CapturingRenderersFactory capturingRenderersFactory;
|
||||
private final CapturingRenderersFactory capturingRenderersFactory;
|
||||
|
||||
private final List<Metadata> metadatas;
|
||||
private final List<List<Cue>> subtitles;
|
||||
|
||||
private PlaybackOutput(
|
||||
SimpleExoPlayer player,
|
||||
@Nullable ShadowMediaCodecConfig codecConfig,
|
||||
@Nullable CapturingRenderersFactory capturingRenderersFactory) {
|
||||
this.codecConfig = codecConfig;
|
||||
SimpleExoPlayer player, CapturingRenderersFactory capturingRenderersFactory) {
|
||||
this.capturingRenderersFactory = capturingRenderersFactory;
|
||||
|
||||
metadatas = Collections.synchronizedList(new ArrayList<>());
|
||||
@ -75,27 +69,12 @@ public final class PlaybackOutput implements Dumper.Dumpable {
|
||||
*/
|
||||
public static PlaybackOutput register(
|
||||
SimpleExoPlayer player, CapturingRenderersFactory capturingRenderersFactory) {
|
||||
return new PlaybackOutput(player, /* codecConfig= */ null, capturingRenderersFactory);
|
||||
}
|
||||
|
||||
/** @deprecated Use {@link #register(SimpleExoPlayer, CapturingRenderersFactory)}. */
|
||||
@Deprecated
|
||||
public static PlaybackOutput register(
|
||||
SimpleExoPlayer player, ShadowMediaCodecConfig mediaCodecConfig) {
|
||||
return new PlaybackOutput(player, mediaCodecConfig, /* capturingRenderersFactory= */ null);
|
||||
return new PlaybackOutput(player, capturingRenderersFactory);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dump(Dumper dumper) {
|
||||
if (codecConfig != null) {
|
||||
ImmutableMap<String, TeeCodec> codecs = codecConfig.getCodecs();
|
||||
ImmutableList<String> mimeTypes = ImmutableList.sortedCopyOf(codecs.keySet());
|
||||
for (String mimeType : mimeTypes) {
|
||||
dumper.add(Assertions.checkNotNull(codecs.get(mimeType)));
|
||||
}
|
||||
} else {
|
||||
Assertions.checkNotNull(capturingRenderersFactory).dump(dumper);
|
||||
}
|
||||
capturingRenderersFactory.dump(dumper);
|
||||
|
||||
dumpMetadata(dumper);
|
||||
dumpSubtitles(dumper);
|
||||
|
@ -15,17 +15,13 @@
|
||||
*/
|
||||
package com.google.android.exoplayer2.robolectric;
|
||||
|
||||
import android.media.MediaCodec;
|
||||
import android.media.MediaCodecInfo;
|
||||
import android.media.MediaFormat;
|
||||
import com.google.android.exoplayer2.testutil.CapturingRenderersFactory;
|
||||
import com.google.android.exoplayer2.util.MimeTypes;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.primitives.Ints;
|
||||
import java.util.HashMap;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.junit.rules.ExternalResource;
|
||||
import org.robolectric.shadows.MediaCodecInfoBuilder;
|
||||
import org.robolectric.shadows.ShadowMediaCodec;
|
||||
@ -35,30 +31,14 @@ import org.robolectric.shadows.ShadowMediaCodecList;
|
||||
* A JUnit @Rule to configure Roboelectric's {@link ShadowMediaCodec}.
|
||||
*
|
||||
* <p>Registers a {@link org.robolectric.shadows.ShadowMediaCodec.CodecConfig} for each audio/video
|
||||
* MIME type known by ExoPlayer, and provides access to the bytes passed to these via {@link
|
||||
* TeeCodec}.
|
||||
* MIME type known by ExoPlayer.
|
||||
*/
|
||||
public final class ShadowMediaCodecConfig extends ExternalResource {
|
||||
|
||||
private final Map<String, TeeCodec> codecsByMimeType;
|
||||
|
||||
private ShadowMediaCodecConfig() {
|
||||
this.codecsByMimeType = new HashMap<>();
|
||||
}
|
||||
|
||||
public static ShadowMediaCodecConfig forAllSupportedMimeTypes() {
|
||||
return new ShadowMediaCodecConfig();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link CapturingRenderersFactory} to access {@link MediaCodec} interactions
|
||||
* instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public ImmutableMap<String, TeeCodec> getCodecs() {
|
||||
return ImmutableMap.copyOf(codecsByMimeType);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void before() throws Throwable {
|
||||
// Video codecs
|
||||
@ -101,7 +81,6 @@ public final class ShadowMediaCodecConfig extends ExternalResource {
|
||||
|
||||
@Override
|
||||
protected void after() {
|
||||
codecsByMimeType.clear();
|
||||
ShadowMediaCodecList.reset();
|
||||
ShadowMediaCodec.clearCodecs();
|
||||
}
|
||||
@ -136,12 +115,11 @@ public final class ShadowMediaCodecConfig extends ExternalResource {
|
||||
.build());
|
||||
// TODO: Update ShadowMediaCodec to consider the MediaFormat.KEY_MAX_INPUT_SIZE value passed
|
||||
// to configure() so we don't have to specify large buffers here.
|
||||
TeeCodec codec = new TeeCodec(mimeType);
|
||||
CodecImpl codec = new CodecImpl(mimeType);
|
||||
ShadowMediaCodec.addDecoder(
|
||||
codecName,
|
||||
new ShadowMediaCodec.CodecConfig(
|
||||
/* inputBufferSize= */ 100_000, /* outputBufferSize= */ 100_000, codec));
|
||||
codecsByMimeType.put(mimeType, codec);
|
||||
}
|
||||
|
||||
private static MediaCodecInfo.CodecProfileLevel createProfileLevel(int profile, int level) {
|
||||
@ -150,4 +128,30 @@ public final class ShadowMediaCodecConfig extends ExternalResource {
|
||||
profileLevel.level = level;
|
||||
return profileLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* A {@link ShadowMediaCodec.CodecConfig.Codec} that passes data through without modifying it.
|
||||
*
|
||||
* <p>Note: This currently drops all audio data - removing this restriction is tracked in
|
||||
* [internal b/174737370].
|
||||
*/
|
||||
private static final class CodecImpl implements ShadowMediaCodec.CodecConfig.Codec {
|
||||
|
||||
private final String mimeType;
|
||||
|
||||
public CodecImpl(String mimeType) {
|
||||
this.mimeType = mimeType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void process(ByteBuffer in, ByteBuffer out) {
|
||||
byte[] bytes = new byte[in.remaining()];
|
||||
in.get(bytes);
|
||||
|
||||
// TODO(internal b/174737370): Output audio bytes as well.
|
||||
if (!MimeTypes.isAudio(mimeType)) {
|
||||
out.put(bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,81 +0,0 @@
|
||||
/*
|
||||
* 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.robolectric;
|
||||
|
||||
import android.media.MediaCodec;
|
||||
import com.google.android.exoplayer2.testutil.CapturingRenderersFactory;
|
||||
import com.google.android.exoplayer2.testutil.Dumper;
|
||||
import com.google.android.exoplayer2.util.MimeTypes;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.robolectric.shadows.ShadowMediaCodec;
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link CapturingRenderersFactory} to access {@link MediaCodec} interactions
|
||||
* instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public final class TeeCodec implements ShadowMediaCodec.CodecConfig.Codec, Dumper.Dumpable {
|
||||
|
||||
private final String mimeType;
|
||||
private final List<byte[]> receivedBuffers;
|
||||
|
||||
public TeeCodec(String mimeType) {
|
||||
this.mimeType = mimeType;
|
||||
this.receivedBuffers = Collections.synchronizedList(new ArrayList<>());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void process(ByteBuffer in, ByteBuffer out) {
|
||||
byte[] bytes = new byte[in.remaining()];
|
||||
in.get(bytes);
|
||||
receivedBuffers.add(bytes);
|
||||
|
||||
if (!MimeTypes.isAudio(mimeType)) {
|
||||
// Don't output audio bytes, because ShadowAudioTrack doesn't advance the playback position so
|
||||
// playback never completes.
|
||||
// TODO: Update ShadowAudioTrack to advance the playback position in a realistic way.
|
||||
out.put(bytes);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dump(Dumper dumper) {
|
||||
if (receivedBuffers.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
dumper.startBlock("MediaCodec (" + mimeType + ")");
|
||||
dumper.add("buffers.length", receivedBuffers.size());
|
||||
for (int i = 0; i < receivedBuffers.size(); i++) {
|
||||
dumper.add("buffers[" + i + "]", receivedBuffers.get(i));
|
||||
}
|
||||
|
||||
dumper.endBlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the buffers received by this codec.
|
||||
*
|
||||
* <p>The list is sorted in the order the buffers were passed to {@link #process(ByteBuffer,
|
||||
* ByteBuffer)}.
|
||||
*/
|
||||
public ImmutableList<byte[]> getReceivedBuffers() {
|
||||
return ImmutableList.copyOf(receivedBuffers);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user