summaryrefslogtreecommitdiff
path: root/apex/media
diff options
context:
space:
mode:
authorSantiago Seifert <aquilescanta@google.com>2020-04-17 17:36:26 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2020-04-17 17:36:26 +0000
commit26e55eb8ab8a8a476ca63d81e5567c16443c056b (patch)
tree0f83c387429882d9c79bad797fca6837e3963d5f /apex/media
parent40d714dc8d3ff70d8a4ee607903f052681abe554 (diff)
parentc6955798175589f240fbacd120d289d1148aceae (diff)
Merge "Populate some missing fields in TrackData" into rvc-dev
Diffstat (limited to 'apex/media')
-rw-r--r--apex/media/framework/java/android/media/MediaParser.java90
1 files changed, 82 insertions, 8 deletions
diff --git a/apex/media/framework/java/android/media/MediaParser.java b/apex/media/framework/java/android/media/MediaParser.java
index 202decc3bfe7..596ad1e830e2 100644
--- a/apex/media/framework/java/android/media/MediaParser.java
+++ b/apex/media/framework/java/android/media/MediaParser.java
@@ -22,12 +22,14 @@ import android.annotation.Nullable;
import android.annotation.StringDef;
import android.media.MediaCodec.CryptoInfo;
import android.text.TextUtils;
+import android.util.Log;
import android.util.Pair;
import android.util.SparseArray;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.ParserException;
+import com.google.android.exoplayer2.drm.DrmInitData.SchemeData;
import com.google.android.exoplayer2.extractor.DefaultExtractorInput;
import com.google.android.exoplayer2.extractor.Extractor;
import com.google.android.exoplayer2.extractor.ExtractorInput;
@@ -59,6 +61,8 @@ import java.io.EOFException;
import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collections;
@@ -66,6 +70,7 @@ import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
+import java.util.UUID;
/**
* Parses media container formats and extracts contained media samples and metadata.
@@ -707,11 +712,14 @@ public final class MediaParser {
// Private constants.
+ private static final String TAG = "MediaParser";
private static final Map<String, ExtractorFactory> EXTRACTOR_FACTORIES_BY_NAME;
private static final Map<String, Class> EXPECTED_TYPE_BY_PARAMETER_NAME;
private static final String TS_MODE_SINGLE_PMT = "single_pmt";
private static final String TS_MODE_MULTI_PMT = "multi_pmt";
private static final String TS_MODE_HLS = "hls";
+ @Nullable
+ private static final Constructor<DrmInitData.SchemeInitData> SCHEME_INIT_DATA_CONSTRUCTOR;
// Instance creation methods.
@@ -851,6 +859,7 @@ public final class MediaParser {
private ExtractorInput mExtractorInput;
private long mPendingSeekPosition;
private long mPendingSeekTimeMicros;
+ private boolean mLoggedSchemeInitDataCreationException;
// Public methods.
@@ -1187,6 +1196,47 @@ public final class MediaParser {
}
}
+ private static final class MediaParserDrmInitData extends DrmInitData {
+
+ private final SchemeInitData[] mSchemeDatas;
+
+ private MediaParserDrmInitData(com.google.android.exoplayer2.drm.DrmInitData exoDrmInitData)
+ throws IllegalAccessException, InstantiationException, InvocationTargetException {
+ mSchemeDatas = new SchemeInitData[exoDrmInitData.schemeDataCount];
+ for (int i = 0; i < mSchemeDatas.length; i++) {
+ mSchemeDatas[i] = toFrameworkSchemeInitData(exoDrmInitData.get(i));
+ }
+ }
+
+ @Override
+ @Nullable
+ public SchemeInitData get(UUID schemeUuid) {
+ for (SchemeInitData schemeInitData : mSchemeDatas) {
+ if (schemeInitData.uuid.equals(schemeUuid)) {
+ return schemeInitData;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public SchemeInitData getSchemeInitDataAt(int index) {
+ return mSchemeDatas[index];
+ }
+
+ @Override
+ public int getSchemeInitDataCount() {
+ return mSchemeDatas.length;
+ }
+
+ private static DrmInitData.SchemeInitData toFrameworkSchemeInitData(
+ SchemeData exoSchemeData)
+ throws IllegalAccessException, InvocationTargetException, InstantiationException {
+ return SCHEME_INIT_DATA_CONSTRUCTOR.newInstance(
+ exoSchemeData.uuid, exoSchemeData.mimeType, exoSchemeData.data);
+ }
+ }
+
private final class ExtractorOutputAdapter implements ExtractorOutput {
private final SparseArray<TrackOutput> mTrackOutputAdapters;
@@ -1373,6 +1423,8 @@ public final class MediaParser {
setOptionalMediaFormatInt(result, MediaFormat.KEY_PCM_ENCODING, format.pcmEncoding);
setOptionalMediaFormatInt(result, MediaFormat.KEY_ROTATION, format.rotationDegrees);
setOptionalMediaFormatInt(result, MediaFormat.KEY_SAMPLE_RATE, format.sampleRate);
+ setOptionalMediaFormatInt(
+ result, MediaFormat.KEY_CAPTION_SERVICE_NUMBER, format.accessibilityChannel);
int selectionFlags = format.selectionFlags;
result.setInteger(
@@ -1398,15 +1450,16 @@ public final class MediaParser {
result.setInteger(MediaFormat.KEY_PIXEL_ASPECT_RATIO_HEIGHT, parHeight);
result.setFloat("pixel-width-height-ratio-float", format.pixelWidthHeightRatio);
}
-
+ if (format.drmInitData != null) {
+ // The crypto mode is propagated along with sample metadata. We also include it in the
+ // format for convenient use from ExoPlayer.
+ result.setString("crypto-mode-fourcc", format.drmInitData.schemeType);
+ }
// LACK OF SUPPORT FOR:
- // format.accessibilityChannel;
// format.containerMimeType;
// format.id;
// format.metadata;
- // format.roleFlags;
// format.stereoMode;
- // format.subsampleOffsetUs;
return result;
}
@@ -1423,10 +1476,19 @@ public final class MediaParser {
}
}
- private static DrmInitData toFrameworkDrmInitData(
- com.google.android.exoplayer2.drm.DrmInitData drmInitData) {
- // TODO: Implement.
- return null;
+ private DrmInitData toFrameworkDrmInitData(
+ com.google.android.exoplayer2.drm.DrmInitData exoDrmInitData) {
+ try {
+ return exoDrmInitData != null && SCHEME_INIT_DATA_CONSTRUCTOR != null
+ ? new MediaParserDrmInitData(exoDrmInitData)
+ : null;
+ } catch (Throwable e) {
+ if (!mLoggedSchemeInitDataCreationException) {
+ mLoggedSchemeInitDataCreationException = true;
+ Log.e(TAG, "Unable to create SchemeInitData instance.");
+ }
+ return null;
+ }
}
private static CryptoInfo toCryptoInfo(TrackOutput.CryptoData encryptionData) {
@@ -1496,5 +1558,17 @@ public final class MediaParser {
expectedTypeByParameterName.put(PARAMETER_TS_DETECT_ACCESS_UNITS, Boolean.class);
expectedTypeByParameterName.put(PARAMETER_TS_ENABLE_HDMV_DTS_AUDIO_STREAMS, Boolean.class);
EXPECTED_TYPE_BY_PARAMETER_NAME = Collections.unmodifiableMap(expectedTypeByParameterName);
+
+ // TODO: Use constructor statically when available.
+ Constructor<DrmInitData.SchemeInitData> constructor;
+ try {
+ constructor =
+ DrmInitData.SchemeInitData.class.getConstructor(
+ UUID.class, String.class, byte[].class);
+ } catch (Throwable e) {
+ Log.e(TAG, "Unable to get SchemeInitData constructor.");
+ constructor = null;
+ }
+ SCHEME_INIT_DATA_CONSTRUCTOR = constructor;
}
}