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
4142namespace android {
@@ -129,8 +130,10 @@ status_t JMediaCodec::flush() {
129130
130131status_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
136139status_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
151155status_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
392423static 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
525561static jint android_media_MediaCodec_dequeueInputBuffer (
0 commit comments