DO NOT MERGE MediaCodec: add methods to query/subscribe vendor parameters am: 197e1a7f5e
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1646730 Change-Id: I741906abf08c9cec198478d50662cdba94580f95
This commit is contained in:
@@ -20445,7 +20445,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;
|
||||
@@ -20464,6 +20466,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
|
||||
@@ -20585,6 +20589,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);
|
||||
|
||||
@@ -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;
|
||||
@@ -4554,6 +4555,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) {
|
||||
|
||||
@@ -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>
|
||||
@@ -82,6 +83,16 @@ enum {
|
||||
EVENT_FRAME_RENDERED = 3,
|
||||
};
|
||||
|
||||
// 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;
|
||||
@@ -138,6 +149,8 @@ static struct {
|
||||
} gByteBufferInfo;
|
||||
|
||||
static struct {
|
||||
jclass clazz;
|
||||
jmethodID ctorId;
|
||||
jmethodID sizeId;
|
||||
jmethodID getId;
|
||||
jmethodID addId;
|
||||
@@ -152,6 +165,13 @@ static struct {
|
||||
jfieldID lockId;
|
||||
} gLinearBlockInfo;
|
||||
|
||||
static struct {
|
||||
jclass clazz;
|
||||
jmethodID ctorId;
|
||||
jfieldID nameId;
|
||||
jfieldID typeId;
|
||||
} gDescriptorInfo;
|
||||
|
||||
struct fields_t {
|
||||
jmethodID postEventFromNativeID;
|
||||
jmethodID lockAndGetContextID;
|
||||
@@ -922,6 +942,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(
|
||||
@@ -2602,6 +2690,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"));
|
||||
@@ -2861,6 +3016,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);
|
||||
@@ -2891,6 +3050,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(
|
||||
@@ -3217,6 +3389,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",
|
||||
|
||||
@@ -162,6 +162,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; }
|
||||
|
||||
protected:
|
||||
|
||||
Reference in New Issue
Block a user