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

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

Merge "API that allows usage of MediaCodec APIs without polling."

parents bca57ee5 aba67139
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -12845,6 +12845,7 @@ package android.media {
    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 void setNotificationCallback(android.media.MediaCodec.NotificationCallback);
    method public final void setParameters(android.os.Bundle);
    method public final void setVideoScalingMode(int);
    method public final void signalEndOfInputStream();
@@ -12894,6 +12895,10 @@ package android.media {
    field public int numSubSamples;
  }
  public static abstract interface MediaCodec.NotificationCallback {
    method public abstract void onCodecNotify(android.media.MediaCodec);
  }
  public final class MediaCodecInfo {
    method public final android.media.MediaCodecInfo.CodecCapabilities getCapabilitiesForType(java.lang.String);
    method public final java.lang.String getName();
@@ -52412,7 +52417,7 @@ package org.json {
    method public java.lang.String getString(java.lang.String) throws org.json.JSONException;
    method public boolean has(java.lang.String);
    method public boolean isNull(java.lang.String);
    method public java.util.Iterator keys();
    method public java.util.Iterator<java.lang.String> keys();
    method public int length();
    method public org.json.JSONArray names();
    method public static java.lang.String numberToString(java.lang.Number) throws org.json.JSONException;
+64 −1
Original line number Diff line number Diff line
@@ -21,6 +21,9 @@ import android.media.MediaCodecList;
import android.media.MediaCrypto;
import android.media.MediaFormat;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.view.Surface;

import java.io.IOException;
@@ -173,6 +176,33 @@ final public class MediaCodec {
     */
    public static final int BUFFER_FLAG_END_OF_STREAM         = 4;

    private EventHandler mEventHandler;
    private NotificationCallback mNotificationCallback;

    static final int EVENT_NOTIFY = 1;

    private class EventHandler extends Handler {
        private MediaCodec mCodec;

        public EventHandler(MediaCodec codec, Looper looper) {
            super(looper);
            mCodec = codec;
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case EVENT_NOTIFY:
                {
                    if (mNotificationCallback != null) {
                        mNotificationCallback.onCodecNotify(mCodec);
                    }
                    break;
                }
            }
        }
    }

    /**
     * Instantiate a decoder supporting input data of the given mime type.
     *
@@ -228,6 +258,15 @@ final public class MediaCodec {

    private MediaCodec(
            String name, boolean nameIsType, boolean encoder) {
        Looper looper;
        if ((looper = Looper.myLooper()) != null) {
            mEventHandler = new EventHandler(this, looper);
        } else if ((looper = Looper.getMainLooper()) != null) {
            mEventHandler = new EventHandler(this, looper);
        } else {
            mEventHandler = null;
        }

        native_setup(name, nameIsType, encoder);
    }

@@ -308,7 +347,15 @@ final public class MediaCodec {
     * To ensure that it is available to other client call {@link #release}
     * and don't just rely on garbage collection to eventually do this for you.
     */
    public native final void stop();
    public final void stop() {
        native_stop();

        if (mEventHandler != null) {
            mEventHandler.removeMessages(EVENT_NOTIFY);
        }
    }

    private native final void native_stop();

    /**
     * Flush both input and output ports of the component, all indices
@@ -639,6 +686,22 @@ final public class MediaCodec {
        setParameters(keys, values);
    }

    public void setNotificationCallback(NotificationCallback cb) {
        mNotificationCallback = cb;
    }

    public interface NotificationCallback {
        void onCodecNotify(MediaCodec codec);
    }

    private void postEventFromNative(
            int what, int arg1, int arg2, Object obj) {
        if (mEventHandler != null) {
            Message msg = mEventHandler.obtainMessage(what, arg1, arg2, obj);
            mEventHandler.sendMessage(msg);
        }
    }

    private native final void setParameters(String[] keys, Object[] values);

    /**
+117 −10
Original line number Diff line number Diff line
@@ -51,6 +51,10 @@ enum {
    DEQUEUE_INFO_OUTPUT_BUFFERS_CHANGED     = -3,
};

enum {
    EVENT_NOTIFY = 1,
};

struct CryptoErrorCodes {
    jint cryptoErrorNoKey;
    jint cryptoErrorKeyExpired;
@@ -59,6 +63,7 @@ struct CryptoErrorCodes {

struct fields_t {
    jfieldID context;
    jmethodID postEventFromNativeID;
    jfieldID cryptoInfoNumSubSamplesID;
    jfieldID cryptoInfoNumBytesOfClearDataID;
    jfieldID cryptoInfoNumBytesOfEncryptedDataID;
@@ -75,7 +80,9 @@ JMediaCodec::JMediaCodec(
        JNIEnv *env, jobject thiz,
        const char *name, bool nameIsType, bool encoder)
    : mClass(NULL),
      mObject(NULL) {
      mObject(NULL),
      mGeneration(1),
      mRequestedActivityNotification(false) {
    jclass clazz = env->GetObjectClass(thiz);
    CHECK(clazz != NULL);

@@ -87,7 +94,7 @@ JMediaCodec::JMediaCodec(

    mLooper->start(
            false,      // runOnCallingThread
            false,       // canCallJava
            true,       // canCallJava
            PRIORITY_FOREGROUND);

    if (nameIsType) {
@@ -101,6 +108,10 @@ status_t JMediaCodec::initCheck() const {
    return mCodec != NULL ? OK : NO_INIT;
}

void JMediaCodec::registerSelf() {
    mLooper->registerHandler(this);
}

JMediaCodec::~JMediaCodec() {
    if (mCodec != NULL) {
        mCodec->release();
@@ -122,7 +133,8 @@ status_t JMediaCodec::configure(
        int flags) {
    sp<Surface> client;
    if (bufferProducer != NULL) {
        mSurfaceTextureClient = new Surface(bufferProducer, true /* controlledByApp */);
        mSurfaceTextureClient =
            new Surface(bufferProducer, true /* controlledByApp */);
    } else {
        mSurfaceTextureClient.clear();
    }
@@ -136,13 +148,32 @@ status_t JMediaCodec::createInputSurface(
}

status_t JMediaCodec::start() {
    return mCodec->start();
    status_t err = mCodec->start();

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

    mActivityNotification = new AMessage(kWhatActivityNotify, id());
    mActivityNotification->setInt32("generation", mGeneration);

    requestActivityNotification();

    return err;
}

status_t JMediaCodec::stop() {
    mSurfaceTextureClient.clear();

    return mCodec->stop();
    status_t err = mCodec->stop();

    sp<AMessage> msg = new AMessage(kWhatStopActivityNotifications, id());
    sp<AMessage> response;
    msg->postAndAwaitResponse(&response);

    mActivityNotification.clear();

    return err;
}

status_t JMediaCodec::flush() {
@@ -174,7 +205,11 @@ status_t JMediaCodec::queueSecureInputBuffer(
}

status_t JMediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) {
    return mCodec->dequeueInputBuffer(index, timeoutUs);
    status_t err = mCodec->dequeueInputBuffer(index, timeoutUs);

    requestActivityNotification();

    return err;
}

status_t JMediaCodec::dequeueOutputBuffer(
@@ -182,9 +217,12 @@ status_t JMediaCodec::dequeueOutputBuffer(
    size_t size, offset;
    int64_t timeUs;
    uint32_t flags;
    status_t err;
    if ((err = mCodec->dequeueOutputBuffer(
                    index, &offset, &size, &timeUs, &flags, timeoutUs)) != OK) {
    status_t err = mCodec->dequeueOutputBuffer(
            index, &offset, &size, &timeUs, &flags, timeoutUs);

    requestActivityNotification();

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

@@ -320,6 +358,67 @@ void JMediaCodec::setVideoScalingMode(int mode) {
    }
}

void JMediaCodec::onMessageReceived(const sp<AMessage> &msg) {
    switch (msg->what()) {
        case kWhatRequestActivityNotifications:
        {
            if (mRequestedActivityNotification) {
                break;
            }

            mCodec->requestActivityNotification(mActivityNotification);
            mRequestedActivityNotification = true;
            break;
        }

        case kWhatActivityNotify:
        {
            {
                int32_t generation;
                CHECK(msg->findInt32("generation", &generation));

                if (generation != mGeneration) {
                    // stale
                    break;
                }

                mRequestedActivityNotification = false;
            }

            JNIEnv *env = AndroidRuntime::getJNIEnv();
            env->CallVoidMethod(
                    mObject,
                    gFields.postEventFromNativeID,
                    EVENT_NOTIFY,
                    0 /* arg1 */,
                    0 /* arg2 */,
                    NULL /* obj */);

            break;
        }

        case kWhatStopActivityNotifications:
        {
            uint32_t replyID;
            CHECK(msg->senderAwaitsResponse(&replyID));

            ++mGeneration;
            mRequestedActivityNotification = false;

            sp<AMessage> response = new AMessage;
            response->postReply(replyID);
            break;
        }

        default:
            TRESPASS();
    }
}

void JMediaCodec::requestActivityNotification() {
    (new AMessage(kWhatRequestActivityNotifications, id()))->post();
}

}  // namespace android

////////////////////////////////////////////////////////////////////////////////
@@ -888,6 +987,12 @@ static void android_media_MediaCodec_native_init(JNIEnv *env) {
    gFields.context = env->GetFieldID(clazz.get(), "mNativeContext", "J");
    CHECK(gFields.context != NULL);

    gFields.postEventFromNativeID =
        env->GetMethodID(
                clazz.get(), "postEventFromNative", "(IIILjava/lang/Object;)V");

    CHECK(gFields.postEventFromNativeID != NULL);

    clazz.reset(env->FindClass("android/media/MediaCodec$CryptoInfo"));
    CHECK(clazz.get() != NULL);

@@ -961,6 +1066,8 @@ static void android_media_MediaCodec_native_setup(
        return;
    }

    codec->registerSelf();

    setMediaCodec(env,thiz, codec);
}

@@ -981,7 +1088,7 @@ static JNINativeMethod gMethods[] = {
      (void *)android_media_MediaCodec_createInputSurface },

    { "start", "()V", (void *)android_media_MediaCodec_start },
    { "stop", "()V", (void *)android_media_MediaCodec_stop },
    { "native_stop", "()V", (void *)android_media_MediaCodec_stop },
    { "flush", "()V", (void *)android_media_MediaCodec_flush },

    { "queueInputBuffer", "(IIIJI)V",
+18 −2
Original line number Diff line number Diff line
@@ -21,8 +21,8 @@

#include <media/hardware/CryptoAPI.h>
#include <media/stagefright/foundation/ABase.h>
#include <media/stagefright/foundation/AHandler.h>
#include <utils/Errors.h>
#include <utils/RefBase.h>

namespace android {

@@ -34,13 +34,15 @@ struct IGraphicBufferProducer;
struct MediaCodec;
class Surface;

struct JMediaCodec : public RefBase {
struct JMediaCodec : public AHandler {
    JMediaCodec(
            JNIEnv *env, jobject thiz,
            const char *name, bool nameIsType, bool encoder);

    status_t initCheck() const;

    void registerSelf();

    status_t configure(
            const sp<AMessage> &format,
            const sp<IGraphicBufferProducer> &bufferProducer,
@@ -94,7 +96,15 @@ struct JMediaCodec : public RefBase {
protected:
    virtual ~JMediaCodec();

    virtual void onMessageReceived(const sp<AMessage> &msg);

private:
    enum {
        kWhatActivityNotify,
        kWhatRequestActivityNotifications,
        kWhatStopActivityNotifications,
    };

    jclass mClass;
    jweak mObject;
    sp<Surface> mSurfaceTextureClient;
@@ -102,6 +112,12 @@ private:
    sp<ALooper> mLooper;
    sp<MediaCodec> mCodec;

    sp<AMessage> mActivityNotification;
    int32_t mGeneration;
    bool mRequestedActivityNotification;

    void requestActivityNotification();

    DISALLOW_EVIL_CONSTRUCTORS(JMediaCodec);
};