Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0d1ba150 authored by Andreas Huber's avatar Andreas Huber Committed by Android (Google) Code Review
Browse files

Merge "DRM errors signaled by the CryptoPlugin are now visible to MediaCodec clients"

parents dca2e81b bfc56f49
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -10973,8 +10973,8 @@ package android.media {
    method public java.nio.ByteBuffer[] getInputBuffers();
    method public java.nio.ByteBuffer[] getOutputBuffers();
    method public final java.util.Map<java.lang.String, java.lang.Object> getOutputFormat();
    method public final void queueInputBuffer(int, int, int, long, int);
    method public final void queueSecureInputBuffer(int, int, android.media.MediaCodec.CryptoInfo, long, int);
    method public final void queueInputBuffer(int, int, int, long, int) throws android.media.MediaCodec.CryptoException;
    method public final void queueSecureInputBuffer(int, int, android.media.MediaCodec.CryptoInfo, long, int) throws android.media.MediaCodec.CryptoException;
    method public final void release();
    method public final void releaseOutputBuffer(int, boolean);
    method public final void start();
@@ -10999,6 +10999,11 @@ package android.media {
    field public int size;
  }
  public static final class MediaCodec.CryptoException extends java.lang.RuntimeException {
    ctor public MediaCodec.CryptoException(int, java.lang.String);
    method public int getErrorCode();
  }
  public static final class MediaCodec.CryptoInfo {
    ctor public MediaCodec.CryptoInfo();
    method public void set(int, int[], int[], byte[], byte[], int);
+18 −2
Original line number Diff line number Diff line
@@ -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.
+45 −9
Original line number Diff line number Diff line
@@ -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(
+5 −2
Original line number Diff line number Diff line
@@ -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);