diff options
author | Santiago Seifert <aquilescanta@google.com> | 2020-04-17 17:36:26 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2020-04-17 17:36:26 +0000 |
commit | 26e55eb8ab8a8a476ca63d81e5567c16443c056b (patch) | |
tree | 0f83c387429882d9c79bad797fca6837e3963d5f | |
parent | 40d714dc8d3ff70d8a4ee607903f052681abe554 (diff) | |
parent | c6955798175589f240fbacd120d289d1148aceae (diff) |
Merge "Populate some missing fields in TrackData" into rvc-dev
-rw-r--r-- | apex/media/framework/java/android/media/MediaParser.java | 90 |
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; } } |