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

Commit 991ae64f authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "fix slow get caps -- DO NOT MERGE" into pi-dev

parents 6d39e550 a0b72a6c
Loading
Loading
Loading
Loading
+20 −2
Original line number Diff line number Diff line
@@ -1602,7 +1602,9 @@ final public class MediaCodec {
    private EventHandler mCallbackHandler;
    private Callback mCallback;
    private OnFrameRenderedListener mOnFrameRenderedListener;
    private Object mListenerLock = new Object();
    private final Object mListenerLock = new Object();
    private MediaCodecInfo mCodecInfo;
    private final Object mCodecInfoLock = new Object();

    private static final int EVENT_CALLBACK = 1;
    private static final int EVENT_SET_CALLBACK = 2;
@@ -3469,8 +3471,24 @@ final public class MediaCodec {
     */
    @NonNull
    public MediaCodecInfo getCodecInfo() {
        return MediaCodecList.getInfoFor(getName());
        // Get the codec name first. If the codec is already released,
        // IllegalStateException will be thrown here.
        String name = getName();
        synchronized (mCodecInfoLock) {
            if (mCodecInfo == null) {
                // Get the codec info for this codec itself first. Only initialize
                // the full codec list if this somehow fails because it can be slow.
                mCodecInfo = getOwnCodecInfo();
                if (mCodecInfo == null) {
                    mCodecInfo = MediaCodecList.getInfoFor(name);
                }
            }
            return mCodecInfo;
        }
    }

    @NonNull
    private native final MediaCodecInfo getOwnCodecInfo();

    @NonNull
    private native final ByteBuffer[] getBuffers(boolean input);
+25 −18
Original line number Diff line number Diff line
@@ -829,14 +829,24 @@ public final class MediaCodecInfo {

        /** @hide */
        public CodecCapabilities dup() {
            return new CodecCapabilities(
                // clone writable arrays
                Arrays.copyOf(profileLevels, profileLevels.length),
                Arrays.copyOf(colorFormats, colorFormats.length),
                isEncoder(),
                mFlagsVerified,
                mDefaultFormat,
                mCapabilitiesInfo);
            CodecCapabilities caps = new CodecCapabilities();

            // profileLevels and colorFormats may be modified by client.
            caps.profileLevels = Arrays.copyOf(profileLevels, profileLevels.length);
            caps.colorFormats = Arrays.copyOf(colorFormats, colorFormats.length);

            caps.mMime = mMime;
            caps.mMaxSupportedInstances = mMaxSupportedInstances;
            caps.mFlagsRequired = mFlagsRequired;
            caps.mFlagsSupported = mFlagsSupported;
            caps.mFlagsVerified = mFlagsVerified;
            caps.mAudioCaps = mAudioCaps;
            caps.mVideoCaps = mVideoCaps;
            caps.mEncoderCaps = mEncoderCaps;
            caps.mDefaultFormat = mDefaultFormat;
            caps.mCapabilitiesInfo = mCapabilitiesInfo;

            return caps;
        }

        /**
@@ -898,13 +908,13 @@ public final class MediaCodecInfo {

            if (mMime.toLowerCase().startsWith("audio/")) {
                mAudioCaps = AudioCapabilities.create(info, this);
                mAudioCaps.setDefaultFormat(mDefaultFormat);
                mAudioCaps.getDefaultFormat(mDefaultFormat);
            } else if (mMime.toLowerCase().startsWith("video/")) {
                mVideoCaps = VideoCapabilities.create(info, this);
            }
            if (encoder) {
                mEncoderCaps = EncoderCapabilities.create(info, this);
                mEncoderCaps.setDefaultFormat(mDefaultFormat);
                mEncoderCaps.getDefaultFormat(mDefaultFormat);
            }

            final Map<String, Object> global = MediaCodecList.getGlobalSettings();
@@ -990,8 +1000,7 @@ public final class MediaCodecInfo {
            return caps;
        }

        /** @hide */
        public void init(MediaFormat info, CodecCapabilities parent) {
        private void init(MediaFormat info, CodecCapabilities parent) {
            mParent = parent;
            initWithPlatformLimits();
            applyLevelLimits();
@@ -1171,7 +1180,7 @@ public final class MediaCodecInfo {
        }

        /** @hide */
        public void setDefaultFormat(MediaFormat format) {
        public void getDefaultFormat(MediaFormat format) {
            // report settings that have only a single choice
            if (mBitrateRange.getLower().equals(mBitrateRange.getUpper())) {
                format.setInteger(MediaFormat.KEY_BIT_RATE, mBitrateRange.getLower());
@@ -1585,8 +1594,7 @@ public final class MediaCodecInfo {
            return caps;
        }

        /** @hide */
        public void init(MediaFormat info, CodecCapabilities parent) {
        private void init(MediaFormat info, CodecCapabilities parent) {
            mParent = parent;
            initWithPlatformLimits();
            applyLevelLimits();
@@ -2707,8 +2715,7 @@ public final class MediaCodecInfo {
            return caps;
        }

        /** @hide */
        public void init(MediaFormat info, CodecCapabilities parent) {
        private void init(MediaFormat info, CodecCapabilities parent) {
            // no support for complexity or quality yet
            mParent = parent;
            mComplexityRange = Range.create(0, 0);
@@ -2789,7 +2796,7 @@ public final class MediaCodecInfo {
        }

        /** @hide */
        public void setDefaultFormat(MediaFormat format) {
        public void getDefaultFormat(MediaFormat format) {
            // don't list trivial quality/complexity as default for now
            if (!mQualityRange.getUpper().equals(mQualityRange.getLower())
                    && mDefaultQuality != null) {
+153 −0
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@
#include "android_util_Binder.h"
#include "jni.h"
#include <nativehelper/JNIHelp.h>
#include <nativehelper/ScopedLocalRef.h>

#include <android/hardware/cas/native/1.0/IDescrambler.h>

@@ -98,6 +99,13 @@ static struct {
    jint AesCbc;
} gCryptoModes;

static struct {
    jclass capsClazz;
    jmethodID capsCtorId;
    jclass profileLevelClazz;
    jfieldID profileField;
    jfieldID levelField;
} gCodecInfo;

struct fields_t {
    jfieldID context;
@@ -625,6 +633,103 @@ status_t JMediaCodec::getName(JNIEnv *env, jstring *nameStr) const {
    return OK;
}

static jobject getCodecCapabilitiesObject(
        JNIEnv *env, const char *mime, bool isEncoder,
        const sp<MediaCodecInfo::Capabilities> &capabilities) {
    Vector<MediaCodecInfo::ProfileLevel> profileLevels;
    Vector<uint32_t> colorFormats;

    sp<AMessage> defaultFormat = new AMessage();
    defaultFormat->setString("mime", mime);

    capabilities->getSupportedColorFormats(&colorFormats);
    capabilities->getSupportedProfileLevels(&profileLevels);
    uint32_t flags = capabilities->getFlags();
    sp<AMessage> details = capabilities->getDetails();

    jobject defaultFormatObj = NULL;
    if (ConvertMessageToMap(env, defaultFormat, &defaultFormatObj)) {
        return NULL;
    }
    ScopedLocalRef<jobject> defaultFormatRef(env, defaultFormatObj);

    jobject detailsObj = NULL;
    if (ConvertMessageToMap(env, details, &detailsObj)) {
        return NULL;
    }
    ScopedLocalRef<jobject> detailsRef(env, detailsObj);

    ScopedLocalRef<jobjectArray> profileLevelArray(env, env->NewObjectArray(
            profileLevels.size(), gCodecInfo.profileLevelClazz, NULL));

    for (size_t i = 0; i < profileLevels.size(); ++i) {
        const MediaCodecInfo::ProfileLevel &src = profileLevels.itemAt(i);

        ScopedLocalRef<jobject> srcRef(env, env->AllocObject(
                gCodecInfo.profileLevelClazz));

        env->SetIntField(srcRef.get(), gCodecInfo.profileField, src.mProfile);
        env->SetIntField(srcRef.get(), gCodecInfo.levelField, src.mLevel);

        env->SetObjectArrayElement(profileLevelArray.get(), i, srcRef.get());
    }

    ScopedLocalRef<jintArray> colorFormatsArray(
            env, env->NewIntArray(colorFormats.size()));
    for (size_t i = 0; i < colorFormats.size(); ++i) {
        jint val = colorFormats.itemAt(i);
        env->SetIntArrayRegion(colorFormatsArray.get(), i, 1, &val);
    }

    return env->NewObject(
            gCodecInfo.capsClazz, gCodecInfo.capsCtorId,
            profileLevelArray.get(), colorFormatsArray.get(), isEncoder, flags,
            defaultFormatRef.get(), detailsRef.get());
}

status_t JMediaCodec::getCodecInfo(JNIEnv *env, jobject *codecInfoObject) const {
    sp<MediaCodecInfo> codecInfo;

    status_t err = mCodec->getCodecInfo(&codecInfo);

    if (err != OK) {
        return err;
    }

    ScopedLocalRef<jstring> nameObject(env,
            env->NewStringUTF(codecInfo->getCodecName()));

    bool isEncoder = codecInfo->isEncoder();

    Vector<AString> mimes;
    codecInfo->getSupportedMimes(&mimes);

    ScopedLocalRef<jobjectArray> capsArrayObj(env,
        env->NewObjectArray(mimes.size(), gCodecInfo.capsClazz, NULL));

    for (size_t i = 0; i < mimes.size(); i++) {
        const sp<MediaCodecInfo::Capabilities> caps =
                codecInfo->getCapabilitiesFor(mimes[i].c_str());

        ScopedLocalRef<jobject> capsObj(env, getCodecCapabilitiesObject(
                env, mimes[i].c_str(), isEncoder, caps));

        env->SetObjectArrayElement(capsArrayObj.get(), i, capsObj.get());
    }

    ScopedLocalRef<jclass> codecInfoClazz(env,
            env->FindClass("android/media/MediaCodecInfo"));
    CHECK(codecInfoClazz.get() != NULL);

    jmethodID codecInfoCtorID = env->GetMethodID(codecInfoClazz.get(), "<init>",
            "(Ljava/lang/String;Z[Landroid/media/MediaCodecInfo$CodecCapabilities;)V");

    *codecInfoObject = env->NewObject(codecInfoClazz.get(), codecInfoCtorID,
            nameObject.get(), isEncoder, capsArrayObj.get());

    return OK;
}

status_t JMediaCodec::getMetrics(JNIEnv *, MediaAnalyticsItem * &reply) const {

    status_t status = mCodec->getMetrics(reply);
@@ -1665,6 +1770,29 @@ static jobject android_media_MediaCodec_getName(
    return NULL;
}

static jobject android_media_MediaCodec_getOwnCodecInfo(
        JNIEnv *env, jobject thiz) {
    ALOGV("android_media_MediaCodec_getOwnCodecInfo");

    sp<JMediaCodec> codec = getMediaCodec(env, thiz);

    if (codec == NULL) {
        throwExceptionAsNecessary(env, INVALID_OPERATION);
        return NULL;
    }

    jobject codecInfoObj;
    status_t err = codec->getCodecInfo(env, &codecInfoObj);

    if (err == OK) {
        return codecInfoObj;
    }

    throwExceptionAsNecessary(env, err);

    return NULL;
}

static jobject
android_media_MediaCodec_native_getMetrics(JNIEnv *env, jobject thiz)
{
@@ -1877,6 +2005,28 @@ static void android_media_MediaCodec_native_init(JNIEnv *env) {
    field = env->GetFieldID(clazz.get(), "mPersistentObject", "J");
    CHECK(field != NULL);
    gPersistentSurfaceClassInfo.mPersistentObject = field;

    clazz.reset(env->FindClass("android/media/MediaCodecInfo$CodecCapabilities"));
    CHECK(clazz.get() != NULL);
    gCodecInfo.capsClazz = (jclass)env->NewGlobalRef(clazz.get());

    method = env->GetMethodID(clazz.get(), "<init>",
            "([Landroid/media/MediaCodecInfo$CodecProfileLevel;[IZI"
            "Ljava/util/Map;Ljava/util/Map;)V");
    CHECK(method != NULL);
    gCodecInfo.capsCtorId = method;

    clazz.reset(env->FindClass("android/media/MediaCodecInfo$CodecProfileLevel"));
    CHECK(clazz.get() != NULL);
    gCodecInfo.profileLevelClazz = (jclass)env->NewGlobalRef(clazz.get());

    field = env->GetFieldID(clazz.get(), "profile", "I");
    CHECK(field != NULL);
    gCodecInfo.profileField = field;

    field = env->GetFieldID(clazz.get(), "level", "I");
    CHECK(field != NULL);
    gCodecInfo.levelField = field;
}

static void android_media_MediaCodec_native_setup(
@@ -2002,6 +2152,9 @@ static const JNINativeMethod gMethods[] = {
    { "getName", "()Ljava/lang/String;",
      (void *)android_media_MediaCodec_getName },

    { "getOwnCodecInfo", "()Landroid/media/MediaCodecInfo;",
        (void *)android_media_MediaCodec_getOwnCodecInfo },

    { "native_getMetrics", "()Landroid/os/PersistableBundle;",
      (void *)android_media_MediaCodec_native_getMetrics},

+2 −0
Original line number Diff line number Diff line
@@ -120,6 +120,8 @@ struct JMediaCodec : public AHandler {

    status_t getName(JNIEnv *env, jstring *name) const;

    status_t getCodecInfo(JNIEnv *env, jobject *codecInfo) const;

    status_t getMetrics(JNIEnv *env, MediaAnalyticsItem * &reply) const;

    status_t setParameters(const sp<AMessage> &params);