diff options
Diffstat (limited to 'media')
-rw-r--r-- | media/java/android/media/MediaCodec.java | 20 | ||||
-rw-r--r-- | media/jni/android_media_MediaCodec.cpp | 54 | ||||
-rw-r--r-- | media/jni/android_media_MediaCodec.h | 7 |
3 files changed, 68 insertions, 13 deletions
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java index 2efacd8..258760f 100644 --- a/media/java/android/media/MediaCodec.java +++ b/media/java/android/media/MediaCodec.java @@ -280,6 +280,19 @@ final public class MediaCodec { */ public native final void flush(); + public final static class CryptoException extends RuntimeException { + public CryptoException(int errorCode, String detailMessage) { + super(detailMessage); + mErrorCode = errorCode; + } + + public int getErrorCode() { + return mErrorCode; + } + + private int mErrorCode; + } + /** After filling a range of the input buffer at the specified index * submit it to the component. * @@ -304,10 +317,13 @@ final public class MediaCodec { * @param presentationTimeUs The time at which this buffer should be rendered. * @param flags A bitmask of flags {@link #FLAG_SYNCFRAME}, * {@link #FLAG_CODECCONFIG} or {@link #FLAG_EOS}. + * @throws CryptoException if a crypto object has been specified in + * {@link #configure} */ public native final void queueInputBuffer( int index, - int offset, int size, long presentationTimeUs, int flags); + int offset, int size, long presentationTimeUs, int flags) + throws CryptoException; /** Metadata describing the structure of a (at least partially) encrypted * input sample. @@ -361,7 +377,7 @@ final public class MediaCodec { int offset, CryptoInfo info, long presentationTimeUs, - int flags); + int flags) throws CryptoException; /** Returns the index of an input buffer to be filled with valid data * or -1 if no such buffer is currently available. diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp index a120a2f..8009fb5 100644 --- a/media/jni/android_media_MediaCodec.cpp +++ b/media/jni/android_media_MediaCodec.cpp @@ -36,6 +36,7 @@ #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/foundation/ALooper.h> #include <media/stagefright/foundation/AMessage.h> +#include <media/stagefright/foundation/AString.h> #include <media/stagefright/MediaErrors.h> namespace android { @@ -129,8 +130,10 @@ status_t JMediaCodec::flush() { status_t JMediaCodec::queueInputBuffer( size_t index, - size_t offset, size_t size, int64_t timeUs, uint32_t flags) { - return mCodec->queueInputBuffer(index, offset, size, timeUs, flags); + size_t offset, size_t size, int64_t timeUs, uint32_t flags, + AString *errorDetailMsg) { + return mCodec->queueInputBuffer( + index, offset, size, timeUs, flags, errorDetailMsg); } status_t JMediaCodec::queueSecureInputBuffer( @@ -142,10 +145,11 @@ status_t JMediaCodec::queueSecureInputBuffer( const uint8_t iv[16], CryptoPlugin::Mode mode, int64_t presentationTimeUs, - uint32_t flags) { + uint32_t flags, + AString *errorDetailMsg) { return mCodec->queueSecureInputBuffer( index, offset, subSamples, numSubSamples, key, iv, mode, - presentationTimeUs, flags); + presentationTimeUs, flags, errorDetailMsg); } status_t JMediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) { @@ -251,7 +255,31 @@ static void android_media_MediaCodec_release(JNIEnv *env, jobject thiz) { setMediaCodec(env, thiz, NULL); } -static jint throwExceptionAsNecessary(JNIEnv *env, status_t err) { +static void throwCryptoException(JNIEnv *env, status_t err, const char *msg) { + jclass clazz = env->FindClass("android/media/MediaCodec$CryptoException"); + CHECK(clazz != NULL); + + jmethodID constructID = + env->GetMethodID(clazz, "<init>", "(ILjava/lang/String;)V"); + CHECK(constructID != NULL); + + jstring msgObj = env->NewStringUTF(msg != NULL ? msg : "Unknown Error"); + + jthrowable exception = + (jthrowable)env->NewObject(clazz, constructID, err, msgObj); + + env->Throw(exception); +} + +static jint throwExceptionAsNecessary( + JNIEnv *env, status_t err, const char *msg = NULL) { + if (err >= ERROR_DRM_WV_VENDOR_MIN && err <= ERROR_DRM_WV_VENDOR_MAX) { + // We'll throw our custom MediaCodec.CryptoException + + throwCryptoException(env, err, msg); + return 0; + } + switch (err) { case OK: return 0; @@ -383,10 +411,13 @@ static void android_media_MediaCodec_queueInputBuffer( return; } + AString errorDetailMsg; + status_t err = codec->queueInputBuffer( - index, offset, size, timestampUs, flags); + index, offset, size, timestampUs, flags, &errorDetailMsg); - throwExceptionAsNecessary(env, err); + throwExceptionAsNecessary( + env, err, errorDetailMsg.empty() ? NULL : errorDetailMsg.c_str()); } static void android_media_MediaCodec_queueSecureInputBuffer( @@ -497,13 +528,17 @@ static void android_media_MediaCodec_queueSecureInputBuffer( } } + AString errorDetailMsg; + if (err == OK) { err = codec->queueSecureInputBuffer( index, offset, subSamples, numSubSamples, (const uint8_t *)key, (const uint8_t *)iv, (CryptoPlugin::Mode)mode, - timestampUs, flags); + timestampUs, + flags, + &errorDetailMsg); } if (iv != NULL) { @@ -519,7 +554,8 @@ static void android_media_MediaCodec_queueSecureInputBuffer( delete[] subSamples; subSamples = NULL; - throwExceptionAsNecessary(env, err); + throwExceptionAsNecessary( + env, err, errorDetailMsg.empty() ? NULL : errorDetailMsg.c_str()); } static jint android_media_MediaCodec_dequeueInputBuffer( diff --git a/media/jni/android_media_MediaCodec.h b/media/jni/android_media_MediaCodec.h index 570c33b..e2688be 100644 --- a/media/jni/android_media_MediaCodec.h +++ b/media/jni/android_media_MediaCodec.h @@ -28,6 +28,7 @@ namespace android { struct ALooper; struct AMessage; +struct AString; struct ICrypto; struct ISurfaceTexture; struct MediaCodec; @@ -52,7 +53,8 @@ struct JMediaCodec : public RefBase { status_t queueInputBuffer( size_t index, - size_t offset, size_t size, int64_t timeUs, uint32_t flags); + size_t offset, size_t size, int64_t timeUs, uint32_t flags, + AString *errorDetailMsg); status_t queueSecureInputBuffer( size_t index, @@ -63,7 +65,8 @@ struct JMediaCodec : public RefBase { const uint8_t iv[16], CryptoPlugin::Mode mode, int64_t presentationTimeUs, - uint32_t flags); + uint32_t flags, + AString *errorDetailMsg); status_t dequeueInputBuffer(size_t *index, int64_t timeoutUs); |