Loading core/api/current.txt +9 −0 Original line number Diff line number Diff line Loading @@ -21345,7 +21345,9 @@ package android.media { method @NonNull public android.media.MediaFormat getOutputFormat(int); method @NonNull public android.media.MediaCodec.OutputFrame getOutputFrame(int); method @Nullable public android.media.Image getOutputImage(int); method @Nullable public android.media.MediaCodec.ParameterDescriptor getParameterDescriptor(@NonNull String); method @NonNull public android.media.MediaCodec.QueueRequest getQueueRequest(int); method @NonNull public java.util.List<java.lang.String> getSupportedVendorParameters(); method @Nullable public static android.media.Image mapHardwareBuffer(@NonNull android.hardware.HardwareBuffer); method public void queueInputBuffer(int, int, int, long, int) throws android.media.MediaCodec.CryptoException; method public void queueSecureInputBuffer(int, int, @NonNull android.media.MediaCodec.CryptoInfo, long, int) throws android.media.MediaCodec.CryptoException; Loading @@ -21365,6 +21367,8 @@ package android.media { method public void signalEndOfInputStream(); method public void start(); method public void stop(); method public void subscribeToVendorParameters(@NonNull java.util.List<java.lang.String>); method public void unsubscribeFromVendorParameters(@NonNull java.util.List<java.lang.String>); field public static final int BUFFER_FLAG_CODEC_CONFIG = 2; // 0x2 field public static final int BUFFER_FLAG_END_OF_STREAM = 4; // 0x4 field public static final int BUFFER_FLAG_KEY_FRAME = 1; // 0x1 Loading Loading @@ -21492,6 +21496,11 @@ package android.media { method public long getPresentationTimeUs(); } public class MediaCodec.ParameterDescriptor { method @NonNull public String getName(); method public int getType(); } public final class MediaCodec.QueueRequest { method public void queue(); method @NonNull public android.media.MediaCodec.QueueRequest setByteBufferParameter(@NonNull String, @NonNull java.nio.ByteBuffer); media/java/android/media/MediaCodec.java +123 −0 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; Loading Loading @@ -4690,6 +4691,128 @@ final public class MediaCodec { private native void native_enableOnFrameRenderedListener(boolean enable); /** * Returns a list of vendor parameter names. * <p> * This method can be called in any codec state except for released state. * * @return a list containing supported vendor parameters; an empty * list if no vendor parameters are supported. The order of the * parameters is arbitrary. * @throws IllegalStateException if in the Released state. */ @NonNull public List<String> getSupportedVendorParameters() { return native_getSupportedVendorParameters(); } @NonNull private native List<String> native_getSupportedVendorParameters(); /** * Contains description of a parameter. */ public class ParameterDescriptor { private ParameterDescriptor() {} /** * Returns the name of the parameter. */ @NonNull public String getName() { return mName; } /** * Returns the type of the parameter. * {@link MediaFormat#TYPE_NULL} is never returned. */ @MediaFormat.Type public int getType() { return mType; } private String mName; private @MediaFormat.Type int mType; } /** * Describe a parameter with the name. * <p> * This method can be called in any codec state except for released state. * * @param name name of the parameter to describe, typically one from * {@link #getSupportedVendorParameters}. * @return {@link ParameterDescriptor} object that describes the parameter. * {@code null} if unrecognized / not able to describe. * @throws IllegalStateException if in the Released state. */ @Nullable public ParameterDescriptor getParameterDescriptor(@NonNull String name) { return native_getParameterDescriptor(name); } @Nullable private native ParameterDescriptor native_getParameterDescriptor(@NonNull String name); /** * Subscribe to vendor parameters, so that changes to these parameters generate * output format change event. * <p> * Unrecognized parameter names or standard (non-vendor) parameter names will be ignored. * {@link #reset} also resets the list of subscribed parameters. * If a parameter in {@code names} is already subscribed, it will remain subscribed. * <p> * This method can be called in any codec state except for released state. When called in * running state with newly subscribed parameters, it takes effect no later than the * processing of the subsequently queued buffer. For the new parameters, the codec will generate * output format change event. * <p> * Note that any vendor parameters set in a {@link #configure} or * {@link #setParameters} call are automatically subscribed. * <p> * See also {@link #INFO_OUTPUT_FORMAT_CHANGED} or {@link Callback#onOutputFormatChanged} * for output format change events. * * @param names names of the vendor parameters to subscribe. This may be an empty list, * and in that case this method will not change the list of subscribed parameters. * @throws IllegalStateException if in the Released state. */ public void subscribeToVendorParameters(@NonNull List<String> names) { native_subscribeToVendorParameters(names); } private native void native_subscribeToVendorParameters(@NonNull List<String> names); /** * Unsubscribe from vendor parameters, so that changes to these parameters * no longer generate output format change event. * <p> * Unrecognized parameter names, standard (non-vendor) parameter names will be ignored. * {@link #reset} also resets the list of subscribed parameters. * If a parameter in {@code names} is already unsubscribed, it will remain unsubscribed. * <p> * This method can be called in any codec state except for released state. When called in * running state with newly unsubscribed parameters, it takes effect no later than the * processing of the subsequently queued buffer. * <p> * Note that any vendor parameters set in a {@link #configure} or * {@link #setParameters} call are automatically subscribed, and with this method * they can be unsubscribed. * <p> * See also {@link #INFO_OUTPUT_FORMAT_CHANGED} or {@link Callback#onOutputFormatChanged} * for output format change events. * * @param names names of the vendor parameters to unsubscribe. This may be an empty list, * and in that case this method will not change the list of subscribed parameters. * @throws IllegalStateException if in the Released state. */ public void unsubscribeFromVendorParameters(@NonNull List<String> names) { native_unsubscribeFromVendorParameters(names); } private native void native_unsubscribeFromVendorParameters(@NonNull List<String> names); private EventHandler getEventHandlerOn( @Nullable Handler handler, @NonNull EventHandler lastHandler) { if (handler == null) { Loading media/jni/android_media_MediaCodec.cpp +187 −0 Original line number Diff line number Diff line Loading @@ -53,6 +53,7 @@ #include <media/MediaCodecBuffer.h> #include <media/hardware/VideoAPI.h> #include <media/stagefright/CodecBase.h> #include <media/stagefright/MediaCodec.h> #include <media/stagefright/foundation/ABuffer.h> #include <media/stagefright/foundation/ADebug.h> Loading Loading @@ -84,6 +85,16 @@ enum { EVENT_FIRST_TUNNEL_FRAME_READY = 4, }; // From MediaFormat.java enum { TYPE_NULL = 0, TYPE_INTEGER = 1, TYPE_LONG = 2, TYPE_FLOAT = 3, TYPE_STRING = 4, TYPE_BYTE_BUFFER = 5, }; static struct CryptoErrorCodes { jint cryptoErrorNoKey; jint cryptoErrorKeyExpired; Loading Loading @@ -140,6 +151,8 @@ static struct { } gByteBufferInfo; static struct { jclass clazz; jmethodID ctorId; jmethodID sizeId; jmethodID getId; jmethodID addId; Loading @@ -154,6 +167,13 @@ static struct { jfieldID lockId; } gLinearBlockInfo; static struct { jclass clazz; jmethodID ctorId; jfieldID nameId; jfieldID typeId; } gDescriptorInfo; struct fields_t { jmethodID postEventFromNativeID; jmethodID lockAndGetContextID; Loading Loading @@ -937,6 +957,74 @@ void JMediaCodec::selectAudioPresentation(const int32_t presentationId, const in (void)mCodec->setParameters(msg); } status_t JMediaCodec::querySupportedVendorParameters(JNIEnv *env, jobject *namesObj) { std::vector<std::string> names; status_t status = mCodec->querySupportedVendorParameters(&names); if (status != OK) { return status; } *namesObj = env->NewObject(gArrayListInfo.clazz, gArrayListInfo.ctorId); for (const std::string &name : names) { ScopedLocalRef<jstring> nameStr{env, env->NewStringUTF(name.c_str())}; (void)env->CallBooleanMethod(*namesObj, gArrayListInfo.addId, nameStr.get()); } return OK; } status_t JMediaCodec::describeParameter(JNIEnv *env, jstring name, jobject *descObj) { const char *tmp = env->GetStringUTFChars(name, nullptr); CodecParameterDescriptor desc; status_t status = mCodec->describeParameter(tmp, &desc); env->ReleaseStringUTFChars(name, tmp); if (status != OK) { return status; } jint type = TYPE_NULL; switch (desc.type) { case AMessage::kTypeInt32: type = TYPE_INTEGER; break; case AMessage::kTypeSize: case AMessage::kTypeInt64: type = TYPE_LONG; break; case AMessage::kTypeFloat: type = TYPE_FLOAT; break; case AMessage::kTypeString: type = TYPE_STRING; break; case AMessage::kTypeBuffer: type = TYPE_BYTE_BUFFER; break; default: type = TYPE_NULL; break; } if (type == TYPE_NULL) { return BAD_VALUE; } *descObj = env->NewObject(gDescriptorInfo.clazz, gDescriptorInfo.ctorId); env->SetObjectField(*descObj, gDescriptorInfo.nameId, name); env->SetIntField(*descObj, gDescriptorInfo.typeId, type); return OK; } static void BuildVectorFromList(JNIEnv *env, jobject list, std::vector<std::string> *vec) { ScopedLocalRef<jclass> listClazz{env, env->FindClass("java/util/List")}; ScopedLocalRef<jclass> iterClazz{env, env->FindClass("java/util/Iterator")}; jmethodID hasNextID = env->GetMethodID(iterClazz.get(), "hasNext", "()Z"); jmethodID nextID = env->GetMethodID(iterClazz.get(), "next", "()Ljava/lang/Object;"); jobject it = env->CallObjectMethod( list, env->GetMethodID(listClazz.get(), "iterator", "()Ljava/util/Iterator;")); while (env->CallBooleanMethod(it, hasNextID)) { jstring name = (jstring)env->CallObjectMethod(it, nextID); const char *tmp = env->GetStringUTFChars(name, nullptr); vec->push_back(tmp); env->ReleaseStringUTFChars(name, tmp); } } status_t JMediaCodec::subscribeToVendorParameters(JNIEnv *env, jobject namesObj) { std::vector<std::string> names; BuildVectorFromList(env, namesObj, &names); return mCodec->subscribeToVendorParameters(names); } status_t JMediaCodec::unsubscribeFromVendorParameters(JNIEnv *env, jobject namesObj) { std::vector<std::string> names; BuildVectorFromList(env, namesObj, &names); return mCodec->unsubscribeFromVendorParameters(names); } static jthrowable createCodecException( JNIEnv *env, status_t err, int32_t actionCode, const char *msg = NULL) { ScopedLocalRef<jclass> clazz( Loading Loading @@ -2671,6 +2759,73 @@ static void android_media_MediaCodec_setAudioPresentation( codec->selectAudioPresentation((int32_t)presentationId, (int32_t)programId); } static jobject android_media_MediaCodec_getSupportedVendorParameters( JNIEnv *env, jobject thiz) { sp<JMediaCodec> codec = getMediaCodec(env, thiz); if (codec == NULL || codec->initCheck() != OK) { throwExceptionAsNecessary(env, INVALID_OPERATION); return NULL; } jobject ret = NULL; status_t status = codec->querySupportedVendorParameters(env, &ret); if (status != OK) { throwExceptionAsNecessary(env, status); } return ret; } static jobject android_media_MediaCodec_getParameterDescriptor( JNIEnv *env, jobject thiz, jstring name) { sp<JMediaCodec> codec = getMediaCodec(env, thiz); if (codec == NULL || codec->initCheck() != OK) { throwExceptionAsNecessary(env, INVALID_OPERATION); return NULL; } jobject ret = NULL; status_t status = codec->describeParameter(env, name, &ret); if (status != OK) { ret = NULL; } return ret; } static void android_media_MediaCodec_subscribeToVendorParameters( JNIEnv *env, jobject thiz, jobject names) { sp<JMediaCodec> codec = getMediaCodec(env, thiz); if (codec == NULL || codec->initCheck() != OK) { throwExceptionAsNecessary(env, INVALID_OPERATION); return; } status_t status = codec->subscribeToVendorParameters(env, names); if (status != OK) { throwExceptionAsNecessary(env, status); } return; } static void android_media_MediaCodec_unsubscribeFromVendorParameters( JNIEnv *env, jobject thiz, jobject names) { sp<JMediaCodec> codec = getMediaCodec(env, thiz); if (codec == NULL || codec->initCheck() != OK) { throwExceptionAsNecessary(env, INVALID_OPERATION); return; } status_t status = codec->unsubscribeFromVendorParameters(env, names); if (status != OK) { throwExceptionAsNecessary(env, status); } return; } static void android_media_MediaCodec_native_init(JNIEnv *env, jclass) { ScopedLocalRef<jclass> clazz( env, env->FindClass("android/media/MediaCodec")); Loading Loading @@ -2930,6 +3085,10 @@ static void android_media_MediaCodec_native_init(JNIEnv *env, jclass) { clazz.reset(env->FindClass("java/util/ArrayList")); CHECK(clazz.get() != NULL); gArrayListInfo.clazz = (jclass)env->NewGlobalRef(clazz.get()); gArrayListInfo.ctorId = env->GetMethodID(clazz.get(), "<init>", "()V"); CHECK(gArrayListInfo.ctorId != NULL); gArrayListInfo.sizeId = env->GetMethodID(clazz.get(), "size", "()I"); CHECK(gArrayListInfo.sizeId != NULL); Loading Loading @@ -2960,6 +3119,19 @@ static void android_media_MediaCodec_native_init(JNIEnv *env, jclass) { gLinearBlockInfo.lockId = env->GetFieldID(clazz.get(), "mLock", "Ljava/lang/Object;"); CHECK(gLinearBlockInfo.lockId != NULL); clazz.reset(env->FindClass("android/media/MediaCodec$ParameterDescriptor")); CHECK(clazz.get() != NULL); gDescriptorInfo.clazz = (jclass)env->NewGlobalRef(clazz.get()); gDescriptorInfo.ctorId = env->GetMethodID(clazz.get(), "<init>", "()V"); CHECK(gDescriptorInfo.ctorId != NULL); gDescriptorInfo.nameId = env->GetFieldID(clazz.get(), "mName", "Ljava/lang/String;"); CHECK(gDescriptorInfo.nameId != NULL); gDescriptorInfo.typeId = env->GetFieldID(clazz.get(), "mType", "I"); CHECK(gDescriptorInfo.typeId != NULL); } static void android_media_MediaCodec_native_setup( Loading Loading @@ -3289,6 +3461,21 @@ static const JNINativeMethod gMethods[] = { { "native_setAudioPresentation", "(II)V", (void *)android_media_MediaCodec_setAudioPresentation }, { "native_getSupportedVendorParameters", "()Ljava/util/List;", (void *)android_media_MediaCodec_getSupportedVendorParameters }, { "native_getParameterDescriptor", "(Ljava/lang/String;)Landroid/media/MediaCodec$ParameterDescriptor;", (void *)android_media_MediaCodec_getParameterDescriptor }, { "native_subscribeToVendorParameters", "(Ljava/util/List;)V", (void *)android_media_MediaCodec_subscribeToVendorParameters}, { "native_unsubscribeFromVendorParameters", "(Ljava/util/List;)V", (void *)android_media_MediaCodec_unsubscribeFromVendorParameters}, { "native_init", "()V", (void *)android_media_MediaCodec_native_init }, { "native_setup", "(Ljava/lang/String;ZZ)V", Loading media/jni/android_media_MediaCodec.h +8 −0 Original line number Diff line number Diff line Loading @@ -164,6 +164,14 @@ struct JMediaCodec : public AHandler { void selectAudioPresentation(const int32_t presentationId, const int32_t programId); status_t querySupportedVendorParameters(JNIEnv *env, jobject *names); status_t describeParameter(JNIEnv *env, jstring name, jobject *desc); status_t subscribeToVendorParameters(JNIEnv *env, jobject names); status_t unsubscribeFromVendorParameters(JNIEnv *env, jobject names); bool hasCryptoOrDescrambler() { return mHasCryptoOrDescrambler; } const sp<ICrypto> &getCrypto() { return mCrypto; } Loading Loading
core/api/current.txt +9 −0 Original line number Diff line number Diff line Loading @@ -21345,7 +21345,9 @@ package android.media { method @NonNull public android.media.MediaFormat getOutputFormat(int); method @NonNull public android.media.MediaCodec.OutputFrame getOutputFrame(int); method @Nullable public android.media.Image getOutputImage(int); method @Nullable public android.media.MediaCodec.ParameterDescriptor getParameterDescriptor(@NonNull String); method @NonNull public android.media.MediaCodec.QueueRequest getQueueRequest(int); method @NonNull public java.util.List<java.lang.String> getSupportedVendorParameters(); method @Nullable public static android.media.Image mapHardwareBuffer(@NonNull android.hardware.HardwareBuffer); method public void queueInputBuffer(int, int, int, long, int) throws android.media.MediaCodec.CryptoException; method public void queueSecureInputBuffer(int, int, @NonNull android.media.MediaCodec.CryptoInfo, long, int) throws android.media.MediaCodec.CryptoException; Loading @@ -21365,6 +21367,8 @@ package android.media { method public void signalEndOfInputStream(); method public void start(); method public void stop(); method public void subscribeToVendorParameters(@NonNull java.util.List<java.lang.String>); method public void unsubscribeFromVendorParameters(@NonNull java.util.List<java.lang.String>); field public static final int BUFFER_FLAG_CODEC_CONFIG = 2; // 0x2 field public static final int BUFFER_FLAG_END_OF_STREAM = 4; // 0x4 field public static final int BUFFER_FLAG_KEY_FRAME = 1; // 0x1 Loading Loading @@ -21492,6 +21496,11 @@ package android.media { method public long getPresentationTimeUs(); } public class MediaCodec.ParameterDescriptor { method @NonNull public String getName(); method public int getType(); } public final class MediaCodec.QueueRequest { method public void queue(); method @NonNull public android.media.MediaCodec.QueueRequest setByteBufferParameter(@NonNull String, @NonNull java.nio.ByteBuffer);
media/java/android/media/MediaCodec.java +123 −0 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; Loading Loading @@ -4690,6 +4691,128 @@ final public class MediaCodec { private native void native_enableOnFrameRenderedListener(boolean enable); /** * Returns a list of vendor parameter names. * <p> * This method can be called in any codec state except for released state. * * @return a list containing supported vendor parameters; an empty * list if no vendor parameters are supported. The order of the * parameters is arbitrary. * @throws IllegalStateException if in the Released state. */ @NonNull public List<String> getSupportedVendorParameters() { return native_getSupportedVendorParameters(); } @NonNull private native List<String> native_getSupportedVendorParameters(); /** * Contains description of a parameter. */ public class ParameterDescriptor { private ParameterDescriptor() {} /** * Returns the name of the parameter. */ @NonNull public String getName() { return mName; } /** * Returns the type of the parameter. * {@link MediaFormat#TYPE_NULL} is never returned. */ @MediaFormat.Type public int getType() { return mType; } private String mName; private @MediaFormat.Type int mType; } /** * Describe a parameter with the name. * <p> * This method can be called in any codec state except for released state. * * @param name name of the parameter to describe, typically one from * {@link #getSupportedVendorParameters}. * @return {@link ParameterDescriptor} object that describes the parameter. * {@code null} if unrecognized / not able to describe. * @throws IllegalStateException if in the Released state. */ @Nullable public ParameterDescriptor getParameterDescriptor(@NonNull String name) { return native_getParameterDescriptor(name); } @Nullable private native ParameterDescriptor native_getParameterDescriptor(@NonNull String name); /** * Subscribe to vendor parameters, so that changes to these parameters generate * output format change event. * <p> * Unrecognized parameter names or standard (non-vendor) parameter names will be ignored. * {@link #reset} also resets the list of subscribed parameters. * If a parameter in {@code names} is already subscribed, it will remain subscribed. * <p> * This method can be called in any codec state except for released state. When called in * running state with newly subscribed parameters, it takes effect no later than the * processing of the subsequently queued buffer. For the new parameters, the codec will generate * output format change event. * <p> * Note that any vendor parameters set in a {@link #configure} or * {@link #setParameters} call are automatically subscribed. * <p> * See also {@link #INFO_OUTPUT_FORMAT_CHANGED} or {@link Callback#onOutputFormatChanged} * for output format change events. * * @param names names of the vendor parameters to subscribe. This may be an empty list, * and in that case this method will not change the list of subscribed parameters. * @throws IllegalStateException if in the Released state. */ public void subscribeToVendorParameters(@NonNull List<String> names) { native_subscribeToVendorParameters(names); } private native void native_subscribeToVendorParameters(@NonNull List<String> names); /** * Unsubscribe from vendor parameters, so that changes to these parameters * no longer generate output format change event. * <p> * Unrecognized parameter names, standard (non-vendor) parameter names will be ignored. * {@link #reset} also resets the list of subscribed parameters. * If a parameter in {@code names} is already unsubscribed, it will remain unsubscribed. * <p> * This method can be called in any codec state except for released state. When called in * running state with newly unsubscribed parameters, it takes effect no later than the * processing of the subsequently queued buffer. * <p> * Note that any vendor parameters set in a {@link #configure} or * {@link #setParameters} call are automatically subscribed, and with this method * they can be unsubscribed. * <p> * See also {@link #INFO_OUTPUT_FORMAT_CHANGED} or {@link Callback#onOutputFormatChanged} * for output format change events. * * @param names names of the vendor parameters to unsubscribe. This may be an empty list, * and in that case this method will not change the list of subscribed parameters. * @throws IllegalStateException if in the Released state. */ public void unsubscribeFromVendorParameters(@NonNull List<String> names) { native_unsubscribeFromVendorParameters(names); } private native void native_unsubscribeFromVendorParameters(@NonNull List<String> names); private EventHandler getEventHandlerOn( @Nullable Handler handler, @NonNull EventHandler lastHandler) { if (handler == null) { Loading
media/jni/android_media_MediaCodec.cpp +187 −0 Original line number Diff line number Diff line Loading @@ -53,6 +53,7 @@ #include <media/MediaCodecBuffer.h> #include <media/hardware/VideoAPI.h> #include <media/stagefright/CodecBase.h> #include <media/stagefright/MediaCodec.h> #include <media/stagefright/foundation/ABuffer.h> #include <media/stagefright/foundation/ADebug.h> Loading Loading @@ -84,6 +85,16 @@ enum { EVENT_FIRST_TUNNEL_FRAME_READY = 4, }; // From MediaFormat.java enum { TYPE_NULL = 0, TYPE_INTEGER = 1, TYPE_LONG = 2, TYPE_FLOAT = 3, TYPE_STRING = 4, TYPE_BYTE_BUFFER = 5, }; static struct CryptoErrorCodes { jint cryptoErrorNoKey; jint cryptoErrorKeyExpired; Loading Loading @@ -140,6 +151,8 @@ static struct { } gByteBufferInfo; static struct { jclass clazz; jmethodID ctorId; jmethodID sizeId; jmethodID getId; jmethodID addId; Loading @@ -154,6 +167,13 @@ static struct { jfieldID lockId; } gLinearBlockInfo; static struct { jclass clazz; jmethodID ctorId; jfieldID nameId; jfieldID typeId; } gDescriptorInfo; struct fields_t { jmethodID postEventFromNativeID; jmethodID lockAndGetContextID; Loading Loading @@ -937,6 +957,74 @@ void JMediaCodec::selectAudioPresentation(const int32_t presentationId, const in (void)mCodec->setParameters(msg); } status_t JMediaCodec::querySupportedVendorParameters(JNIEnv *env, jobject *namesObj) { std::vector<std::string> names; status_t status = mCodec->querySupportedVendorParameters(&names); if (status != OK) { return status; } *namesObj = env->NewObject(gArrayListInfo.clazz, gArrayListInfo.ctorId); for (const std::string &name : names) { ScopedLocalRef<jstring> nameStr{env, env->NewStringUTF(name.c_str())}; (void)env->CallBooleanMethod(*namesObj, gArrayListInfo.addId, nameStr.get()); } return OK; } status_t JMediaCodec::describeParameter(JNIEnv *env, jstring name, jobject *descObj) { const char *tmp = env->GetStringUTFChars(name, nullptr); CodecParameterDescriptor desc; status_t status = mCodec->describeParameter(tmp, &desc); env->ReleaseStringUTFChars(name, tmp); if (status != OK) { return status; } jint type = TYPE_NULL; switch (desc.type) { case AMessage::kTypeInt32: type = TYPE_INTEGER; break; case AMessage::kTypeSize: case AMessage::kTypeInt64: type = TYPE_LONG; break; case AMessage::kTypeFloat: type = TYPE_FLOAT; break; case AMessage::kTypeString: type = TYPE_STRING; break; case AMessage::kTypeBuffer: type = TYPE_BYTE_BUFFER; break; default: type = TYPE_NULL; break; } if (type == TYPE_NULL) { return BAD_VALUE; } *descObj = env->NewObject(gDescriptorInfo.clazz, gDescriptorInfo.ctorId); env->SetObjectField(*descObj, gDescriptorInfo.nameId, name); env->SetIntField(*descObj, gDescriptorInfo.typeId, type); return OK; } static void BuildVectorFromList(JNIEnv *env, jobject list, std::vector<std::string> *vec) { ScopedLocalRef<jclass> listClazz{env, env->FindClass("java/util/List")}; ScopedLocalRef<jclass> iterClazz{env, env->FindClass("java/util/Iterator")}; jmethodID hasNextID = env->GetMethodID(iterClazz.get(), "hasNext", "()Z"); jmethodID nextID = env->GetMethodID(iterClazz.get(), "next", "()Ljava/lang/Object;"); jobject it = env->CallObjectMethod( list, env->GetMethodID(listClazz.get(), "iterator", "()Ljava/util/Iterator;")); while (env->CallBooleanMethod(it, hasNextID)) { jstring name = (jstring)env->CallObjectMethod(it, nextID); const char *tmp = env->GetStringUTFChars(name, nullptr); vec->push_back(tmp); env->ReleaseStringUTFChars(name, tmp); } } status_t JMediaCodec::subscribeToVendorParameters(JNIEnv *env, jobject namesObj) { std::vector<std::string> names; BuildVectorFromList(env, namesObj, &names); return mCodec->subscribeToVendorParameters(names); } status_t JMediaCodec::unsubscribeFromVendorParameters(JNIEnv *env, jobject namesObj) { std::vector<std::string> names; BuildVectorFromList(env, namesObj, &names); return mCodec->unsubscribeFromVendorParameters(names); } static jthrowable createCodecException( JNIEnv *env, status_t err, int32_t actionCode, const char *msg = NULL) { ScopedLocalRef<jclass> clazz( Loading Loading @@ -2671,6 +2759,73 @@ static void android_media_MediaCodec_setAudioPresentation( codec->selectAudioPresentation((int32_t)presentationId, (int32_t)programId); } static jobject android_media_MediaCodec_getSupportedVendorParameters( JNIEnv *env, jobject thiz) { sp<JMediaCodec> codec = getMediaCodec(env, thiz); if (codec == NULL || codec->initCheck() != OK) { throwExceptionAsNecessary(env, INVALID_OPERATION); return NULL; } jobject ret = NULL; status_t status = codec->querySupportedVendorParameters(env, &ret); if (status != OK) { throwExceptionAsNecessary(env, status); } return ret; } static jobject android_media_MediaCodec_getParameterDescriptor( JNIEnv *env, jobject thiz, jstring name) { sp<JMediaCodec> codec = getMediaCodec(env, thiz); if (codec == NULL || codec->initCheck() != OK) { throwExceptionAsNecessary(env, INVALID_OPERATION); return NULL; } jobject ret = NULL; status_t status = codec->describeParameter(env, name, &ret); if (status != OK) { ret = NULL; } return ret; } static void android_media_MediaCodec_subscribeToVendorParameters( JNIEnv *env, jobject thiz, jobject names) { sp<JMediaCodec> codec = getMediaCodec(env, thiz); if (codec == NULL || codec->initCheck() != OK) { throwExceptionAsNecessary(env, INVALID_OPERATION); return; } status_t status = codec->subscribeToVendorParameters(env, names); if (status != OK) { throwExceptionAsNecessary(env, status); } return; } static void android_media_MediaCodec_unsubscribeFromVendorParameters( JNIEnv *env, jobject thiz, jobject names) { sp<JMediaCodec> codec = getMediaCodec(env, thiz); if (codec == NULL || codec->initCheck() != OK) { throwExceptionAsNecessary(env, INVALID_OPERATION); return; } status_t status = codec->unsubscribeFromVendorParameters(env, names); if (status != OK) { throwExceptionAsNecessary(env, status); } return; } static void android_media_MediaCodec_native_init(JNIEnv *env, jclass) { ScopedLocalRef<jclass> clazz( env, env->FindClass("android/media/MediaCodec")); Loading Loading @@ -2930,6 +3085,10 @@ static void android_media_MediaCodec_native_init(JNIEnv *env, jclass) { clazz.reset(env->FindClass("java/util/ArrayList")); CHECK(clazz.get() != NULL); gArrayListInfo.clazz = (jclass)env->NewGlobalRef(clazz.get()); gArrayListInfo.ctorId = env->GetMethodID(clazz.get(), "<init>", "()V"); CHECK(gArrayListInfo.ctorId != NULL); gArrayListInfo.sizeId = env->GetMethodID(clazz.get(), "size", "()I"); CHECK(gArrayListInfo.sizeId != NULL); Loading Loading @@ -2960,6 +3119,19 @@ static void android_media_MediaCodec_native_init(JNIEnv *env, jclass) { gLinearBlockInfo.lockId = env->GetFieldID(clazz.get(), "mLock", "Ljava/lang/Object;"); CHECK(gLinearBlockInfo.lockId != NULL); clazz.reset(env->FindClass("android/media/MediaCodec$ParameterDescriptor")); CHECK(clazz.get() != NULL); gDescriptorInfo.clazz = (jclass)env->NewGlobalRef(clazz.get()); gDescriptorInfo.ctorId = env->GetMethodID(clazz.get(), "<init>", "()V"); CHECK(gDescriptorInfo.ctorId != NULL); gDescriptorInfo.nameId = env->GetFieldID(clazz.get(), "mName", "Ljava/lang/String;"); CHECK(gDescriptorInfo.nameId != NULL); gDescriptorInfo.typeId = env->GetFieldID(clazz.get(), "mType", "I"); CHECK(gDescriptorInfo.typeId != NULL); } static void android_media_MediaCodec_native_setup( Loading Loading @@ -3289,6 +3461,21 @@ static const JNINativeMethod gMethods[] = { { "native_setAudioPresentation", "(II)V", (void *)android_media_MediaCodec_setAudioPresentation }, { "native_getSupportedVendorParameters", "()Ljava/util/List;", (void *)android_media_MediaCodec_getSupportedVendorParameters }, { "native_getParameterDescriptor", "(Ljava/lang/String;)Landroid/media/MediaCodec$ParameterDescriptor;", (void *)android_media_MediaCodec_getParameterDescriptor }, { "native_subscribeToVendorParameters", "(Ljava/util/List;)V", (void *)android_media_MediaCodec_subscribeToVendorParameters}, { "native_unsubscribeFromVendorParameters", "(Ljava/util/List;)V", (void *)android_media_MediaCodec_unsubscribeFromVendorParameters}, { "native_init", "()V", (void *)android_media_MediaCodec_native_init }, { "native_setup", "(Ljava/lang/String;ZZ)V", Loading
media/jni/android_media_MediaCodec.h +8 −0 Original line number Diff line number Diff line Loading @@ -164,6 +164,14 @@ struct JMediaCodec : public AHandler { void selectAudioPresentation(const int32_t presentationId, const int32_t programId); status_t querySupportedVendorParameters(JNIEnv *env, jobject *names); status_t describeParameter(JNIEnv *env, jstring name, jobject *desc); status_t subscribeToVendorParameters(JNIEnv *env, jobject names); status_t unsubscribeFromVendorParameters(JNIEnv *env, jobject names); bool hasCryptoOrDescrambler() { return mHasCryptoOrDescrambler; } const sp<ICrypto> &getCrypto() { return mCrypto; } Loading