Loading api/current.txt +6 −1 Original line number Diff line number Diff line Loading @@ -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(); Loading Loading @@ -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(); Loading Loading @@ -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; media/java/android/media/MediaCodec.java +64 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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. * Loading Loading @@ -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); } Loading Loading @@ -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 Loading Loading @@ -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); /** Loading media/jni/android_media_MediaCodec.cpp +117 −10 Original line number Diff line number Diff line Loading @@ -51,6 +51,10 @@ enum { DEQUEUE_INFO_OUTPUT_BUFFERS_CHANGED = -3, }; enum { EVENT_NOTIFY = 1, }; struct CryptoErrorCodes { jint cryptoErrorNoKey; jint cryptoErrorKeyExpired; Loading @@ -59,6 +63,7 @@ struct CryptoErrorCodes { struct fields_t { jfieldID context; jmethodID postEventFromNativeID; jfieldID cryptoInfoNumSubSamplesID; jfieldID cryptoInfoNumBytesOfClearDataID; jfieldID cryptoInfoNumBytesOfEncryptedDataID; Loading @@ -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); Loading @@ -87,7 +94,7 @@ JMediaCodec::JMediaCodec( mLooper->start( false, // runOnCallingThread false, // canCallJava true, // canCallJava PRIORITY_FOREGROUND); if (nameIsType) { Loading @@ -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(); Loading @@ -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(); } Loading @@ -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() { Loading Loading @@ -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( Loading @@ -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; } Loading Loading @@ -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 //////////////////////////////////////////////////////////////////////////////// Loading Loading @@ -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); Loading Loading @@ -961,6 +1066,8 @@ static void android_media_MediaCodec_native_setup( return; } codec->registerSelf(); setMediaCodec(env,thiz, codec); } Loading @@ -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", Loading media/jni/android_media_MediaCodec.h +18 −2 Original line number Diff line number Diff line Loading @@ -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 { Loading @@ -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, Loading Loading @@ -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; Loading @@ -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); }; Loading Loading
api/current.txt +6 −1 Original line number Diff line number Diff line Loading @@ -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(); Loading Loading @@ -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(); Loading Loading @@ -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;
media/java/android/media/MediaCodec.java +64 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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. * Loading Loading @@ -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); } Loading Loading @@ -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 Loading Loading @@ -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); /** Loading
media/jni/android_media_MediaCodec.cpp +117 −10 Original line number Diff line number Diff line Loading @@ -51,6 +51,10 @@ enum { DEQUEUE_INFO_OUTPUT_BUFFERS_CHANGED = -3, }; enum { EVENT_NOTIFY = 1, }; struct CryptoErrorCodes { jint cryptoErrorNoKey; jint cryptoErrorKeyExpired; Loading @@ -59,6 +63,7 @@ struct CryptoErrorCodes { struct fields_t { jfieldID context; jmethodID postEventFromNativeID; jfieldID cryptoInfoNumSubSamplesID; jfieldID cryptoInfoNumBytesOfClearDataID; jfieldID cryptoInfoNumBytesOfEncryptedDataID; Loading @@ -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); Loading @@ -87,7 +94,7 @@ JMediaCodec::JMediaCodec( mLooper->start( false, // runOnCallingThread false, // canCallJava true, // canCallJava PRIORITY_FOREGROUND); if (nameIsType) { Loading @@ -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(); Loading @@ -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(); } Loading @@ -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() { Loading Loading @@ -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( Loading @@ -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; } Loading Loading @@ -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 //////////////////////////////////////////////////////////////////////////////// Loading Loading @@ -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); Loading Loading @@ -961,6 +1066,8 @@ static void android_media_MediaCodec_native_setup( return; } codec->registerSelf(); setMediaCodec(env,thiz, codec); } Loading @@ -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", Loading
media/jni/android_media_MediaCodec.h +18 −2 Original line number Diff line number Diff line Loading @@ -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 { Loading @@ -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, Loading Loading @@ -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; Loading @@ -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); }; Loading