Skip to content

Commit 0d1ba15

Browse files
theandi666Android (Google) Code Review
authored andcommitted
Merge "DRM errors signaled by the CryptoPlugin are now visible to MediaCodec clients"
2 parents dca2e81 + bfc56f4 commit 0d1ba15

File tree

4 files changed

+75
-15
lines changed

4 files changed

+75
-15
lines changed

api/current.txt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10973,8 +10973,8 @@ package android.media {
1097310973
method public java.nio.ByteBuffer[] getInputBuffers();
1097410974
method public java.nio.ByteBuffer[] getOutputBuffers();
1097510975
method public final java.util.Map<java.lang.String, java.lang.Object> getOutputFormat();
10976-
method public final void queueInputBuffer(int, int, int, long, int);
10977-
method public final void queueSecureInputBuffer(int, int, android.media.MediaCodec.CryptoInfo, long, int);
10976+
method public final void queueInputBuffer(int, int, int, long, int) throws android.media.MediaCodec.CryptoException;
10977+
method public final void queueSecureInputBuffer(int, int, android.media.MediaCodec.CryptoInfo, long, int) throws android.media.MediaCodec.CryptoException;
1097810978
method public final void release();
1097910979
method public final void releaseOutputBuffer(int, boolean);
1098010980
method public final void start();
@@ -10999,6 +10999,11 @@ package android.media {
1099910999
field public int size;
1100011000
}
1100111001

11002+
public static final class MediaCodec.CryptoException extends java.lang.RuntimeException {
11003+
ctor public MediaCodec.CryptoException(int, java.lang.String);
11004+
method public int getErrorCode();
11005+
}
11006+
1100211007
public static final class MediaCodec.CryptoInfo {
1100311008
ctor public MediaCodec.CryptoInfo();
1100411009
method public void set(int, int[], int[], byte[], byte[], int);

media/java/android/media/MediaCodec.java

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,19 @@ private native final void native_configure(
280280
*/
281281
public native final void flush();
282282

283+
public final static class CryptoException extends RuntimeException {
284+
public CryptoException(int errorCode, String detailMessage) {
285+
super(detailMessage);
286+
mErrorCode = errorCode;
287+
}
288+
289+
public int getErrorCode() {
290+
return mErrorCode;
291+
}
292+
293+
private int mErrorCode;
294+
}
295+
283296
/** After filling a range of the input buffer at the specified index
284297
* submit it to the component.
285298
*
@@ -304,10 +317,13 @@ private native final void native_configure(
304317
* @param presentationTimeUs The time at which this buffer should be rendered.
305318
* @param flags A bitmask of flags {@link #FLAG_SYNCFRAME},
306319
* {@link #FLAG_CODECCONFIG} or {@link #FLAG_EOS}.
320+
* @throws CryptoException if a crypto object has been specified in
321+
* {@link #configure}
307322
*/
308323
public native final void queueInputBuffer(
309324
int index,
310-
int offset, int size, long presentationTimeUs, int flags);
325+
int offset, int size, long presentationTimeUs, int flags)
326+
throws CryptoException;
311327

312328
/** Metadata describing the structure of a (at least partially) encrypted
313329
* input sample.
@@ -361,7 +377,7 @@ public native final void queueSecureInputBuffer(
361377
int offset,
362378
CryptoInfo info,
363379
long presentationTimeUs,
364-
int flags);
380+
int flags) throws CryptoException;
365381

366382
/** Returns the index of an input buffer to be filled with valid data
367383
* or -1 if no such buffer is currently available.

media/jni/android_media_MediaCodec.cpp

Lines changed: 45 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include <media/stagefright/foundation/ADebug.h>
3737
#include <media/stagefright/foundation/ALooper.h>
3838
#include <media/stagefright/foundation/AMessage.h>
39+
#include <media/stagefright/foundation/AString.h>
3940
#include <media/stagefright/MediaErrors.h>
4041

4142
namespace android {
@@ -129,8 +130,10 @@ status_t JMediaCodec::flush() {
129130

130131
status_t JMediaCodec::queueInputBuffer(
131132
size_t index,
132-
size_t offset, size_t size, int64_t timeUs, uint32_t flags) {
133-
return mCodec->queueInputBuffer(index, offset, size, timeUs, flags);
133+
size_t offset, size_t size, int64_t timeUs, uint32_t flags,
134+
AString *errorDetailMsg) {
135+
return mCodec->queueInputBuffer(
136+
index, offset, size, timeUs, flags, errorDetailMsg);
134137
}
135138

136139
status_t JMediaCodec::queueSecureInputBuffer(
@@ -142,10 +145,11 @@ status_t JMediaCodec::queueSecureInputBuffer(
142145
const uint8_t iv[16],
143146
CryptoPlugin::Mode mode,
144147
int64_t presentationTimeUs,
145-
uint32_t flags) {
148+
uint32_t flags,
149+
AString *errorDetailMsg) {
146150
return mCodec->queueSecureInputBuffer(
147151
index, offset, subSamples, numSubSamples, key, iv, mode,
148-
presentationTimeUs, flags);
152+
presentationTimeUs, flags, errorDetailMsg);
149153
}
150154

151155
status_t JMediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) {
@@ -251,7 +255,31 @@ static void android_media_MediaCodec_release(JNIEnv *env, jobject thiz) {
251255
setMediaCodec(env, thiz, NULL);
252256
}
253257

254-
static jint throwExceptionAsNecessary(JNIEnv *env, status_t err) {
258+
static void throwCryptoException(JNIEnv *env, status_t err, const char *msg) {
259+
jclass clazz = env->FindClass("android/media/MediaCodec$CryptoException");
260+
CHECK(clazz != NULL);
261+
262+
jmethodID constructID =
263+
env->GetMethodID(clazz, "<init>", "(ILjava/lang/String;)V");
264+
CHECK(constructID != NULL);
265+
266+
jstring msgObj = env->NewStringUTF(msg != NULL ? msg : "Unknown Error");
267+
268+
jthrowable exception =
269+
(jthrowable)env->NewObject(clazz, constructID, err, msgObj);
270+
271+
env->Throw(exception);
272+
}
273+
274+
static jint throwExceptionAsNecessary(
275+
JNIEnv *env, status_t err, const char *msg = NULL) {
276+
if (err >= ERROR_DRM_WV_VENDOR_MIN && err <= ERROR_DRM_WV_VENDOR_MAX) {
277+
// We'll throw our custom MediaCodec.CryptoException
278+
279+
throwCryptoException(env, err, msg);
280+
return 0;
281+
}
282+
255283
switch (err) {
256284
case OK:
257285
return 0;
@@ -383,10 +411,13 @@ static void android_media_MediaCodec_queueInputBuffer(
383411
return;
384412
}
385413

414+
AString errorDetailMsg;
415+
386416
status_t err = codec->queueInputBuffer(
387-
index, offset, size, timestampUs, flags);
417+
index, offset, size, timestampUs, flags, &errorDetailMsg);
388418

389-
throwExceptionAsNecessary(env, err);
419+
throwExceptionAsNecessary(
420+
env, err, errorDetailMsg.empty() ? NULL : errorDetailMsg.c_str());
390421
}
391422

392423
static void android_media_MediaCodec_queueSecureInputBuffer(
@@ -497,13 +528,17 @@ static void android_media_MediaCodec_queueSecureInputBuffer(
497528
}
498529
}
499530

531+
AString errorDetailMsg;
532+
500533
if (err == OK) {
501534
err = codec->queueSecureInputBuffer(
502535
index, offset,
503536
subSamples, numSubSamples,
504537
(const uint8_t *)key, (const uint8_t *)iv,
505538
(CryptoPlugin::Mode)mode,
506-
timestampUs, flags);
539+
timestampUs,
540+
flags,
541+
&errorDetailMsg);
507542
}
508543

509544
if (iv != NULL) {
@@ -519,7 +554,8 @@ static void android_media_MediaCodec_queueSecureInputBuffer(
519554
delete[] subSamples;
520555
subSamples = NULL;
521556

522-
throwExceptionAsNecessary(env, err);
557+
throwExceptionAsNecessary(
558+
env, err, errorDetailMsg.empty() ? NULL : errorDetailMsg.c_str());
523559
}
524560

525561
static jint android_media_MediaCodec_dequeueInputBuffer(

media/jni/android_media_MediaCodec.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ namespace android {
2828

2929
struct ALooper;
3030
struct AMessage;
31+
struct AString;
3132
struct ICrypto;
3233
struct ISurfaceTexture;
3334
struct MediaCodec;
@@ -52,7 +53,8 @@ struct JMediaCodec : public RefBase {
5253

5354
status_t queueInputBuffer(
5455
size_t index,
55-
size_t offset, size_t size, int64_t timeUs, uint32_t flags);
56+
size_t offset, size_t size, int64_t timeUs, uint32_t flags,
57+
AString *errorDetailMsg);
5658

5759
status_t queueSecureInputBuffer(
5860
size_t index,
@@ -63,7 +65,8 @@ struct JMediaCodec : public RefBase {
6365
const uint8_t iv[16],
6466
CryptoPlugin::Mode mode,
6567
int64_t presentationTimeUs,
66-
uint32_t flags);
68+
uint32_t flags,
69+
AString *errorDetailMsg);
6770

6871
status_t dequeueInputBuffer(size_t *index, int64_t timeoutUs);
6972

0 commit comments

Comments
 (0)