Skip to content

Commit 91befdc

Browse files
committed
Information required to decrypt buffers is now packaged into MediaCodec.CryptoInfo
New API on MediaExtractor to retrieve a CryptoInfo structure where applicable. Change-Id: I18edfc9ac56a4544c8f17cba24401b96dacbff7d related-to-bug: 6275919
1 parent 26fbf27 commit 91befdc

File tree

6 files changed

+262
-31
lines changed

6 files changed

+262
-31
lines changed

api/current.txt

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10960,7 +10960,7 @@ package android.media {
1096010960
method public java.nio.ByteBuffer[] getOutputBuffers();
1096110961
method public final java.util.Map<java.lang.String, java.lang.Object> getOutputFormat();
1096210962
method public final void queueInputBuffer(int, int, int, long, int);
10963-
method public final void queueSecureInputBuffer(int, int, int[], int[], int, byte[], byte[], int, long, int);
10963+
method public final void queueSecureInputBuffer(int, int, android.media.MediaCodec.CryptoInfo, long, int);
1096410964
method public final void release();
1096510965
method public final void releaseOutputBuffer(int, boolean);
1096610966
method public final void start();
@@ -10985,6 +10985,17 @@ package android.media {
1098510985
field public int size;
1098610986
}
1098710987

10988+
public static final class MediaCodec.CryptoInfo {
10989+
ctor public MediaCodec.CryptoInfo();
10990+
method public void set(int, int[], int[], byte[], byte[], int);
10991+
field public byte[] iv;
10992+
field public byte[] key;
10993+
field public int mode;
10994+
field public int[] numBytesOfClearData;
10995+
field public int[] numBytesOfEncryptedData;
10996+
field public int numSubSamples;
10997+
}
10998+
1098810999
public final class MediaCodecList {
1098911000
method public static final int countCodecs();
1099011001
method public static final android.media.MediaCodecList.CodecCapabilities getCodecCapabilities(int, java.lang.String);
@@ -11016,6 +11027,7 @@ package android.media {
1101611027
ctor public MediaExtractor();
1101711028
method public boolean advance();
1101811029
method public int countTracks();
11030+
method public boolean getSampleCryptoInfo(android.media.MediaCodec.CryptoInfo);
1101911031
method public int getSampleFlags();
1102011032
method public long getSampleTime();
1102111033
method public int getSampleTrackIndex();

media/java/android/media/MediaCodec.java

Lines changed: 43 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -309,36 +309,57 @@ public native final void queueInputBuffer(
309309
int index,
310310
int offset, int size, long presentationTimeUs, int flags);
311311

312+
/** Metadata describing the structure of a (at least partially) encrypted
313+
* input sample.
314+
* A buffer's data is considered to be partitioned into "subSamples",
315+
* each subSample starts with a (potentially empty) run of plain,
316+
* unencrypted bytes followed by a (also potentially empty) run of
317+
* encrypted bytes.
318+
* numBytesOfClearData can be null to indicate that all data is encrypted.
319+
*/
320+
public final static class CryptoInfo {
321+
public void set(
322+
int newNumSubSamples,
323+
int[] newNumBytesOfClearData,
324+
int[] newNumBytesOfEncryptedData,
325+
byte[] newKey,
326+
byte[] newIV,
327+
int newMode) {
328+
numSubSamples = newNumSubSamples;
329+
numBytesOfClearData = newNumBytesOfClearData;
330+
numBytesOfEncryptedData = newNumBytesOfEncryptedData;
331+
key = newKey;
332+
iv = newIV;
333+
mode = newMode;
334+
}
335+
336+
/** The number of subSamples that make up the buffer's contents. */
337+
public int numSubSamples;
338+
/** The number of leading unencrypted bytes in each subSample. */
339+
public int[] numBytesOfClearData;
340+
/** The number of trailing encrypted bytes in each subSample. */
341+
public int[] numBytesOfEncryptedData;
342+
/** A 16-byte opaque key */
343+
public byte[] key;
344+
/** A 16-byte initialization vector */
345+
public byte[] iv;
346+
/** The type of encryption that has been applied */
347+
public int mode;
348+
};
349+
312350
/** Similar to {@link #queueInputBuffer} but submits a buffer that is
313-
* potentially encrypted. The buffer's data is considered to be
314-
* partitioned into "subSamples", each subSample starts with a
315-
* (potentially empty) run of plain, unencrypted bytes followed
316-
* by a (also potentially empty) run of encrypted bytes.
351+
* potentially encrypted.
317352
* @param index The index of a client-owned input buffer previously returned
318353
* in a call to {@link #dequeueInputBuffer}.
319354
* @param offset The byte offset into the input buffer at which the data starts.
320-
* @param numBytesOfClearData The number of leading unencrypted bytes in
321-
* each subSample.
322-
* @param numBytesOfEncryptedData The number of trailing encrypted bytes
323-
* in each subSample.
324-
* @param numSubSamples The number of subSamples that make up the
325-
* buffer's contents.
326-
* @param key A 16-byte opaque key
327-
* @param iv A 16-byte initialization vector
328-
* @param mode The type of encryption that has been applied
329-
*
330-
* Either numBytesOfClearData or numBytesOfEncryptedData (but not both)
331-
* can be null to indicate that all respective sizes are 0.
355+
* @param presentationTimeUs The time at which this buffer should be rendered.
356+
* @param flags A bitmask of flags {@link #FLAG_SYNCFRAME},
357+
* {@link #FLAG_CODECCONFIG} or {@link #FLAG_EOS}.
332358
*/
333359
public native final void queueSecureInputBuffer(
334360
int index,
335361
int offset,
336-
int[] numBytesOfClearData,
337-
int[] numBytesOfEncryptedData,
338-
int numSubSamples,
339-
byte[] key,
340-
byte[] iv,
341-
int mode,
362+
CryptoInfo info,
342363
long presentationTimeUs,
343364
int flags);
344365

media/java/android/media/MediaExtractor.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import android.content.ContentResolver;
2020
import android.content.Context;
2121
import android.content.res.AssetFileDescriptor;
22+
import android.media.MediaCodec;
2223
import android.net.Uri;
2324
import java.io.FileDescriptor;
2425
import java.io.IOException;
@@ -235,6 +236,15 @@ protected void finalize() {
235236
/** Returns the current sample's flags. */
236237
public native int getSampleFlags();
237238

239+
/** If the sample flags indicate that the current sample is at least
240+
* partially encrypted, this call returns relevant information about
241+
* the structure of the sample data required for decryption.
242+
* @param info The android.media.MediaCodec.CryptoInfo structure
243+
* to be filled in.
244+
* @return true iff the sample flags contain {@link #SAMPLE_FLAG_ENCRYPTED}
245+
*/
246+
public native boolean getSampleCryptoInfo(MediaCodec.CryptoInfo info);
247+
238248
private static native final void native_init();
239249
private native final void native_setup();
240250
private native final void native_finalize();

media/jni/android_media_MediaCodec.cpp

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,13 @@ enum {
4949

5050
struct fields_t {
5151
jfieldID context;
52+
53+
jfieldID cryptoInfoNumSubSamplesID;
54+
jfieldID cryptoInfoNumBytesOfClearDataID;
55+
jfieldID cryptoInfoNumBytesOfEncryptedDataID;
56+
jfieldID cryptoInfoKeyID;
57+
jfieldID cryptoInfoIVID;
58+
jfieldID cryptoInfoModeID;
5259
};
5360

5461
static fields_t gFields;
@@ -387,12 +394,7 @@ static void android_media_MediaCodec_queueSecureInputBuffer(
387394
jobject thiz,
388395
jint index,
389396
jint offset,
390-
jintArray numBytesOfClearDataObj,
391-
jintArray numBytesOfEncryptedDataObj,
392-
jint numSubSamples,
393-
jbyteArray keyObj,
394-
jbyteArray ivObj,
395-
jint mode,
397+
jobject cryptoInfoObj,
396398
jlong timestampUs,
397399
jint flags) {
398400
ALOGV("android_media_MediaCodec_queueSecureInputBuffer");
@@ -404,6 +406,25 @@ static void android_media_MediaCodec_queueSecureInputBuffer(
404406
return;
405407
}
406408

409+
jint numSubSamples =
410+
env->GetIntField(cryptoInfoObj, gFields.cryptoInfoNumSubSamplesID);
411+
412+
jintArray numBytesOfClearDataObj =
413+
(jintArray)env->GetObjectField(
414+
cryptoInfoObj, gFields.cryptoInfoNumBytesOfClearDataID);
415+
416+
jintArray numBytesOfEncryptedDataObj =
417+
(jintArray)env->GetObjectField(
418+
cryptoInfoObj, gFields.cryptoInfoNumBytesOfEncryptedDataID);
419+
420+
jbyteArray keyObj =
421+
(jbyteArray)env->GetObjectField(cryptoInfoObj, gFields.cryptoInfoKeyID);
422+
423+
jbyteArray ivObj =
424+
(jbyteArray)env->GetObjectField(cryptoInfoObj, gFields.cryptoInfoIVID);
425+
426+
jint mode = env->GetIntField(cryptoInfoObj, gFields.cryptoInfoModeID);
427+
407428
status_t err = OK;
408429

409430
CryptoPlugin::SubSample *subSamples = NULL;
@@ -612,6 +633,30 @@ static void android_media_MediaCodec_native_init(JNIEnv *env) {
612633

613634
gFields.context = env->GetFieldID(clazz, "mNativeContext", "I");
614635
CHECK(gFields.context != NULL);
636+
637+
clazz = env->FindClass("android/media/MediaCodec$CryptoInfo");
638+
CHECK(clazz != NULL);
639+
640+
gFields.cryptoInfoNumSubSamplesID =
641+
env->GetFieldID(clazz, "numSubSamples", "I");
642+
CHECK(gFields.cryptoInfoNumSubSamplesID != NULL);
643+
644+
gFields.cryptoInfoNumBytesOfClearDataID =
645+
env->GetFieldID(clazz, "numBytesOfClearData", "[I");
646+
CHECK(gFields.cryptoInfoNumBytesOfClearDataID != NULL);
647+
648+
gFields.cryptoInfoNumBytesOfEncryptedDataID =
649+
env->GetFieldID(clazz, "numBytesOfEncryptedData", "[I");
650+
CHECK(gFields.cryptoInfoNumBytesOfEncryptedDataID != NULL);
651+
652+
gFields.cryptoInfoKeyID = env->GetFieldID(clazz, "key", "[B");
653+
CHECK(gFields.cryptoInfoKeyID != NULL);
654+
655+
gFields.cryptoInfoIVID = env->GetFieldID(clazz, "iv", "[B");
656+
CHECK(gFields.cryptoInfoIVID != NULL);
657+
658+
gFields.cryptoInfoModeID = env->GetFieldID(clazz, "mode", "I");
659+
CHECK(gFields.cryptoInfoModeID != NULL);
615660
}
616661

617662
static void android_media_MediaCodec_native_setup(
@@ -666,7 +711,7 @@ static JNINativeMethod gMethods[] = {
666711
{ "queueInputBuffer", "(IIIJI)V",
667712
(void *)android_media_MediaCodec_queueInputBuffer },
668713

669-
{ "queueSecureInputBuffer", "(II[I[II[B[BIJI)V",
714+
{ "queueSecureInputBuffer", "(IILandroid/media/MediaCodec$CryptoInfo;JI)V",
670715
(void *)android_media_MediaCodec_queueSecureInputBuffer },
671716

672717
{ "dequeueInputBuffer", "(J)I",

0 commit comments

Comments
 (0)